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;