Mercurial > dropbear
comparison netio.c @ 1077:26c1f9b8f82e coverity
merge main
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Tue, 14 Apr 2015 20:44:30 +0800 |
parents | d92597ef089e |
children | b3b772646974 |
comparison
equal
deleted
inserted
replaced
1062:210982935887 | 1077:26c1f9b8f82e |
---|---|
74 struct msghdr message; | 74 struct msghdr message; |
75 #endif | 75 #endif |
76 | 76 |
77 for (r = c->res_iter; r; r = r->ai_next) | 77 for (r = c->res_iter; r; r = r->ai_next) |
78 { | 78 { |
79 assert(c->sock == -1); | 79 dropbear_assert(c->sock == -1); |
80 | 80 |
81 c->sock = socket(c->res_iter->ai_family, c->res_iter->ai_socktype, c->res_iter->ai_protocol); | 81 c->sock = socket(c->res_iter->ai_family, c->res_iter->ai_socktype, c->res_iter->ai_protocol); |
82 if (c->sock < 0) { | 82 if (c->sock < 0) { |
83 continue; | 83 continue; |
84 } | 84 } |
97 memset(&message, 0x0, sizeof(message)); | 97 memset(&message, 0x0, sizeof(message)); |
98 message.msg_name = r->ai_addr; | 98 message.msg_name = r->ai_addr; |
99 message.msg_namelen = r->ai_addrlen; | 99 message.msg_namelen = r->ai_addrlen; |
100 | 100 |
101 if (c->writequeue) { | 101 if (c->writequeue) { |
102 int iovlen; /* Linux msg_iovlen is a size_t */ | 102 /* 6 is arbitrary, enough to hold initial packets */ |
103 message.msg_iov = packet_queue_to_iovec(c->writequeue, &iovlen); | 103 int iovlen = 6; /* Linux msg_iovlen is a size_t */ |
104 struct iovec iov[6]; | |
105 packet_queue_to_iovec(c->writequeue, iov, &iovlen); | |
106 message.msg_iov = iov; | |
104 message.msg_iovlen = iovlen; | 107 message.msg_iovlen = iovlen; |
105 res = sendmsg(c->sock, &message, MSG_FASTOPEN); | 108 res = sendmsg(c->sock, &message, MSG_FASTOPEN); |
106 if (res < 0 && errno != EINPROGRESS) { | 109 if (res < 0 && errno != EINPROGRESS) { |
110 m_free(c->errstring); | |
111 c->errstring = m_strdup(strerror(errno)); | |
107 /* Not entirely sure which kind of errors are normal - 2.6.32 seems to | 112 /* Not entirely sure which kind of errors are normal - 2.6.32 seems to |
108 return EPIPE for any (nonblocking?) sendmsg(). just fall back */ | 113 return EPIPE for any (nonblocking?) sendmsg(). just fall back */ |
109 TRACE(("sendmsg tcp_fastopen failed, falling back. %s", strerror(errno))); | 114 TRACE(("sendmsg tcp_fastopen failed, falling back. %s", strerror(errno))); |
110 /* No kernel MSG_FASTOPEN support. Fall back below */ | 115 /* No kernel MSG_FASTOPEN support. Fall back below */ |
111 fastopen = 0; | 116 fastopen = 0; |
112 /* Set to NULL to avoid trying again */ | 117 /* Set to NULL to avoid trying again */ |
113 c->writequeue = NULL; | 118 c->writequeue = NULL; |
114 } | 119 } |
115 m_free(message.msg_iov); | |
116 packet_queue_consume(c->writequeue, res); | 120 packet_queue_consume(c->writequeue, res); |
117 } | 121 } |
118 #endif | 122 #endif |
119 | 123 |
120 /* Normal connect(), used as fallback for TCP fastopen too */ | 124 /* Normal connect(), used as fallback for TCP fastopen too */ |
122 res = connect(c->sock, r->ai_addr, r->ai_addrlen); | 126 res = connect(c->sock, r->ai_addr, r->ai_addrlen); |
123 } | 127 } |
124 | 128 |
125 if (res < 0 && errno != EINPROGRESS) { | 129 if (res < 0 && errno != EINPROGRESS) { |
126 /* failure */ | 130 /* failure */ |
131 m_free(c->errstring); | |
132 c->errstring = m_strdup(strerror(errno)); | |
127 close(c->sock); | 133 close(c->sock); |
128 c->sock = -1; | 134 c->sock = -1; |
129 continue; | 135 continue; |
130 } else { | 136 } else { |
131 /* new connection was successful, wait for it to complete */ | 137 /* new connection was successful, wait for it to complete */ |
235 TRACE(("connect to %s port %s failed.", c->remotehost, c->remoteport)) | 241 TRACE(("connect to %s port %s failed.", c->remotehost, c->remoteport)) |
236 m_close(c->sock); | 242 m_close(c->sock); |
237 c->sock = -1; | 243 c->sock = -1; |
238 | 244 |
239 m_free(c->errstring); | 245 m_free(c->errstring); |
240 c->errstring = strerror(val); | 246 c->errstring = m_strdup(strerror(val)); |
241 } else { | 247 } else { |
242 /* New connection has been established */ | 248 /* New connection has been established */ |
243 c->cb(DROPBEAR_SUCCESS, c->sock, c->cb_data, NULL); | 249 c->cb(DROPBEAR_SUCCESS, c->sock, c->cb_data, NULL); |
244 remove_connect(c, iter); | 250 remove_connect(c, iter); |
245 TRACE(("leave handle_connect_fds - success")) | 251 TRACE(("leave handle_connect_fds - success")) |
252 | 258 |
253 void connect_set_writequeue(struct dropbear_progress_connection *c, struct Queue *writequeue) { | 259 void connect_set_writequeue(struct dropbear_progress_connection *c, struct Queue *writequeue) { |
254 c->writequeue = writequeue; | 260 c->writequeue = writequeue; |
255 } | 261 } |
256 | 262 |
257 struct iovec * packet_queue_to_iovec(struct Queue *queue, int *ret_iov_count) { | 263 void packet_queue_to_iovec(struct Queue *queue, struct iovec *iov, unsigned int *iov_count) { |
258 struct iovec *iov = NULL; | |
259 struct Link *l; | 264 struct Link *l; |
260 unsigned int i; | 265 unsigned int i; |
261 int len; | 266 int len; |
262 buffer *writebuf; | 267 buffer *writebuf; |
263 | 268 |
264 #ifndef IOV_MAX | 269 #ifndef IOV_MAX |
265 #define IOV_MAX UIO_MAXIOV | 270 #define IOV_MAX UIO_MAXIOV |
266 #endif | 271 #endif |
267 | 272 |
268 *ret_iov_count = MIN(queue->count, IOV_MAX); | 273 *iov_count = MIN(MIN(queue->count, IOV_MAX), *iov_count); |
269 | 274 |
270 iov = m_malloc(sizeof(*iov) * *ret_iov_count); | 275 for (l = queue->head, i = 0; i < *iov_count; l = l->link, i++) |
271 for (l = queue->head, i = 0; l; l = l->link, i++) | |
272 { | 276 { |
273 writebuf = (buffer*)l->item; | 277 writebuf = (buffer*)l->item; |
274 len = writebuf->len - 1 - writebuf->pos; | 278 len = writebuf->len - 1 - writebuf->pos; |
275 dropbear_assert(len > 0); | 279 dropbear_assert(len > 0); |
276 TRACE2(("write_packet writev #%d type %d len %d/%d", i, writebuf->data[writebuf->len-1], | 280 TRACE2(("write_packet writev #%d type %d len %d/%d", i, writebuf->data[writebuf->len-1], |
277 len, writebuf->len-1)) | 281 len, writebuf->len-1)) |
278 iov[i].iov_base = buf_getptr(writebuf, len); | 282 iov[i].iov_base = buf_getptr(writebuf, len); |
279 iov[i].iov_len = len; | 283 iov[i].iov_len = len; |
280 } | 284 } |
281 | |
282 return iov; | |
283 } | 285 } |
284 | 286 |
285 void packet_queue_consume(struct Queue *queue, ssize_t written) { | 287 void packet_queue_consume(struct Queue *queue, ssize_t written) { |
286 buffer *writebuf; | 288 buffer *writebuf; |
287 int len; | 289 int len; |