>Number:         151023
>Category:       bin
>Synopsis:       [patch] ping6(8) exits before all ICMPv6 echo replies are 
>received
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Sep 28 09:00:23 UTC 2010
>Closed-Date:
>Last-Modified:
>Originator:     Tianjie Mao
>Release:        7.2-RELEASE
>Organization:
>Environment:
FreeBSD venus 7.2-RELEASE FreeBSD 7.2-RELEASE #5: Sat Jun 26 11:02:12 CST 2010  
   r...@venus:/usr/src/sys/amd64/compile/IPSEC  amd64
>Description:
An interval timer (itimer) allows a process to do repeated work at a given 
frequency.  If an -i or -f option is specified, the FreeBSD ping6(8) will use 
this value to call setitimer(2) to register the timer, then the signal handler 
is called at every expiry of the timer, sending an ICMPv6 packet each time.

However, the KAME version of ping6 utility immediately exits the loop after 
knowing that it is the last packet to send, which causes unread replies from a 
remote host to be ignored.

This is a bug and can be fixed by setting itimer to zero as soon as the last 
packet is sent, then continue the loop to see if any replies are received.
>How-To-Repeat:
Suppose there is an average RTT seconds round-trip delay between v6host1 and 
v6host2.
INT is the interval (seconds) between packets.
CNT is the total number of packets to send.

Run as root on v6host1:
v6host1# ping6 -i $INT -c $CNT -q v6host2

Then the reply might look like this (0.01 interval, 245.816 ms delay, 100 
packets):

--- ipv6.sjtu.edu.cn ping6 statistics ---
100 packets transmitted, 76 packets received, 24.0% packet loss
round-trip min/avg/max/std-dev = 244.446/245.816/247.826/0.705 ms

After re-adjusting $INT and switching to another destination host with a 
different RTT, one would simply conclude with the following formula:

estimated-packets-lost = RTT / INT
>Fix:
Apply the attached patch to src/sbin/ping6/ping6.c and the problem will be 
fixed.

Tested against CVS revision 1.39 but this is supposed to work on older versions 
as well.

Patch attached with submission follows:

diff -uNr ping6.c.orig ping6.c
--- ping6.c.orig        2010-06-16 23:49:17.000000000 +0800
+++ ping6.c     2010-09-28 15:41:22.000000000 +0800
@@ -1091,8 +1091,14 @@
                /* signal handling */
                if (seenalrm) {
                        /* last packet sent, timeout reached? */
-                       if (npackets && ntransmitted >= npackets)
-                               break;
+                       if (npackets && ntransmitted >= npackets) {
+                               struct timeval zerotime = {0, 0};
+                               itimer.it_value = zerotime;
+                               itimer.it_interval = zerotime;
+                               (void)setitimer(ITIMER_REAL, &itimer, NULL);
+                               seenalrm = 0;   /* clear flag */
+                               continue;
+                       }
                        retransmit();
                        seenalrm = 0;
                        continue;


>Release-Note:
>Audit-Trail:
>Unformatted:
_______________________________________________
freebsd-bugs@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-bugs
To unsubscribe, send any mail to "freebsd-bugs-unsubscr...@freebsd.org"

Reply via email to