1 /* -*- c-file-style: "linux" -*-
3 Copyright (C) 1992-2001 by Andrew Tridgell <tridge@samba.org>
4 Copyright (C) 2001, 2002 by Martin Pool <mbp@samba.org>
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 * Socket functions used in rsync.
26 * This file is now converted to use the new-style getaddrinfo()
27 * interface, which supports IPv6 but is also supported on recent
28 * IPv4-only machines. On systems that don't have that interface, we
29 * emulate it using the KAME implementation.
34 /* Establish a proxy connection on an open socket to a web roxy by
35 * using the CONNECT method. */
36 static int establish_proxy_connection(int fd, char *host, int port)
41 snprintf(buffer, sizeof(buffer), "CONNECT %s:%d HTTP/1.0\r\n\r\n", host, port);
42 if (write(fd, buffer, strlen(buffer)) != strlen(buffer)) {
43 rprintf(FERROR, "failed to write to proxy: %s\n",
48 for (cp = buffer; cp < &buffer[sizeof(buffer) - 1]; cp++) {
49 if (read(fd, cp, 1) != 1) {
50 rprintf(FERROR, "failed to read from proxy: %s\n",
63 if (strncmp(buffer, "HTTP/", 5) != 0) {
64 rprintf(FERROR, "bad response from proxy - %s\n",
68 for (cp = &buffer[5]; isdigit(*cp) || (*cp == '.'); cp++)
73 rprintf(FERROR, "bad response from proxy - %s\n",
77 /* throw away the rest of the HTTP header */
79 for (cp = buffer; cp < &buffer[sizeof(buffer) - 1];
81 if (read(fd, cp, 1) != 1) {
82 rprintf(FERROR, "failed to read from proxy: %s\n",
89 if ((cp > buffer) && (*cp == '\n'))
91 if ((cp == buffer) && ((*cp == '\n') || (*cp == '\r')))
99 * Try to set the local address for a newly-created socket. Return -1
102 int try_bind_local(int s,
103 int ai_family, int ai_socktype,
104 const char *bind_address)
107 struct addrinfo bhints, *bres_all, *r;
109 memset(&bhints, 0, sizeof(bhints));
110 bhints.ai_family = ai_family;
111 bhints.ai_socktype = ai_socktype;
112 bhints.ai_flags = AI_PASSIVE;
113 if ((error = getaddrinfo(bind_address, NULL, &bhints, &bres_all))) {
114 rprintf(FERROR, RSYNC_NAME ": getaddrinfo %s: %s\n",
115 bind_address, gai_strerror(error));
119 for (r = bres_all; r; r = r->ai_next) {
120 if (bind(s, r->ai_addr, r->ai_addrlen) == -1)
125 /* no error message; there might be some problem that allows
126 * creation of the socket but not binding, perhaps if the
127 * machine has no ipv6 address of this name. */
133 * Open a socket to a tcp remote host with the specified port .
135 * Based on code from Warren. Proxy support by Stephen Rothwell.
136 * getaddrinfo() rewrite contributed by KAME.net.
138 * Now that we support IPv6 we need to look up the remote machine's
139 * address first, using @p af_hint to set a preference for the type
140 * of address. Then depending on whether it has v4 or v6 addresses we
141 * try to open a connection.
143 * The loop allows for machines with some addresses which may not be
144 * reachable, perhaps because we can't e.g. route ipv6 to that network
145 * but we can get ip4 packets through.
147 * @param bind_address Local address to use. Normally NULL to bind
148 * the wildcard address.
150 * @param af_hint Address family, e.g. AF_INET or AF_INET6.
152 int open_socket_out(char *host, int port, const char *bind_address,
155 int type = SOCK_STREAM;
159 struct addrinfo hints, *res0, *res;
166 /* if we have a RSYNC_PROXY env variable then redirect our
167 * connetcion via a web proxy at the given address. The format
168 * is hostname:port */
169 h = getenv("RSYNC_PROXY");
170 proxied = (h != NULL) && (*h != '\0');
173 strlcpy(buffer, h, sizeof(buffer));
174 cp = strchr(buffer, ':');
177 "invalid proxy specification: should be HOST:PORT\n");
184 snprintf(portbuf, sizeof(portbuf), "%d", port);
188 memset(&hints, 0, sizeof(hints));
189 hints.ai_family = af_hint;
190 hints.ai_socktype = type;
191 error = getaddrinfo(h, portbuf, &hints, &res0);
193 rprintf(FERROR, RSYNC_NAME ": getaddrinfo: %s %s: %s\n",
194 h, portbuf, gai_strerror(error));
199 /* Try to connect to all addresses for this machine until we get
200 * through. It might e.g. be multi-homed, or have both IPv4 and IPv6
201 * addresses. We need to create a socket for each record, since the
202 * address record tells us what protocol to use to try to connect. */
203 for (res = res0; res; res = res->ai_next) {
204 s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
209 if (try_bind_local(s, res->ai_family, type,
210 bind_address) == -1) {
216 if (connect(s, res->ai_addr, res->ai_addrlen) < 0) {
222 establish_proxy_connection(s, host, port) != 0) {
231 rprintf(FERROR, RSYNC_NAME ": failed to connect to %s: %s\n",
240 * Open an outgoing socket, but allow for it to be intercepted by
241 * $RSYNC_CONNECT_PROG, which will execute a program across a TCP
242 * socketpair rather than really opening a socket.
244 * We use this primarily in testing to detect TCP flow bugs, but not
245 * cause security problems by really opening remote connections.
247 * This is based on the Samba LIBSMB_PROG feature.
249 * @param bind_address Local address to use. Normally NULL to get the stack default.
251 int open_socket_out_wrapped (char *host,
253 const char *bind_address,
258 if ((prog = getenv ("RSYNC_CONNECT_PROG")) != NULL)
259 return sock_exec (prog);
261 return open_socket_out (host, port, bind_address,
268 * Open a socket of the specified type, port and address for incoming data
270 * Try to be better about handling the results of getaddrinfo(): when
271 * opening an inbound socket, we might get several address results,
272 * e.g. for the machine's ipv4 and ipv6 name.
274 * If binding a wildcard, then any one of them should do. If an address
275 * was specified but it's insufficiently specific then that's not our
278 * However, some of the advertized addresses may not work because e.g. we
279 * don't have IPv6 support in the kernel. In that case go on and try all
280 * addresses until one succeeds.
282 * @param bind_address Local address to bind, or NULL to allow it to
285 static int open_socket_in(int type, int port, const char *bind_address,
290 struct addrinfo hints, *all_ai, *resp;
294 memset(&hints, 0, sizeof(hints));
295 hints.ai_family = af_hint;
296 hints.ai_socktype = type;
297 hints.ai_flags = AI_PASSIVE;
298 snprintf(portbuf, sizeof(portbuf), "%d", port);
299 error = getaddrinfo(bind_address, portbuf, &hints, &all_ai);
301 rprintf(FERROR, RSYNC_NAME ": getaddrinfo: bind address %s: %s\n",
302 bind_address, gai_strerror(error));
306 /* We may not be able to create the socket, if for example the
307 * machine knows about IPv6 in the C library, but not in the
309 for (resp = all_ai; resp; resp = resp->ai_next) {
310 s = socket(resp->ai_family, resp->ai_socktype,
314 /* See if there's another address that will work... */
317 setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
318 (char *)&one, sizeof one);
320 /* now we've got a socket - we need to bind it */
321 if (bind(s, all_ai->ai_addr, all_ai->ai_addrlen) < 0) {
322 /* Nope, try another */
330 rprintf(FERROR, RSYNC_NAME ": open inbound socket on port %d failed: "
335 freeaddrinfo(all_ai);
341 * Determine if a file descriptor is in fact a socket
343 int is_a_socket(int fd)
349 /* Parameters to getsockopt, setsockopt etc are very
350 * unstandardized across platforms, so don't be surprised if
351 * there are compiler warnings on e.g. SCO OpenSwerver or AIX.
352 * It seems they all eventually get the right idea.
354 * Debian says: ``The fifth argument of getsockopt and
355 * setsockopt is in reality an int [*] (and this is what BSD
356 * 4.* and libc4 and libc5 have). Some POSIX confusion
357 * resulted in the present socklen_t. The draft standard has
358 * not been adopted yet, but glibc2 already follows it and
359 * also has socklen_t [*]. See also accept(2).''
361 * We now return to your regularly scheduled programming. */
362 return(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&v, &l) == 0);
366 void start_accept_loop(int port, int (*fn)(int ))
369 extern char *bind_address;
370 extern int default_af_hint;
372 /* open an incoming socket */
373 s = open_socket_in(SOCK_STREAM, port, bind_address, default_af_hint);
375 exit_cleanup(RERR_SOCKETIO);
377 /* ready to listen */
378 if (listen(s, 5) == -1) {
380 exit_cleanup(RERR_SOCKETIO);
384 /* now accept incoming connections - forking a new process
385 for each incoming connection */
389 struct sockaddr_storage addr;
390 int addrlen = sizeof(addr);
392 /* close log file before the potentially very long select so
393 file can be trimmed by another process instead of growing
400 if (select(s+1, &fds, NULL, NULL, NULL) != 1) {
404 if(!FD_ISSET(s, &fds)) continue;
406 fd = accept(s,(struct sockaddr *)&addr,&addrlen);
408 if (fd == -1) continue;
410 signal(SIGCHLD, SIG_IGN);
412 /* we shouldn't have any children left hanging around
413 but I have had reports that on Digital Unix zombies
414 are produced, so this ensures that they are reaped */
416 while (waitpid(-1, NULL, WNOHANG) > 0);
421 /* open log file in child before possibly giving
432 enum SOCK_OPT_TYPES {OPT_BOOL,OPT_INT,OPT_ON};
441 } socket_options[] = {
442 {"SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE, 0, OPT_BOOL},
443 {"SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR, 0, OPT_BOOL},
444 {"SO_BROADCAST", SOL_SOCKET, SO_BROADCAST, 0, OPT_BOOL},
446 {"TCP_NODELAY", IPPROTO_TCP, TCP_NODELAY, 0, OPT_BOOL},
448 #ifdef IPTOS_LOWDELAY
449 {"IPTOS_LOWDELAY", IPPROTO_IP, IP_TOS, IPTOS_LOWDELAY, OPT_ON},
451 #ifdef IPTOS_THROUGHPUT
452 {"IPTOS_THROUGHPUT", IPPROTO_IP, IP_TOS, IPTOS_THROUGHPUT, OPT_ON},
455 {"SO_SNDBUF", SOL_SOCKET, SO_SNDBUF, 0, OPT_INT},
458 {"SO_RCVBUF", SOL_SOCKET, SO_RCVBUF, 0, OPT_INT},
461 {"SO_SNDLOWAT", SOL_SOCKET, SO_SNDLOWAT, 0, OPT_INT},
464 {"SO_RCVLOWAT", SOL_SOCKET, SO_RCVLOWAT, 0, OPT_INT},
467 {"SO_SNDTIMEO", SOL_SOCKET, SO_SNDTIMEO, 0, OPT_INT},
470 {"SO_RCVTIMEO", SOL_SOCKET, SO_RCVTIMEO, 0, OPT_INT},
476 /****************************************************************************
477 set user socket options
478 ****************************************************************************/
479 void set_socket_options(int fd, char *options)
482 if (!options || !*options) return;
484 options = strdup(options);
486 if (!options) out_of_memory("set_socket_options");
488 for (tok=strtok(options, " \t,"); tok; tok=strtok(NULL," \t,")) {
494 if ((p = strchr(tok,'='))) {
500 for (i=0;socket_options[i].name;i++)
501 if (strcmp(socket_options[i].name,tok)==0)
504 if (!socket_options[i].name) {
505 rprintf(FERROR,"Unknown socket option %s\n",tok);
509 switch (socket_options[i].opttype) {
512 ret = setsockopt(fd,socket_options[i].level,
513 socket_options[i].option,(char *)&value,sizeof(int));
518 rprintf(FERROR,"syntax error - %s does not take a value\n",tok);
521 int on = socket_options[i].value;
522 ret = setsockopt(fd,socket_options[i].level,
523 socket_options[i].option,(char *)&on,sizeof(int));
529 rprintf(FERROR, "failed to set socket option %s: %s\n", tok,
536 /****************************************************************************
537 become a daemon, discarding the controlling terminal
538 ****************************************************************************/
539 void become_daemon(void)
547 /* detach from the terminal */
552 i = open("/dev/tty", O_RDWR);
554 ioctl(i, (int) TIOCNOTTY, (char *)0);
557 #endif /* TIOCNOTTY */
559 /* make sure that stdin, stdout an stderr don't stuff things
560 up (library functions, for example) */
563 open("/dev/null", O_RDWR);
568 * Return the IP addr of the client as a string
570 char *client_addr(int fd)
572 struct sockaddr_storage ss;
573 int length = sizeof(ss);
574 static char addr_buf[100];
575 static int initialised;
577 if (initialised) return addr_buf;
581 if (getpeername(fd, (struct sockaddr *)&ss, &length)) {
582 exit_cleanup(RERR_SOCKETIO);
585 getnameinfo((struct sockaddr *)&ss, length,
586 addr_buf, sizeof(addr_buf), NULL, 0, NI_NUMERICHOST);
591 static int get_sockaddr_family(const struct sockaddr_storage *ss)
593 return ((struct sockaddr *) ss)->sa_family;
598 * Return the DNS name of the client
600 char *client_name(int fd)
602 struct sockaddr_storage ss;
603 int length = sizeof(ss);
604 static char name_buf[100];
605 static char port_buf[100];
606 char *def = "UNKNOWN";
607 static int initialised;
608 struct addrinfo hints, *res, *res0;
611 if (initialised) return name_buf;
615 strcpy(name_buf,def);
617 if (getpeername(fd, (struct sockaddr *)&ss, &length)) {
618 /* FIXME: Can we really not continue? */
619 rprintf(FERROR, RSYNC_NAME ": getpeername on fd%d failed: %s\n",
620 fd, strerror(errno));
621 exit_cleanup(RERR_SOCKETIO);
625 if (get_sockaddr_family(&ss) == AF_INET6 &&
626 IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)&ss)->sin6_addr)) {
627 /* OK, so ss is in the IPv6 family, but it is really
628 * an IPv4 address: something like
629 * "::ffff:10.130.1.2". If we use it as-is, then the
630 * reverse lookup might fail or perhaps something else
631 * bad might happen. So instead we convert it to an
632 * equivalent address in the IPv4 address family. */
633 struct sockaddr_in6 sin6;
634 struct sockaddr_in *sin;
636 memcpy(&sin6, &ss, sizeof(sin6));
637 sin = (struct sockaddr_in *)&ss;
638 memset(sin, 0, sizeof(*sin));
639 sin->sin_family = AF_INET;
640 length = sizeof(struct sockaddr_in);
641 #ifdef HAVE_SOCKADDR_LEN
642 sin->sin_len = length;
644 sin->sin_port = sin6.sin6_port;
645 /* FIXME: Isn't there a macro we can use here rather
646 * than grovelling through the struct? It might be
647 * wrong on some systems. */
648 memcpy(&sin->sin_addr, &sin6.sin6_addr.s6_addr[12],
649 sizeof(sin->sin_addr));
654 if (getnameinfo((struct sockaddr *)&ss, length,
655 name_buf, sizeof(name_buf), port_buf, sizeof(port_buf),
656 NI_NAMEREQD | NI_NUMERICSERV) != 0) {
657 strcpy(name_buf, def);
658 rprintf(FERROR, "reverse name lookup failed\n");
662 memset(&hints, 0, sizeof(hints));
663 hints.ai_family = PF_UNSPEC;
664 hints.ai_flags = AI_CANONNAME;
665 hints.ai_socktype = SOCK_STREAM;
666 error = getaddrinfo(name_buf, port_buf, &hints, &res0);
668 strcpy(name_buf, def);
670 RSYNC_NAME ": forward name lookup for %s failed: %s\n",
672 gai_strerror(error));
676 /* XXX sin6_flowinfo and other fields */
677 for (res = res0; res; res = res->ai_next) {
678 if (res->ai_family != get_sockaddr_family(&ss))
680 if (res->ai_addrlen != length)
682 if (memcmp(res->ai_addr, &ss, res->ai_addrlen) == 0)
687 strcpy(name_buf, def);
688 rprintf(FERROR, RSYNC_NAME ": "
689 "reverse name lookup for \"%s\" failed on fd%d - spoofed address? \n",
698 /*******************************************************************
699 this is like socketpair but uses tcp. It is used by the Samba
701 The function guarantees that nobody else can attach to the socket,
702 or if they do that this function fails and the socket gets closed
703 returns 0 on success, -1 on failure
704 the resulting file descriptors are symmetrical
705 ******************************************************************/
706 static int socketpair_tcp(int fd[2])
709 struct sockaddr_in sock;
710 struct sockaddr_in sock2;
711 socklen_t socklen = sizeof(sock);
712 int connect_done = 0;
714 fd[0] = fd[1] = listener = -1;
716 memset(&sock, 0, sizeof(sock));
718 if ((listener = socket(PF_INET, SOCK_STREAM, 0)) == -1) goto failed;
720 memset(&sock2, 0, sizeof(sock2));
721 #ifdef HAVE_SOCK_SIN_LEN
722 sock2.sin_len = sizeof(sock2);
724 sock2.sin_family = PF_INET;
726 bind(listener, (struct sockaddr *)&sock2, sizeof(sock2));
728 if (listen(listener, 1) != 0) goto failed;
730 if (getsockname(listener, (struct sockaddr *)&sock, &socklen) != 0) goto failed;
732 if ((fd[1] = socket(PF_INET, SOCK_STREAM, 0)) == -1) goto failed;
734 set_nonblocking(fd[1]);
736 sock.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
738 if (connect(fd[1],(struct sockaddr *)&sock,sizeof(sock)) == -1) {
739 if (errno != EINPROGRESS) goto failed;
744 if ((fd[0] = accept(listener, (struct sockaddr *)&sock, &socklen)) == -1) goto failed;
747 if (connect_done == 0) {
748 if (connect(fd[1],(struct sockaddr *)&sock,sizeof(sock)) != 0
749 && errno != EISCONN) goto failed;
752 set_blocking (fd[1]);
758 if (fd[0] != -1) close(fd[0]);
759 if (fd[1] != -1) close(fd[1]);
760 if (listener != -1) close(listener);
765 /*******************************************************************
766 run a program on a local tcp socket, this is used to launch smbd
767 when regression testing
768 the return value is a socket which is attached to a subprocess
769 running "prog". stdin and stdout are attached. stderr is left
770 attached to the original stderr
771 ******************************************************************/
772 int sock_exec(const char *prog)
775 if (socketpair_tcp(fd) != 0) {
776 rprintf (FERROR, RSYNC_NAME
777 ": socketpair_tcp failed (%s)\n",
789 RSYNC_NAME ": execute socket program \"%s\"\n",
791 exit (system (prog));