diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-06-18 08:55:57 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-06-18 08:55:57 +0000 |
commit | 7679145cfa61e41099645bdeecb6a8c2743c6772 (patch) | |
tree | f130799bb1bd2f0721cb832c2dcee92b8d80c2ce | |
parent | ebd27aabaab98bef2f2d0fe0d7bf4261e5c3ffcd (diff) | |
download | busybox-w32-7679145cfa61e41099645bdeecb6a8c2743c6772.tar.gz busybox-w32-7679145cfa61e41099645bdeecb6a8c2743c6772.tar.bz2 busybox-w32-7679145cfa61e41099645bdeecb6a8c2743c6772.zip |
ping: fix write-after-allocated-mem bug
ping: use monotonic_us instead of gettimeofday: smaller code and
needs only 4 bytes in the packet
ping: display roundtrip times with 1/1000th of ms, not 1/10 ms precision.
wget: small optimization
function old new delta
pingstats 243 259 +16
sendping6 98 93 -5
sendping4 183 178 -5
.rodata 129715 129707 -8
progressmeter 867 855 -12
unpack_tail 320 272 -48
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/5 up/down: 16/-78) Total: -62 bytes
-rw-r--r-- | networking/ping.c | 63 | ||||
-rw-r--r-- | networking/wget.c | 6 |
2 files changed, 32 insertions, 37 deletions
diff --git a/networking/ping.c b/networking/ping.c index e94b7914f..c4a498cd8 100644 --- a/networking/ping.c +++ b/networking/ping.c | |||
@@ -242,8 +242,8 @@ struct globals { | |||
242 | int if_index; | 242 | int if_index; |
243 | unsigned long ntransmitted, nreceived, nrepeats, pingcount; | 243 | unsigned long ntransmitted, nreceived, nrepeats, pingcount; |
244 | uint16_t myid; | 244 | uint16_t myid; |
245 | unsigned tmin, tmax; | 245 | unsigned tmin, tmax; /* in us */ |
246 | unsigned long tsum; | 246 | unsigned long long tsum; /* in us, sum of all times */ |
247 | const char *hostname; | 247 | const char *hostname; |
248 | const char *dotted; | 248 | const char *dotted; |
249 | union { | 249 | union { |
@@ -301,11 +301,13 @@ static void pingstats(int junk ATTRIBUTE_UNUSED) | |||
301 | if (ntransmitted) | 301 | if (ntransmitted) |
302 | ntransmitted = (ntransmitted - nreceived) * 100 / ntransmitted; | 302 | ntransmitted = (ntransmitted - nreceived) * 100 / ntransmitted; |
303 | printf("%lu%% packet loss\n", ntransmitted); | 303 | printf("%lu%% packet loss\n", ntransmitted); |
304 | if (tmin != UINT_MAX) | 304 | if (tmin != UINT_MAX) { |
305 | printf("round-trip min/avg/max = %u.%u/%lu.%lu/%u.%u ms\n", | 305 | unsigned tavg = tsum / (nreceived + nrepeats); |
306 | tmin / 10, tmin % 10, | 306 | printf("round-trip min/avg/max = %u.%03u/%u.%03u/%u.%03u ms\n", |
307 | (tsum / (nreceived + nrepeats)) / 10, | 307 | tmin / 1000, tmin % 1000, |
308 | (tsum / (nreceived + nrepeats)) % 10, tmax / 10, tmax % 10); | 308 | tavg / 1000, tavg % 1000, |
309 | tmax / 1000, tmax % 1000); | ||
310 | } | ||
309 | exit(nreceived == 0); /* (nreceived == 0) is true (1) -- 'failure' */ | 311 | exit(nreceived == 0); /* (nreceived == 0) is true (1) -- 'failure' */ |
310 | } | 312 | } |
311 | 313 | ||
@@ -334,7 +336,9 @@ static void sendping_tail(void (*sp)(int), const void *pkt, int size_pkt) | |||
334 | 336 | ||
335 | static void sendping4(int junk ATTRIBUTE_UNUSED) | 337 | static void sendping4(int junk ATTRIBUTE_UNUSED) |
336 | { | 338 | { |
337 | struct icmp *pkt = alloca(datalen + ICMP_MINLEN); | 339 | /* +4 reserves a place for timestamp, which may end up sitting |
340 | * *after* packet. Saves one if() */ | ||
341 | struct icmp *pkt = alloca(datalen + ICMP_MINLEN + 4); | ||
338 | 342 | ||
339 | pkt->icmp_type = ICMP_ECHO; | 343 | pkt->icmp_type = ICMP_ECHO; |
340 | pkt->icmp_code = 0; | 344 | pkt->icmp_code = 0; |
@@ -342,10 +346,9 @@ static void sendping4(int junk ATTRIBUTE_UNUSED) | |||
342 | pkt->icmp_seq = htons(ntransmitted); /* don't ++ here, it can be a macro */ | 346 | pkt->icmp_seq = htons(ntransmitted); /* don't ++ here, it can be a macro */ |
343 | pkt->icmp_id = myid; | 347 | pkt->icmp_id = myid; |
344 | 348 | ||
345 | // I can't fucking believe someone thought it's okay to do it like this... | 349 | /* We don't do hton, because we will read it back on the same machine */ |
346 | // where's hton? Where is a provision for different word size, structure padding, etc?? | 350 | /*if (datalen >= 4)*/ |
347 | // FIXME! | 351 | *(uint32_t*)&pkt->icmp_dun = monotonic_us(); |
348 | gettimeofday((struct timeval *) &pkt->icmp_dun, NULL); | ||
349 | 352 | ||
350 | pkt->icmp_cksum = in_cksum((unsigned short *) pkt, datalen + ICMP_MINLEN); | 353 | pkt->icmp_cksum = in_cksum((unsigned short *) pkt, datalen + ICMP_MINLEN); |
351 | 354 | ||
@@ -354,7 +357,7 @@ static void sendping4(int junk ATTRIBUTE_UNUSED) | |||
354 | #if ENABLE_PING6 | 357 | #if ENABLE_PING6 |
355 | static void sendping6(int junk ATTRIBUTE_UNUSED) | 358 | static void sendping6(int junk ATTRIBUTE_UNUSED) |
356 | { | 359 | { |
357 | struct icmp6_hdr *pkt = alloca(datalen + sizeof(struct icmp6_hdr)); | 360 | struct icmp6_hdr *pkt = alloca(datalen + sizeof(struct icmp6_hdr) + 4); |
358 | 361 | ||
359 | pkt->icmp6_type = ICMP6_ECHO_REQUEST; | 362 | pkt->icmp6_type = ICMP6_ECHO_REQUEST; |
360 | pkt->icmp6_code = 0; | 363 | pkt->icmp6_code = 0; |
@@ -362,8 +365,8 @@ static void sendping6(int junk ATTRIBUTE_UNUSED) | |||
362 | pkt->icmp6_seq = htons(ntransmitted); /* don't ++ here, it can be a macro */ | 365 | pkt->icmp6_seq = htons(ntransmitted); /* don't ++ here, it can be a macro */ |
363 | pkt->icmp6_id = myid; | 366 | pkt->icmp6_id = myid; |
364 | 367 | ||
365 | // FIXME! | 368 | /*if (datalen >= 4)*/ |
366 | gettimeofday((struct timeval *) &pkt->icmp6_data8[4], NULL); | 369 | *(uint32_t*)(&pkt->icmp6_data8[4]) = monotonic_us(); |
367 | 370 | ||
368 | sendping_tail(sendping6, pkt, datalen + sizeof(struct icmp6_hdr)); | 371 | sendping_tail(sendping6, pkt, datalen + sizeof(struct icmp6_hdr)); |
369 | } | 372 | } |
@@ -417,7 +420,7 @@ static const char *icmp6_type_name(int id) | |||
417 | } | 420 | } |
418 | #endif | 421 | #endif |
419 | 422 | ||
420 | static void unpack_tail(int sz, struct timeval *tp, | 423 | static void unpack_tail(int sz, uint32_t *tp, |
421 | const char *from_str, | 424 | const char *from_str, |
422 | uint16_t recv_seq, int ttl) | 425 | uint16_t recv_seq, int ttl) |
423 | { | 426 | { |
@@ -427,17 +430,9 @@ static void unpack_tail(int sz, struct timeval *tp, | |||
427 | ++nreceived; | 430 | ++nreceived; |
428 | 431 | ||
429 | if (tp) { | 432 | if (tp) { |
430 | struct timeval tv; | 433 | /* (int32_t) cast is for hypothetical 64-bit unsigned */ |
431 | 434 | /* (doesn't hurt 32-bit real-world anyway) */ | |
432 | gettimeofday(&tv, NULL); | 435 | triptime = (int32_t) ((uint32_t)monotonic_us() - *tp); |
433 | tv.tv_usec -= tp->tv_usec; | ||
434 | if (tv.tv_usec < 0) { | ||
435 | --tv.tv_sec; | ||
436 | tv.tv_usec += 1000000; | ||
437 | } | ||
438 | tv.tv_sec -= tp->tv_sec; | ||
439 | |||
440 | triptime = tv.tv_sec * 10000 + (tv.tv_usec / 100); | ||
441 | tsum += triptime; | 436 | tsum += triptime; |
442 | if (triptime < tmin) | 437 | if (triptime < tmin) |
443 | tmin = triptime; | 438 | tmin = triptime; |
@@ -459,7 +454,7 @@ static void unpack_tail(int sz, struct timeval *tp, | |||
459 | printf("%d bytes from %s: seq=%u ttl=%d", sz, | 454 | printf("%d bytes from %s: seq=%u ttl=%d", sz, |
460 | from_str, recv_seq, ttl); | 455 | from_str, recv_seq, ttl); |
461 | if (tp) | 456 | if (tp) |
462 | printf(" time=%u.%u ms", triptime / 10, triptime % 10); | 457 | printf(" time=%u.%03u ms", triptime / 1000, triptime % 1000); |
463 | puts(dupmsg); | 458 | puts(dupmsg); |
464 | fflush(stdout); | 459 | fflush(stdout); |
465 | } | 460 | } |
@@ -483,10 +478,10 @@ static void unpack4(char *buf, int sz, struct sockaddr_in *from) | |||
483 | 478 | ||
484 | if (icmppkt->icmp_type == ICMP_ECHOREPLY) { | 479 | if (icmppkt->icmp_type == ICMP_ECHOREPLY) { |
485 | uint16_t recv_seq = ntohs(icmppkt->icmp_seq); | 480 | uint16_t recv_seq = ntohs(icmppkt->icmp_seq); |
486 | struct timeval *tp = NULL; | 481 | uint32_t *tp = NULL; |
487 | 482 | ||
488 | if (sz >= ICMP_MINLEN + sizeof(struct timeval)) | 483 | if (sz >= ICMP_MINLEN + sizeof(uint32_t)) |
489 | tp = (struct timeval *) icmppkt->icmp_data; | 484 | tp = (uint32_t *) icmppkt->icmp_data; |
490 | unpack_tail(sz, tp, | 485 | unpack_tail(sz, tp, |
491 | inet_ntoa(*(struct in_addr *) &from->sin_addr.s_addr), | 486 | inet_ntoa(*(struct in_addr *) &from->sin_addr.s_addr), |
492 | recv_seq, iphdr->ttl); | 487 | recv_seq, iphdr->ttl); |
@@ -512,10 +507,10 @@ static void unpack6(char *packet, int sz, struct sockaddr_in6 *from, int hoplimi | |||
512 | 507 | ||
513 | if (icmppkt->icmp6_type == ICMP6_ECHO_REPLY) { | 508 | if (icmppkt->icmp6_type == ICMP6_ECHO_REPLY) { |
514 | uint16_t recv_seq = ntohs(icmppkt->icmp6_seq); | 509 | uint16_t recv_seq = ntohs(icmppkt->icmp6_seq); |
515 | struct timeval *tp = NULL; | 510 | uint32_t *tp = NULL; |
516 | 511 | ||
517 | if (sz >= sizeof(struct icmp6_hdr) + sizeof(struct timeval)) | 512 | if (sz >= sizeof(struct icmp6_hdr) + sizeof(uint32_t)) |
518 | tp = (struct timeval *) &icmppkt->icmp6_data8[4]; | 513 | tp = (uint32_t *) &icmppkt->icmp6_data8[4]; |
519 | unpack_tail(sz, tp, | 514 | unpack_tail(sz, tp, |
520 | inet_ntop(AF_INET6, &pingaddr.sin6.sin6_addr, | 515 | inet_ntop(AF_INET6, &pingaddr.sin6.sin6_addr, |
521 | buf, sizeof(buf)), | 516 | buf, sizeof(buf)), |
diff --git a/networking/wget.c b/networking/wget.c index 8be37a744..ef27ab058 100644 --- a/networking/wget.c +++ b/networking/wget.c | |||
@@ -8,7 +8,7 @@ | |||
8 | 8 | ||
9 | /* We want libc to give us xxx64 functions also */ | 9 | /* We want libc to give us xxx64 functions also */ |
10 | /* http://www.unix.org/version2/whatsnew/lfs20mar.html */ | 10 | /* http://www.unix.org/version2/whatsnew/lfs20mar.html */ |
11 | #define _LARGEFILE64_SOURCE 1 | 11 | //#define _LARGEFILE64_SOURCE 1 |
12 | 12 | ||
13 | #include <getopt.h> /* for struct option */ | 13 | #include <getopt.h> /* for struct option */ |
14 | #include "libbb.h" | 14 | #include "libbb.h" |
@@ -710,7 +710,7 @@ progressmeter(int flag) | |||
710 | 710 | ||
711 | fprintf(stderr, "\r%-20.20s%4d%% ", curfile, ratio); | 711 | fprintf(stderr, "\r%-20.20s%4d%% ", curfile, ratio); |
712 | 712 | ||
713 | barlength = getttywidth() - 51; | 713 | barlength = getttywidth() - 49; |
714 | if (barlength > 0) { | 714 | if (barlength > 0) { |
715 | /* god bless gcc for variable arrays :) */ | 715 | /* god bless gcc for variable arrays :) */ |
716 | i = barlength * ratio / 100; | 716 | i = barlength * ratio / 100; |
@@ -728,7 +728,7 @@ progressmeter(int flag) | |||
728 | abbrevsize >>= 10; | 728 | abbrevsize >>= 10; |
729 | } | 729 | } |
730 | /* see http://en.wikipedia.org/wiki/Tera */ | 730 | /* see http://en.wikipedia.org/wiki/Tera */ |
731 | fprintf(stderr, "%6d %c%c ", (int)abbrevsize, " KMGTPEZY"[i], i?'B':' '); | 731 | fprintf(stderr, "%6d%c ", (int)abbrevsize, " kMGTPEZY"[i]); |
732 | 732 | ||
733 | // Nuts! Ain't it easier to update progress meter ONLY when we transferred++? | 733 | // Nuts! Ain't it easier to update progress meter ONLY when we transferred++? |
734 | // FIXME: get rid of alarmtimer + updateprogressmeter mess | 734 | // FIXME: get rid of alarmtimer + updateprogressmeter mess |