1 /* -*- c-file-style: "linux" -*-
3 Copyright (C) 1992-2001 by Andrew Tridgell <tridge@samba.org>
4 Copyright (C) 2001 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.
29 /* Establish a proxy connection on an open socket to a web roxy by
30 * using the CONNECT method. */
31 static int establish_proxy_connection(int fd, char *host, int port)
36 snprintf(buffer, sizeof(buffer), "CONNECT %s:%d HTTP/1.0\r\n\r\n", host, port);
37 if (write(fd, buffer, strlen(buffer)) != strlen(buffer)) {
38 rprintf(FERROR, "failed to write to proxy: %s\n",
43 for (cp = buffer; cp < &buffer[sizeof(buffer) - 1]; cp++) {
44 if (read(fd, cp, 1) != 1) {
45 rprintf(FERROR, "failed to read from proxy: %s\n",
58 if (strncmp(buffer, "HTTP/", 5) != 0) {
59 rprintf(FERROR, "bad response from proxy - %s\n",
63 for (cp = &buffer[5]; isdigit(*cp) || (*cp == '.'); cp++)
68 rprintf(FERROR, "bad response from proxy - %s\n",
72 /* throw away the rest of the HTTP header */
74 for (cp = buffer; cp < &buffer[sizeof(buffer) - 1];
76 if (read(fd, cp, 1) != 1) {
77 rprintf(FERROR, "failed to read from proxy: %s\n",
84 if ((cp > buffer) && (*cp == '\n'))
86 if ((cp == buffer) && ((*cp == '\n') || (*cp == '\r')))
94 * Try to set the local address for a newly-created socket. Return -1
97 int try_bind_local(int s,
98 int ai_family, int ai_socktype,
99 const char *bind_address)
102 struct addrinfo bhints, *bres_all, *r;
104 memset(&bhints, 0, sizeof(bhints));
105 bhints.ai_family = ai_family;
106 bhints.ai_socktype = ai_socktype;
107 bhints.ai_flags = AI_PASSIVE;
108 if (getaddrinfo(bind_address, NULL, &bhints, &bres_all) == -1) {
109 rprintf(FERROR, RSYNC_NAME ": getaddrinfo %s: %s\n",
110 bind_address, gai_strerror(error));
114 for (r = bres_all; r; r = r->ai_next) {
115 if (bind(s, r->ai_addr, r->ai_addrlen) == -1)
120 /* no error message; there might be some problem that allows
121 * creation of the socket but not binding, perhaps if the
122 * machine has no ipv6 address of this name. */
128 * Open a socket to a tcp remote host with the specified port .
130 * Based on code from Warren. Proxy support by Stephen Rothwell.
131 * getaddrinfo() rewrite contributed by KAME.net.
133 * Now that we support IPv6 we need to look up the remote machine's
134 * address first, using @p af_hint to set a preference for the type
135 * of address. Then depending on whether it has v4 or v6 addresses we
136 * try to open a connection.
138 * The loop allows for machines with some addresses which may not be
139 * reachable, perhaps because we can't e.g. route ipv6 to that network
140 * but we can get ip4 packets through.
142 * @param bind_address Local address to use. Normally NULL to bind
143 * the wildcard address.
145 * @param af_hint Address family, e.g. AF_INET or AF_INET6.
147 int open_socket_out(char *host, int port, const char *bind_address,
150 int type = SOCK_STREAM;
154 struct addrinfo hints, *res0, *res;
161 /* if we have a RSYNC_PROXY env variable then redirect our
162 * connetcion via a web proxy at the given address. The format
163 * is hostname:port */
164 h = getenv("RSYNC_PROXY");
165 proxied = (h != NULL) && (*h != '\0');
168 strlcpy(buffer, h, sizeof(buffer));
169 cp = strchr(buffer, ':');
172 "invalid proxy specification: should be HOST:PORT\n");
179 snprintf(portbuf, sizeof(portbuf), "%d", port);
183 memset(&hints, 0, sizeof(hints));
184 hints.ai_family = af_hint;
185 hints.ai_socktype = type;
186 error = getaddrinfo(h, portbuf, &hints, &res0);
188 rprintf(FERROR, RSYNC_NAME ": getaddrinfo: %s %s: %s\n",
189 h, portbuf, gai_strerror(error));
194 /* Try to connect to all addresses for this machine until we get
195 * through. It might e.g. be multi-homed, or have both IPv4 and IPv6
196 * addresses. We need to create a socket for each record, since the
197 * address record tells us what protocol to use to try to connect. */
198 for (res = res0; res; res = res->ai_next) {
199 s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
204 if (try_bind_local(s, res->ai_family, type,
205 bind_address) == -1) {
211 if (connect(s, res->ai_addr, res->ai_addrlen) < 0) {
217 establish_proxy_connection(s, host, port) != 0) {
226 rprintf(FERROR, RSYNC_NAME ": failed to connect to %s: %s\n",
235 * Open an outgoing socket, but allow for it to be intercepted by
236 * $RSYNC_CONNECT_PROG, which will execute a program across a TCP
237 * socketpair rather than really opening a socket.
239 * We use this primarily in testing to detect TCP flow bugs, but not
240 * cause security problems by really opening remote connections.
242 * This is based on the Samba LIBSMB_PROG feature.
244 * @param bind_address Local address to use. Normally NULL to get the stack default.
246 int open_socket_out_wrapped (char *host,
248 const char *bind_address,
253 if ((prog = getenv ("RSYNC_CONNECT_PROG")) != NULL)
254 return sock_exec (prog);
256 return open_socket_out (host, port, bind_address,
263 * Open a socket of the specified type, port and address for incoming data
265 * Try to be better about handling the results of getaddrinfo(): when
266 * opening an inbound socket, we might get several address results,
267 * e.g. for the machine's ipv4 and ipv6 name.
269 * If binding a wildcard, then any one of them should do. If an address
270 * was specified but it's insufficiently specific then that's not our
273 * However, some of the advertized addresses may not work because e.g. we
274 * don't have IPv6 support in the kernel. In that case go on and try all
275 * addresses until one succeeds.
277 * @param bind_address Local address to bind, or NULL to allow it to
280 static int open_socket_in(int type, int port, const char *bind_address,
285 struct addrinfo hints, *all_ai, *resp;
289 memset(&hints, 0, sizeof(hints));
290 hints.ai_family = af_hint;
291 hints.ai_socktype = type;
292 hints.ai_flags = AI_PASSIVE;
293 snprintf(portbuf, sizeof(portbuf), "%d", port);
294 error = getaddrinfo(bind_address, portbuf, &hints, &all_ai);
296 rprintf(FERROR, RSYNC_NAME ": getaddrinfo: bind address %s: %s\n",
297 bind_address, gai_strerror(error));
301 /* We may not be able to create the socket, if for example the
302 * machine knows about IPv6 in the C library, but not in the
304 for (resp = all_ai; resp; resp = resp->ai_next) {
305 s = socket(resp->ai_family, resp->ai_socktype,
309 /* See if there's another address that will work... */
312 setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
313 (char *)&one, sizeof one);
315 /* now we've got a socket - we need to bind it */
316 if (bind(s, all_ai->ai_addr, all_ai->ai_addrlen) < 0) {
317 /* Nope, try another */
325 rprintf(FERROR, RSYNC_NAME ": open inbound socket on port %d failed: "
330 freeaddrinfo(all_ai);
336 * Determine if a file descriptor is in fact a socket
338 int is_a_socket(int fd)
344 /* Parameters to getsockopt, setsockopt etc are very
345 * unstandardized across platforms, so don't be surprised if
346 * there are compiler warnings on e.g. SCO OpenSwerver or AIX.
347 * It seems they all eventually get the right idea.
349 * Debian says: ``The fifth argument of getsockopt and
350 * setsockopt is in reality an int [*] (and this is what BSD
351 * 4.* and libc4 and libc5 have). Some POSIX confusion
352 * resulted in the present socklen_t. The draft standard has
353 * not been adopted yet, but glibc2 already follows it and
354 * also has socklen_t [*]. See also accept(2).''
356 * We now return to your regularly scheduled programming. */
357 return(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&v, &l) == 0);
361 void start_accept_loop(int port, int (*fn)(int ))
364 extern char *bind_address;
365 extern int default_af_hint;
367 /* open an incoming socket */
368 s = open_socket_in(SOCK_STREAM, port, bind_address, default_af_hint);
370 exit_cleanup(RERR_SOCKETIO);
372 /* ready to listen */
373 if (listen(s, 5) == -1) {
375 exit_cleanup(RERR_SOCKETIO);
379 /* now accept incoming connections - forking a new process
380 for each incoming connection */
384 struct sockaddr_storage addr;
385 int addrlen = sizeof(addr);
387 /* close log file before the potentially very long select so
388 file can be trimmed by another process instead of growing
395 if (select(s+1, &fds, NULL, NULL, NULL) != 1) {
399 if(!FD_ISSET(s, &fds)) continue;
401 fd = accept(s,(struct sockaddr *)&addr,&addrlen);
403 if (fd == -1) continue;
405 signal(SIGCHLD, SIG_IGN);
407 /* we shouldn't have any children left hanging around
408 but I have had reports that on Digital Unix zombies
409 are produced, so this ensures that they are reaped */
411 while (waitpid(-1, NULL, WNOHANG) > 0);
416 /* open log file in child before possibly giving
427 enum SOCK_OPT_TYPES {OPT_BOOL,OPT_INT,OPT_ON};
436 } socket_options[] = {
437 {"SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE, 0, OPT_BOOL},
438 {"SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR, 0, OPT_BOOL},
439 {"SO_BROADCAST", SOL_SOCKET, SO_BROADCAST, 0, OPT_BOOL},
441 {"TCP_NODELAY", IPPROTO_TCP, TCP_NODELAY, 0, OPT_BOOL},
443 #ifdef IPTOS_LOWDELAY
444 {"IPTOS_LOWDELAY", IPPROTO_IP, IP_TOS, IPTOS_LOWDELAY, OPT_ON},
446 #ifdef IPTOS_THROUGHPUT
447 {"IPTOS_THROUGHPUT", IPPROTO_IP, IP_TOS, IPTOS_THROUGHPUT, OPT_ON},
450 {"SO_SNDBUF", SOL_SOCKET, SO_SNDBUF, 0, OPT_INT},
453 {"SO_RCVBUF", SOL_SOCKET, SO_RCVBUF, 0, OPT_INT},
456 {"SO_SNDLOWAT", SOL_SOCKET, SO_SNDLOWAT, 0, OPT_INT},
459 {"SO_RCVLOWAT", SOL_SOCKET, SO_RCVLOWAT, 0, OPT_INT},
462 {"SO_SNDTIMEO", SOL_SOCKET, SO_SNDTIMEO, 0, OPT_INT},
465 {"SO_RCVTIMEO", SOL_SOCKET, SO_RCVTIMEO, 0, OPT_INT},
471 /****************************************************************************
472 set user socket options
473 ****************************************************************************/
474 void set_socket_options(int fd, char *options)
477 if (!options || !*options) return;
479 options = strdup(options);
481 if (!options) out_of_memory("set_socket_options");
483 for (tok=strtok(options, " \t,"); tok; tok=strtok(NULL," \t,")) {
489 if ((p = strchr(tok,'='))) {
495 for (i=0;socket_options[i].name;i++)
496 if (strcmp(socket_options[i].name,tok)==0)
499 if (!socket_options[i].name) {
500 rprintf(FERROR,"Unknown socket option %s\n",tok);
504 switch (socket_options[i].opttype) {
507 ret = setsockopt(fd,socket_options[i].level,
508 socket_options[i].option,(char *)&value,sizeof(int));
513 rprintf(FERROR,"syntax error - %s does not take a value\n",tok);
516 int on = socket_options[i].value;
517 ret = setsockopt(fd,socket_options[i].level,
518 socket_options[i].option,(char *)&on,sizeof(int));
524 rprintf(FERROR, "failed to set socket option %s: %s\n", tok,
531 /****************************************************************************
532 become a daemon, discarding the controlling terminal
533 ****************************************************************************/
534 void become_daemon(void)
542 /* detach from the terminal */
547 i = open("/dev/tty", O_RDWR);
549 ioctl(i, (int) TIOCNOTTY, (char *)0);
552 #endif /* TIOCNOTTY */
554 /* make sure that stdin, stdout an stderr don't stuff things
555 up (library functions, for example) */
558 open("/dev/null", O_RDWR);
563 * Return the IP addr of the client as a string
565 char *client_addr(int fd)
567 struct sockaddr_storage ss;
568 int length = sizeof(ss);
569 static char addr_buf[100];
570 static int initialised;
572 if (initialised) return addr_buf;
576 if (getpeername(fd, (struct sockaddr *)&ss, &length)) {
577 exit_cleanup(RERR_SOCKETIO);
580 getnameinfo((struct sockaddr *)&ss, length,
581 addr_buf, sizeof(addr_buf), NULL, 0, NI_NUMERICHOST);
586 static int get_sockaddr_family(const struct sockaddr_storage *ss)
588 return ((struct sockaddr *) ss)->sa_family;
593 * Return the DNS name of the client
595 char *client_name(int fd)
597 struct sockaddr_storage ss;
598 int length = sizeof(ss);
599 static char name_buf[100];
600 static char port_buf[100];
601 char *def = "UNKNOWN";
602 static int initialised;
603 struct addrinfo hints, *res, *res0;
606 if (initialised) return name_buf;
610 strcpy(name_buf,def);
612 if (getpeername(fd, (struct sockaddr *)&ss, &length)) {
613 /* FIXME: Can we really not continue? */
614 rprintf(FERROR, RSYNC_NAME ": getpeername on fd%d failed: %s\n",
615 fd, strerror(errno));
616 exit_cleanup(RERR_SOCKETIO);
620 if (get_sockaddr_family(&ss) == AF_INET6 &&
621 IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)&ss)->sin6_addr)) {
622 struct sockaddr_in6 sin6;
623 struct sockaddr_in *sin;
625 memcpy(&sin6, &ss, sizeof(sin6));
626 sin = (struct sockaddr_in *)&ss;
627 memset(sin, 0, sizeof(*sin));
628 sin->sin_family = AF_INET;
629 length = sizeof(struct sockaddr_in);
630 #ifdef HAVE_SOCKADDR_LEN
631 sin->sin_len = length;
633 sin->sin_port = sin6.sin6_port;
634 memcpy(&sin->sin_addr, &sin6.sin6_addr.s6_addr[12],
635 sizeof(sin->sin_addr));
640 if (getnameinfo((struct sockaddr *)&ss, length,
641 name_buf, sizeof(name_buf), port_buf, sizeof(port_buf),
642 NI_NAMEREQD | NI_NUMERICSERV) != 0) {
643 strcpy(name_buf, def);
644 rprintf(FERROR, "reverse name lookup failed\n");
648 memset(&hints, 0, sizeof(hints));
649 hints.ai_family = PF_UNSPEC;
650 hints.ai_flags = AI_CANONNAME;
651 hints.ai_socktype = SOCK_STREAM;
652 error = getaddrinfo(name_buf, port_buf, &hints, &res0);
654 strcpy(name_buf, def);
656 RSYNC_NAME ": forward name lookup for %s failed: %s\n",
658 gai_strerror(error));
662 /* XXX sin6_flowinfo and other fields */
663 for (res = res0; res; res = res->ai_next) {
664 if (res->ai_family != get_sockaddr_family(&ss))
666 if (res->ai_addrlen != length)
668 if (memcmp(res->ai_addr, &ss, res->ai_addrlen) == 0)
672 /* TODO: Do a forward lookup as well to prevent spoofing */
675 strcpy(name_buf, def);
676 rprintf(FERROR, RSYNC_NAME ": "
677 "reverse name lookup mismatch on fd%d - spoofed address?\n",
686 /*******************************************************************
687 this is like socketpair but uses tcp. It is used by the Samba
689 The function guarantees that nobody else can attach to the socket,
690 or if they do that this function fails and the socket gets closed
691 returns 0 on success, -1 on failure
692 the resulting file descriptors are symmetrical
693 ******************************************************************/
694 static int socketpair_tcp(int fd[2])
697 struct sockaddr_in sock;
698 struct sockaddr_in sock2;
699 socklen_t socklen = sizeof(sock);
700 int connect_done = 0;
702 fd[0] = fd[1] = listener = -1;
704 memset(&sock, 0, sizeof(sock));
706 if ((listener = socket(PF_INET, SOCK_STREAM, 0)) == -1) goto failed;
708 memset(&sock2, 0, sizeof(sock2));
709 #ifdef HAVE_SOCK_SIN_LEN
710 sock2.sin_len = sizeof(sock2);
712 sock2.sin_family = PF_INET;
714 bind(listener, (struct sockaddr *)&sock2, sizeof(sock2));
716 if (listen(listener, 1) != 0) goto failed;
718 if (getsockname(listener, (struct sockaddr *)&sock, &socklen) != 0) goto failed;
720 if ((fd[1] = socket(PF_INET, SOCK_STREAM, 0)) == -1) goto failed;
722 set_nonblocking(fd[1]);
724 sock.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
726 if (connect(fd[1],(struct sockaddr *)&sock,sizeof(sock)) == -1) {
727 if (errno != EINPROGRESS) goto failed;
732 if ((fd[0] = accept(listener, (struct sockaddr *)&sock, &socklen)) == -1) goto failed;
735 if (connect_done == 0) {
736 if (connect(fd[1],(struct sockaddr *)&sock,sizeof(sock)) != 0
737 && errno != EISCONN) goto failed;
740 set_blocking (fd[1]);
746 if (fd[0] != -1) close(fd[0]);
747 if (fd[1] != -1) close(fd[1]);
748 if (listener != -1) close(listener);
753 /*******************************************************************
754 run a program on a local tcp socket, this is used to launch smbd
755 when regression testing
756 the return value is a socket which is attached to a subprocess
757 running "prog". stdin and stdout are attached. stderr is left
758 attached to the original stderr
759 ******************************************************************/
760 int sock_exec(const char *prog)
763 if (socketpair_tcp(fd) != 0) {
764 rprintf (FERROR, RSYNC_NAME
765 ": socketpair_tcp failed (%s)\n",
777 RSYNC_NAME ": execute socket program \"%s\"\n",
779 exit (system (prog));