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;