With -vv, client shows a message when opening a daemon connection.
[rsync/rsync.git] / socket.c
... / ...
CommitLineData
1/* -*- c-file-style: "linux" -*-
2
3 rsync -- fast file replication program
4
5 Copyright (C) 1992-2001 by Andrew Tridgell <tridge@samba.org>
6 Copyright (C) 2001, 2002 by Martin Pool <mbp@samba.org>
7
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.
12
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.
17
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.
21*/
22
23/**
24 * @file socket.c
25 *
26 * Socket functions used in rsync.
27 *
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.
32 **/
33
34#include "rsync.h"
35
36
37/* Establish a proxy connection on an open socket to a web roxy by
38 * using the CONNECT method. */
39static int establish_proxy_connection(int fd, char *host, int port)
40{
41 char buffer[1024];
42 char *cp;
43
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",
47 strerror(errno));
48 return -1;
49 }
50
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",
54 strerror(errno));
55 return -1;
56 }
57 if (*cp == '\n')
58 break;
59 }
60
61 if (*cp != '\n')
62 cp++;
63 *cp-- = '\0';
64 if (*cp == '\r')
65 *cp = '\0';
66 if (strncmp(buffer, "HTTP/", 5) != 0) {
67 rprintf(FERROR, "bad response from proxy - %s\n",
68 buffer);
69 return -1;
70 }
71 for (cp = &buffer[5]; isdigit(*cp) || (*cp == '.'); cp++)
72 ;
73 while (*cp == ' ')
74 cp++;
75 if (*cp != '2') {
76 rprintf(FERROR, "bad response from proxy - %s\n",
77 buffer);
78 return -1;
79 }
80 /* throw away the rest of the HTTP header */
81 while (1) {
82 for (cp = buffer; cp < &buffer[sizeof(buffer) - 1];
83 cp++) {
84 if (read(fd, cp, 1) != 1) {
85 rprintf(FERROR, "failed to read from proxy: %s\n",
86 strerror(errno));
87 return -1;
88 }
89 if (*cp == '\n')
90 break;
91 }
92 if ((cp > buffer) && (*cp == '\n'))
93 cp--;
94 if ((cp == buffer) && ((*cp == '\n') || (*cp == '\r')))
95 break;
96 }
97 return 0;
98}
99
100
101/**
102 * Try to set the local address for a newly-created socket. Return -1
103 * if this fails.
104 **/
105int try_bind_local(int s,
106 int ai_family, int ai_socktype,
107 const char *bind_address)
108{
109 int error;
110 struct addrinfo bhints, *bres_all, *r;
111
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));
119 return -1;
120 }
121
122 for (r = bres_all; r; r = r->ai_next) {
123 if (bind(s, r->ai_addr, r->ai_addrlen) == -1)
124 continue;
125 return s;
126 }
127
128 /* no error message; there might be some problem that allows
129 * creation of the socket but not binding, perhaps if the
130 * machine has no ipv6 address of this name. */
131 return -1;
132}
133
134
135/**
136 * Open a socket to a tcp remote host with the specified port .
137 *
138 * Based on code from Warren. Proxy support by Stephen Rothwell.
139 * getaddrinfo() rewrite contributed by KAME.net.
140 *
141 * Now that we support IPv6 we need to look up the remote machine's
142 * address first, using @p af_hint to set a preference for the type
143 * of address. Then depending on whether it has v4 or v6 addresses we
144 * try to open a connection.
145 *
146 * The loop allows for machines with some addresses which may not be
147 * reachable, perhaps because we can't e.g. route ipv6 to that network
148 * but we can get ip4 packets through.
149 *
150 * @param bind_address Local address to use. Normally NULL to bind
151 * the wildcard address.
152 *
153 * @param af_hint Address family, e.g. AF_INET or AF_INET6.
154 **/
155int open_socket_out(char *host, int port, const char *bind_address,
156 int af_hint)
157{
158 int type = SOCK_STREAM;
159 int error;
160 int s;
161 struct addrinfo hints, *res0, *res;
162 char portbuf[10];
163 char *h;
164 int proxied = 0;
165 char buffer[1024];
166 char *cp;
167
168 /* if we have a RSYNC_PROXY env variable then redirect our
169 * connetcion via a web proxy at the given address. The format
170 * is hostname:port */
171 h = getenv("RSYNC_PROXY");
172 proxied = (h != NULL) && (*h != '\0');
173
174 if (proxied) {
175 strlcpy(buffer, h, sizeof(buffer));
176 cp = strchr(buffer, ':');
177 if (cp == NULL) {
178 rprintf(FERROR,
179 "invalid proxy specification: should be HOST:PORT\n");
180 return -1;
181 }
182 *cp++ = '\0';
183 strcpy(portbuf, cp);
184 h = buffer;
185 } else {
186 snprintf(portbuf, sizeof(portbuf), "%d", port);
187 h = host;
188 }
189
190 memset(&hints, 0, sizeof(hints));
191 hints.ai_family = af_hint;
192 hints.ai_socktype = type;
193 error = getaddrinfo(h, portbuf, &hints, &res0);
194 if (error) {
195 rprintf(FERROR, RSYNC_NAME ": getaddrinfo: %s %s: %s\n",
196 h, portbuf, gai_strerror(error));
197 return -1;
198 }
199
200 s = -1;
201 /* Try to connect to all addresses for this machine until we get
202 * through. It might e.g. be multi-homed, or have both IPv4 and IPv6
203 * addresses. We need to create a socket for each record, since the
204 * address record tells us what protocol to use to try to connect. */
205 for (res = res0; res; res = res->ai_next) {
206 s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
207 if (s < 0)
208 continue;
209
210 if (bind_address)
211 if (try_bind_local(s, res->ai_family, type,
212 bind_address) == -1) {
213 close(s);
214 s = -1;
215 continue;
216 }
217
218 if (connect(s, res->ai_addr, res->ai_addrlen) < 0) {
219 close(s);
220 s = -1;
221 continue;
222 }
223 if (proxied &&
224 establish_proxy_connection(s, host, port) != 0) {
225 close(s);
226 s = -1;
227 continue;
228 } else
229 break;
230 }
231 freeaddrinfo(res0);
232 if (s < 0) {
233 rprintf(FERROR, RSYNC_NAME ": failed to connect to %s: %s\n",
234 h, strerror(errno));
235 return -1;
236 }
237 return s;
238}
239
240
241/**
242 * Open an outgoing socket, but allow for it to be intercepted by
243 * $RSYNC_CONNECT_PROG, which will execute a program across a TCP
244 * socketpair rather than really opening a socket.
245 *
246 * We use this primarily in testing to detect TCP flow bugs, but not
247 * cause security problems by really opening remote connections.
248 *
249 * This is based on the Samba LIBSMB_PROG feature.
250 *
251 * @param bind_address Local address to use. Normally NULL to get the stack default.
252 **/
253int open_socket_out_wrapped (char *host,
254 int port,
255 const char *bind_address,
256 int af_hint)
257{
258 char *prog;
259
260 if ((prog = getenv ("RSYNC_CONNECT_PROG")) != NULL)
261 return sock_exec (prog);
262 else
263 return open_socket_out (host, port, bind_address,
264 af_hint);
265}
266
267
268
269/**
270 * Open a socket of the specified type, port and address for incoming data
271 *
272 * Try to be better about handling the results of getaddrinfo(): when
273 * opening an inbound socket, we might get several address results,
274 * e.g. for the machine's ipv4 and ipv6 name.
275 *
276 * If binding a wildcard, then any one of them should do. If an address
277 * was specified but it's insufficiently specific then that's not our
278 * fault.
279 *
280 * However, some of the advertized addresses may not work because e.g. we
281 * don't have IPv6 support in the kernel. In that case go on and try all
282 * addresses until one succeeds.
283 *
284 * @param bind_address Local address to bind, or NULL to allow it to
285 * default.
286 **/
287static int open_socket_in(int type, int port, const char *bind_address,
288 int af_hint)
289{
290 int one=1;
291 int s;
292 struct addrinfo hints, *all_ai, *resp;
293 char portbuf[10];
294 int error;
295
296 memset(&hints, 0, sizeof(hints));
297 hints.ai_family = af_hint;
298 hints.ai_socktype = type;
299 hints.ai_flags = AI_PASSIVE;
300 snprintf(portbuf, sizeof(portbuf), "%d", port);
301 error = getaddrinfo(bind_address, portbuf, &hints, &all_ai);
302 if (error) {
303 rprintf(FERROR, RSYNC_NAME ": getaddrinfo: bind address %s: %s\n",
304 bind_address, gai_strerror(error));
305 return -1;
306 }
307
308 /* We may not be able to create the socket, if for example the
309 * machine knows about IPv6 in the C library, but not in the
310 * kernel. */
311 for (resp = all_ai; resp; resp = resp->ai_next) {
312 s = socket(resp->ai_family, resp->ai_socktype,
313 resp->ai_protocol);
314
315 if (s == -1)
316 /* See if there's another address that will work... */
317 continue;
318
319 setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
320 (char *)&one, sizeof one);
321
322 /* now we've got a socket - we need to bind it */
323 if (bind(s, all_ai->ai_addr, all_ai->ai_addrlen) < 0) {
324 /* Nope, try another */
325 close(s);
326 continue;
327 }
328
329 return s;
330 }
331
332 rprintf(FERROR, RSYNC_NAME ": open inbound socket on port %d failed: "
333 "%s\n",
334 port,
335 strerror(errno));
336
337 freeaddrinfo(all_ai);
338 return -1;
339}
340
341
342/*
343 * Determine if a file descriptor is in fact a socket
344 */
345int is_a_socket(int fd)
346{
347 int v;
348 socklen_t l;
349 l = sizeof(int);
350
351 /* Parameters to getsockopt, setsockopt etc are very
352 * unstandardized across platforms, so don't be surprised if
353 * there are compiler warnings on e.g. SCO OpenSwerver or AIX.
354 * It seems they all eventually get the right idea.
355 *
356 * Debian says: ``The fifth argument of getsockopt and
357 * setsockopt is in reality an int [*] (and this is what BSD
358 * 4.* and libc4 and libc5 have). Some POSIX confusion
359 * resulted in the present socklen_t. The draft standard has
360 * not been adopted yet, but glibc2 already follows it and
361 * also has socklen_t [*]. See also accept(2).''
362 *
363 * We now return to your regularly scheduled programming. */
364 return(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&v, &l) == 0);
365}
366
367
368void start_accept_loop(int port, int (*fn)(int ))
369{
370 int s;
371 extern char *bind_address;
372 extern int default_af_hint;
373
374 /* open an incoming socket */
375 s = open_socket_in(SOCK_STREAM, port, bind_address, default_af_hint);
376 if (s == -1)
377 exit_cleanup(RERR_SOCKETIO);
378
379 /* ready to listen */
380 if (listen(s, 5) == -1) {
381 close(s);
382 exit_cleanup(RERR_SOCKETIO);
383 }
384
385
386 /* now accept incoming connections - forking a new process
387 for each incoming connection */
388 while (1) {
389 fd_set fds;
390 pid_t pid;
391 int fd;
392 struct sockaddr_storage addr;
393 socklen_t addrlen = sizeof addr;
394
395 /* close log file before the potentially very long select so
396 file can be trimmed by another process instead of growing
397 forever */
398 log_close();
399
400 FD_ZERO(&fds);
401 FD_SET(s, &fds);
402
403 if (select(s+1, &fds, NULL, NULL, NULL) != 1) {
404 continue;
405 }
406
407 if(!FD_ISSET(s, &fds)) continue;
408
409 fd = accept(s,(struct sockaddr *)&addr,&addrlen);
410
411 if (fd == -1) continue;
412
413 signal(SIGCHLD, SIG_IGN);
414
415 /* we shouldn't have any children left hanging around
416 but I have had reports that on Digital Unix zombies
417 are produced, so this ensures that they are reaped */
418#ifdef WNOHANG
419 while (waitpid(-1, NULL, WNOHANG) > 0);
420#endif
421
422 if ((pid = fork()) == 0) {
423 close(s);
424 /* open log file in child before possibly giving
425 up privileges */
426 log_open();
427 _exit(fn(fd));
428 } else if (pid < 0) {
429 rprintf(FERROR,
430 RSYNC_NAME
431 ": could not create child server process: %s\n",
432 strerror(errno));
433 close(fd);
434 /* This might have happened because we're
435 * overloaded. Sleep briefly before trying to
436 * accept again. */
437 sleep(2);
438 } else {
439 /* Parent doesn't need this fd anymore. */
440 close(fd);
441 }
442 }
443}
444
445
446enum SOCK_OPT_TYPES {OPT_BOOL,OPT_INT,OPT_ON};
447
448struct
449{
450 char *name;
451 int level;
452 int option;
453 int value;
454 int opttype;
455} socket_options[] = {
456 {"SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE, 0, OPT_BOOL},
457 {"SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR, 0, OPT_BOOL},
458 {"SO_BROADCAST", SOL_SOCKET, SO_BROADCAST, 0, OPT_BOOL},
459#ifdef TCP_NODELAY
460 {"TCP_NODELAY", IPPROTO_TCP, TCP_NODELAY, 0, OPT_BOOL},
461#endif
462#ifdef IPTOS_LOWDELAY
463 {"IPTOS_LOWDELAY", IPPROTO_IP, IP_TOS, IPTOS_LOWDELAY, OPT_ON},
464#endif
465#ifdef IPTOS_THROUGHPUT
466 {"IPTOS_THROUGHPUT", IPPROTO_IP, IP_TOS, IPTOS_THROUGHPUT, OPT_ON},
467#endif
468#ifdef SO_SNDBUF
469 {"SO_SNDBUF", SOL_SOCKET, SO_SNDBUF, 0, OPT_INT},
470#endif
471#ifdef SO_RCVBUF
472 {"SO_RCVBUF", SOL_SOCKET, SO_RCVBUF, 0, OPT_INT},
473#endif
474#ifdef SO_SNDLOWAT
475 {"SO_SNDLOWAT", SOL_SOCKET, SO_SNDLOWAT, 0, OPT_INT},
476#endif
477#ifdef SO_RCVLOWAT
478 {"SO_RCVLOWAT", SOL_SOCKET, SO_RCVLOWAT, 0, OPT_INT},
479#endif
480#ifdef SO_SNDTIMEO
481 {"SO_SNDTIMEO", SOL_SOCKET, SO_SNDTIMEO, 0, OPT_INT},
482#endif
483#ifdef SO_RCVTIMEO
484 {"SO_RCVTIMEO", SOL_SOCKET, SO_RCVTIMEO, 0, OPT_INT},
485#endif
486 {NULL,0,0,0,0}};
487
488
489
490/****************************************************************************
491set user socket options
492****************************************************************************/
493void set_socket_options(int fd, char *options)
494{
495 char *tok;
496 if (!options || !*options) return;
497
498 options = strdup(options);
499
500 if (!options) out_of_memory("set_socket_options");
501
502 for (tok=strtok(options, " \t,"); tok; tok=strtok(NULL," \t,")) {
503 int ret=0,i;
504 int value = 1;
505 char *p;
506 int got_value = 0;
507
508 if ((p = strchr(tok,'='))) {
509 *p = 0;
510 value = atoi(p+1);
511 got_value = 1;
512 }
513
514 for (i=0;socket_options[i].name;i++)
515 if (strcmp(socket_options[i].name,tok)==0)
516 break;
517
518 if (!socket_options[i].name) {
519 rprintf(FERROR,"Unknown socket option %s\n",tok);
520 continue;
521 }
522
523 switch (socket_options[i].opttype) {
524 case OPT_BOOL:
525 case OPT_INT:
526 ret = setsockopt(fd,socket_options[i].level,
527 socket_options[i].option,(char *)&value,sizeof(int));
528 break;
529
530 case OPT_ON:
531 if (got_value)
532 rprintf(FERROR,"syntax error - %s does not take a value\n",tok);
533
534 {
535 int on = socket_options[i].value;
536 ret = setsockopt(fd,socket_options[i].level,
537 socket_options[i].option,(char *)&on,sizeof(int));
538 }
539 break;
540 }
541
542 if (ret != 0)
543 rprintf(FERROR, "failed to set socket option %s: %s\n", tok,
544 strerror(errno));
545 }
546
547 free(options);
548}
549
550/****************************************************************************
551become a daemon, discarding the controlling terminal
552****************************************************************************/
553void become_daemon(void)
554{
555 int i;
556
557 if (fork()) {
558 _exit(0);
559 }
560
561 /* detach from the terminal */
562#ifdef HAVE_SETSID
563 setsid();
564#else
565#ifdef TIOCNOTTY
566 i = open("/dev/tty", O_RDWR);
567 if (i >= 0) {
568 ioctl(i, (int) TIOCNOTTY, (char *)0);
569 close(i);
570 }
571#endif /* TIOCNOTTY */
572#endif
573 /* make sure that stdin, stdout an stderr don't stuff things
574 up (library functions, for example) */
575 for (i=0;i<3;i++) {
576 close(i);
577 open("/dev/null", O_RDWR);
578 }
579}
580
581
582/*******************************************************************
583this is like socketpair but uses tcp. It is used by the Samba
584regression test code
585The function guarantees that nobody else can attach to the socket,
586or if they do that this function fails and the socket gets closed
587returns 0 on success, -1 on failure
588the resulting file descriptors are symmetrical
589 ******************************************************************/
590static int socketpair_tcp(int fd[2])
591{
592 int listener;
593 struct sockaddr_in sock;
594 struct sockaddr_in sock2;
595 socklen_t socklen = sizeof(sock);
596 int connect_done = 0;
597
598 fd[0] = fd[1] = listener = -1;
599
600 memset(&sock, 0, sizeof(sock));
601
602 if ((listener = socket(PF_INET, SOCK_STREAM, 0)) == -1) goto failed;
603
604 memset(&sock2, 0, sizeof(sock2));
605#ifdef HAVE_SOCKADDR_LEN
606 sock2.sin_len = sizeof(sock2);
607#endif
608 sock2.sin_family = PF_INET;
609
610 bind(listener, (struct sockaddr *)&sock2, sizeof(sock2));
611
612 if (listen(listener, 1) != 0) goto failed;
613
614 if (getsockname(listener, (struct sockaddr *)&sock, &socklen) != 0) goto failed;
615
616 if ((fd[1] = socket(PF_INET, SOCK_STREAM, 0)) == -1) goto failed;
617
618 set_nonblocking(fd[1]);
619
620 sock.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
621
622 if (connect(fd[1],(struct sockaddr *)&sock,sizeof(sock)) == -1) {
623 if (errno != EINPROGRESS) goto failed;
624 } else {
625 connect_done = 1;
626 }
627
628 if ((fd[0] = accept(listener, (struct sockaddr *)&sock, &socklen)) == -1) goto failed;
629
630 close(listener);
631 if (connect_done == 0) {
632 if (connect(fd[1],(struct sockaddr *)&sock,sizeof(sock)) != 0
633 && errno != EISCONN) goto failed;
634 }
635
636 set_blocking (fd[1]);
637
638 /* all OK! */
639 return 0;
640
641 failed:
642 if (fd[0] != -1) close(fd[0]);
643 if (fd[1] != -1) close(fd[1]);
644 if (listener != -1) close(listener);
645 return -1;
646}
647
648
649
650/**
651 * Run a program on a local tcp socket, so that we can talk to it's
652 * stdin and stdout. This is used to fake a connection to a daemon
653 * for testing -- not for the normal case of running SSH.
654 *
655 * @return a socket which is attached to a subprocess running
656 * "prog". stdin and stdout are attached. stderr is left attached to
657 * the original stderr
658 **/
659int sock_exec(const char *prog)
660{
661 int fd[2];
662
663 if (socketpair_tcp(fd) != 0) {
664 rprintf (FERROR, RSYNC_NAME
665 ": socketpair_tcp failed (%s)\n",
666 strerror(errno));
667 return -1;
668 }
669 if (fork() == 0) {
670 close(fd[0]);
671 close(0);
672 close(1);
673 dup(fd[1]);
674 dup(fd[1]);
675 if (verbose > 3) {
676 /* Can't use rprintf because we've forked. */
677 fprintf (stderr,
678 RSYNC_NAME ": execute socket program \"%s\"\n",
679 prog);
680 }
681 exit (system (prog));
682 }
683 close (fd[1]);
684 return fd[0];
685}
686
687
688