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