tech-net archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

ftp diags with multiple peer addresses, some unreachable



Hi,

a discussion on tech-user@ has reminded me that the same perceived problem
came up at least one time in the past.

When a peer name resolves to multiple addresses, and the first one
in the list is not reachable, ftp tries the next one until the list
is exausted or a connection succeeds. (This can happen often on
the current network, when servers have e.g. one or multiple IPv6
and IPv4 address records in DNS, and the client doesn't have
connectivity for one of the address families).

This works fine per default - here's output from my test setup:

# ftp ftp.netbsd.org
Trying 2001:470:1f05:3d::21:21 ...
ftp: Can't connect to `2001:470:1f05:3d::21:21': No route to host
Trying 199.233.217.249:21 ...
Connected to ftp.netbsd.org.
220 ftp.NetBSD.org FTP server (NetBSD-ftpd 20100320) ready.
Name (ftp.netbsd.org:root): 

However, if the verbose mode is switched off (e.g. through the 
command line option -V), it looks like this with the normal tool:


> ftp -V ftp.netbsd.org
ftp: Can't connect to `2001:470:1f05:3d::21:21': No route to host
Name (ftp.netbsd.org:ignatios): 

Note that we get an error message and then a prompt for auth
information. How are those related? The "Name" prompt is not for
the address mentioned on the line above!

My proposal is to suppress, in terse mode only, the error message
*for EHOSTUNREACH* if we still have more addresses to try.

The verbose output from above doesn't change (in fact, it's from my
patched ftp); the terse one changes to this:

# ftp -V ftp.netbsd.org
Name (ftp.netbsd.org:root):

I do not think that other errors should be suppressed in any case.
The exception for EHOSTUNREACH is IMO warranted because it's a
condition that will show up often; and the user has explicitly asked
to not be bothered with non-fatal messages.

Diff is appended.

Regards,
        -is
? usr.bin/ftp/ftp.c.blame
Index: usr.bin/ftp/extern.h
===================================================================
RCS file: /cvsroot/src/usr.bin/ftp/extern.h,v
retrieving revision 1.79
diff -u -r1.79 extern.h
--- usr.bin/ftp/extern.h        16 Sep 2011 15:39:26 -0000      1.79
+++ usr.bin/ftp/extern.h        28 Jun 2012 11:58:23 -0000
@@ -239,7 +239,7 @@
 void   updatelocalcwd(void);
 void   updateremotecwd(void);
 void   user(int, char **);
-int    ftp_connect(int, const struct sockaddr *, socklen_t);
+int    ftp_connect(int, const struct sockaddr *, socklen_t, int);
 int    ftp_listen(int, int);
 int    ftp_poll(struct pollfd *, int, int);
 void   *ftp_malloc(size_t);
Index: usr.bin/ftp/fetch.c
===================================================================
RCS file: /cvsroot/src/usr.bin/ftp/fetch.c,v
retrieving revision 1.195
diff -u -r1.195 fetch.c
--- usr.bin/ftp/fetch.c 10 Dec 2011 05:53:58 -0000      1.195
+++ usr.bin/ftp/fetch.c 28 Jun 2012 11:58:23 -0000
@@ -734,7 +734,8 @@
                                continue;
                        }
 
-                       if (ftp_connect(s, res->ai_addr, res->ai_addrlen) < 0) {
+                       if (ftp_connect(s, res->ai_addr, res->ai_addrlen,
+                           verbose || !res->ai_next) < 0) {
                                close(s);
                                s = -1;
                                continue;
Index: usr.bin/ftp/ftp.c
===================================================================
RCS file: /cvsroot/src/usr.bin/ftp/ftp.c,v
retrieving revision 1.163
diff -u -r1.163 ftp.c
--- usr.bin/ftp/ftp.c   10 Dec 2011 05:53:58 -0000      1.163
+++ usr.bin/ftp/ftp.c   28 Jun 2012 11:58:23 -0000
@@ -208,7 +208,8 @@
                            hname, sname);
                        continue;
                }
-               if (ftp_connect(s, res->ai_addr, res->ai_addrlen) < 0) {
+               if (ftp_connect(s, res->ai_addr, res->ai_addrlen,
+                   verbose || !res->ai_next) < 0) {
                        close(s);
                        s = -1;
                        continue;
@@ -1468,7 +1469,7 @@
                        goto bad;
 
                if (ftp_connect(data, (struct sockaddr *)&data_addr.si_su,
-                   data_addr.su_len) < 0) {
+                   data_addr.su_len, 1) < 0) {
                        if (activefallback) {
                                (void)close(data);
                                data = -1;
Index: usr.bin/ftp/util.c
===================================================================
RCS file: /cvsroot/src/usr.bin/ftp/util.c,v
retrieving revision 1.156
diff -u -r1.156 util.c
--- usr.bin/ftp/util.c  10 Dec 2011 05:53:58 -0000      1.156
+++ usr.bin/ftp/util.c  28 Jun 2012 11:58:23 -0000
@@ -1351,7 +1351,7 @@
  * error message displayed.)
  */
 int
-ftp_connect(int sock, const struct sockaddr *name, socklen_t namelen)
+ftp_connect(int sock, const struct sockaddr *name, socklen_t namelen, int pe)
 {
        int             flags, rv, timeout, error;
        socklen_t       slen;
@@ -1417,8 +1417,9 @@
        rv = connect(sock, name, namelen);      /* inititate the connection */
        if (rv == -1) {                         /* connection error */
                if (errno != EINPROGRESS) {     /* error isn't "please wait" */
+                       if (pe || (errno != EHOSTUNREACH))
  connecterror:
-                       warn("Can't connect to `%s:%s'", hname, sname);
+                               warn("Can't connect to `%s:%s'", hname, sname);
                        return -1;
                }
 


Home | Main Index | Thread Index | Old Index