Commit d5d4b282 authored by Martin Pool's avatar Martin Pool

Put the new address family option into an options struct. We have too

many globals already.

Better error messages for network-related failures.
parent a037edac
...@@ -78,7 +78,8 @@ int start_socket_client(char *host, char *path, int argc, char *argv[]) ...@@ -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("USER");
if (!user) user = getenv("LOGNAME"); 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) { if (fd == -1) {
exit_cleanup(RERR_SOCKETIO); exit_cleanup(RERR_SOCKETIO);
} }
......
...@@ -74,8 +74,8 @@ int modify_window=0; ...@@ -74,8 +74,8 @@ int modify_window=0;
#endif #endif
int blocking_io=0; int blocking_io=0;
/** Network address family. **/ /** Global options set from command line. **/
int af = AF_INET; struct global_opts global_opts;
int read_batch=0; /* dw */ int read_batch=0; /* dw */
int write_batch=0; /* dw */ int write_batch=0; /* dw */
...@@ -314,8 +314,8 @@ static struct poptOption long_options[] = { ...@@ -314,8 +314,8 @@ static struct poptOption long_options[] = {
{"read-batch", 'f', POPT_ARG_STRING, &batch_ext, 'f'}, {"read-batch", 'f', POPT_ARG_STRING, &batch_ext, 'f'},
{"write-batch", 'F', POPT_ARG_NONE, &write_batch, 0}, {"write-batch", 'F', POPT_ARG_NONE, &write_batch, 0},
#ifdef INET6 #ifdef INET6
{0, '4', POPT_ARG_VAL, &af, AF_INET }, {0, '4', POPT_ARG_VAL, &global_opts.af, AF_INET },
{0, '6', POPT_ARG_VAL, &af, AF_INET6 }, {0, '6', POPT_ARG_VAL, &global_opts.af, AF_INET6 },
#endif #endif
{0,0,0,0} {0,0,0,0}
}; };
......
...@@ -562,3 +562,8 @@ size_t strlcat(char *d, const char *s, size_t bufsize); ...@@ -562,3 +562,8 @@ size_t strlcat(char *d, const char *s, size_t bufsize);
extern int verbose; extern int verbose;
extern struct global_opts {
/** Network address family. **/
int af_hint;
} global_opts;
...@@ -18,10 +18,11 @@ ...@@ -18,10 +18,11 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 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" #include "rsync.h"
...@@ -29,7 +30,7 @@ ...@@ -29,7 +30,7 @@
#include "lib/addrinfo.h" #include "lib/addrinfo.h"
#endif #endif
extern int af; // extern int af; /* NO MORE BLOODY GLOBALS! */
/* Establish a proxy connection on an open socket to a web roxy by /* Establish a proxy connection on an open socket to a web roxy by
* using the CONNECT method. */ * using the CONNECT method. */
...@@ -96,14 +97,28 @@ static int establish_proxy_connection(int fd, char *host, int port) ...@@ -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 type = SOCK_STREAM;
int error; int error;
...@@ -139,11 +154,12 @@ int open_socket_out(char *host, int port, const char *bind_address) ...@@ -139,11 +154,12 @@ int open_socket_out(char *host, int port, const char *bind_address)
} }
memset(&hints, 0, sizeof(hints)); memset(&hints, 0, sizeof(hints));
hints.ai_family = af; hints.ai_family = af_hint;
hints.ai_socktype = type; hints.ai_socktype = type;
error = getaddrinfo(h, portbuf, &hints, &res0); error = getaddrinfo(h, portbuf, &hints, &res0);
if (error) { 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; return -1;
} }
...@@ -162,7 +178,7 @@ int open_socket_out(char *host, int port, const char *bind_address) ...@@ -162,7 +178,7 @@ int open_socket_out(char *host, int port, const char *bind_address)
bhints.ai_flags = AI_PASSIVE; bhints.ai_flags = AI_PASSIVE;
error = getaddrinfo(bind_address, NULL, &bhints, &bres); error = getaddrinfo(bind_address, NULL, &bhints, &bres);
if (error) { if (error) {
rprintf(FERROR, RSYNC_NAME ": getaddrinfo: bind address %s: %s\n", rprintf(FERROR, RSYNC_NAME ": getaddrinfo: bind address %s <noport>: %s\n",
bind_address, gai_strerror(error)); bind_address, gai_strerror(error));
continue; continue;
} }
...@@ -212,14 +228,16 @@ int open_socket_out(char *host, int port, const char *bind_address) ...@@ -212,14 +228,16 @@ int open_socket_out(char *host, int port, const char *bind_address)
**/ **/
int open_socket_out_wrapped (char *host, int open_socket_out_wrapped (char *host,
int port, int port,
const char *bind_address) const char *bind_address,
int af_hint)
{ {
char *prog; char *prog;
if ((prog = getenv ("RSYNC_CONNECT_PROG")) != NULL) if ((prog = getenv ("RSYNC_CONNECT_PROG")) != NULL)
return sock_exec (prog); return sock_exec (prog);
else 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, ...@@ -230,7 +248,8 @@ int open_socket_out_wrapped (char *host,
* @param bind_address Local address to bind, or NULL to allow it to * @param bind_address Local address to bind, or NULL to allow it to
* default. * 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 one=1;
int s; int s;
...@@ -239,7 +258,7 @@ static int open_socket_in(int type, int port, const char *bind_address) ...@@ -239,7 +258,7 @@ static int open_socket_in(int type, int port, const char *bind_address)
int error; int error;
memset(&hints, 0, sizeof(hints)); memset(&hints, 0, sizeof(hints));
hints.ai_family = af; hints.ai_family = af_hint;
hints.ai_socktype = type; hints.ai_socktype = type;
hints.ai_flags = AI_PASSIVE; hints.ai_flags = AI_PASSIVE;
snprintf(portbuf, sizeof(portbuf), "%d", port); snprintf(portbuf, sizeof(portbuf), "%d", port);
...@@ -311,7 +330,8 @@ void start_accept_loop(int port, int (*fn)(int )) ...@@ -311,7 +330,8 @@ void start_accept_loop(int port, int (*fn)(int ))
extern char *bind_address; extern char *bind_address;
/* open an incoming socket */ /* 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) if (s == -1)
exit_cleanup(RERR_SOCKETIO); exit_cleanup(RERR_SOCKETIO);
...@@ -550,6 +570,9 @@ char *client_name(int fd) ...@@ -550,6 +570,9 @@ char *client_name(int fd)
strcpy(name_buf,def); strcpy(name_buf,def);
if (getpeername(fd, (struct sockaddr *)&ss, &length)) { 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); exit_cleanup(RERR_SOCKETIO);
} }
...@@ -610,8 +633,9 @@ char *client_name(int fd) ...@@ -610,8 +633,9 @@ char *client_name(int fd)
if (res == NULL) { if (res == NULL) {
strcpy(name_buf, def); strcpy(name_buf, def);
rprintf(FERROR, rprintf(FERROR, RSYNC_NAME ": "
"reverse name lookup mismatch - spoofed address?\n"); "reverse name lookup mismatch on fd%d - spoofed address?\n",
fd);
} }
freeaddrinfo(res0); freeaddrinfo(res0);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment