Add more rules for make distclean.
[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 if (verbose >= 2) {
186 rprintf(FINFO, "connection via http proxy %s port %s\n",
187 h, portbuf);
188 }
189 } else {
190 snprintf(portbuf, sizeof(portbuf), "%d", port);
191 h = host;
192 }
193
194 memset(&hints, 0, sizeof(hints));
195 hints.ai_family = af_hint;
196 hints.ai_socktype = type;
197 error = getaddrinfo(h, portbuf, &hints, &res0);
198 if (error) {
199 rprintf(FERROR, RSYNC_NAME ": getaddrinfo: %s %s: %s\n",
200 h, portbuf, gai_strerror(error));
201 return -1;
202 }
203
204 s = -1;
205 /* Try to connect to all addresses for this machine until we get
206 * through. It might e.g. be multi-homed, or have both IPv4 and IPv6
207 * addresses. We need to create a socket for each record, since the
208 * address record tells us what protocol to use to try to connect. */
209 for (res = res0; res; res = res->ai_next) {
210 s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
211 if (s < 0)
212 continue;
213
214 if (bind_address)
215 if (try_bind_local(s, res->ai_family, type,
216 bind_address) == -1) {
217 close(s);
218 s = -1;
219 continue;
220 }
221
222 if (connect(s, res->ai_addr, res->ai_addrlen) < 0) {
223 close(s);
224 s = -1;
225 continue;
226 }
227 if (proxied &&
228 establish_proxy_connection(s, host, port) != 0) {
229 close(s);
230 s = -1;
231 continue;
232 } else
233 break;
234 }
235 freeaddrinfo(res0);
236 if (s < 0) {
237 rprintf(FERROR, RSYNC_NAME ": failed to connect to %s: %s\n",
238 h, strerror(errno));
239 return -1;
240 }
241 return s;
242}
243
244
245/**
246 * Open an outgoing socket, but allow for it to be intercepted by
247 * $RSYNC_CONNECT_PROG, which will execute a program across a TCP
248 * socketpair rather than really opening a socket.
249 *
250 * We use this primarily in testing to detect TCP flow bugs, but not
251 * cause security problems by really opening remote connections.
252 *
253 * This is based on the Samba LIBSMB_PROG feature.
254 *
255 * @param bind_address Local address to use. Normally NULL to get the stack default.
256 **/
257int open_socket_out_wrapped (char *host,
258 int port,
259 const char *bind_address,
260 int af_hint)
261{
262 char *prog;
263
264 if ((prog = getenv ("RSYNC_CONNECT_PROG")) != NULL)
265 return sock_exec (prog);
266 else
267 return open_socket_out (host, port, bind_address,
268 af_hint);
269}
270
271
272
273/**
274 * Open a socket of the specified type, port and address for incoming data
275 *
276 * Try to be better about handling the results of getaddrinfo(): when
277 * opening an inbound socket, we might get several address results,
278 * e.g. for the machine's ipv4 and ipv6 name.
279 *
280 * If binding a wildcard, then any one of them should do. If an address
281 * was specified but it's insufficiently specific then that's not our
282 * fault.
283 *
284 * However, some of the advertized addresses may not work because e.g. we
285 * don't have IPv6 support in the kernel. In that case go on and try all
286 * addresses until one succeeds.
287 *
288 * @param bind_address Local address to bind, or NULL to allow it to
289 * default.
290 **/
291static int open_socket_in(int type, int port, const char *bind_address,
292 int af_hint)
293{
294 int one=1;
295 int s;
296 struct addrinfo hints, *all_ai, *resp;
297 char portbuf[10];
298 int error;
299
300 memset(&hints, 0, sizeof(hints));
301 hints.ai_family = af_hint;
302 hints.ai_socktype = type;
303 hints.ai_flags = AI_PASSIVE;
304 snprintf(portbuf, sizeof(portbuf), "%d", port);
305 error = getaddrinfo(bind_address, portbuf, &hints, &all_ai);
306 if (error) {
307 rprintf(FERROR, RSYNC_NAME ": getaddrinfo: bind address %s: %s\n",
308 bind_address, gai_strerror(error));
309 return -1;
310 }
311
312 /* We may not be able to create the socket, if for example the
313 * machine knows about IPv6 in the C library, but not in the
314 * kernel. */
315 for (resp = all_ai; resp; resp = resp->ai_next) {
316 s = socket(resp->ai_family, resp->ai_socktype,
317 resp->ai_protocol);
318
319 if (s == -1)
320 /* See if there's another address that will work... */
321 continue;
322
323 setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
324 (char *)&one, sizeof one);
325
326 /* now we've got a socket - we need to bind it */
327 if (bind(s, all_ai->ai_addr, all_ai->ai_addrlen) < 0) {
328 /* Nope, try another */
329 close(s);
330 continue;
331 }
332
333 return s;
334 }
335
336 rprintf(FERROR, RSYNC_NAME ": open inbound socket on port %d failed: "
337 "%s\n",
338 port,
339 strerror(errno));
340
341 freeaddrinfo(all_ai);
342 return -1;
343}
344
345
346/*
347 * Determine if a file descriptor is in fact a socket
348 */
349int is_a_socket(int fd)
350{
351 int v;
352 socklen_t l;
353 l = sizeof(int);
354
355 /* Parameters to getsockopt, setsockopt etc are very
356 * unstandardized across platforms, so don't be surprised if
357 * there are compiler warnings on e.g. SCO OpenSwerver or AIX.
358 * It seems they all eventually get the right idea.
359 *
360 * Debian says: ``The fifth argument of getsockopt and
361 * setsockopt is in reality an int [*] (and this is what BSD
362 * 4.* and libc4 and libc5 have). Some POSIX confusion
363 * resulted in the present socklen_t. The draft standard has
364 * not been adopted yet, but glibc2 already follows it and
365 * also has socklen_t [*]. See also accept(2).''
366 *
367 * We now return to your regularly scheduled programming. */
368 return(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&v, &l) == 0);
369}
370
371
372void start_accept_loop(int port, int (*fn)(int ))
373{
374 int s;
375 extern char *bind_address;
376 extern int default_af_hint;
377
378 /* open an incoming socket */
379 s = open_socket_in(SOCK_STREAM, port, bind_address, default_af_hint);
380 if (s == -1)
381 exit_cleanup(RERR_SOCKETIO);
382
383 /* ready to listen */
384 if (listen(s, 5) == -1) {
385 close(s);
386 exit_cleanup(RERR_SOCKETIO);
387 }
388
389
390 /* now accept incoming connections - forking a new process
391 for each incoming connection */
392 while (1) {
393 fd_set fds;
394 pid_t pid;
395 int fd;
396 struct sockaddr_storage addr;
397 socklen_t addrlen = sizeof addr;
398
399 /* close log file before the potentially very long select so
400 file can be trimmed by another process instead of growing
401 forever */
402 log_close();
403
404 FD_ZERO(&fds);
405 FD_SET(s, &fds);
406
407 if (select(s+1, &fds, NULL, NULL, NULL) != 1) {
408 continue;
409 }
410
411 if(!FD_ISSET(s, &fds)) continue;
412
413 fd = accept(s,(struct sockaddr *)&addr,&addrlen);
414
415 if (fd == -1) continue;
416
417 signal(SIGCHLD, SIG_IGN);
418
419 /* we shouldn't have any children left hanging around
420 but I have had reports that on Digital Unix zombies
421 are produced, so this ensures that they are reaped */
422#ifdef WNOHANG
423 while (waitpid(-1, NULL, WNOHANG) > 0);
424#endif
425
426 if ((pid = fork()) == 0) {
427 close(s);
428 /* open log file in child before possibly giving
429 up privileges */
430 log_open();
431 _exit(fn(fd));
432 } else if (pid < 0) {
433 rprintf(FERROR,
434 RSYNC_NAME
435 ": could not create child server process: %s\n",
436 strerror(errno));
437 close(fd);
438 /* This might have happened because we're
439 * overloaded. Sleep briefly before trying to
440 * accept again. */
441 sleep(2);
442 } else {
443 /* Parent doesn't need this fd anymore. */
444 close(fd);
445 }
446 }
447}
448
449
450enum SOCK_OPT_TYPES {OPT_BOOL,OPT_INT,OPT_ON};
451
452struct
453{
454 char *name;
455 int level;
456 int option;
457 int value;
458 int opttype;
459} socket_options[] = {
460 {"SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE, 0, OPT_BOOL},
461 {"SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR, 0, OPT_BOOL},
462 {"SO_BROADCAST", SOL_SOCKET, SO_BROADCAST, 0, OPT_BOOL},
463#ifdef TCP_NODELAY
464 {"TCP_NODELAY", IPPROTO_TCP, TCP_NODELAY, 0, OPT_BOOL},
465#endif
466#ifdef IPTOS_LOWDELAY
467 {"IPTOS_LOWDELAY", IPPROTO_IP, IP_TOS, IPTOS_LOWDELAY, OPT_ON},
468#endif
469#ifdef IPTOS_THROUGHPUT
470 {"IPTOS_THROUGHPUT", IPPROTO_IP, IP_TOS, IPTOS_THROUGHPUT, OPT_ON},
471#endif
472#ifdef SO_SNDBUF
473 {"SO_SNDBUF", SOL_SOCKET, SO_SNDBUF, 0, OPT_INT},
474#endif
475#ifdef SO_RCVBUF
476 {"SO_RCVBUF", SOL_SOCKET, SO_RCVBUF, 0, OPT_INT},
477#endif
478#ifdef SO_SNDLOWAT
479 {"SO_SNDLOWAT", SOL_SOCKET, SO_SNDLOWAT, 0, OPT_INT},
480#endif
481#ifdef SO_RCVLOWAT
482 {"SO_RCVLOWAT", SOL_SOCKET, SO_RCVLOWAT, 0, OPT_INT},
483#endif
484#ifdef SO_SNDTIMEO
485 {"SO_SNDTIMEO", SOL_SOCKET, SO_SNDTIMEO, 0, OPT_INT},
486#endif
487#ifdef SO_RCVTIMEO
488 {"SO_RCVTIMEO", SOL_SOCKET, SO_RCVTIMEO, 0, OPT_INT},
489#endif
490 {NULL,0,0,0,0}};
491
492
493
494/****************************************************************************
495set user socket options
496****************************************************************************/
497void set_socket_options(int fd, char *options)
498{
499 char *tok;
500 if (!options || !*options) return;
501
502 options = strdup(options);
503
504 if (!options) out_of_memory("set_socket_options");
505
506 for (tok=strtok(options, " \t,"); tok; tok=strtok(NULL," \t,")) {
507 int ret=0,i;
508 int value = 1;
509 char *p;
510 int got_value = 0;
511
512 if ((p = strchr(tok,'='))) {
513 *p = 0;
514 value = atoi(p+1);
515 got_value = 1;
516 }
517
518 for (i=0;socket_options[i].name;i++)
519 if (strcmp(socket_options[i].name,tok)==0)
520 break;
521
522 if (!socket_options[i].name) {
523 rprintf(FERROR,"Unknown socket option %s\n",tok);
524 continue;
525 }
526
527 switch (socket_options[i].opttype) {
528 case OPT_BOOL:
529 case OPT_INT:
530 ret = setsockopt(fd,socket_options[i].level,
531 socket_options[i].option,(char *)&value,sizeof(int));
532 break;
533
534 case OPT_ON:
535 if (got_value)
536 rprintf(FERROR,"syntax error - %s does not take a value\n",tok);
537
538 {
539 int on = socket_options[i].value;
540 ret = setsockopt(fd,socket_options[i].level,
541 socket_options[i].option,(char *)&on,sizeof(int));
542 }
543 break;
544 }
545
546 if (ret != 0)
547 rprintf(FERROR, "failed to set socket option %s: %s\n", tok,
548 strerror(errno));
549 }
550
551 free(options);
552}
553
554/****************************************************************************
555become a daemon, discarding the controlling terminal
556****************************************************************************/
557void become_daemon(void)
558{
559 int i;
560
561 if (fork()) {
562 _exit(0);
563 }
564
565 /* detach from the terminal */
566#ifdef HAVE_SETSID
567 setsid();
568#else
569#ifdef TIOCNOTTY
570 i = open("/dev/tty", O_RDWR);
571 if (i >= 0) {
572 ioctl(i, (int) TIOCNOTTY, (char *)0);
573 close(i);
574 }
575#endif /* TIOCNOTTY */
576#endif
577 /* make sure that stdin, stdout an stderr don't stuff things
578 up (library functions, for example) */
579 for (i=0;i<3;i++) {
580 close(i);
581 open("/dev/null", O_RDWR);
582 }
583}
584
585
586/*******************************************************************
587this is like socketpair but uses tcp. It is used by the Samba
588regression test code
589The function guarantees that nobody else can attach to the socket,
590or if they do that this function fails and the socket gets closed
591returns 0 on success, -1 on failure
592the resulting file descriptors are symmetrical
593 ******************************************************************/
594static int socketpair_tcp(int fd[2])
595{
596 int listener;
597 struct sockaddr_in sock;
598 struct sockaddr_in sock2;
599 socklen_t socklen = sizeof(sock);
600 int connect_done = 0;
601
602 fd[0] = fd[1] = listener = -1;
603
604 memset(&sock, 0, sizeof(sock));
605
606 if ((listener = socket(PF_INET, SOCK_STREAM, 0)) == -1) goto failed;
607
608 memset(&sock2, 0, sizeof(sock2));
609#ifdef HAVE_SOCKADDR_LEN
610 sock2.sin_len = sizeof(sock2);
611#endif
612 sock2.sin_family = PF_INET;
613
614 bind(listener, (struct sockaddr *)&sock2, sizeof(sock2));
615
616 if (listen(listener, 1) != 0) goto failed;
617
618 if (getsockname(listener, (struct sockaddr *)&sock, &socklen) != 0) goto failed;
619
620 if ((fd[1] = socket(PF_INET, SOCK_STREAM, 0)) == -1) goto failed;
621
622 set_nonblocking(fd[1]);
623
624 sock.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
625
626 if (connect(fd[1],(struct sockaddr *)&sock,sizeof(sock)) == -1) {
627 if (errno != EINPROGRESS) goto failed;
628 } else {
629 connect_done = 1;
630 }
631
632 if ((fd[0] = accept(listener, (struct sockaddr *)&sock, &socklen)) == -1) goto failed;
633
634 close(listener);
635 if (connect_done == 0) {
636 if (connect(fd[1],(struct sockaddr *)&sock,sizeof(sock)) != 0
637 && errno != EISCONN) goto failed;
638 }
639
640 set_blocking (fd[1]);
641
642 /* all OK! */
643 return 0;
644
645 failed:
646 if (fd[0] != -1) close(fd[0]);
647 if (fd[1] != -1) close(fd[1]);
648 if (listener != -1) close(listener);
649 return -1;
650}
651
652
653
654/**
655 * Run a program on a local tcp socket, so that we can talk to it's
656 * stdin and stdout. This is used to fake a connection to a daemon
657 * for testing -- not for the normal case of running SSH.
658 *
659 * @return a socket which is attached to a subprocess running
660 * "prog". stdin and stdout are attached. stderr is left attached to
661 * the original stderr
662 **/
663int sock_exec(const char *prog)
664{
665 int fd[2];
666
667 if (socketpair_tcp(fd) != 0) {
668 rprintf (FERROR, RSYNC_NAME
669 ": socketpair_tcp failed (%s)\n",
670 strerror(errno));
671 return -1;
672 }
673 if (fork() == 0) {
674 close(fd[0]);
675 close(0);
676 close(1);
677 dup(fd[1]);
678 dup(fd[1]);
679 if (verbose > 3) {
680 /* Can't use rprintf because we've forked. */
681 fprintf (stderr,
682 RSYNC_NAME ": execute socket program \"%s\"\n",
683 prog);
684 }
685 exit (system (prog));
686 }
687 close (fd[1]);
688 return fd[0];
689}
690
691
692