From d5d4b282203f9cb06e77e67021ffdd62abb24d89 Mon Sep 17 00:00:00 2001 From: Martin Pool Date: Mon, 26 Nov 2001 04:52:19 +0000 Subject: [PATCH] Put the new address family option into an options struct. We have too many globals already. Better error messages for network-related failures. --- clientserver.c | 3 ++- options.c | 8 +++---- rsync.h | 5 ++++ socket.c | 62 ++++++++++++++++++++++++++++++++++---------------- 4 files changed, 54 insertions(+), 24 deletions(-) diff --git a/clientserver.c b/clientserver.c index 318a0ec9..aefdb54a 100644 --- a/clientserver.c +++ b/clientserver.c @@ -78,7 +78,8 @@ int start_socket_client(char *host, char *path, int argc, char *argv[]) if (!user) user = getenv("USER"); if (!user) user = getenv("LOGNAME"); - fd = open_socket_out_wrapped (host, rsync_port, bind_address); + fd = open_socket_out_wrapped (host, rsync_port, bind_address, + global_opts.af_hint); if (fd == -1) { exit_cleanup(RERR_SOCKETIO); } diff --git a/options.c b/options.c index 01f4d827..93951176 100644 --- a/options.c +++ b/options.c @@ -74,8 +74,8 @@ int modify_window=0; #endif int blocking_io=0; -/** Network address family. **/ -int af = AF_INET; +/** Global options set from command line. **/ +struct global_opts global_opts; int read_batch=0; /* dw */ int write_batch=0; /* dw */ @@ -314,8 +314,8 @@ static struct poptOption long_options[] = { {"read-batch", 'f', POPT_ARG_STRING, &batch_ext, 'f'}, {"write-batch", 'F', POPT_ARG_NONE, &write_batch, 0}, #ifdef INET6 - {0, '4', POPT_ARG_VAL, &af, AF_INET }, - {0, '6', POPT_ARG_VAL, &af, AF_INET6 }, + {0, '4', POPT_ARG_VAL, &global_opts.af, AF_INET }, + {0, '6', POPT_ARG_VAL, &global_opts.af, AF_INET6 }, #endif {0,0,0,0} }; diff --git a/rsync.h b/rsync.h index c634bc39..9f231199 100644 --- a/rsync.h +++ b/rsync.h @@ -562,3 +562,8 @@ size_t strlcat(char *d, const char *s, size_t bufsize); extern int verbose; + +extern struct global_opts { + /** Network address family. **/ + int af_hint; +} global_opts; diff --git a/socket.c b/socket.c index 0595dc22..993431df 100644 --- a/socket.c +++ b/socket.c @@ -18,10 +18,11 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* - socket functions used in rsync - - */ +/** + * @file socket.c + * + * Socket functions used in rsync. + **/ #include "rsync.h" @@ -29,7 +30,7 @@ #include "lib/addrinfo.h" #endif -extern int af; +// extern int af; /* NO MORE BLOODY GLOBALS! */ /* Establish a proxy connection on an open socket to a web roxy by * using the CONNECT method. */ @@ -96,14 +97,28 @@ static int establish_proxy_connection(int fd, char *host, int port) -/** Open a socket to a tcp remote host with the specified port . +/** + * Open a socket to a tcp remote host with the specified port . * - * Based on code from Warren. Proxy support by Stephen Rothwell + * Based on code from Warren. Proxy support by Stephen Rothwell. + * getaddrinfo() rewrite contributed by KAME.net. * + * Now that we support IPv6 we need to look up the remote machine's + * address first, using @p af_hint to set a preference for the type + * of address. Then depending on whether it has v4 or v6 addresses we + * try to open a connection. * - * @param bind_address Local address to use. Normally NULL to get the stack default. + * The loop allows for machines with some addresses which may not be + * reachable, perhaps because we can't e.g. route ipv6 to that network + * but we can get ip4 packets through. + * + * @param bind_address Local address to use. Normally NULL to bind + * the wildcard address. + * + * @param af_hint Address family, e.g. AF_INET or AF_INET6. **/ -int open_socket_out(char *host, int port, const char *bind_address) +int open_socket_out(char *host, int port, const char *bind_address, + int af_hint) { int type = SOCK_STREAM; int error; @@ -139,11 +154,12 @@ int open_socket_out(char *host, int port, const char *bind_address) } memset(&hints, 0, sizeof(hints)); - hints.ai_family = af; + hints.ai_family = af_hint; hints.ai_socktype = type; error = getaddrinfo(h, portbuf, &hints, &res0); if (error) { - rprintf(FERROR, RSYNC_NAME ": getaddrinfo: %s: %s\n", portbuf, gai_strerror(error)); + rprintf(FERROR, RSYNC_NAME ": getaddrinfo: %s %s: %s\n", + h, portbuf, gai_strerror(error)); return -1; } @@ -162,7 +178,7 @@ int open_socket_out(char *host, int port, const char *bind_address) bhints.ai_flags = AI_PASSIVE; error = getaddrinfo(bind_address, NULL, &bhints, &bres); if (error) { - rprintf(FERROR, RSYNC_NAME ": getaddrinfo: bind address %s: %s\n", + rprintf(FERROR, RSYNC_NAME ": getaddrinfo: bind address %s : %s\n", bind_address, gai_strerror(error)); continue; } @@ -212,14 +228,16 @@ int open_socket_out(char *host, int port, const char *bind_address) **/ int open_socket_out_wrapped (char *host, int port, - const char *bind_address) + const char *bind_address, + int af_hint) { char *prog; if ((prog = getenv ("RSYNC_CONNECT_PROG")) != NULL) return sock_exec (prog); else - return open_socket_out (host, port, bind_address); + return open_socket_out (host, port, bind_address, + af_hint); } @@ -230,7 +248,8 @@ int open_socket_out_wrapped (char *host, * @param bind_address Local address to bind, or NULL to allow it to * default. **/ -static int open_socket_in(int type, int port, const char *bind_address) +static int open_socket_in(int type, int port, const char *bind_address, + int af_hint) { int one=1; int s; @@ -239,7 +258,7 @@ static int open_socket_in(int type, int port, const char *bind_address) int error; memset(&hints, 0, sizeof(hints)); - hints.ai_family = af; + hints.ai_family = af_hint; hints.ai_socktype = type; hints.ai_flags = AI_PASSIVE; snprintf(portbuf, sizeof(portbuf), "%d", port); @@ -311,7 +330,8 @@ void start_accept_loop(int port, int (*fn)(int )) extern char *bind_address; /* open an incoming socket */ - s = open_socket_in(SOCK_STREAM, port, bind_address); + s = open_socket_in(SOCK_STREAM, port, bind_address, + global_opts.af_hint); if (s == -1) exit_cleanup(RERR_SOCKETIO); @@ -550,6 +570,9 @@ char *client_name(int fd) strcpy(name_buf,def); if (getpeername(fd, (struct sockaddr *)&ss, &length)) { + /* FIXME: Can we really not continue? */ + rprintf(FERROR, RSYNC_NAME ": getpeername on fd%d failed: %s\n", + strerror(errno)); exit_cleanup(RERR_SOCKETIO); } @@ -610,8 +633,9 @@ char *client_name(int fd) if (res == NULL) { strcpy(name_buf, def); - rprintf(FERROR, - "reverse name lookup mismatch - spoofed address?\n"); + rprintf(FERROR, RSYNC_NAME ": " + "reverse name lookup mismatch on fd%d - spoofed address?\n", + fd); } freeaddrinfo(res0); -- 2.34.1