Mercurial > dropbear
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) { |