Date: Thu, 13 Jul 1995 18:10:04 -0700 From: Bill Fenner <fenner@parc.xerox.com> To: freebsd-bugs Subject: bin/612: traceroute doesn't time out if rec'ing other ICMP traffic Message-ID: <199507140110.SAA08535@freefall.cdrom.com> In-Reply-To: Your message of Thu, 13 Jul 1995 17:55:38 PDT <199507140055.RAA07567@fenestro.parc.xerox.com>
next in thread | previous in thread | raw e-mail | index | archive | help
>Number: 612 >Category: bin >Synopsis: traceroute doesn't print * if other ICMP traffic exists >Confidential: no >Severity: serious >Priority: medium >Responsible: freebsd-bugs (FreeBSD bugs mailing list) >State: open >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Thu Jul 13 18:10:02 1995 >Originator: Bill Fenner >Organization: Xerox PARC >Release: FreeBSD 2.1.0-Development i386 >Environment: >Description: traceroute will not time hops out and print a * if other ICMP traffic is occurring (i.e. destination unreachable, pings, ping replies,...), which is not necessarily under control of the person running traceroute. (I first experienced this on a busy web server which gets lots of 'time exceeded' and 'host unreachable' errors due to HTTP requests) >How-To-Repeat: ping somehost & traceroute someotherhostthatwilltimeout the traceroute will hang at the first lost packet / unresponsive router and will never print a * until you kill the ping, at which point it will resume. >Fix: Make the timeout calculated from the time that the probe was sent, instead of assuming that if select returned it returned the response to our probe. *** traceroute.c.orig Thu Jul 13 17:41:05 1995 --- traceroute.c Thu Jul 13 17:49:56 1995 *************** *** 268,274 **** u_char packet[512]; /* last inbound (icmp) packet */ struct opacket *outpacket; /* last output (udp) packet */ ! int wait_for_reply __P((int, struct sockaddr_in *)); void send_probe __P((int, int)); double deltaT __P((struct timeval *, struct timeval *)); int packet_ok __P((u_char *, int, struct sockaddr_in *, int)); --- 268,274 ---- u_char packet[512]; /* last inbound (icmp) packet */ struct opacket *outpacket; /* last output (udp) packet */ ! int wait_for_reply __P((int, struct sockaddr_in *, struct timeval *)); void send_probe __P((int, int)); double deltaT __P((struct timeval *, struct timeval *)); int packet_ok __P((u_char *, int, struct sockaddr_in *, int)); *************** *** 500,506 **** (void) gettimeofday(&t1, &tz); send_probe(++seq, ttl); ! while (cc = wait_for_reply(s, &from)) { (void) gettimeofday(&t2, &tz); if ((i = packet_ok(packet, cc, &from, seq))) { if (from.sin_addr.s_addr != lastaddr) { --- 500,506 ---- (void) gettimeofday(&t1, &tz); send_probe(++seq, ttl); ! while (cc = wait_for_reply(s, &from, &t1)) { (void) gettimeofday(&t2, &tz); if ((i = packet_ok(packet, cc, &from, seq))) { if (from.sin_addr.s_addr != lastaddr) { *************** *** 552,569 **** } int ! wait_for_reply(sock, from) int sock; struct sockaddr_in *from; { fd_set fds; ! struct timeval wait; int cc = 0; int fromlen = sizeof (*from); FD_ZERO(&fds); FD_SET(sock, &fds); ! wait.tv_sec = waittime; wait.tv_usec = 0; if (select(sock+1, &fds, (fd_set *)0, (fd_set *)0, &wait) > 0) cc=recvfrom(s, (char *)packet, sizeof(packet), 0, --- 552,578 ---- } int ! wait_for_reply(sock, from, sent) int sock; struct sockaddr_in *from; + struct timeval *sent; { fd_set fds; ! struct timeval now, wait; int cc = 0; int fromlen = sizeof (*from); FD_ZERO(&fds); FD_SET(sock, &fds); ! gettimeofday(&now, NULL); ! wait.tv_sec = (sent->tv_sec + waittime) - now.tv_sec; ! wait.tv_usec = sent->tv_usec - now.tv_usec; ! if (wait.tv_usec < 0) { ! wait.tv_usec += 1000000; ! wait.tv_sec--; ! } ! if (wait.tv_sec < 0) ! wait.tv_sec = wait.tv_usec = 0; if (select(sock+1, &fds, (fd_set *)0, (fd_set *)0, &wait) > 0) cc=recvfrom(s, (char *)packet, sizeof(packet), 0, >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199507140110.SAA08535>