diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-06-17 19:09:05 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-06-17 19:09:05 +0000 |
commit | 459be35234cc24b69309eb0ee22600024c73713e (patch) | |
tree | 15ac4122d9c42ec75ba68d342827e37fcb1306ed /networking | |
parent | e79dd06782175d50f639180cde5b2c56933aa2ee (diff) |
hwclock: size optimizations
libbb/time.c: new file, introducing monotonic_us()
pscan, traceroute, arping: use it instead of gettimeofday
ping, zcip: TODO
function old new delta
monotonic_us - 89 +89
find_pair 164 180 +16
.rodata 129747 129763 +16
refresh 1144 1152 +8
............
timeout 8 4 -4
static.start 8 4 -4
last 8 4 -4
parse_conf 1303 1284 -19
time_main 1149 1124 -25
gettimeofday_us 39 - -39
arping_main 2042 1969 -73
hwclock_main 594 501 -93
catcher 485 380 -105
traceroute_main 4300 4117 -183
------------------------------------------------------------------------------
(add/remove: 2/1 grow/shrink: 8/11 up/down: 157/-562) Total: -405 bytes
Diffstat (limited to 'networking')
-rw-r--r-- | networking/arping.c | 125 | ||||
-rw-r--r-- | networking/pscan.c | 28 | ||||
-rw-r--r-- | networking/traceroute.c | 53 | ||||
-rw-r--r-- | networking/wget.c | 2 |
4 files changed, 83 insertions, 125 deletions
diff --git a/networking/arping.c b/networking/arping.c index 1b2604902..a022e70ea 100644 --- a/networking/arping.c +++ b/networking/arping.c @@ -8,9 +8,6 @@ * Busybox port: Nick Fedchik <nick@fedchik.org.ua> */ -//#include <sys/ioctl.h> -//#include <signal.h> - #include <arpa/inet.h> #include <net/if.h> #include <netinet/ether.h> @@ -18,42 +15,42 @@ #include "libbb.h" +/* We don't expect to see 1000+ seconds delay, unsigned is enough */ +#define MONOTONIC_US() ((unsigned)monotonic_us()) + static struct in_addr src; static struct in_addr dst; static struct sockaddr_ll me; static struct sockaddr_ll he; -static struct timeval last; - -enum cfg_e { - dad = 1, - unsolicited = 2, - advert = 4, - quiet = 8, - quit_on_reply = 16, - broadcast_only = 32, - unicasting = 64 +static unsigned last; + +enum { + DAD = 1, + UNSOLICITED = 2, + ADVERT = 4, + QUIET = 8, + QUIT_ON_REPLY = 16, + BCAST_ONLY = 32, + UNICASTING = 64 }; static int cfg; static int s; static unsigned count = UINT_MAX; -static unsigned timeout; +static unsigned timeout_us; static int sent; static int brd_sent; static int received; static int brd_recv; static int req_recv; -#define MS_TDIFF(tv1,tv2) ( ((tv1).tv_sec-(tv2).tv_sec)*1000 + \ - ((tv1).tv_usec-(tv2).tv_usec)/1000 ) - static int send_pack(int sock, struct in_addr *src_addr, struct in_addr *dst_addr, struct sockaddr_ll *ME, struct sockaddr_ll *HE) { int err; - struct timeval now; - RESERVE_CONFIG_UBUFFER(buf, 256); + unsigned now; + unsigned char buf[256]; struct arphdr *ah = (struct arphdr *) buf; unsigned char *p = (unsigned char *) (ah + 1); @@ -62,7 +59,7 @@ static int send_pack(int sock, struct in_addr *src_addr, ah->ar_pro = htons(ETH_P_IP); ah->ar_hln = ME->sll_halen; ah->ar_pln = 4; - ah->ar_op = cfg & advert ? htons(ARPOP_REPLY) : htons(ARPOP_REQUEST); + ah->ar_op = cfg & ADVERT ? htons(ARPOP_REPLY) : htons(ARPOP_REQUEST); memcpy(p, &ME->sll_addr, ah->ar_hln); p += ME->sll_halen; @@ -70,7 +67,7 @@ static int send_pack(int sock, struct in_addr *src_addr, memcpy(p, src_addr, 4); p += 4; - if (cfg & advert) + if (cfg & ADVERT) memcpy(p, &ME->sll_addr, ah->ar_hln); else memcpy(p, &HE->sll_addr, ah->ar_hln); @@ -79,21 +76,21 @@ static int send_pack(int sock, struct in_addr *src_addr, memcpy(p, dst_addr, 4); p += 4; - gettimeofday(&now, NULL); + now = MONOTONIC_US(); err = sendto(sock, buf, p - buf, 0, (struct sockaddr *) HE, sizeof(*HE)); if (err == p - buf) { last = now; sent++; - if (!(cfg & unicasting)) + if (!(cfg & UNICASTING)) brd_sent++; } - RELEASE_CONFIG_BUFFER(buf); return err; } +static void finish(void) ATTRIBUTE_NORETURN; static void finish(void) { - if (!(cfg & quiet)) { + if (!(cfg & QUIET)) { printf("Sent %d probe(s) (%d broadcast(s))\n" "Received %d repl%s" " (%d request(s), %d broadcast(s))\n", @@ -101,30 +98,31 @@ static void finish(void) received, (received == 1) ? "ies" : "y", req_recv, brd_recv); } - if (cfg & dad) + if (cfg & DAD) exit(!!received); - if (cfg & unsolicited) + if (cfg & UNSOLICITED) exit(0); exit(!received); } static void catcher(void) { - struct timeval tv; - static struct timeval start; + static unsigned start; - gettimeofday(&tv, NULL); + unsigned now; - if (start.tv_sec == 0) - start = tv; + now = MONOTONIC_US(); + if (start == 0) + start = now; - if (count-- == 0 - || (timeout && MS_TDIFF(tv, start) > timeout * 1000 + 500)) + if (count == 0 || (timeout_us && (now - start) > (timeout_us + 500000))) finish(); - if (last.tv_sec == 0 || MS_TDIFF(tv, last) > 500) { + count--; + + if (last == 0 || (now - last) > 500000) { send_pack(s, &src, &dst, &me, &he); - if (count == 0 && (cfg & unsolicited)) + if (count == 0 && (cfg & UNSOLICITED)) finish(); } alarm(1); @@ -162,7 +160,7 @@ static int recv_pack(unsigned char *buf, int len, struct sockaddr_ll *FROM) return 0; memcpy(&src_ip, p + ah->ar_hln, 4); memcpy(&dst_ip, p + ah->ar_hln + 4 + ah->ar_hln, 4); - if (!(cfg & dad)) { + if (!(cfg & DAD)) { if (src_ip.s_addr != dst.s_addr) return 0; if (src.s_addr != dst_ip.s_addr) @@ -190,11 +188,8 @@ static int recv_pack(unsigned char *buf, int len, struct sockaddr_ll *FROM) if (src.s_addr && src.s_addr != dst_ip.s_addr) return 0; } - if (!(cfg & quiet)) { + if (!(cfg & QUIET)) { int s_printed = 0; - struct timeval tv; - - gettimeofday(&tv, NULL); printf("%scast re%s from %s [%s]", FROM->sll_pkttype == PACKET_HOST ? "Uni" : "Broad", @@ -212,13 +207,8 @@ static int recv_pack(unsigned char *buf, int len, struct sockaddr_ll *FROM) ether_ntoa((struct ether_addr *) p + ah->ar_hln + 4)); } - if (last.tv_sec) { - long usecs = (tv.tv_sec - last.tv_sec) * 1000000 + - tv.tv_usec - last.tv_usec; - long msecs = (usecs + 500) / 1000; - - usecs -= msecs * 1000 - 500; - printf(" %ld.%03ldms\n", msecs, usecs); + if (last) { + printf(" %u.%03ums\n", last / 1000, last % 1000); } else { printf(" UNSOLICITED?\n"); } @@ -229,11 +219,11 @@ static int recv_pack(unsigned char *buf, int len, struct sockaddr_ll *FROM) brd_recv++; if (ah->ar_op == htons(ARPOP_REQUEST)) req_recv++; - if (cfg & quit_on_reply) + if (cfg & QUIT_ON_REPLY) finish(); - if (!(cfg & broadcast_only)) { + if (!(cfg & BCAST_ONLY)) { memcpy(he.sll_addr, p, me.sll_halen); - cfg |= unicasting; + cfg |= UNICASTING; } return 1; } @@ -245,6 +235,7 @@ int arping_main(int argc, char **argv) int ifindex; char *source = NULL; char *target; + unsigned char *packet; s = xsocket(PF_PACKET, SOCK_DGRAM, 0); @@ -258,28 +249,23 @@ int arping_main(int argc, char **argv) /* Dad also sets quit_on_reply. * Advert also sets unsolicited. */ - opt_complementary = "Df:AU"; + opt_complementary = "=1:Df:AU"; opt = getopt32(argc, argv, "DUAqfbc:w:I:s:", &_count, &_timeout, &device, &source); cfg |= opt & 0x3f; /* set respective flags */ if (opt & 0x40) /* -c: count */ count = xatou(_count); if (opt & 0x80) /* -w: timeout */ - timeout = xatoul_range(_timeout, 0, INT_MAX/2000); - //if (opt & 0x100) /* -i: interface */ - if (strlen(device) > IF_NAMESIZE) { + timeout_us = xatou_range(_timeout, 0, INT_MAX/2000000) * 1000000; + //if (opt & 0x100) /* -I: interface */ + if (strlen(device) >= IF_NAMESIZE) { bb_error_msg_and_die("interface name '%s' is too long", device); } //if (opt & 0x200) /* -s: source */ } - argc -= optind; - argv += optind; - - if (argc != 1) - bb_show_usage(); - target = *argv; + target = argv[optind]; xfunc_error_retval = 2; @@ -301,7 +287,7 @@ int arping_main(int argc, char **argv) } if (ifr.ifr_flags & (IFF_NOARP | IFF_LOOPBACK)) { bb_error_msg("interface %s is not ARPable", device); - return (cfg & dad ? 0 : 2); + return (cfg & DAD ? 0 : 2); } } @@ -317,10 +303,10 @@ int arping_main(int argc, char **argv) bb_error_msg_and_die("invalid source address %s", source); } - if (!(cfg & dad) && (cfg & unsolicited) && src.s_addr == 0) + if (!(cfg & DAD) && (cfg & UNSOLICITED) && src.s_addr == 0) src = dst; - if (!(cfg & dad) || src.s_addr) { + if (!(cfg & DAD) || src.s_addr) { struct sockaddr_in saddr; int probe_fd = xsocket(AF_INET, SOCK_DGRAM, 0); @@ -333,7 +319,7 @@ int arping_main(int argc, char **argv) if (src.s_addr) { saddr.sin_addr = src; xbind(probe_fd, (struct sockaddr *) &saddr, sizeof(saddr)); - } else if (!(cfg & dad)) { + } else if (!(cfg & DAD)) { socklen_t alen = sizeof(saddr); saddr.sin_port = htons(1025); @@ -364,18 +350,18 @@ int arping_main(int argc, char **argv) } if (me.sll_halen == 0) { bb_error_msg("interface \"%s\" is not ARPable (no ll address)", device); - return (cfg & dad ? 0 : 2); + return (cfg & DAD ? 0 : 2); } he = me; memset(he.sll_addr, -1, he.sll_halen); - if (!(cfg & quiet)) { + if (!(cfg & QUIET)) { printf("ARPING to %s from %s via %s\n", inet_ntoa(dst), inet_ntoa(src), device ? device : "unknown"); } - if (!src.s_addr && !(cfg & dad)) { + if (!src.s_addr && !(cfg & DAD)) { bb_error_msg_and_die("no src address in the non-DAD mode"); } @@ -394,9 +380,9 @@ int arping_main(int argc, char **argv) catcher(); + packet = xmalloc(4096); while (1) { sigset_t sset, osset; - RESERVE_CONFIG_UBUFFER(packet, 4096); struct sockaddr_ll from; socklen_t alen = sizeof(from); int cc; @@ -412,6 +398,5 @@ int arping_main(int argc, char **argv) sigprocmask(SIG_BLOCK, &sset, &osset); recv_pack(packet, cc, &from); sigprocmask(SIG_SETMASK, &osset, NULL); - RELEASE_CONFIG_BUFFER(packet); } } diff --git a/networking/pscan.c b/networking/pscan.c index 10bf3b606..9fa6993e8 100644 --- a/networking/pscan.c +++ b/networking/pscan.c @@ -17,19 +17,6 @@ #define DERR(...) ((void)0) #endif -/* return time in usec */ -// TODO: move to libbb and use in traceroute, zcip, arping etc -// (maybe also use absolute monotonic clock - no time warps -// due to admin resetting date/time?) -static unsigned gettimeofday_us(void) -{ - struct timeval now; - - if (gettimeofday(&now, NULL)) - return 0; - return (now.tv_sec * 1000000 + now.tv_usec); -} - static const char *port_name(unsigned port) { struct servent *server; @@ -40,6 +27,9 @@ static const char *port_name(unsigned port) return "unknown"; } +/* We don't expect to see 1000+ seconds delay, unsigned is enough */ +#define MONOTONIC_US() ((unsigned)monotonic_us()) + int pscan_main(int argc, char **argv); int pscan_main(int argc, char **argv) { @@ -91,7 +81,7 @@ int pscan_main(int argc, char **argv) /* Nonblocking connect typically "fails" with errno == EINPROGRESS */ ndelay_on(s); DMSG("connect to port %u", port); - start = gettimeofday_us(); + start = MONOTONIC_US(); if (connect(s, &lsap->sa, lsap->len) == 0) { /* Unlikely, for me even localhost fails :) */ DMSG("connect succeeded"); @@ -110,15 +100,15 @@ int pscan_main(int argc, char **argv) closed_ports++; break; } - DERR("port %u errno %d @%u", port, errno, gettimeofday_us() - start); - if ((gettimeofday_us() - start) > rtt_4) + DERR("port %u errno %d @%u", port, errno, MONOTONIC_US() - start); + if ((MONOTONIC_US() - start) > rtt_4) break; /* Can sleep (much) longer than specified delay. * We check rtt BEFORE we usleep, otherwise * on localhost we'll do zero writes done (!) * before we exceed (rather small) rtt */ usleep(rtt_4/8); - DMSG("write to port %u @%u", port, gettimeofday_us() - start); + DMSG("write to port %u @%u", port, MONOTONIC_US() - start); if (write(s, " ", 1) >= 0) { /* We were able to write to the socket */ open: open_ports++; @@ -126,13 +116,13 @@ int pscan_main(int argc, char **argv) break; } } - DMSG("out of loop @%u", gettimeofday_us() - start); + DMSG("out of loop @%u", MONOTONIC_US() - start); /* Estimate new rtt - we don't want to wait entire timeout * for each port. *4 allows for rise in net delay. * We increase rtt quickly (*4), decrease slowly (4/8 == 1/2) * because we don't want to accidentally miss ports. */ - rtt_4 = (gettimeofday_us() - start) * 4; + rtt_4 = (MONOTONIC_US() - start) * 4; if (rtt_4 < min_rtt) rtt_4 = min_rtt; if (rtt_4 > timeout) diff --git a/networking/traceroute.c b/networking/traceroute.c index 40533a82d..9fc15d390 100644 --- a/networking/traceroute.c +++ b/networking/traceroute.c @@ -275,7 +275,8 @@ struct hostinfo { struct outdata { unsigned char seq; /* sequence number of this packet */ unsigned char ttl; /* ttl packet left with */ - struct timeval tv ATTRIBUTE_PACKED; /* time packet left */ +// UNUSED. Retaining to have the same packet size. + struct timeval tv_UNUSED ATTRIBUTE_PACKED; /* time packet left */ }; struct IFADDRLIST { @@ -533,37 +534,19 @@ findsaddr(const struct sockaddr_in *to, struct sockaddr_in *from) */ -/* - * Subtract 2 timeval structs: out = out - in. - * Out is assumed to be >= in. - */ -static inline void -tvsub(struct timeval *out, struct timeval *in) -{ - - if ((out->tv_usec -= in->tv_usec) < 0) { - --out->tv_sec; - out->tv_usec += 1000000; - } - out->tv_sec -= in->tv_sec; -} - static int -wait_for_reply(int sock, struct sockaddr_in *fromp, const struct timeval *tp) +wait_for_reply(int sock, struct sockaddr_in *fromp) { fd_set fds; - struct timeval now, tvwait; - struct timezone tz; + struct timeval tvwait; int cc = 0; socklen_t fromlen = sizeof(*fromp); FD_ZERO(&fds); FD_SET(sock, &fds); - tvwait.tv_sec = tp->tv_sec + waittime; - tvwait.tv_usec = tp->tv_usec; - (void)gettimeofday(&now, &tz); - tvsub(&tvwait, &now); + tvwait.tv_sec = waittime; + tvwait.tv_usec = 0; if (select(sock + 1, &fds, NULL, NULL, &tvwait) > 0) cc = recvfrom(sock, (char *)packet, sizeof(packet), 0, @@ -609,7 +592,7 @@ in_cksum(uint16_t *addr, int len) static void -send_probe(int seq, int ttl, struct timeval *tp) +send_probe(int seq, int ttl) { int cc; struct udpiphdr *ui, *oui; @@ -633,7 +616,8 @@ send_probe(int seq, int ttl, struct timeval *tp) /* Payload */ outdata->seq = seq; outdata->ttl = ttl; - memcpy(&outdata->tv, tp, sizeof(outdata->tv)); +// UNUSED: was storing gettimeofday's result there, but never ever checked it + /*memcpy(&outdata->tv, tp, sizeof(outdata->tv));*/ #if ENABLE_FEATURE_TRACEROUTE_USE_ICMP if (useicmp) @@ -706,7 +690,6 @@ send_probe(int seq, int ttl, struct timeval *tp) packlen, (struct sockaddr *)&whereto, sizeof(whereto)); if (cc != packlen) { bb_info_msg("wrote %s %d chars, ret=%d", hostname, packlen, cc); -// (void)fflush(stdout); } } @@ -908,9 +891,9 @@ getaddr(uint32_t *ap, const char *host) #endif static void -print_delta_ms(struct timeval *t1p, struct timeval *t2p) +print_delta_ms(unsigned t1p, unsigned t2p) { - unsigned tt = (t2p->tv_sec - t1p->tv_sec) * 1000000 + (t2p->tv_usec - t1p->tv_usec); + unsigned tt = t2p - t1p; printf(" %u.%03u ms", tt/1000, tt%1000); } @@ -1230,17 +1213,17 @@ int traceroute_main(int argc, char **argv) printf("%2d ", ttl); for (probe = 0; probe < nprobes; ++probe) { int cc; - struct timeval t1, t2; - struct timezone tz; + unsigned t1; + unsigned t2; struct ip *ip; if (sentfirst && pausemsecs > 0) usleep(pausemsecs * 1000); - (void)gettimeofday(&t1, &tz); - send_probe(++seq, ttl, &t1); + t1 = monotonic_us(); + send_probe(++seq, ttl); ++sentfirst; - while ((cc = wait_for_reply(s, from, &t1)) != 0) { - (void)gettimeofday(&t2, &tz); + while ((cc = wait_for_reply(s, from)) != 0) { + t2 = monotonic_us(); i = packet_ok(packet, cc, from, seq); /* Skip short packet */ if (i == 0) @@ -1251,7 +1234,7 @@ int traceroute_main(int argc, char **argv) lastaddr = from->sin_addr.s_addr; ++gotlastaddr; } - print_delta_ms(&t1, &t2); + print_delta_ms(t1, t2); ip = (struct ip *)packet; if (op & OPT_TTL_FLAG) printf(" (%d)", ip->ip_ttl); diff --git a/networking/wget.c b/networking/wget.c index fe669bbdd..fc7f7c32c 100644 --- a/networking/wget.c +++ b/networking/wget.c @@ -705,7 +705,7 @@ progressmeter(int flag) ratio = 100; if (totalsize != 0 && !chunked) { /* long long helps to have working ETA even if !LFS */ - ratio = (int) (100 * (unsigned long long)(transferred+beg_range) / totalsize); + ratio = (int) (100ULL * (transferred+beg_range) / totalsize); ratio = MIN(ratio, 100); } |