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;
158 struct addrinfo hints, *res0, *res;
165 /* if we have a RSYNC_PROXY env variable then redirect our
166 * connetcion via a web proxy at the given address. The format
167 * is hostname:port */
168 h = getenv("RSYNC_PROXY");
169 proxied = (h != NULL) && (*h != '\0');
172 strlcpy(buffer, h, sizeof(buffer));
173 cp = strchr(buffer, ':');
176 "invalid proxy specification: should be HOST:PORT\n");
183 snprintf(portbuf, sizeof(portbuf), "%d", port);
187 memset(&hints, 0, sizeof(hints));
188 hints.ai_family = af_hint;
189 hints.ai_socktype = type;
190 error = getaddrinfo(h, portbuf, &hints, &res0);
192 rprintf(FERROR, RSYNC_NAME ": getaddrinfo: %s %s: %s\n",
193 h, portbuf, gai_strerror(error));
198 /* Try to connect to all addresses for this machine until we get
199 * through. It might e.g. be multi-homed, or have both IPv4 and IPv6
200 * addresses. We need to create a socket for each record, since the
201 * address record tells us what protocol to use to try to connect. */
202 for (res = res0; res; res = res->ai_next) {
203 s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
208 if (try_bind_local(s, res->ai_family, type,
209 bind_address) == -1) {
215 if (connect(s, res->ai_addr, res->ai_addrlen) < 0) {
221 establish_proxy_connection(s, host, port) != 0) {
230 rprintf(FERROR, RSYNC_NAME ": failed to connect to %s: %s\n",
239 * Open an outgoing socket, but allow for it to be intercepted by
240 * $RSYNC_CONNECT_PROG, which will execute a program across a TCP
241 * socketpair rather than really opening a socket.
243 * We use this primarily in testing to detect TCP flow bugs, but not
244 * cause security problems by really opening remote connections.
246 * This is based on the Samba LIBSMB_PROG feature.
248 * @param bind_address Local address to use. Normally NULL to get the stack default.
250 int open_socket_out_wrapped (char *host,
252 const char *bind_address,
257 if ((prog = getenv ("RSYNC_CONNECT_PROG")) != NULL)
258 return sock_exec (prog);
260 return open_socket_out (host, port, bind_address,
267 * Open a socket of the specified type, port and address for incoming data
269 * Try to be better about handling the results of getaddrinfo(): when
270 * opening an inbound socket, we might get several address results,
271 * e.g. for the machine's ipv4 and ipv6 name.
273 * If binding a wildcard, then any one of them should do. If an address
274 * was specified but it's insufficiently specific then that's not our
277 * However, some of the advertized addresses may not work because e.g. we
278 * don't have IPv6 support in the kernel. In that case go on and try all
279 * addresses until one succeeds.
281 * @param bind_address Local address to bind, or NULL to allow it to
284 static int open_socket_in(int type, int port, const char *bind_address,
289 struct addrinfo hints, *all_ai, *resp;
293 memset(&hints, 0, sizeof(hints));
294 hints.ai_family = af_hint;
295 hints.ai_socktype = type;
296 hints.ai_flags = AI_PASSIVE;
297 snprintf(portbuf, sizeof(portbuf), "%d", port);
298 error = getaddrinfo(bind_address, portbuf, &hints, &all_ai);
300 rprintf(FERROR, RSYNC_NAME ": getaddrinfo: bind address %s: %s\n",
301 bind_address, gai_strerror(error));
305 /* We may not be able to create the socket, if for example the
306 * machine knows about IPv6 in the C library, but not in the
308 for (resp = all_ai; resp; resp = resp->ai_next) {
309 s = socket(resp->ai_family, resp->ai_socktype,
313 /* See if there's another address that will work... */
316 setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
317 (char *)&one, sizeof one);
319 /* now we've got a socket - we need to bind it */
320 if (bind(s, all_ai->ai_addr, all_ai->ai_addrlen) < 0) {
321 /* Nope, try another */
329 rprintf(FERROR, RSYNC_NAME ": open inbound socket on port %d failed: "
334 freeaddrinfo(all_ai);
340 * Determine if a file descriptor is in fact a socket
342 int is_a_socket(int fd)
348 /* Parameters to getsockopt, setsockopt etc are very
349 * unstandardized across platforms, so don't be surprised if
350 * there are compiler warnings on e.g. SCO OpenSwerver or AIX.
351 * It seems they all eventually get the right idea.
353 * Debian says: ``The fifth argument of getsockopt and
354 * setsockopt is in reality an int [*] (and this is what BSD
355 * 4.* and libc4 and libc5 have). Some POSIX confusion
356 * resulted in the present socklen_t. The draft standard has
357 * not been adopted yet, but glibc2 already follows it and
358 * also has socklen_t [*]. See also accept(2).''
360 * We now return to your regularly scheduled programming. */
361 return(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&v, &l) == 0);
365 void start_accept_loop(int port, int (*fn)(int ))
368 extern char *bind_address;
369 extern int default_af_hint;
371 /* open an incoming socket */
372 s = open_socket_in(SOCK_STREAM, port, bind_address, default_af_hint);
374 exit_cleanup(RERR_SOCKETIO);
376 /* ready to listen */
377 if (listen(s, 5) == -1) {
379 exit_cleanup(RERR_SOCKETIO);
383 /* now accept incoming connections - forking a new process
384 for each incoming connection */
388 struct sockaddr_storage addr;
389 int addrlen = sizeof(addr);
391 /* close log file before the potentially very long select so
392 file can be trimmed by another process instead of growing
399 if (select(s+1, &fds, NULL, NULL, NULL) != 1) {
403 if(!FD_ISSET(s, &fds)) continue;
405 fd = accept(s,(struct sockaddr *)&addr,&addrlen);
407 if (fd == -1) continue;
409 signal(SIGCHLD, SIG_IGN);
411 /* we shouldn't have any children left hanging around
412 but I have had reports that on Digital Unix zombies
413 are produced, so this ensures that they are reaped */
415 while (waitpid(-1, NULL, WNOHANG) > 0);
420 /* open log file in child before possibly giving
431 enum SOCK_OPT_TYPES {OPT_BOOL,OPT_INT,OPT_ON};
440 } socket_options[] = {
441 {"SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE, 0, OPT_BOOL},
442 {"SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR, 0, OPT_BOOL},
443 {"SO_BROADCAST", SOL_SOCKET, SO_BROADCAST, 0, OPT_BOOL},
445 {"TCP_NODELAY", IPPROTO_TCP, TCP_NODELAY, 0, OPT_BOOL},
447 #ifdef IPTOS_LOWDELAY
448 {"IPTOS_LOWDELAY", IPPROTO_IP, IP_TOS, IPTOS_LOWDELAY, OPT_ON},
450 #ifdef IPTOS_THROUGHPUT
451 {"IPTOS_THROUGHPUT", IPPROTO_IP, IP_TOS, IPTOS_THROUGHPUT, OPT_ON},
454 {"SO_SNDBUF", SOL_SOCKET, SO_SNDBUF, 0, OPT_INT},
457 {"SO_RCVBUF", SOL_SOCKET, SO_RCVBUF, 0, OPT_INT},
460 {"SO_SNDLOWAT", SOL_SOCKET, SO_SNDLOWAT, 0, OPT_INT},
463 {"SO_RCVLOWAT", SOL_SOCKET, SO_RCVLOWAT, 0, OPT_INT},
466 {"SO_SNDTIMEO", SOL_SOCKET, SO_SNDTIMEO, 0, OPT_INT},
469 {"SO_RCVTIMEO", SOL_SOCKET, SO_RCVTIMEO, 0, OPT_INT},
475 /****************************************************************************
476 set user socket options
477 ****************************************************************************/
478 void set_socket_options(int fd, char *options)
481 if (!options || !*options) return;
483 options = strdup(options);
485 if (!options) out_of_memory("set_socket_options");
487 for (tok=strtok(options, " \t,"); tok; tok=strtok(NULL," \t,")) {
493 if ((p = strchr(tok,'='))) {
499 for (i=0;socket_options[i].name;i++)
500 if (strcmp(socket_options[i].name,tok)==0)
503 if (!socket_options[i].name) {
504 rprintf(FERROR,"Unknown socket option %s\n",tok);
508 switch (socket_options[i].opttype) {
511 ret = setsockopt(fd,socket_options[i].level,
512 socket_options[i].option,(char *)&value,sizeof(int));
517 rprintf(FERROR,"syntax error - %s does not take a value\n",tok);
520 int on = socket_options[i].value;
521 ret = setsockopt(fd,socket_options[i].level,
522 socket_options[i].option,(char *)&on,sizeof(int));
528 rprintf(FERROR, "failed to set socket option %s: %s\n", tok,
535 /****************************************************************************
536 become a daemon, discarding the controlling terminal
537 ****************************************************************************/
538 void become_daemon(void)
546 /* detach from the terminal */
551 i = open("/dev/tty", O_RDWR);
553 ioctl(i, (int) TIOCNOTTY, (char *)0);
556 #endif /* TIOCNOTTY */
558 /* make sure that stdin, stdout an stderr don't stuff things
559 up (library functions, for example) */
562 open("/dev/null", O_RDWR);
567 * Return the IP addr of the client as a string
569 char *client_addr(int fd)
571 struct sockaddr_storage ss;
572 int length = sizeof(ss);
573 static char addr_buf[100];
574 static int initialised;
576 if (initialised) return addr_buf;
580 if (getpeername(fd, (struct sockaddr *)&ss, &length)) {
581 exit_cleanup(RERR_SOCKETIO);
584 getnameinfo((struct sockaddr *)&ss, length,
585 addr_buf, sizeof(addr_buf), NULL, 0, NI_NUMERICHOST);
590 static int get_sockaddr_family(const struct sockaddr_storage *ss)
592 return ((struct sockaddr *) ss)->sa_family;
597 * Return the DNS name of the client
599 char *client_name(int fd)
601 struct sockaddr_storage ss;
602 int length = sizeof(ss);
603 static char name_buf[100];
604 static char port_buf[100];
605 char *def = "UNKNOWN";
606 static int initialised;
607 struct addrinfo hints, *res, *res0;
610 if (initialised) return name_buf;
614 strcpy(name_buf,def);
616 if (getpeername(fd, (struct sockaddr *)&ss, &length)) {
617 /* FIXME: Can we really not continue? */
618 rprintf(FERROR, RSYNC_NAME ": getpeername on fd%d failed: %s\n",
619 fd, strerror(errno));
620 exit_cleanup(RERR_SOCKETIO);
624 if (get_sockaddr_family(&ss) == AF_INET6 &&
625 IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)&ss)->sin6_addr)) {
626 /* OK, so ss is in the IPv6 family, but it is really
627 * an IPv4 address: something like
628 * "::ffff:10.130.1.2". If we use it as-is, then the
629 * reverse lookup might fail or perhaps something else
630 * bad might happen. So instead we convert it to an
631 * equivalent address in the IPv4 address family. */
632 struct sockaddr_in6 sin6;
633 struct sockaddr_in *sin;
635 memcpy(&sin6, &ss, sizeof(sin6));
636 sin = (struct sockaddr_in *)&ss;
637 memset(sin, 0, sizeof(*sin));
638 sin->sin_family = AF_INET;
639 length = sizeof(struct sockaddr_in);
640 #ifdef HAVE_SOCKADDR_LEN
641 sin->sin_len = length;
643 sin->sin_port = sin6.sin6_port;
644 /* FIXME: Isn't there a macro we can use here rather
645 * than grovelling through the struct? It might be
646 * wrong on some systems. */
647 memcpy(&sin->sin_addr, &sin6.sin6_addr.s6_addr[12],
648 sizeof(sin->sin_addr));
653 if (getnameinfo((struct sockaddr *)&ss, length,
654 name_buf, sizeof(name_buf), port_buf, sizeof(port_buf),
655 NI_NAMEREQD | NI_NUMERICSERV) != 0) {
656 strcpy(name_buf, def);
657 rprintf(FERROR, "reverse name lookup failed\n");
661 memset(&hints, 0, sizeof(hints));
662 hints.ai_family = PF_UNSPEC;
663 hints.ai_flags = AI_CANONNAME;
664 hints.ai_socktype = SOCK_STREAM;
665 error = getaddrinfo(name_buf, port_buf, &hints, &res0);
667 strcpy(name_buf, def);
669 RSYNC_NAME ": forward name lookup for %s failed: %s\n",
671 gai_strerror(error));
675 /* XXX sin6_flowinfo and other fields */
676 for (res = res0; res; res = res->ai_next) {
677 if (res->ai_family != get_sockaddr_family(&ss))
679 if (res->ai_addrlen != length)
681 if (memcmp(res->ai_addr, &ss, res->ai_addrlen) == 0)
686 strcpy(name_buf, def);
687 rprintf(FERROR, RSYNC_NAME ": "
688 "reverse name lookup for \"%s\" failed on fd%d - spoofed address? \n",
697 /*******************************************************************
698 this is like socketpair but uses tcp. It is used by the Samba
700 The function guarantees that nobody else can attach to the socket,
701 or if they do that this function fails and the socket gets closed
702 returns 0 on success, -1 on failure
703 the resulting file descriptors are symmetrical
704 ******************************************************************/
705 static int socketpair_tcp(int fd[2])
708 struct sockaddr_in sock;
709 struct sockaddr_in sock2;
710 socklen_t socklen = sizeof(sock);
711 int connect_done = 0;
713 fd[0] = fd[1] = listener = -1;
715 memset(&sock, 0, sizeof(sock));
717 if ((listener = socket(PF_INET, SOCK_STREAM, 0)) == -1) goto failed;
719 memset(&sock2, 0, sizeof(sock2));
720 #ifdef HAVE_SOCK_SIN_LEN
721 sock2.sin_len = sizeof(sock2);
723 sock2.sin_family = PF_INET;
725 bind(listener, (struct sockaddr *)&sock2, sizeof(sock2));
727 if (listen(listener, 1) != 0) goto failed;
729 if (getsockname(listener, (struct sockaddr *)&sock, &socklen) != 0) goto failed;
731 if ((fd[1] = socket(PF_INET, SOCK_STREAM, 0)) == -1) goto failed;
733 set_nonblocking(fd[1]);
735 sock.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
737 if (connect(fd[1],(struct sockaddr *)&sock,sizeof(sock)) == -1) {
738 if (errno != EINPROGRESS) goto failed;
743 if ((fd[0] = accept(listener, (struct sockaddr *)&sock, &socklen)) == -1) goto failed;
746 if (connect_done == 0) {
747 if (connect(fd[1],(struct sockaddr *)&sock,sizeof(sock)) != 0
748 && errno != EISCONN) goto failed;
751 set_blocking (fd[1]);
757 if (fd[0] != -1) close(fd[0]);
758 if (fd[1] != -1) close(fd[1]);
759 if (listener != -1) close(listener);
764 /*******************************************************************
765 run a program on a local tcp socket, this is used to launch smbd
766 when regression testing
767 the return value is a socket which is attached to a subprocess
768 running "prog". stdin and stdout are attached. stderr is left
769 attached to the original stderr
770 ******************************************************************/
771 int sock_exec(const char *prog)
774 if (socketpair_tcp(fd) != 0) {
775 rprintf (FERROR, RSYNC_NAME
776 ": socketpair_tcp failed (%s)\n",
788 RSYNC_NAME ": execute socket program \"%s\"\n",
790 exit (system (prog));