From fenner@parc.xerox.com  Thu Jul 13 18:04:20 1995
Received: from alpha.xerox.com (alpha.Xerox.COM [13.1.64.93])
          by freefall.cdrom.com (8.6.10/8.6.6) with SMTP id SAA08389
          for <FreeBSD-gnats-submit@freebsd.org>; Thu, 13 Jul 1995 18:04:20 -0700
Received: from fenestro.parc.xerox.com ([13.0.208.199]) by alpha.xerox.com with SMTP id <14941(5)>; Thu, 13 Jul 1995 18:03:37 PDT
Received: (from fenner@localhost) by fenestro.parc.xerox.com (8.6.11/8.6.9) id RAA07567; Thu, 13 Jul 1995 17:55:38 -0700
Message-Id: <199507140055.RAA07567@fenestro.parc.xerox.com>
Date: Thu, 13 Jul 1995 17:55:38 PDT
From: Bill Fenner <fenner@parc.xerox.com>
Reply-To: fenner@parc.xerox.com
To: FreeBSD-gnats-submit@freebsd.org
Subject: traceroute doesn't time out if rec'ing other ICMP traffic
X-Send-Pr-Version: 3.2

>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:          closed
>Quarter:
>Keywords:
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Jul 13 18:10:02 1995
>Closed-Date:    Sat Jul 22 18:25:41 PDT 1995
>Last-Modified:
>Originator:     Bill Fenner
>Release:        FreeBSD 2.1.0-Development i386
>Organization:
Xerox PARC
>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,

>Release-Note:
>Audit-Trail:
State-Changed-From-To: open->closed 
State-Changed-By: ache 
State-Changed-When: Sat Jul 22 18:25:41 PDT 1995 
State-Changed-Why:  
Fix applied in traceroute.c v1.3 
>Unformatted:



