From marcs@valis.worldgate.com  Sun Oct  5 11:28:28 1997
Received: from valis.worldgate.com (marcs@valis.worldgate.com [198.161.84.2])
          by hub.freebsd.org (8.8.7/8.8.7) with ESMTP id LAA03298
          for <FreeBSD-gnats-submit@freebsd.org>; Sun, 5 Oct 1997 11:28:27 -0700 (PDT)
Received: (from marcs@localhost)
	by valis.worldgate.com (8.8.7/8.8.7) id MAA28895;
	Sun, 5 Oct 1997 12:28:19 -0600 (MDT)
Message-Id: <199710051828.MAA28895@valis.worldgate.com>
Date: Sun, 5 Oct 1997 12:28:19 -0600 (MDT)
From: marcs@znep.com
Reply-To: marcs@znep.com
To: FreeBSD-gnats-submit@freebsd.org
Subject: ping hangs on unresolvable hosts
X-Send-Pr-Version: 3.2

>Number:         4696
>Category:       bin
>Synopsis:       ping hangs on certain unresolvable hosts
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sun Oct  5 11:30:00 PDT 1997
>Closed-Date:    Sun Feb 29 13:06:53 PST 2004
>Last-Modified:  Sun Feb 29 13:06:53 PST 2004
>Originator:     Marc Slemko
>Release:        FreeBSD 2.2-STABLE i386
>Organization:
>Environment:

FreeBSD 2.2-stable; same problem should be in -current from an examination
of the code.
	

>Description:

$ ping cban
PING cban.cban.com (204.209.160.1): 56 data bytes
^C^C^C^C^C^C^C
[... and it doesn't exit...]

The namesever for the above host is not reachable right now, so
trying to do the reverse lookup hangs for a long period of
time.  The problem is that ^C won't exit.  This is because 
the SIGINT signal handler just sets a flag telling ping to 
exit.  That doesn't do anything because ping in a select() in 
res_send which is retried if it gets an EINTR.

0x80873b1 in select ()
(gdb) up
#1  0x806b5a0 in res_send ()
(gdb) up
#2  0x8067eaa in res_query ()
(gdb) up
#3  0x8063786 in _gethostbydnsaddr ()
(gdb) up
#4  0x8062156 in gethostbyaddr ()
(gdb) up
#5  0x361e in pr_addr (ina={s_addr = 1772147148}) at ping.c:1168
1168            if ((options & F_NUMERIC) ||
(gdb)


This problem was introduced in revision 1.22 of ping.c.
	

>How-To-Repeat:

Find a host where all the nameservers are unreachable for the reverse
lookup.  ping it.

>Fix:

Perhaps do a setjmp somewhere then have the signal handler do a 
longjmp out and have it check the flag then.

Lowering the _res timeouts for the resolver would help a little,
but isn't really a good solution because it would still hang for
a bit and because it would result in false negatives for reverses
for a small number of hosts.
	
	

>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: gnats-admin->freebsd-bugs 
Responsible-Changed-By: max 
Responsible-Changed-When: Mon Oct 6 15:44:23 PDT 1997 
Responsible-Changed-Why:  
Misfiled PR. 
State-Changed-From-To: open->closed 
State-Changed-By: kris 
State-Changed-When: Mon Sep 4 15:21:48 PDT 2000 
State-Changed-Why:  
Fixed by sef in r1.24 of ping.c on 1997/07/13 

http://www.freebsd.org/cgi/query-pr.cgi?pr=4696 

From: Bruce Evans <bde@zeta.org.au>
To: kris@FreeBSD.ORG
Cc: marcs@znep.com, freebsd-gnats-submit@FreeBSD.ORG
Subject: Re: bin/4696: ping hangs on certain unresolvable hosts
Date: Wed, 6 Sep 2000 01:09:49 +1100 (EST)

 On Mon, 4 Sep 2000 kris@FreeBSD.ORG wrote:
 
 > Synopsis: ping hangs on certain unresolvable hosts
 > 
 > State-Changed-From-To: open->closed
 > State-Changed-By: kris
 > State-Changed-When: Mon Sep 4 15:21:48 PDT 2000
 > State-Changed-Why: 
 > Fixed by sef in r1.24 of ping.c on 1997/07/13
 
 No, this was only fixed for some values of "certain", and not the ones
 described in the PR.
 
 Rev.1.24 of ping.c mainly makes all syscalls return EINTR when they are
 interrupted by a SIGINT or SIGALRM.  This fixes hangs in sendto() and/or
 recvmsg(), but has no effect on the hangs described in the PR since
 those involve select() and select() always returns EINTR when it is
 interrupted.  As described in the PR, res_send() retries almost endlessly
 after select() returns EINTR.
 
 I think this is a bug in res_send().  It can't be aborted by non-broken
 signal handlers except by ones that do little more than call _exit(2).
 ping used to have broken signal handlers that did lots of unsafe cleanups
 before exiting unsafely by calling exit(3).
 
 PR 20613 is about essentially the same bug for "fetch -T n".  The timeout
 doesn't work when the SIGALRM occurs in res_send(), since res_send() just
 retries after select() returns EINTR.
 
 Bruce
 
 
State-Changed-From-To: closed->open 
State-Changed-By: bde 
State-Changed-When: Wed Sep 6 07:12:22 PDT 2000 
State-Changed-Why:  
Closed in error. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=4696 
State-Changed-From-To: open->patched 
State-Changed-By: iedowse 
State-Changed-When: Sun Feb 8 14:04:13 PST 2004 
State-Changed-Why:  

A partial workaround has been committed in revision 1.102 of ping.c. 
This just allows you to exit ping by hitting ^C a second time in 
the case where it is waiting for gethostbyaddr() to complete. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=4696 
State-Changed-From-To: patched->closed 
State-Changed-By: iedowse 
State-Changed-When: Sun Feb 29 13:05:48 PST 2004 
State-Changed-Why:  

Patch MFC'd to -STABLE now. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=4696 
>Unformatted:
