comparison dbutil.c @ 1046:b8f4b7027191 coverity

merge
author Matt Johnston <matt@ucc.asn.au>
date Tue, 24 Feb 2015 22:48:34 +0800
parents d3925ed45a85
children 01eea88963f3
comparison
equal deleted inserted replaced
1014:37c510c2ac7c 1046:b8f4b7027191
148 va_end(param); 148 va_end(param);
149 } 149 }
150 150
151 151
152 #ifdef DEBUG_TRACE 152 #ifdef DEBUG_TRACE
153
154 static double debug_start_time = -1;
155
156 void debug_start_net()
157 {
158 if (getenv("DROPBEAR_DEBUG_NET_TIMESTAMP"))
159 {
160 /* Timestamps start from first network activity */
161 struct timeval tv;
162 gettimeofday(&tv, NULL);
163 debug_start_time = tv.tv_sec + (tv.tv_usec / 1000000.0);
164 TRACE(("Resetting Dropbear TRACE timestamps"))
165 }
166 }
167
168 static double time_since_start()
169 {
170 double nowf;
171 struct timeval tv;
172 gettimeofday(&tv, NULL);
173 nowf = tv.tv_sec + (tv.tv_usec / 1000000.0);
174 if (debug_start_time < 0)
175 {
176 debug_start_time = nowf;
177 return 0;
178 }
179 return nowf - debug_start_time;
180 }
181
153 void dropbear_trace(const char* format, ...) { 182 void dropbear_trace(const char* format, ...) {
154 va_list param; 183 va_list param;
155 struct timeval tv;
156 184
157 if (!debug_trace) { 185 if (!debug_trace) {
158 return; 186 return;
159 } 187 }
160 188
161 gettimeofday(&tv, NULL);
162
163 va_start(param, format); 189 va_start(param, format);
164 fprintf(stderr, "TRACE (%d) %d.%d: ", getpid(), (int)tv.tv_sec, (int)tv.tv_usec); 190 fprintf(stderr, "TRACE (%d) %f: ", getpid(), time_since_start());
165 vfprintf(stderr, format, param); 191 vfprintf(stderr, format, param);
166 fprintf(stderr, "\n"); 192 fprintf(stderr, "\n");
167 va_end(param); 193 va_end(param);
168 } 194 }
169 195
170 void dropbear_trace2(const char* format, ...) { 196 void dropbear_trace2(const char* format, ...) {
171 static int trace_env = -1; 197 static int trace_env = -1;
172 va_list param; 198 va_list param;
173 struct timeval tv;
174 199
175 if (trace_env == -1) { 200 if (trace_env == -1) {
176 trace_env = getenv("DROPBEAR_TRACE2") ? 1 : 0; 201 trace_env = getenv("DROPBEAR_TRACE2") ? 1 : 0;
177 } 202 }
178 203
179 if (!(debug_trace && trace_env)) { 204 if (!(debug_trace && trace_env)) {
180 return; 205 return;
181 } 206 }
182 207
183 gettimeofday(&tv, NULL);
184
185 va_start(param, format); 208 va_start(param, format);
186 fprintf(stderr, "TRACE2 (%d) %d.%d: ", getpid(), (int)tv.tv_sec, (int)tv.tv_usec); 209 fprintf(stderr, "TRACE2 (%d) %f: ", getpid(), time_since_start());
187 vfprintf(stderr, format, param); 210 vfprintf(stderr, format, param);
188 fprintf(stderr, "\n"); 211 fprintf(stderr, "\n");
189 va_end(param); 212 va_end(param);
190 } 213 }
191 #endif /* DEBUG_TRACE */ 214 #endif /* DEBUG_TRACE */
388 } 411 }
389 return fd; 412 return fd;
390 } 413 }
391 #endif 414 #endif
392 415
416 #if defined(__linux__) && defined(TCP_DEFER_ACCEPT)
417 static void set_piggyback_ack(int sock) {
418 /* Undocumented Linux feature - set TCP_DEFER_ACCEPT and data will be piggybacked
419 on the 3rd packet (ack) of the TCP handshake. Saves a IP packet.
420 http://thread.gmane.org/gmane.linux.network/224627/focus=224727
421 "Piggyback the final ACK of the three way TCP connection establishment with the data" */
422 int val = 1;
423 /* No error checking, this is opportunistic */
424 int err = setsockopt(sock, IPPROTO_TCP, TCP_DEFER_ACCEPT, (void*)&val, sizeof(val));
425 if (err)
426 {
427 TRACE(("Failed setsockopt TCP_DEFER_ACCEPT: %s", strerror(errno)))
428 }
429 }
430 #endif
431
432
393 /* Connect via TCP to a host. Connection will try ipv4 or ipv6, will 433 /* Connect via TCP to a host. Connection will try ipv4 or ipv6, will
394 * return immediately if nonblocking is set. On failure, if errstring 434 * return immediately if nonblocking is set. On failure, if errstring
395 * wasn't null, it will be a newly malloced error message */ 435 * wasn't null, it will be a newly malloced error message */
396 436
397 /* TODO: maxfd */ 437 /* TODO: maxfd */
398 int connect_remote(const char* remotehost, const char* remoteport, 438 int connect_remote(const char* remotehost, const char* remoteport, char ** errstring) {
399 int nonblocking, char ** errstring) {
400 439
401 struct addrinfo *res0 = NULL, *res = NULL, hints; 440 struct addrinfo *res0 = NULL, *res = NULL, hints;
402 int sock; 441 int sock;
403 int err; 442 int err;
404 443
433 if (sock < 0) { 472 if (sock < 0) {
434 err = errno; 473 err = errno;
435 continue; 474 continue;
436 } 475 }
437 476
438 if (nonblocking) { 477 setnonblocking(sock);
439 setnonblocking(sock); 478
440 } 479 #if defined(__linux__) && defined(TCP_DEFER_ACCEPT)
480 set_piggyback_ack(sock);
481 #endif
441 482
442 if (connect(sock, res->ai_addr, res->ai_addrlen) < 0) { 483 if (connect(sock, res->ai_addr, res->ai_addrlen) < 0) {
443 if (errno == EINPROGRESS && nonblocking) { 484 if (errno == EINPROGRESS) {
444 TRACE(("Connect in progress")) 485 TRACE(("Connect in progress"))
445 break; 486 break;
446 } else { 487 } else {
447 err = errno; 488 err = errno;
448 close(sock); 489 close(sock);
452 } 493 }
453 494
454 break; /* Success */ 495 break; /* Success */
455 } 496 }
456 497
457 if (sock < 0 && !(errno == EINPROGRESS && nonblocking)) { 498 if (sock < 0 && !(errno == EINPROGRESS)) {
458 /* Failed */ 499 /* Failed */
459 if (errstring != NULL && *errstring == NULL) { 500 if (errstring != NULL && *errstring == NULL) {
460 int len; 501 int len;
461 len = 20 + strlen(strerror(err)); 502 len = 20 + strlen(strerror(err));
462 *errstring = (char*)m_malloc(len); 503 *errstring = (char*)m_malloc(len);
825 } 866 }
826 #endif 867 #endif
827 868
828 /* make sure that the socket closes */ 869 /* make sure that the socket closes */
829 void m_close(int fd) { 870 void m_close(int fd) {
871 int val;
830 872
831 if (fd == -1) { 873 if (fd == -1) {
832 return; 874 return;
833 } 875 }
834 876
835 int val;
836 do { 877 do {
837 val = close(fd); 878 val = close(fd);
838 } while (val < 0 && errno == EINTR); 879 } while (val < 0 && errno == EINTR);
839 880
840 if (val < 0 && errno != EBADF) { 881 if (val < 0 && errno != EBADF) {