Skip site navigation (1)Skip section navigation (2)
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>