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)
125 freeaddrinfo(bres_all);
129 /* no error message; there might be some problem that allows
130 * creation of the socket but not binding, perhaps if the
131 * machine has no ipv6 address of this name. */
132 freeaddrinfo(bres_all);
138 * Open a socket to a tcp remote host with the specified port .
140 * Based on code from Warren. Proxy support by Stephen Rothwell.
141 * getaddrinfo() rewrite contributed by KAME.net.
143 * Now that we support IPv6 we need to look up the remote machine's
144 * address first, using @p af_hint to set a preference for the type
145 * of address. Then depending on whether it has v4 or v6 addresses we
146 * try to open a connection.
148 * The loop allows for machines with some addresses which may not be
149 * reachable, perhaps because we can't e.g. route ipv6 to that network
150 * but we can get ip4 packets through.
152 * @param bind_address Local address to use. Normally NULL to bind
153 * the wildcard address.
155 * @param af_hint Address family, e.g. AF_INET or AF_INET6.
157 int open_socket_out(char *host, int port, const char *bind_address,
160 int type = SOCK_STREAM;
163 struct addrinfo hints, *res0, *res;
170 /* if we have a RSYNC_PROXY env variable then redirect our
171 * connetcion via a web proxy at the given address. The format
172 * is hostname:port */
173 h = getenv("RSYNC_PROXY");
174 proxied = (h != NULL) && (*h != '\0');
177 strlcpy(buffer, h, sizeof(buffer));
178 cp = strchr(buffer, ':');
181 "invalid proxy specification: should be HOST:PORT\n");
188 rprintf(FINFO, "connection via http proxy %s port %s\n",
192 snprintf(portbuf, sizeof(portbuf), "%d", port);
196 memset(&hints, 0, sizeof(hints));
197 hints.ai_family = af_hint;
198 hints.ai_socktype = type;
199 error = getaddrinfo(h, portbuf, &hints, &res0);
201 rprintf(FERROR, RSYNC_NAME ": getaddrinfo: %s %s: %s\n",
202 h, portbuf, gai_strerror(error));
207 /* Try to connect to all addresses for this machine until we get
208 * through. It might e.g. be multi-homed, or have both IPv4 and IPv6
209 * addresses. We need to create a socket for each record, since the
210 * address record tells us what protocol to use to try to connect. */
211 for (res = res0; res; res = res->ai_next) {
212 s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
217 if (try_bind_local(s, res->ai_family, type,
218 bind_address) == -1) {
224 if (connect(s, res->ai_addr, res->ai_addrlen) < 0) {
230 establish_proxy_connection(s, host, port) != 0) {
239 rprintf(FERROR, RSYNC_NAME ": failed to connect to %s: %s\n",
248 * Open an outgoing socket, but allow for it to be intercepted by
249 * $RSYNC_CONNECT_PROG, which will execute a program across a TCP
250 * socketpair rather than really opening a socket.
252 * We use this primarily in testing to detect TCP flow bugs, but not
253 * cause security problems by really opening remote connections.
255 * This is based on the Samba LIBSMB_PROG feature.
257 * @param bind_address Local address to use. Normally NULL to get the stack default.
259 int open_socket_out_wrapped (char *host,
261 const char *bind_address,
266 if ((prog = getenv ("RSYNC_CONNECT_PROG")) != NULL)
267 return sock_exec (prog);
269 return open_socket_out (host, port, bind_address,
276 * Open a socket of the specified type, port and address for incoming data
278 * Try to be better about handling the results of getaddrinfo(): when
279 * opening an inbound socket, we might get several address results,
280 * e.g. for the machine's ipv4 and ipv6 name.
282 * If binding a wildcard, then any one of them should do. If an address
283 * was specified but it's insufficiently specific then that's not our
286 * However, some of the advertized addresses may not work because e.g. we
287 * don't have IPv6 support in the kernel. In that case go on and try all
288 * addresses until one succeeds.
290 * @param bind_address Local address to bind, or NULL to allow it to
293 static int open_socket_in(int type, int port, const char *bind_address,
298 struct addrinfo hints, *all_ai, *resp;
302 memset(&hints, 0, sizeof(hints));
303 hints.ai_family = af_hint;
304 hints.ai_socktype = type;
305 hints.ai_flags = AI_PASSIVE;
306 snprintf(portbuf, sizeof(portbuf), "%d", port);
307 error = getaddrinfo(bind_address, portbuf, &hints, &all_ai);
309 rprintf(FERROR, RSYNC_NAME ": getaddrinfo: bind address %s: %s\n",
310 bind_address, gai_strerror(error));
314 /* We may not be able to create the socket, if for example the
315 * machine knows about IPv6 in the C library, but not in the
317 for (resp = all_ai; resp; resp = resp->ai_next) {
318 s = socket(resp->ai_family, resp->ai_socktype,
322 /* See if there's another address that will work... */
325 setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
326 (char *)&one, sizeof one);
328 /* now we've got a socket - we need to bind it */
329 if (bind(s, all_ai->ai_addr, all_ai->ai_addrlen) < 0) {
330 /* Nope, try another */
335 freeaddrinfo(all_ai);
339 rprintf(FERROR, RSYNC_NAME ": open inbound socket on port %d failed: "
344 freeaddrinfo(all_ai);
350 * Determine if a file descriptor is in fact a socket
352 int is_a_socket(int fd)
358 /* Parameters to getsockopt, setsockopt etc are very
359 * unstandardized across platforms, so don't be surprised if
360 * there are compiler warnings on e.g. SCO OpenSwerver or AIX.
361 * It seems they all eventually get the right idea.
363 * Debian says: ``The fifth argument of getsockopt and
364 * setsockopt is in reality an int [*] (and this is what BSD
365 * 4.* and libc4 and libc5 have). Some POSIX confusion
366 * resulted in the present socklen_t. The draft standard has
367 * not been adopted yet, but glibc2 already follows it and
368 * also has socklen_t [*]. See also accept(2).''
370 * We now return to your regularly scheduled programming. */
371 return(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&v, &l) == 0);
375 void start_accept_loop(int port, int (*fn)(int ))
378 extern char *bind_address;
379 extern int default_af_hint;
381 /* open an incoming socket */
382 s = open_socket_in(SOCK_STREAM, port, bind_address, default_af_hint);
384 exit_cleanup(RERR_SOCKETIO);
386 /* ready to listen */
387 if (listen(s, 5) == -1) {
389 exit_cleanup(RERR_SOCKETIO);
393 /* now accept incoming connections - forking a new process
394 for each incoming connection */
399 struct sockaddr_storage addr;
400 socklen_t addrlen = sizeof addr;
402 /* close log file before the potentially very long select so
403 file can be trimmed by another process instead of growing
410 if (select(s+1, &fds, NULL, NULL, NULL) != 1) {
414 if(!FD_ISSET(s, &fds)) continue;
416 fd = accept(s,(struct sockaddr *)&addr,&addrlen);
418 if (fd == -1) continue;
420 signal(SIGCHLD, SIG_IGN);
422 /* we shouldn't have any children left hanging around
423 but I have had reports that on Digital Unix zombies
424 are produced, so this ensures that they are reaped */
426 while (waitpid(-1, NULL, WNOHANG) > 0);
429 if ((pid = fork()) == 0) {
431 /* open log file in child before possibly giving
435 } else if (pid < 0) {
438 ": could not create child server process: %s\n",
441 /* This might have happened because we're
442 * overloaded. Sleep briefly before trying to
446 /* Parent doesn't need this fd anymore. */
453 enum SOCK_OPT_TYPES {OPT_BOOL,OPT_INT,OPT_ON};
462 } socket_options[] = {
463 {"SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE, 0, OPT_BOOL},
464 {"SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR, 0, OPT_BOOL},
465 {"SO_BROADCAST", SOL_SOCKET, SO_BROADCAST, 0, OPT_BOOL},
467 {"TCP_NODELAY", IPPROTO_TCP, TCP_NODELAY, 0, OPT_BOOL},
469 #ifdef IPTOS_LOWDELAY
470 {"IPTOS_LOWDELAY", IPPROTO_IP, IP_TOS, IPTOS_LOWDELAY, OPT_ON},
472 #ifdef IPTOS_THROUGHPUT
473 {"IPTOS_THROUGHPUT", IPPROTO_IP, IP_TOS, IPTOS_THROUGHPUT, OPT_ON},
476 {"SO_SNDBUF", SOL_SOCKET, SO_SNDBUF, 0, OPT_INT},
479 {"SO_RCVBUF", SOL_SOCKET, SO_RCVBUF, 0, OPT_INT},
482 {"SO_SNDLOWAT", SOL_SOCKET, SO_SNDLOWAT, 0, OPT_INT},
485 {"SO_RCVLOWAT", SOL_SOCKET, SO_RCVLOWAT, 0, OPT_INT},
488 {"SO_SNDTIMEO", SOL_SOCKET, SO_SNDTIMEO, 0, OPT_INT},
491 {"SO_RCVTIMEO", SOL_SOCKET, SO_RCVTIMEO, 0, OPT_INT},
497 /****************************************************************************
498 set user socket options
499 ****************************************************************************/
500 void set_socket_options(int fd, char *options)
503 if (!options || !*options) return;
505 options = strdup(options);
507 if (!options) out_of_memory("set_socket_options");
509 for (tok=strtok(options, " \t,"); tok; tok=strtok(NULL," \t,")) {
515 if ((p = strchr(tok,'='))) {
521 for (i=0;socket_options[i].name;i++)
522 if (strcmp(socket_options[i].name,tok)==0)
525 if (!socket_options[i].name) {
526 rprintf(FERROR,"Unknown socket option %s\n",tok);
530 switch (socket_options[i].opttype) {
533 ret = setsockopt(fd,socket_options[i].level,
534 socket_options[i].option,(char *)&value,sizeof(int));
539 rprintf(FERROR,"syntax error - %s does not take a value\n",tok);
542 int on = socket_options[i].value;
543 ret = setsockopt(fd,socket_options[i].level,
544 socket_options[i].option,(char *)&on,sizeof(int));
550 rprintf(FERROR, "failed to set socket option %s: %s\n", tok,
557 /****************************************************************************
558 become a daemon, discarding the controlling terminal
559 ****************************************************************************/
560 void become_daemon(void)
568 /* detach from the terminal */
573 i = open("/dev/tty", O_RDWR);
575 ioctl(i, (int) TIOCNOTTY, (char *)0);
578 #endif /* TIOCNOTTY */
580 /* make sure that stdin, stdout an stderr don't stuff things
581 up (library functions, for example) */
584 open("/dev/null", O_RDWR);
589 /*******************************************************************
590 this is like socketpair but uses tcp. It is used by the Samba
592 The function guarantees that nobody else can attach to the socket,
593 or if they do that this function fails and the socket gets closed
594 returns 0 on success, -1 on failure
595 the resulting file descriptors are symmetrical
596 ******************************************************************/
597 static int socketpair_tcp(int fd[2])
600 struct sockaddr_in sock;
601 struct sockaddr_in sock2;
602 socklen_t socklen = sizeof(sock);
603 int connect_done = 0;
605 fd[0] = fd[1] = listener = -1;
607 memset(&sock, 0, sizeof(sock));
609 if ((listener = socket(PF_INET, SOCK_STREAM, 0)) == -1) goto failed;
611 memset(&sock2, 0, sizeof(sock2));
612 #ifdef HAVE_SOCKADDR_LEN
613 sock2.sin_len = sizeof(sock2);
615 sock2.sin_family = PF_INET;
617 bind(listener, (struct sockaddr *)&sock2, sizeof(sock2));
619 if (listen(listener, 1) != 0) goto failed;
621 if (getsockname(listener, (struct sockaddr *)&sock, &socklen) != 0) goto failed;
623 if ((fd[1] = socket(PF_INET, SOCK_STREAM, 0)) == -1) goto failed;
625 set_nonblocking(fd[1]);
627 sock.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
629 if (connect(fd[1],(struct sockaddr *)&sock,sizeof(sock)) == -1) {
630 if (errno != EINPROGRESS) goto failed;
635 if ((fd[0] = accept(listener, (struct sockaddr *)&sock, &socklen)) == -1) goto failed;
638 if (connect_done == 0) {
639 if (connect(fd[1],(struct sockaddr *)&sock,sizeof(sock)) != 0
640 && errno != EISCONN) goto failed;
643 set_blocking (fd[1]);
649 if (fd[0] != -1) close(fd[0]);
650 if (fd[1] != -1) close(fd[1]);
651 if (listener != -1) close(listener);
658 * Run a program on a local tcp socket, so that we can talk to it's
659 * stdin and stdout. This is used to fake a connection to a daemon
660 * for testing -- not for the normal case of running SSH.
662 * @return a socket which is attached to a subprocess running
663 * "prog". stdin and stdout are attached. stderr is left attached to
664 * the original stderr
666 int sock_exec(const char *prog)
670 if (socketpair_tcp(fd) != 0) {
671 rprintf (FERROR, RSYNC_NAME
672 ": socketpair_tcp failed (%s)\n",
683 /* Can't use rprintf because we've forked. */
685 RSYNC_NAME ": execute socket program \"%s\"\n",
688 exit (system (prog));