bin/103206: tftp does not set proper exit status when a host is down.

John Hickey jjh-freebsd at
Tue Sep 12 20:00:59 PDT 2006

>Number:         103206
>Category:       bin
>Synopsis:       tftp does not set proper exit status when a host is down.
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Sep 13 03:00:41 GMT 2006
>Originator:     John Hickey
>Release:        FreeBSD 6.1-STABLE
FreeBSD monolith 6.1-STABLE FreeBSD 6.1-STABLE #3: Thu Jun 15 18:33:32 CDT 2006     root at monolith:/usr/src/sys/i386/compile/monolith  i386

If a host is marked as down (e.g. we tried to reach it already with no sucess), tftp will return an exit status of 0.  The output from the code in "How to repeat the problem section" illustrates this behavior.

[host:~] > ./test                                                                                                                                                            
Transfer timed out.                                                                                   
tftp: sendto: Host is down                                                                                   
[host:~] > 

Here is why we exit with code zero the second time, but not the first.                                
The initial timeout is handled by the function 'timer' in tftp, called by                             
sigalarm every so often.  This bails us out the first time.  More                                     
importantly, it sets the variable txrx_error to 1.  The second time we                                
try, the sendto in recvfile fails immediately.  This means we goto the                                
abort label in the recvfile function. Unfortunately nowhere along the way is                                   
txrx_error set to anything, so we get an exit code of 0.  The patch is                                
pretty simple, just add 'txrx_error = 1;' to the end of recvfile function,                            
which is where the abort code is (and I put it in sendfile for parity).                          
Here is a small program to repeat the behavior (note the host should be down):

   #include <stdio.h>                                                                                  
   #include <unistd.h>                                                                                           
   #include <stdlib.h>

   main() {                                                                            
       int code;                                                                                                 
       do {                                                                                   
           code = system("echo get foobar | tftp");                                                                                         
           fprintf(stderr, "code=%i\n", code);                                                                                  
           if(code!=0) sleep(10);                                                                                        
       } while(code!=0);                                                                                                                                                             
Index: tftp.c
RCS file: /home/ncvs/src/usr.bin/tftp/tftp.c,v
retrieving revision 1.12
diff -u -r1.12 tftp.c
--- tftp.c      5 Aug 2005 09:58:49 -0000       1.12
+++ tftp.c      13 Sep 2006 02:53:05 -0000
@@ -205,6 +205,7 @@
        if (amount > 0)
                printstats("Sent", amount);
+       txrx_error = 1;
@@ -330,6 +331,7 @@
        if (amount > 0)
                printstats("Received", amount);
+       txrx_error = 1;
 static int


More information about the freebsd-bugs mailing list