1 /* -*- c-file-style: "linux" -*-
3 rsync -- fast file replication program
5 Copyright (C) 1992-2001 by Andrew Tridgell <tridge@samba.org>
6 Copyright (C) 2001, 2002 by Martin Pool <mbp@samba.org>
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 * Socket functions used in rsync.
28 * This file is now converted to use the new-style getaddrinfo()
29 * interface, which supports IPv6 but is also supported on recent
30 * IPv4-only machines. On systems that don't have that interface, we
31 * emulate it using the KAME implementation.
37 /* Establish a proxy connection on an open socket to a web roxy by
38 * using the CONNECT method. */
39 static int establish_proxy_connection(int fd, char *host, int port)
44 snprintf(buffer, sizeof(buffer), "CONNECT %s:%d HTTP/1.0\r\n\r\n", host, port);
45 if (write(fd, buffer, strlen(buffer)) != (int) strlen(buffer)) {
46 rprintf(FERROR, "failed to write to proxy: %s\n",
51 for (cp = buffer; cp < &buffer[sizeof(buffer) - 1]; cp++) {
52 if (read(fd, cp, 1) != 1) {
53 rprintf(FERROR, "failed to read from proxy: %s\n",
66 if (strncmp(buffer, "HTTP/", 5) != 0) {
67 rprintf(FERROR, "bad response from proxy - %s\n",
71 for (cp = &buffer[5]; isdigit(*cp) || (*cp == '.'); cp++)
76 rprintf(FERROR, "bad response from proxy - %s\n",
80 /* throw away the rest of the HTTP header */
82 for (cp = buffer; cp < &buffer[sizeof(buffer) - 1];
84 if (read(fd, cp, 1) != 1) {
85 rprintf(FERROR, "failed to read from proxy: %s\n",
92 if ((cp > buffer) && (*cp == '\n'))
94 if ((cp == buffer) && ((*cp == '\n') || (*cp == '\r')))
102 * Try to set the local address for a newly-created socket. Return -1
105 int try_bind_local(int s,
106 int ai_family, int ai_socktype,
107 const char *bind_address)
110 struct addrinfo bhints, *bres_all, *r;
112 memset(&bhints, 0, sizeof(bhints));
113 bhints.ai_family = ai_family;
114 bhints.ai_socktype = ai_socktype;
115 bhints.ai_flags = AI_PASSIVE;
116 if ((error = getaddrinfo(bind_address, NULL, &bhints, &bres_all))) {
117 rprintf(FERROR, RSYNC_NAME ": getaddrinfo %s: %s\n",
118 bind_address, gai_strerror(error));
122 for (r = bres_all; r; r = r->ai_next) {
123 if (bind(s, r->ai_addr, r->ai_addrlen) == -1)
128 /* no error message; there might be some problem that allows
129 * creation of the socket but not binding, perhaps if the
130 * machine has no ipv6 address of this name. */
136 * Open a socket to a tcp remote host with the specified port .
138 * Based on code from Warren. Proxy support by Stephen Rothwell.
139 * getaddrinfo() rewrite contributed by KAME.net.
141 * Now that we support IPv6 we need to look up the remote machine's
142 * address first, using @p af_hint to set a preference for the type
143 * of address. Then depending on whether it has v4 or v6 addresses we
144 * try to open a connection.
146 * The loop allows for machines with some addresses which may not be
147 * reachable, perhaps because we can't e.g. route ipv6 to that network
148 * but we can get ip4 packets through.
150 * @param bind_address Local address to use. Normally NULL to bind
151 * the wildcard address.
153 * @param af_hint Address family, e.g. AF_INET or AF_INET6.
155 int open_socket_out(char *host, int port, const char *bind_address,
158 int type = SOCK_STREAM;
161 struct addrinfo hints, *res0, *res;
168 /* if we have a RSYNC_PROXY env variable then redirect our
169 * connetcion via a web proxy at the given address. The format
170 * is hostname:port */
171 h = getenv("RSYNC_PROXY");
172 proxied = (h != NULL) && (*h != '\0');
175 strlcpy(buffer, h, sizeof(buffer));
176 cp = strchr(buffer, ':');
179 "invalid proxy specification: should be HOST:PORT\n");
186 rprintf(FINFO, "connection via http proxy %s port %s\n",
190 snprintf(portbuf, sizeof(portbuf), "%d", port);
194 memset(&hints, 0, sizeof(hints));
195 hints.ai_family = af_hint;
196 hints.ai_socktype = type;
197 error = getaddrinfo(h, portbuf, &hints, &res0);
199 rprintf(FERROR, RSYNC_NAME ": getaddrinfo: %s %s: %s\n",
200 h, portbuf, gai_strerror(error));
205 /* Try to connect to all addresses for this machine until we get
206 * through. It might e.g. be multi-homed, or have both IPv4 and IPv6
207 * addresses. We need to create a socket for each record, since the
208 * address record tells us what protocol to use to try to connect. */
209 for (res = res0; res; res = res->ai_next) {
210 s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
215 if (try_bind_local(s, res->ai_family, type,
216 bind_address) == -1) {
222 if (connect(s, res->ai_addr, res->ai_addrlen) < 0) {
228 establish_proxy_connection(s, host, port) != 0) {
237 rprintf(FERROR, RSYNC_NAME ": failed to connect to %s: %s\n",
246 * Open an outgoing socket, but allow for it to be intercepted by
247 * $RSYNC_CONNECT_PROG, which will execute a program across a TCP
248 * socketpair rather than really opening a socket.
250 * We use this primarily in testing to detect TCP flow bugs, but not
251 * cause security problems by really opening remote connections.
253 * This is based on the Samba LIBSMB_PROG feature.
255 * @param bind_address Local address to use. Normally NULL to get the stack default.
257 int open_socket_out_wrapped (char *host,
259 const char *bind_address,
264 if ((prog = getenv ("RSYNC_CONNECT_PROG")) != NULL)
265 return sock_exec (prog);
267 return open_socket_out (host, port, bind_address,
274 * Open a socket of the specified type, port and address for incoming data
276 * Try to be better about handling the results of getaddrinfo(): when
277 * opening an inbound socket, we might get several address results,
278 * e.g. for the machine's ipv4 and ipv6 name.
280 * If binding a wildcard, then any one of them should do. If an address
281 * was specified but it's insufficiently specific then that's not our
284 * However, some of the advertized addresses may not work because e.g. we
285 * don't have IPv6 support in the kernel. In that case go on and try all
286 * addresses until one succeeds.
288 * @param bind_address Local address to bind, or NULL to allow it to
291 static int open_socket_in(int type, int port, const char *bind_address,
296 struct addrinfo hints, *all_ai, *resp;
300 memset(&hints, 0, sizeof(hints));
301 hints.ai_family = af_hint;
302 hints.ai_socktype = type;
303 hints.ai_flags = AI_PASSIVE;
304 snprintf(portbuf, sizeof(portbuf), "%d", port);
305 error = getaddrinfo(bind_address, portbuf, &hints, &all_ai);
307 rprintf(FERROR, RSYNC_NAME ": getaddrinfo: bind address %s: %s\n",
308 bind_address, gai_strerror(error));
312 /* We may not be able to create the socket, if for example the
313 * machine knows about IPv6 in the C library, but not in the
315 for (resp = all_ai; resp; resp = resp->ai_next) {
316 s = socket(resp->ai_family, resp->ai_socktype,
320 /* See if there's another address that will work... */
323 setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
324 (char *)&one, sizeof one);
326 /* now we've got a socket - we need to bind it */
327 if (bind(s, all_ai->ai_addr, all_ai->ai_addrlen) < 0) {
328 /* Nope, try another */
336 rprintf(FERROR, RSYNC_NAME ": open inbound socket on port %d failed: "
341 freeaddrinfo(all_ai);
347 * Determine if a file descriptor is in fact a socket
349 int is_a_socket(int fd)
355 /* Parameters to getsockopt, setsockopt etc are very
356 * unstandardized across platforms, so don't be surprised if
357 * there are compiler warnings on e.g. SCO OpenSwerver or AIX.
358 * It seems they all eventually get the right idea.
360 * Debian says: ``The fifth argument of getsockopt and
361 * setsockopt is in reality an int [*] (and this is what BSD
362 * 4.* and libc4 and libc5 have). Some POSIX confusion
363 * resulted in the present socklen_t. The draft standard has
364 * not been adopted yet, but glibc2 already follows it and
365 * also has socklen_t [*]. See also accept(2).''
367 * We now return to your regularly scheduled programming. */
368 return(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&v, &l) == 0);
372 void start_accept_loop(int port, int (*fn)(int ))
375 extern char *bind_address;
376 extern int default_af_hint;
378 /* open an incoming socket */
379 s = open_socket_in(SOCK_STREAM, port, bind_address, default_af_hint);
381 exit_cleanup(RERR_SOCKETIO);
383 /* ready to listen */
384 if (listen(s, 5) == -1) {
386 exit_cleanup(RERR_SOCKETIO);
390 /* now accept incoming connections - forking a new process
391 for each incoming connection */
396 struct sockaddr_storage addr;
397 socklen_t addrlen = sizeof addr;
399 /* close log file before the potentially very long select so
400 file can be trimmed by another process instead of growing
407 if (select(s+1, &fds, NULL, NULL, NULL) != 1) {
411 if(!FD_ISSET(s, &fds)) continue;
413 fd = accept(s,(struct sockaddr *)&addr,&addrlen);
415 if (fd == -1) continue;
417 signal(SIGCHLD, SIG_IGN);
419 /* we shouldn't have any children left hanging around
420 but I have had reports that on Digital Unix zombies
421 are produced, so this ensures that they are reaped */
423 while (waitpid(-1, NULL, WNOHANG) > 0);
426 if ((pid = fork()) == 0) {
428 /* open log file in child before possibly giving
432 } else if (pid < 0) {
435 ": could not create child server process: %s\n",
438 /* This might have happened because we're
439 * overloaded. Sleep briefly before trying to
443 /* Parent doesn't need this fd anymore. */
450 enum SOCK_OPT_TYPES {OPT_BOOL,OPT_INT,OPT_ON};
459 } socket_options[] = {
460 {"SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE, 0, OPT_BOOL},
461 {"SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR, 0, OPT_BOOL},
462 {"SO_BROADCAST", SOL_SOCKET, SO_BROADCAST, 0, OPT_BOOL},
464 {"TCP_NODELAY", IPPROTO_TCP, TCP_NODELAY, 0, OPT_BOOL},
466 #ifdef IPTOS_LOWDELAY
467 {"IPTOS_LOWDELAY", IPPROTO_IP, IP_TOS, IPTOS_LOWDELAY, OPT_ON},
469 #ifdef IPTOS_THROUGHPUT
470 {"IPTOS_THROUGHPUT", IPPROTO_IP, IP_TOS, IPTOS_THROUGHPUT, OPT_ON},
473 {"SO_SNDBUF", SOL_SOCKET, SO_SNDBUF, 0, OPT_INT},
476 {"SO_RCVBUF", SOL_SOCKET, SO_RCVBUF, 0, OPT_INT},
479 {"SO_SNDLOWAT", SOL_SOCKET, SO_SNDLOWAT, 0, OPT_INT},
482 {"SO_RCVLOWAT", SOL_SOCKET, SO_RCVLOWAT, 0, OPT_INT},
485 {"SO_SNDTIMEO", SOL_SOCKET, SO_SNDTIMEO, 0, OPT_INT},
488 {"SO_RCVTIMEO", SOL_SOCKET, SO_RCVTIMEO, 0, OPT_INT},
494 /****************************************************************************
495 set user socket options
496 ****************************************************************************/
497 void set_socket_options(int fd, char *options)
500 if (!options || !*options) return;
502 options = strdup(options);
504 if (!options) out_of_memory("set_socket_options");
506 for (tok=strtok(options, " \t,"); tok; tok=strtok(NULL," \t,")) {
512 if ((p = strchr(tok,'='))) {
518 for (i=0;socket_options[i].name;i++)
519 if (strcmp(socket_options[i].name,tok)==0)
522 if (!socket_options[i].name) {
523 rprintf(FERROR,"Unknown socket option %s\n",tok);
527 switch (socket_options[i].opttype) {
530 ret = setsockopt(fd,socket_options[i].level,
531 socket_options[i].option,(char *)&value,sizeof(int));
536 rprintf(FERROR,"syntax error - %s does not take a value\n",tok);
539 int on = socket_options[i].value;
540 ret = setsockopt(fd,socket_options[i].level,
541 socket_options[i].option,(char *)&on,sizeof(int));
547 rprintf(FERROR, "failed to set socket option %s: %s\n", tok,
554 /****************************************************************************
555 become a daemon, discarding the controlling terminal
556 ****************************************************************************/
557 void become_daemon(void)
565 /* detach from the terminal */
570 i = open("/dev/tty", O_RDWR);
572 ioctl(i, (int) TIOCNOTTY, (char *)0);
575 #endif /* TIOCNOTTY */
577 /* make sure that stdin, stdout an stderr don't stuff things
578 up (library functions, for example) */
581 open("/dev/null", O_RDWR);
586 /*******************************************************************
587 this is like socketpair but uses tcp. It is used by the Samba
589 The function guarantees that nobody else can attach to the socket,
590 or if they do that this function fails and the socket gets closed
591 returns 0 on success, -1 on failure
592 the resulting file descriptors are symmetrical
593 ******************************************************************/
594 static int socketpair_tcp(int fd[2])
597 struct sockaddr_in sock;
598 struct sockaddr_in sock2;
599 socklen_t socklen = sizeof(sock);
600 int connect_done = 0;
602 fd[0] = fd[1] = listener = -1;
604 memset(&sock, 0, sizeof(sock));
606 if ((listener = socket(PF_INET, SOCK_STREAM, 0)) == -1) goto failed;
608 memset(&sock2, 0, sizeof(sock2));
609 #ifdef HAVE_SOCKADDR_LEN
610 sock2.sin_len = sizeof(sock2);
612 sock2.sin_family = PF_INET;
614 bind(listener, (struct sockaddr *)&sock2, sizeof(sock2));
616 if (listen(listener, 1) != 0) goto failed;
618 if (getsockname(listener, (struct sockaddr *)&sock, &socklen) != 0) goto failed;
620 if ((fd[1] = socket(PF_INET, SOCK_STREAM, 0)) == -1) goto failed;
622 set_nonblocking(fd[1]);
624 sock.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
626 if (connect(fd[1],(struct sockaddr *)&sock,sizeof(sock)) == -1) {
627 if (errno != EINPROGRESS) goto failed;
632 if ((fd[0] = accept(listener, (struct sockaddr *)&sock, &socklen)) == -1) goto failed;
635 if (connect_done == 0) {
636 if (connect(fd[1],(struct sockaddr *)&sock,sizeof(sock)) != 0
637 && errno != EISCONN) goto failed;
640 set_blocking (fd[1]);
646 if (fd[0] != -1) close(fd[0]);
647 if (fd[1] != -1) close(fd[1]);
648 if (listener != -1) close(listener);
655 * Run a program on a local tcp socket, so that we can talk to it's
656 * stdin and stdout. This is used to fake a connection to a daemon
657 * for testing -- not for the normal case of running SSH.
659 * @return a socket which is attached to a subprocess running
660 * "prog". stdin and stdout are attached. stderr is left attached to
661 * the original stderr
663 int sock_exec(const char *prog)
667 if (socketpair_tcp(fd) != 0) {
668 rprintf (FERROR, RSYNC_NAME
669 ": socketpair_tcp failed (%s)\n",
680 /* Can't use rprintf because we've forked. */
682 RSYNC_NAME ": execute socket program \"%s\"\n",
685 exit (system (prog));