| 1 | This patch adds a connection timeout option, --contimeout. |
| 2 | |
| 3 | To use this patch, run these commands for a successful build: |
| 4 | |
| 5 | patch -p1 <patches/contimeout.diff |
| 6 | ./configure (optional if already run) |
| 7 | make |
| 8 | |
| 9 | --- old/errcode.h |
| 10 | +++ new/errcode.h |
| 11 | @@ -45,6 +45,7 @@ |
| 12 | #define RERR_DEL_LIMIT 25 /* skipped some deletes due to --max-delete */ |
| 13 | |
| 14 | #define RERR_TIMEOUT 30 /* timeout in data send/receive */ |
| 15 | +#define RERR_CONTIMEOUT 35 /* timeout waiting for daemon connection */ |
| 16 | |
| 17 | /* Although it doesn't seem to be specified anywhere, |
| 18 | * ssh and the shell seem to return these values: |
| 19 | --- old/log.c |
| 20 | +++ new/log.c |
| 21 | @@ -86,6 +86,7 @@ struct { |
| 22 | { RERR_PARTIAL , "some files could not be transferred" }, |
| 23 | { RERR_VANISHED , "some files vanished before they could be transferred" }, |
| 24 | { RERR_TIMEOUT , "timeout in data send/receive" }, |
| 25 | + { RERR_CONTIMEOUT , "timeout waiting for daemon connection" }, |
| 26 | { RERR_CMD_FAILED , "remote shell failed" }, |
| 27 | { RERR_CMD_KILLED , "remote shell killed" }, |
| 28 | { RERR_CMD_RUN , "remote command could not be run" }, |
| 29 | --- old/options.c |
| 30 | +++ new/options.c |
| 31 | @@ -99,6 +99,7 @@ int xfer_dirs = -1; |
| 32 | int am_daemon = 0; |
| 33 | int do_stats = 0; |
| 34 | int do_progress = 0; |
| 35 | +int connect_timeout = 0; |
| 36 | int keep_partial = 0; |
| 37 | int safe_symlinks = 0; |
| 38 | int copy_unsafe_links = 0; |
| 39 | @@ -603,6 +604,7 @@ static struct poptOption long_options[] |
| 40 | {"no-numeric-ids", 0, POPT_ARG_VAL, &numeric_ids, 0, 0, 0 }, |
| 41 | {"timeout", 0, POPT_ARG_INT, &io_timeout, 0, 0, 0 }, |
| 42 | {"no-timeout", 0, POPT_ARG_VAL, &io_timeout, 0, 0, 0 }, |
| 43 | + {"contimeout", 0, POPT_ARG_INT, &connect_timeout, 0, 0, 0 }, |
| 44 | {"rsh", 'e', POPT_ARG_STRING, &shell_cmd, 0, 0, 0 }, |
| 45 | {"rsync-path", 0, POPT_ARG_STRING, &rsync_path, 0, 0, 0 }, |
| 46 | {"temp-dir", 'T', POPT_ARG_STRING, &tmpdir, 0, 0, 0 }, |
| 47 | --- old/rsync.yo |
| 48 | +++ new/rsync.yo |
| 49 | @@ -2775,6 +2775,7 @@ dit(bf(23)) Partial transfer due to erro |
| 50 | dit(bf(24)) Partial transfer due to vanished source files |
| 51 | dit(bf(25)) The --max-delete limit stopped deletions |
| 52 | dit(bf(30)) Timeout in data send/receive |
| 53 | +dit(bf(35)) Timeout waiting for daemon connection |
| 54 | enddit() |
| 55 | |
| 56 | manpagesection(ENVIRONMENT VARIABLES) |
| 57 | --- old/socket.c |
| 58 | +++ new/socket.c |
| 59 | @@ -32,6 +32,7 @@ |
| 60 | |
| 61 | extern char *bind_address; |
| 62 | extern int default_af_hint; |
| 63 | +extern int connect_timeout; |
| 64 | |
| 65 | #ifdef HAVE_SIGACTION |
| 66 | static struct sigaction sigact; |
| 67 | @@ -157,6 +158,11 @@ int try_bind_local(int s, int ai_family, |
| 68 | return -1; |
| 69 | } |
| 70 | |
| 71 | +/* connect() timeout handler based on alarm() */ |
| 72 | +static RETSIGTYPE contimeout_handler(UNUSED(int val)) |
| 73 | +{ |
| 74 | + connect_timeout = -1; |
| 75 | +} |
| 76 | |
| 77 | /** |
| 78 | * Open a socket to a tcp remote host with the specified port . |
| 79 | @@ -261,11 +267,27 @@ int open_socket_out(char *host, int port |
| 80 | s = -1; |
| 81 | continue; |
| 82 | } |
| 83 | - if (connect(s, res->ai_addr, res->ai_addrlen) < 0) { |
| 84 | + if (connect_timeout > 0) { |
| 85 | + SIGACTION(SIGALRM, contimeout_handler); |
| 86 | + alarm(connect_timeout); |
| 87 | + } |
| 88 | + |
| 89 | + while (connect(s, res->ai_addr, res->ai_addrlen) < 0) { |
| 90 | + if (connect_timeout < 0) |
| 91 | + exit_cleanup(RERR_CONTIMEOUT); |
| 92 | + if (errno == EINTR) |
| 93 | + continue; |
| 94 | close(s); |
| 95 | s = -1; |
| 96 | - continue; |
| 97 | + break; |
| 98 | } |
| 99 | + |
| 100 | + if (connect_timeout > 0) |
| 101 | + alarm(0); |
| 102 | + |
| 103 | + if (s < 0) |
| 104 | + continue; |
| 105 | + |
| 106 | if (proxied |
| 107 | && establish_proxy_connection(s, host, port, |
| 108 | proxy_user, proxy_pass) != 0) { |