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.
36 /* Establish a proxy connection on an open socket to a web roxy by
37 * using the CONNECT method. */
38 static int establish_proxy_connection(int fd, char *host, int port)
43 snprintf(buffer, sizeof(buffer), "CONNECT %s:%d HTTP/1.0\r\n\r\n", host, port);
44 if (write(fd, buffer, strlen(buffer)) != strlen(buffer)) {
45 rprintf(FERROR, "failed to write to proxy: %s\n",
50 for (cp = buffer; cp < &buffer[sizeof(buffer) - 1]; cp++) {
51 if (read(fd, cp, 1) != 1) {
52 rprintf(FERROR, "failed to read from proxy: %s\n",
65 if (strncmp(buffer, "HTTP/", 5) != 0) {
66 rprintf(FERROR, "bad response from proxy - %s\n",
70 for (cp = &buffer[5]; isdigit(*cp) || (*cp == '.'); cp++)
75 rprintf(FERROR, "bad response from proxy - %s\n",
79 /* throw away the rest of the HTTP header */
81 for (cp = buffer; cp < &buffer[sizeof(buffer) - 1];
83 if (read(fd, cp, 1) != 1) {
84 rprintf(FERROR, "failed to read from proxy: %s\n",
91 if ((cp > buffer) && (*cp == '\n'))
93 if ((cp == buffer) && ((*cp == '\n') || (*cp == '\r')))
101 * Try to set the local address for a newly-created socket. Return -1
104 int try_bind_local(int s,
105 int ai_family, int ai_socktype,
106 const char *bind_address)
109 struct addrinfo bhints, *bres_all, *r;
111 memset(&bhints, 0, sizeof(bhints));
112 bhints.ai_family = ai_family;
113 bhints.ai_socktype = ai_socktype;
114 bhints.ai_flags = AI_PASSIVE;
115 if ((error = getaddrinfo(bind_address, NULL, &bhints, &bres_all))) {
116 rprintf(FERROR, RSYNC_NAME ": getaddrinfo %s: %s\n",
117 bind_address, gai_strerror(error));
121 for (r = bres_all; r; r = r->ai_next) {
122 if (bind(s, r->ai_addr, r->ai_addrlen) == -1)
127 /* no error message; there might be some problem that allows
128 * creation of the socket but not binding, perhaps if the
129 * machine has no ipv6 address of this name. */
135 * Open a socket to a tcp remote host with the specified port .
137 * Based on code from Warren. Proxy support by Stephen Rothwell.
138 * getaddrinfo() rewrite contributed by KAME.net.
140 * Now that we support IPv6 we need to look up the remote machine's
141 * address first, using @p af_hint to set a preference for the type
142 * of address. Then depending on whether it has v4 or v6 addresses we
143 * try to open a connection.
145 * The loop allows for machines with some addresses which may not be
146 * reachable, perhaps because we can't e.g. route ipv6 to that network
147 * but we can get ip4 packets through.
149 * @param bind_address Local address to use. Normally NULL to bind
150 * the wildcard address.
152 * @param af_hint Address family, e.g. AF_INET or AF_INET6.
154 int open_socket_out(char *host, int port, const char *bind_address,
157 int type = SOCK_STREAM;
160 struct addrinfo hints, *res0, *res;
167 /* if we have a RSYNC_PROXY env variable then redirect our
168 * connetcion via a web proxy at the given address. The format
169 * is hostname:port */
170 h = getenv("RSYNC_PROXY");
171 proxied = (h != NULL) && (*h != '\0');
174 strlcpy(buffer, h, sizeof(buffer));
175 cp = strchr(buffer, ':');
178 "invalid proxy specification: should be HOST:PORT\n");
185 snprintf(portbuf, sizeof(portbuf), "%d", port);
189 memset(&hints, 0, sizeof(hints));
190 hints.ai_family = af_hint;
191 hints.ai_socktype = type;
192 error = getaddrinfo(h, portbuf, &hints, &res0);
194 rprintf(FERROR, RSYNC_NAME ": getaddrinfo: %s %s: %s\n",
195 h, portbuf, gai_strerror(error));
200 /* Try to connect to all addresses for this machine until we get
201 * through. It might e.g. be multi-homed, or have both IPv4 and IPv6
202 * addresses. We need to create a socket for each record, since the
203 * address record tells us what protocol to use to try to connect. */
204 for (res = res0; res; res = res->ai_next) {
205 s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
210 if (try_bind_local(s, res->ai_family, type,
211 bind_address) == -1) {
217 if (connect(s, res->ai_addr, res->ai_addrlen) < 0) {
223 establish_proxy_connection(s, host, port) != 0) {
232 rprintf(FERROR, RSYNC_NAME ": failed to connect to %s: %s\n",
241 * Open an outgoing socket, but allow for it to be intercepted by
242 * $RSYNC_CONNECT_PROG, which will execute a program across a TCP
243 * socketpair rather than really opening a socket.
245 * We use this primarily in testing to detect TCP flow bugs, but not
246 * cause security problems by really opening remote connections.
248 * This is based on the Samba LIBSMB_PROG feature.
250 * @param bind_address Local address to use. Normally NULL to get the stack default.
252 int open_socket_out_wrapped (char *host,
254 const char *bind_address,
259 if ((prog = getenv ("RSYNC_CONNECT_PROG")) != NULL)
260 return sock_exec (prog);
262 return open_socket_out (host, port, bind_address,
269 * Open a socket of the specified type, port and address for incoming data
271 * Try to be better about handling the results of getaddrinfo(): when
272 * opening an inbound socket, we might get several address results,
273 * e.g. for the machine's ipv4 and ipv6 name.
275 * If binding a wildcard, then any one of them should do. If an address
276 * was specified but it's insufficiently specific then that's not our
279 * However, some of the advertized addresses may not work because e.g. we
280 * don't have IPv6 support in the kernel. In that case go on and try all
281 * addresses until one succeeds.
283 * @param bind_address Local address to bind, or NULL to allow it to
286 static int open_socket_in(int type, int port, const char *bind_address,
291 struct addrinfo hints, *all_ai, *resp;
295 memset(&hints, 0, sizeof(hints));
296 hints.ai_family = af_hint;
297 hints.ai_socktype = type;
298 hints.ai_flags = AI_PASSIVE;
299 snprintf(portbuf, sizeof(portbuf), "%d", port);
300 error = getaddrinfo(bind_address, portbuf, &hints, &all_ai);
302 rprintf(FERROR, RSYNC_NAME ": getaddrinfo: bind address %s: %s\n",
303 bind_address, gai_strerror(error));
307 /* We may not be able to create the socket, if for example the
308 * machine knows about IPv6 in the C library, but not in the
310 for (resp = all_ai; resp; resp = resp->ai_next) {
311 s = socket(resp->ai_family, resp->ai_socktype,
315 /* See if there's another address that will work... */
318 setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
319 (char *)&one, sizeof one);
321 /* now we've got a socket - we need to bind it */
322 if (bind(s, all_ai->ai_addr, all_ai->ai_addrlen) < 0) {
323 /* Nope, try another */
331 rprintf(FERROR, RSYNC_NAME ": open inbound socket on port %d failed: "
336 freeaddrinfo(all_ai);
342 * Determine if a file descriptor is in fact a socket
344 int is_a_socket(int fd)
350 /* Parameters to getsockopt, setsockopt etc are very
351 * unstandardized across platforms, so don't be surprised if
352 * there are compiler warnings on e.g. SCO OpenSwerver or AIX.
353 * It seems they all eventually get the right idea.
355 * Debian says: ``The fifth argument of getsockopt and
356 * setsockopt is in reality an int [*] (and this is what BSD
357 * 4.* and libc4 and libc5 have). Some POSIX confusion
358 * resulted in the present socklen_t. The draft standard has
359 * not been adopted yet, but glibc2 already follows it and
360 * also has socklen_t [*]. See also accept(2).''
362 * We now return to your regularly scheduled programming. */
363 return(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&v, &l) == 0);
367 void start_accept_loop(int port, int (*fn)(int ))
370 extern char *bind_address;
371 extern int default_af_hint;
373 /* open an incoming socket */
374 s = open_socket_in(SOCK_STREAM, port, bind_address, default_af_hint);
376 exit_cleanup(RERR_SOCKETIO);
378 /* ready to listen */
379 if (listen(s, 5) == -1) {
381 exit_cleanup(RERR_SOCKETIO);
385 /* now accept incoming connections - forking a new process
386 for each incoming connection */
390 struct sockaddr_storage addr;
391 socklen_t addrlen = sizeof addr;
393 /* close log file before the potentially very long select so
394 file can be trimmed by another process instead of growing
401 if (select(s+1, &fds, NULL, NULL, NULL) != 1) {
405 if(!FD_ISSET(s, &fds)) continue;
407 fd = accept(s,(struct sockaddr *)&addr,&addrlen);
409 if (fd == -1) continue;
411 signal(SIGCHLD, SIG_IGN);
413 /* we shouldn't have any children left hanging around
414 but I have had reports that on Digital Unix zombies
415 are produced, so this ensures that they are reaped */
417 while (waitpid(-1, NULL, WNOHANG) > 0);
422 /* open log file in child before possibly giving
433 enum SOCK_OPT_TYPES {OPT_BOOL,OPT_INT,OPT_ON};
442 } socket_options[] = {
443 {"SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE, 0, OPT_BOOL},
444 {"SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR, 0, OPT_BOOL},
445 {"SO_BROADCAST", SOL_SOCKET, SO_BROADCAST, 0, OPT_BOOL},
447 {"TCP_NODELAY", IPPROTO_TCP, TCP_NODELAY, 0, OPT_BOOL},
449 #ifdef IPTOS_LOWDELAY
450 {"IPTOS_LOWDELAY", IPPROTO_IP, IP_TOS, IPTOS_LOWDELAY, OPT_ON},
452 #ifdef IPTOS_THROUGHPUT
453 {"IPTOS_THROUGHPUT", IPPROTO_IP, IP_TOS, IPTOS_THROUGHPUT, OPT_ON},
456 {"SO_SNDBUF", SOL_SOCKET, SO_SNDBUF, 0, OPT_INT},
459 {"SO_RCVBUF", SOL_SOCKET, SO_RCVBUF, 0, OPT_INT},
462 {"SO_SNDLOWAT", SOL_SOCKET, SO_SNDLOWAT, 0, OPT_INT},
465 {"SO_RCVLOWAT", SOL_SOCKET, SO_RCVLOWAT, 0, OPT_INT},
468 {"SO_SNDTIMEO", SOL_SOCKET, SO_SNDTIMEO, 0, OPT_INT},
471 {"SO_RCVTIMEO", SOL_SOCKET, SO_RCVTIMEO, 0, OPT_INT},
477 /****************************************************************************
478 set user socket options
479 ****************************************************************************/
480 void set_socket_options(int fd, char *options)
483 if (!options || !*options) return;
485 options = strdup(options);
487 if (!options) out_of_memory("set_socket_options");
489 for (tok=strtok(options, " \t,"); tok; tok=strtok(NULL," \t,")) {
495 if ((p = strchr(tok,'='))) {
501 for (i=0;socket_options[i].name;i++)
502 if (strcmp(socket_options[i].name,tok)==0)
505 if (!socket_options[i].name) {
506 rprintf(FERROR,"Unknown socket option %s\n",tok);
510 switch (socket_options[i].opttype) {
513 ret = setsockopt(fd,socket_options[i].level,
514 socket_options[i].option,(char *)&value,sizeof(int));
519 rprintf(FERROR,"syntax error - %s does not take a value\n",tok);
522 int on = socket_options[i].value;
523 ret = setsockopt(fd,socket_options[i].level,
524 socket_options[i].option,(char *)&on,sizeof(int));
530 rprintf(FERROR, "failed to set socket option %s: %s\n", tok,
537 /****************************************************************************
538 become a daemon, discarding the controlling terminal
539 ****************************************************************************/
540 void become_daemon(void)
548 /* detach from the terminal */
553 i = open("/dev/tty", O_RDWR);
555 ioctl(i, (int) TIOCNOTTY, (char *)0);
558 #endif /* TIOCNOTTY */
560 /* make sure that stdin, stdout an stderr don't stuff things
561 up (library functions, for example) */
564 open("/dev/null", O_RDWR);
569 * Return the IP addr of the client as a string
571 char *client_addr(int fd)
573 struct sockaddr_storage ss;
574 socklen_t length = sizeof ss;
575 static char addr_buf[100];
576 static int initialised;
578 if (initialised) return addr_buf;
582 if (getpeername(fd, (struct sockaddr *)&ss, &length)) {
583 exit_cleanup(RERR_SOCKETIO);
586 getnameinfo((struct sockaddr *)&ss, length,
587 addr_buf, sizeof(addr_buf), NULL, 0, NI_NUMERICHOST);
592 static int get_sockaddr_family(const struct sockaddr_storage *ss)
594 return ((struct sockaddr *) ss)->sa_family;
599 * Return the DNS name of the client.
601 * The name is statically cached so that repeated lookups are quick,
602 * so there is a limit of one lookup per customer.
604 char *client_name(int fd)
606 struct sockaddr_storage ss;
607 socklen_t length = sizeof ss;
608 static char name_buf[100];
609 static char port_buf[100];
610 char *def = "UNKNOWN";
611 static int initialised;
612 struct addrinfo hints, *res, *res0;
615 if (initialised) return name_buf;
619 strcpy(name_buf,def);
621 if (getpeername(fd, (struct sockaddr *)&ss, &length)) {
622 /* FIXME: Can we really not continue? */
623 rprintf(FERROR, RSYNC_NAME ": getpeername on fd%d failed: %s\n",
624 fd, strerror(errno));
625 exit_cleanup(RERR_SOCKETIO);
629 if (get_sockaddr_family(&ss) == AF_INET6 &&
630 IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)&ss)->sin6_addr)) {
631 /* OK, so ss is in the IPv6 family, but it is really
632 * an IPv4 address: something like
633 * "::ffff:10.130.1.2". If we use it as-is, then the
634 * reverse lookup might fail or perhaps something else
635 * bad might happen. So instead we convert it to an
636 * equivalent address in the IPv4 address family. */
637 struct sockaddr_in6 sin6;
638 struct sockaddr_in *sin;
640 memcpy(&sin6, &ss, sizeof(sin6));
641 sin = (struct sockaddr_in *)&ss;
642 memset(sin, 0, sizeof(*sin));
643 sin->sin_family = AF_INET;
644 length = sizeof(struct sockaddr_in);
645 #ifdef HAVE_SOCKADDR_LEN
646 sin->sin_len = length;
648 sin->sin_port = sin6.sin6_port;
649 /* FIXME: Isn't there a macro we can use here rather
650 * than grovelling through the struct? It might be
651 * wrong on some systems. */
652 memcpy(&sin->sin_addr, &sin6.sin6_addr.s6_addr[12],
653 sizeof(sin->sin_addr));
658 if (getnameinfo((struct sockaddr *)&ss, length,
659 name_buf, sizeof(name_buf), port_buf, sizeof(port_buf),
660 NI_NAMEREQD | NI_NUMERICSERV) != 0) {
661 strcpy(name_buf, def);
662 rprintf(FERROR, "reverse name lookup failed\n");
666 memset(&hints, 0, sizeof(hints));
667 hints.ai_family = PF_UNSPEC;
668 hints.ai_flags = AI_CANONNAME;
669 hints.ai_socktype = SOCK_STREAM;
670 error = getaddrinfo(name_buf, port_buf, &hints, &res0);
672 strcpy(name_buf, def);
674 RSYNC_NAME ": forward name lookup for %s failed: %s\n",
676 gai_strerror(error));
680 /* XXX sin6_flowinfo and other fields */
681 for (res = res0; res; res = res->ai_next) {
682 if (res->ai_family != get_sockaddr_family(&ss))
684 if (res->ai_addrlen != length)
686 if (memcmp(res->ai_addr, &ss, res->ai_addrlen) == 0)
691 strcpy(name_buf, def);
692 rprintf(FERROR, RSYNC_NAME ": "
693 "reverse name lookup for \"%s\" failed on fd%d - spoofed address? \n",
702 /*******************************************************************
703 this is like socketpair but uses tcp. It is used by the Samba
705 The function guarantees that nobody else can attach to the socket,
706 or if they do that this function fails and the socket gets closed
707 returns 0 on success, -1 on failure
708 the resulting file descriptors are symmetrical
709 ******************************************************************/
710 static int socketpair_tcp(int fd[2])
713 struct sockaddr_in sock;
714 struct sockaddr_in sock2;
715 socklen_t socklen = sizeof(sock);
716 int connect_done = 0;
718 fd[0] = fd[1] = listener = -1;
720 memset(&sock, 0, sizeof(sock));
722 if ((listener = socket(PF_INET, SOCK_STREAM, 0)) == -1) goto failed;
724 memset(&sock2, 0, sizeof(sock2));
725 #ifdef HAVE_SOCK_SIN_LEN
726 sock2.sin_len = sizeof(sock2);
728 sock2.sin_family = PF_INET;
730 bind(listener, (struct sockaddr *)&sock2, sizeof(sock2));
732 if (listen(listener, 1) != 0) goto failed;
734 if (getsockname(listener, (struct sockaddr *)&sock, &socklen) != 0) goto failed;
736 if ((fd[1] = socket(PF_INET, SOCK_STREAM, 0)) == -1) goto failed;
738 set_nonblocking(fd[1]);
740 sock.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
742 if (connect(fd[1],(struct sockaddr *)&sock,sizeof(sock)) == -1) {
743 if (errno != EINPROGRESS) goto failed;
748 if ((fd[0] = accept(listener, (struct sockaddr *)&sock, &socklen)) == -1) goto failed;
751 if (connect_done == 0) {
752 if (connect(fd[1],(struct sockaddr *)&sock,sizeof(sock)) != 0
753 && errno != EISCONN) goto failed;
756 set_blocking (fd[1]);
762 if (fd[0] != -1) close(fd[0]);
763 if (fd[1] != -1) close(fd[1]);
764 if (listener != -1) close(listener);
769 /*******************************************************************
770 run a program on a local tcp socket, this is used to launch smbd
771 when regression testing
772 the return value is a socket which is attached to a subprocess
773 running "prog". stdin and stdout are attached. stderr is left
774 attached to the original stderr
775 ******************************************************************/
776 int sock_exec(const char *prog)
779 if (socketpair_tcp(fd) != 0) {
780 rprintf (FERROR, RSYNC_NAME
781 ": socketpair_tcp failed (%s)\n",
793 RSYNC_NAME ": execute socket program \"%s\"\n",
795 exit (system (prog));