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>
index | next in thread | previous in thread | raw e-mail
>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:
help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199507140110.SAA08535>
