Mercurial > dropbear
comparison netio.c @ 1072:686cd3e8e13e
avoid malloc for iovec
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Fri, 20 Mar 2015 22:53:32 +0800 |
parents | ce21d0bfaf98 |
children | 88043f9d40bd |
comparison
equal
deleted
inserted
replaced
1067:ce21d0bfaf98 | 1072:686cd3e8e13e |
---|---|
70 struct addrinfo *r; | 70 struct addrinfo *r; |
71 int res = 0; | 71 int res = 0; |
72 int fastopen = 0; | 72 int fastopen = 0; |
73 #ifdef DROPBEAR_TCP_FAST_OPEN | 73 #ifdef DROPBEAR_TCP_FAST_OPEN |
74 struct msghdr message; | 74 struct msghdr message; |
75 struct iovec message; | |
75 #endif | 76 #endif |
76 | 77 |
77 for (r = c->res_iter; r; r = r->ai_next) | 78 for (r = c->res_iter; r; r = r->ai_next) |
78 { | 79 { |
79 dropbear_assert(c->sock == -1); | 80 dropbear_assert(c->sock == -1); |
97 memset(&message, 0x0, sizeof(message)); | 98 memset(&message, 0x0, sizeof(message)); |
98 message.msg_name = r->ai_addr; | 99 message.msg_name = r->ai_addr; |
99 message.msg_namelen = r->ai_addrlen; | 100 message.msg_namelen = r->ai_addrlen; |
100 | 101 |
101 if (c->writequeue) { | 102 if (c->writequeue) { |
102 int iovlen; /* Linux msg_iovlen is a size_t */ | 103 /* 6 is arbitrary, enough to hold initial packets */ |
103 message.msg_iov = packet_queue_to_iovec(c->writequeue, &iovlen); | 104 int iovlen = 6; /* Linux msg_iovlen is a size_t */ |
105 struct iov[6]; | |
106 packet_queue_to_iovec(c->writequeue, iov, &iovlen); | |
107 message.msg_iov = &iov; | |
104 message.msg_iovlen = iovlen; | 108 message.msg_iovlen = iovlen; |
105 res = sendmsg(c->sock, &message, MSG_FASTOPEN); | 109 res = sendmsg(c->sock, &message, MSG_FASTOPEN); |
106 if (res < 0 && errno != EINPROGRESS) { | 110 if (res < 0 && errno != EINPROGRESS) { |
107 m_free(c->errstring); | 111 m_free(c->errstring); |
108 c->errstring = m_strdup(strerror(errno)); | 112 c->errstring = m_strdup(strerror(errno)); |
112 /* No kernel MSG_FASTOPEN support. Fall back below */ | 116 /* No kernel MSG_FASTOPEN support. Fall back below */ |
113 fastopen = 0; | 117 fastopen = 0; |
114 /* Set to NULL to avoid trying again */ | 118 /* Set to NULL to avoid trying again */ |
115 c->writequeue = NULL; | 119 c->writequeue = NULL; |
116 } | 120 } |
117 m_free(message.msg_iov); | |
118 packet_queue_consume(c->writequeue, res); | 121 packet_queue_consume(c->writequeue, res); |
119 } | 122 } |
120 #endif | 123 #endif |
121 | 124 |
122 /* Normal connect(), used as fallback for TCP fastopen too */ | 125 /* Normal connect(), used as fallback for TCP fastopen too */ |
256 | 259 |
257 void connect_set_writequeue(struct dropbear_progress_connection *c, struct Queue *writequeue) { | 260 void connect_set_writequeue(struct dropbear_progress_connection *c, struct Queue *writequeue) { |
258 c->writequeue = writequeue; | 261 c->writequeue = writequeue; |
259 } | 262 } |
260 | 263 |
261 struct iovec * packet_queue_to_iovec(struct Queue *queue, int *ret_iov_count) { | 264 void packet_queue_to_iovec(struct Queue *queue, struct iovec *iov, unsigned int *iov_count) { |
262 struct iovec *iov = NULL; | |
263 struct Link *l; | 265 struct Link *l; |
264 unsigned int i; | 266 unsigned int i; |
265 int len; | 267 int len; |
266 buffer *writebuf; | 268 buffer *writebuf; |
267 | 269 |
268 #ifndef IOV_MAX | 270 #ifndef IOV_MAX |
269 #define IOV_MAX UIO_MAXIOV | 271 #define IOV_MAX UIO_MAXIOV |
270 #endif | 272 #endif |
271 | 273 |
272 *ret_iov_count = MIN(queue->count, IOV_MAX); | 274 *iov_count = MIN(MIN(queue->count, IOV_MAX), *iov_count); |
273 | 275 |
274 iov = m_malloc(sizeof(*iov) * *ret_iov_count); | |
275 for (l = queue->head, i = 0; l; l = l->link, i++) | 276 for (l = queue->head, i = 0; l; l = l->link, i++) |
276 { | 277 { |
277 writebuf = (buffer*)l->item; | 278 writebuf = (buffer*)l->item; |
278 len = writebuf->len - 1 - writebuf->pos; | 279 len = writebuf->len - 1 - writebuf->pos; |
279 dropbear_assert(len > 0); | 280 dropbear_assert(len > 0); |
280 TRACE2(("write_packet writev #%d type %d len %d/%d", i, writebuf->data[writebuf->len-1], | 281 TRACE2(("write_packet writev #%d type %d len %d/%d", i, writebuf->data[writebuf->len-1], |
281 len, writebuf->len-1)) | 282 len, writebuf->len-1)) |
282 iov[i].iov_base = buf_getptr(writebuf, len); | 283 iov[i].iov_base = buf_getptr(writebuf, len); |
283 iov[i].iov_len = len; | 284 iov[i].iov_len = len; |
284 } | 285 } |
285 | |
286 return iov; | |
287 } | 286 } |
288 | 287 |
289 void packet_queue_consume(struct Queue *queue, ssize_t written) { | 288 void packet_queue_consume(struct Queue *queue, ssize_t written) { |
290 buffer *writebuf; | 289 buffer *writebuf; |
291 int len; | 290 int len; |