Fix inverted sense of error check.
[rsync/rsync.git] / socket.c
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 static int lookup_name(const struct sockaddr_storage *ss,
37                        socklen_t ss_len,
38                        char *name_buf, size_t name_buf_len,
39                        char *port_buf, size_t port_buf_len);
40
41 static int check_name(const struct sockaddr_storage *ss,
42                       socklen_t ss_len,
43                       const char *name_buf,
44                       const char *port_buf);
45
46 /* Establish a proxy connection on an open socket to a web roxy by
47  * using the CONNECT method. */
48 static int establish_proxy_connection(int fd, char *host, int port)
49 {
50         char buffer[1024];
51         char *cp;
52
53         snprintf(buffer, sizeof(buffer), "CONNECT %s:%d HTTP/1.0\r\n\r\n", host, port);
54         if (write(fd, buffer, strlen(buffer)) != strlen(buffer)) {
55                 rprintf(FERROR, "failed to write to proxy: %s\n",
56                         strerror(errno));
57                 return -1;
58         }
59
60         for (cp = buffer; cp < &buffer[sizeof(buffer) - 1]; cp++) {
61                 if (read(fd, cp, 1) != 1) {
62                         rprintf(FERROR, "failed to read from proxy: %s\n",
63                                 strerror(errno));
64                         return -1;
65                 }
66                 if (*cp == '\n')
67                         break;
68         }
69
70         if (*cp != '\n')
71                 cp++;
72         *cp-- = '\0';
73         if (*cp == '\r')
74                 *cp = '\0';
75         if (strncmp(buffer, "HTTP/", 5) != 0) {
76                 rprintf(FERROR, "bad response from proxy - %s\n",
77                         buffer);
78                 return -1;
79         }
80         for (cp = &buffer[5]; isdigit(*cp) || (*cp == '.'); cp++)
81                 ;
82         while (*cp == ' ')
83                 cp++;
84         if (*cp != '2') {
85                 rprintf(FERROR, "bad response from proxy - %s\n",
86                         buffer);
87                 return -1;
88         }
89         /* throw away the rest of the HTTP header */
90         while (1) {
91                 for (cp = buffer; cp < &buffer[sizeof(buffer) - 1];
92                      cp++) {
93                         if (read(fd, cp, 1) != 1) {
94                                 rprintf(FERROR, "failed to read from proxy: %s\n",
95                                         strerror(errno));
96                                 return -1;
97                         }
98                         if (*cp == '\n')
99                                 break;
100                 }
101                 if ((cp > buffer) && (*cp == '\n'))
102                         cp--;
103                 if ((cp == buffer) && ((*cp == '\n') || (*cp == '\r')))
104                         break;
105         }
106         return 0;
107 }
108
109
110 /**
111  * Try to set the local address for a newly-created socket.  Return -1
112  * if this fails.
113  **/
114 int try_bind_local(int s,
115                    int ai_family, int ai_socktype,
116                    const char *bind_address)
117 {
118         int error;
119         struct addrinfo bhints, *bres_all, *r;
120
121         memset(&bhints, 0, sizeof(bhints));
122         bhints.ai_family = ai_family;
123         bhints.ai_socktype = ai_socktype;
124         bhints.ai_flags = AI_PASSIVE;
125         if ((error = getaddrinfo(bind_address, NULL, &bhints, &bres_all))) {
126                 rprintf(FERROR, RSYNC_NAME ": getaddrinfo %s: %s\n",
127                         bind_address, gai_strerror(error));
128                 return -1;
129         }
130
131         for (r = bres_all; r; r = r->ai_next) {
132                 if (bind(s, r->ai_addr, r->ai_addrlen) == -1)
133                         continue;
134                 return s;
135         }
136
137         /* no error message; there might be some problem that allows
138          * creation of the socket but not binding, perhaps if the
139          * machine has no ipv6 address of this name. */
140         return -1;
141 }
142
143
144 /**
145  * Open a socket to a tcp remote host with the specified port .
146  *
147  * Based on code from Warren.  Proxy support by Stephen Rothwell.
148  * getaddrinfo() rewrite contributed by KAME.net.
149  *
150  * Now that we support IPv6 we need to look up the remote machine's
151  * address first, using @p af_hint to set a preference for the type
152  * of address.  Then depending on whether it has v4 or v6 addresses we
153  * try to open a connection.
154  *
155  * The loop allows for machines with some addresses which may not be
156  * reachable, perhaps because we can't e.g. route ipv6 to that network
157  * but we can get ip4 packets through.
158  *
159  * @param bind_address Local address to use.  Normally NULL to bind
160  * the wildcard address.
161  *
162  * @param af_hint Address family, e.g. AF_INET or AF_INET6.
163  **/
164 int open_socket_out(char *host, int port, const char *bind_address,
165                     int af_hint)
166 {
167         int type = SOCK_STREAM;
168         int error;
169         int s;
170         struct addrinfo hints, *res0, *res;
171         char portbuf[10];
172         char *h;
173         int proxied = 0;
174         char buffer[1024];
175         char *cp;
176
177         /* if we have a RSYNC_PROXY env variable then redirect our
178          * connetcion via a web proxy at the given address. The format
179          * is hostname:port */
180         h = getenv("RSYNC_PROXY");
181         proxied = (h != NULL) && (*h != '\0');
182
183         if (proxied) {
184                 strlcpy(buffer, h, sizeof(buffer));
185                 cp = strchr(buffer, ':');
186                 if (cp == NULL) {
187                         rprintf(FERROR,
188                                 "invalid proxy specification: should be HOST:PORT\n");
189                         return -1;
190                 }
191                 *cp++ = '\0';
192                 strcpy(portbuf, cp);
193                 h = buffer;
194         } else {
195                 snprintf(portbuf, sizeof(portbuf), "%d", port);
196                 h = host;
197         }
198
199         memset(&hints, 0, sizeof(hints));
200         hints.ai_family = af_hint;
201         hints.ai_socktype = type;
202         error = getaddrinfo(h, portbuf, &hints, &res0);
203         if (error) {
204                 rprintf(FERROR, RSYNC_NAME ": getaddrinfo: %s %s: %s\n",
205                         h, portbuf, gai_strerror(error));
206                 return -1;
207         }
208
209         s = -1;
210         /* Try to connect to all addresses for this machine until we get
211          * through.  It might e.g. be multi-homed, or have both IPv4 and IPv6
212          * addresses.  We need to create a socket for each record, since the
213          * address record tells us what protocol to use to try to connect. */
214         for (res = res0; res; res = res->ai_next) {
215                 s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
216                 if (s < 0)
217                         continue;
218
219                 if (bind_address)
220                         if (try_bind_local(s, res->ai_family, type,
221                                            bind_address) == -1) {
222                                 close(s);
223                                 s = -1;
224                                 continue;
225                         }
226
227                 if (connect(s, res->ai_addr, res->ai_addrlen) < 0) {
228                         close(s);
229                         s = -1;
230                         continue;
231                 }
232                 if (proxied &&
233                     establish_proxy_connection(s, host, port) != 0) {
234                         close(s);
235                         s = -1;
236                         continue;
237                 } else
238                         break;
239         }
240         freeaddrinfo(res0);
241         if (s < 0) {
242                 rprintf(FERROR, RSYNC_NAME ": failed to connect to %s: %s\n",
243                         h, strerror(errno));
244                 return -1;
245         }
246         return s;
247 }
248
249
250 /**
251  * Open an outgoing socket, but allow for it to be intercepted by
252  * $RSYNC_CONNECT_PROG, which will execute a program across a TCP
253  * socketpair rather than really opening a socket.
254  *
255  * We use this primarily in testing to detect TCP flow bugs, but not
256  * cause security problems by really opening remote connections.
257  *
258  * This is based on the Samba LIBSMB_PROG feature.
259  *
260  * @param bind_address Local address to use.  Normally NULL to get the stack default.
261  **/
262 int open_socket_out_wrapped (char *host,
263                              int port,
264                              const char *bind_address,
265                              int af_hint)
266 {
267         char *prog;
268
269         if ((prog = getenv ("RSYNC_CONNECT_PROG")) != NULL) 
270                 return sock_exec (prog);
271         else 
272                 return open_socket_out (host, port, bind_address,
273                                         af_hint);
274 }
275
276
277
278 /**
279  * Open a socket of the specified type, port and address for incoming data
280  *
281  * Try to be better about handling the results of getaddrinfo(): when
282  * opening an inbound socket, we might get several address results,
283  * e.g. for the machine's ipv4 and ipv6 name.  
284  * 
285  * If binding a wildcard, then any one of them should do.  If an address
286  * was specified but it's insufficiently specific then that's not our
287  * fault.  
288  * 
289  * However, some of the advertized addresses may not work because e.g. we
290  * don't have IPv6 support in the kernel.  In that case go on and try all
291  * addresses until one succeeds.
292  * 
293  * @param bind_address Local address to bind, or NULL to allow it to
294  * default.
295  **/
296 static int open_socket_in(int type, int port, const char *bind_address,
297                           int af_hint)
298 {
299         int one=1;
300         int s;
301         struct addrinfo hints, *all_ai, *resp;
302         char portbuf[10];
303         int error;
304
305         memset(&hints, 0, sizeof(hints));
306         hints.ai_family = af_hint;
307         hints.ai_socktype = type;
308         hints.ai_flags = AI_PASSIVE;
309         snprintf(portbuf, sizeof(portbuf), "%d", port);
310         error = getaddrinfo(bind_address, portbuf, &hints, &all_ai);
311         if (error) {
312                 rprintf(FERROR, RSYNC_NAME ": getaddrinfo: bind address %s: %s\n",
313                         bind_address, gai_strerror(error));
314                 return -1;
315         }
316
317         /* We may not be able to create the socket, if for example the
318          * machine knows about IPv6 in the C library, but not in the
319          * kernel. */
320         for (resp = all_ai; resp; resp = resp->ai_next) {
321                 s = socket(resp->ai_family, resp->ai_socktype,
322                            resp->ai_protocol);
323
324                 if (s == -1) 
325                         /* See if there's another address that will work... */
326                         continue;
327                 
328                 setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
329                            (char *)&one, sizeof one);
330                 
331                 /* now we've got a socket - we need to bind it */
332                 if (bind(s, all_ai->ai_addr, all_ai->ai_addrlen) < 0) {
333                         /* Nope, try another */
334                         close(s);
335                         continue;
336                 }
337                 
338                 return s;
339         }
340
341         rprintf(FERROR, RSYNC_NAME ": open inbound socket on port %d failed: "
342                 "%s\n",
343                 port, 
344                 strerror(errno));
345
346         freeaddrinfo(all_ai);
347         return -1; 
348 }
349
350
351 /*
352  * Determine if a file descriptor is in fact a socket
353  */
354 int is_a_socket(int fd)
355 {
356         int v;
357         socklen_t l;
358         l = sizeof(int);
359
360         /* Parameters to getsockopt, setsockopt etc are very
361          * unstandardized across platforms, so don't be surprised if
362          * there are compiler warnings on e.g. SCO OpenSwerver or AIX.
363          * It seems they all eventually get the right idea.
364          *
365          * Debian says: ``The fifth argument of getsockopt and
366          * setsockopt is in reality an int [*] (and this is what BSD
367          * 4.* and libc4 and libc5 have).  Some POSIX confusion
368          * resulted in the present socklen_t.  The draft standard has
369          * not been adopted yet, but glibc2 already follows it and
370          * also has socklen_t [*]. See also accept(2).''
371          *
372          * We now return to your regularly scheduled programming.  */
373         return(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&v, &l) == 0);
374 }
375
376
377 void start_accept_loop(int port, int (*fn)(int ))
378 {
379         int s;
380         extern char *bind_address;
381         extern int default_af_hint;
382
383         /* open an incoming socket */
384         s = open_socket_in(SOCK_STREAM, port, bind_address, default_af_hint);
385         if (s == -1)
386                 exit_cleanup(RERR_SOCKETIO);
387
388         /* ready to listen */
389         if (listen(s, 5) == -1) {
390                 close(s);
391                 exit_cleanup(RERR_SOCKETIO);
392         }
393
394
395         /* now accept incoming connections - forking a new process
396            for each incoming connection */
397         while (1) {
398                 fd_set fds;
399                 int fd;
400                 struct sockaddr_storage addr;
401                 socklen_t addrlen = sizeof addr;
402
403                 /* close log file before the potentially very long select so
404                    file can be trimmed by another process instead of growing
405                    forever */
406                 log_close();
407
408                 FD_ZERO(&fds);
409                 FD_SET(s, &fds);
410
411                 if (select(s+1, &fds, NULL, NULL, NULL) != 1) {
412                         continue;
413                 }
414
415                 if(!FD_ISSET(s, &fds)) continue;
416
417                 fd = accept(s,(struct sockaddr *)&addr,&addrlen);
418
419                 if (fd == -1) continue;
420
421                 signal(SIGCHLD, SIG_IGN);
422
423                 /* we shouldn't have any children left hanging around
424                    but I have had reports that on Digital Unix zombies
425                    are produced, so this ensures that they are reaped */
426 #ifdef WNOHANG
427                 while (waitpid(-1, NULL, WNOHANG) > 0);
428 #endif
429
430                 if (fork()==0) {
431                         close(s);
432                         /* open log file in child before possibly giving
433                            up privileges  */
434                         log_open();
435                         _exit(fn(fd));
436                 }
437
438                 close(fd);
439         }
440 }
441
442
443 enum SOCK_OPT_TYPES {OPT_BOOL,OPT_INT,OPT_ON};
444
445 struct
446 {
447   char *name;
448   int level;
449   int option;
450   int value;
451   int opttype;
452 } socket_options[] = {
453   {"SO_KEEPALIVE",      SOL_SOCKET,    SO_KEEPALIVE,    0,                 OPT_BOOL},
454   {"SO_REUSEADDR",      SOL_SOCKET,    SO_REUSEADDR,    0,                 OPT_BOOL},
455   {"SO_BROADCAST",      SOL_SOCKET,    SO_BROADCAST,    0,                 OPT_BOOL},
456 #ifdef TCP_NODELAY
457   {"TCP_NODELAY",       IPPROTO_TCP,   TCP_NODELAY,     0,                 OPT_BOOL},
458 #endif
459 #ifdef IPTOS_LOWDELAY
460   {"IPTOS_LOWDELAY",    IPPROTO_IP,    IP_TOS,          IPTOS_LOWDELAY,    OPT_ON},
461 #endif
462 #ifdef IPTOS_THROUGHPUT
463   {"IPTOS_THROUGHPUT",  IPPROTO_IP,    IP_TOS,          IPTOS_THROUGHPUT,  OPT_ON},
464 #endif
465 #ifdef SO_SNDBUF
466   {"SO_SNDBUF",         SOL_SOCKET,    SO_SNDBUF,       0,                 OPT_INT},
467 #endif
468 #ifdef SO_RCVBUF
469   {"SO_RCVBUF",         SOL_SOCKET,    SO_RCVBUF,       0,                 OPT_INT},
470 #endif
471 #ifdef SO_SNDLOWAT
472   {"SO_SNDLOWAT",       SOL_SOCKET,    SO_SNDLOWAT,     0,                 OPT_INT},
473 #endif
474 #ifdef SO_RCVLOWAT
475   {"SO_RCVLOWAT",       SOL_SOCKET,    SO_RCVLOWAT,     0,                 OPT_INT},
476 #endif
477 #ifdef SO_SNDTIMEO
478   {"SO_SNDTIMEO",       SOL_SOCKET,    SO_SNDTIMEO,     0,                 OPT_INT},
479 #endif
480 #ifdef SO_RCVTIMEO
481   {"SO_RCVTIMEO",       SOL_SOCKET,    SO_RCVTIMEO,     0,                 OPT_INT},
482 #endif
483   {NULL,0,0,0,0}};
484
485         
486
487 /****************************************************************************
488 set user socket options
489 ****************************************************************************/
490 void set_socket_options(int fd, char *options)
491 {
492         char *tok;
493         if (!options || !*options) return;
494
495         options = strdup(options);
496         
497         if (!options) out_of_memory("set_socket_options");
498
499         for (tok=strtok(options, " \t,"); tok; tok=strtok(NULL," \t,")) {
500                 int ret=0,i;
501                 int value = 1;
502                 char *p;
503                 int got_value = 0;
504
505                 if ((p = strchr(tok,'='))) {
506                         *p = 0;
507                         value = atoi(p+1);
508                         got_value = 1;
509                 }
510
511                 for (i=0;socket_options[i].name;i++)
512                         if (strcmp(socket_options[i].name,tok)==0)
513                                 break;
514
515                 if (!socket_options[i].name) {
516                         rprintf(FERROR,"Unknown socket option %s\n",tok);
517                         continue;
518                 }
519
520                 switch (socket_options[i].opttype) {
521                 case OPT_BOOL:
522                 case OPT_INT:
523                         ret = setsockopt(fd,socket_options[i].level,
524                                          socket_options[i].option,(char *)&value,sizeof(int));
525                         break;
526                         
527                 case OPT_ON:
528                         if (got_value)
529                                 rprintf(FERROR,"syntax error - %s does not take a value\n",tok);
530
531                         {
532                                 int on = socket_options[i].value;
533                                 ret = setsockopt(fd,socket_options[i].level,
534                                                  socket_options[i].option,(char *)&on,sizeof(int));
535                         }
536                         break;    
537                 }
538                 
539                 if (ret != 0)
540                         rprintf(FERROR, "failed to set socket option %s: %s\n", tok,
541                                 strerror(errno));
542         }
543
544         free(options);
545 }
546
547 /****************************************************************************
548 become a daemon, discarding the controlling terminal
549 ****************************************************************************/
550 void become_daemon(void)
551 {
552         int i;
553
554         if (fork()) {
555                 _exit(0);
556         }
557
558         /* detach from the terminal */
559 #ifdef HAVE_SETSID
560         setsid();
561 #else
562 #ifdef TIOCNOTTY
563         i = open("/dev/tty", O_RDWR);
564         if (i >= 0) {
565                 ioctl(i, (int) TIOCNOTTY, (char *)0);      
566                 close(i);
567         }
568 #endif /* TIOCNOTTY */
569 #endif
570         /* make sure that stdin, stdout an stderr don't stuff things
571            up (library functions, for example) */
572         for (i=0;i<3;i++) {
573                 close(i); 
574                 open("/dev/null", O_RDWR);
575         }
576 }
577
578 /**
579  * Return the IP addr of the client as a string 
580  **/
581 char *client_addr(int fd)
582 {
583         struct sockaddr_storage ss;
584         socklen_t length = sizeof ss;
585         static char addr_buf[100];
586         static int initialised;
587
588         if (initialised) return addr_buf;
589
590         initialised = 1;
591
592         if (getpeername(fd, (struct sockaddr *)&ss, &length)) {
593                 exit_cleanup(RERR_SOCKETIO);
594         }
595
596         getnameinfo((struct sockaddr *)&ss, length,
597                 addr_buf, sizeof(addr_buf), NULL, 0, NI_NUMERICHOST);
598         return addr_buf;
599 }
600
601
602 static int get_sockaddr_family(const struct sockaddr_storage *ss)
603 {
604         return ((struct sockaddr *) ss)->sa_family;
605 }
606
607
608 /**
609  * Return the DNS name of the client.
610  *
611  * The name is statically cached so that repeated lookups are quick,
612  * so there is a limit of one lookup per customer.
613  **/
614 char *client_name(int fd)
615 {
616         struct sockaddr_storage ss;
617         socklen_t ss_len = sizeof ss;
618         static char name_buf[100];
619         static char port_buf[100];
620         static int initialised;
621
622         if (initialised) return name_buf;
623
624         initialised = 1;
625
626         if (getpeername(fd, (struct sockaddr *)&ss, &ss_len)) {
627                 /* FIXME: Can we really not continue? */
628                 rprintf(FERROR, RSYNC_NAME ": getpeername on fd%d failed: %s\n",
629                         fd, strerror(errno));
630                 exit_cleanup(RERR_SOCKETIO);
631         }
632
633         if (!lookup_name(&ss, ss_len, name_buf, sizeof name_buf, port_buf, sizeof port_buf))
634                 check_name(&ss, ss_len, name_buf, port_buf);
635
636         return name_buf;
637 }
638
639
640 /**
641  * Look up a name from @p ss into @p name_buf.
642  **/
643 static int lookup_name(const struct sockaddr_storage *ss,
644                        socklen_t ss_len,
645                        char *name_buf, size_t name_buf_len,
646                        char *port_buf, size_t port_buf_len)
647 {
648         int name_err;
649         const char *def = "UNKNOWN";
650         
651 #ifdef INET6
652         if (get_sockaddr_family(ss) == AF_INET6 && 
653             IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)ss)->sin6_addr)) {
654                 /* OK, so ss is in the IPv6 family, but it is really
655                  * an IPv4 address: something like
656                  * "::ffff:10.130.1.2".  If we use it as-is, then the
657                  * reverse lookup might fail or perhaps something else
658                  * bad might happen.  So instead we convert it to an
659                  * equivalent address in the IPv4 address family.  */
660                 struct sockaddr_in6 sin6;
661                 struct sockaddr_in *sin;
662
663                 memcpy(&sin6, ss, sizeof(sin6));
664                 sin = (struct sockaddr_in *)ss;
665                 memset(sin, 0, sizeof(*sin));
666                 sin->sin_family = AF_INET;
667                 ss_len = sizeof(struct sockaddr_in);
668 #ifdef HAVE_SOCKADDR_LEN
669                 sin->sin_len = ss_len;
670 #endif
671                 sin->sin_port = sin6.sin6_port;
672                 /* FIXME: Isn't there a macro we can use here rather
673                  * than grovelling through the struct?  It might be
674                  * wrong on some systems. */
675                 memcpy(&sin->sin_addr, &sin6.sin6_addr.s6_addr[12],
676                         sizeof(sin->sin_addr));
677         }
678 #endif
679
680         /* reverse lookup */
681         name_err = getnameinfo((struct sockaddr *) ss, ss_len,
682                                name_buf, name_buf_len,
683                                port_buf, port_buf_len,
684                                NI_NAMEREQD | NI_NUMERICSERV);
685         if (name_err != 0) {
686                 strcpy(name_buf, def);
687                 rprintf(FERROR, RSYNC_NAME ": name lookup failed: %s\n",
688                         gai_strerror(name_err));
689                 return name_err;
690         }
691
692         return 0;
693 }
694
695
696
697 /* Do a forward lookup on name_buf and make sure it corresponds to ss
698  * -- otherwise we may be being spoofed.  If we suspect we are, then
699  * we don't abort the connection but just emit a warning. */
700 static int check_name(const struct sockaddr_storage *ss,
701                       socklen_t ss_len,
702                       const char *name_buf,
703                       const char *port_buf)
704 {
705         struct addrinfo hints, *res, *res0;
706         int error;
707
708         memset(&hints, 0, sizeof(hints));
709         hints.ai_family = PF_UNSPEC;
710         hints.ai_flags = AI_CANONNAME;
711         hints.ai_socktype = SOCK_STREAM;
712         error = getaddrinfo(name_buf, port_buf, &hints, &res0);
713         if (error) {
714                 /* We still use the name found by the reverse lookup,
715                  * but emit a warning. */
716                 rprintf(FERROR,
717                         RSYNC_NAME ": forward name lookup for %s:%s failed: %s\n",
718                         name_buf, port_buf,
719                         gai_strerror(error));
720                 return error;
721         }
722
723
724         /* We expect that one of the results will be the same as ss. */
725         for (res = res0; res; res = res->ai_next) {
726                 if (res->ai_family != get_sockaddr_family(ss))
727                         continue;
728                 if (res->ai_addrlen != ss_len)
729                         continue;
730                 if (memcmp(res->ai_addr, ss, res->ai_addrlen) == 0)
731                         break;
732         }
733
734         if (res == NULL) {
735                 /* We hit the end of the list without finding an
736                  * address that was the same as ss. */
737                 rprintf(FERROR, RSYNC_NAME
738                         ": no address record for \"%s\" corresponds to peer name: spoofed address?\n",
739                         name_buf);
740         }
741
742         freeaddrinfo(res0);
743         return 0;
744 }
745
746
747 /*******************************************************************
748 this is like socketpair but uses tcp. It is used by the Samba
749 regression test code
750 The function guarantees that nobody else can attach to the socket,
751 or if they do that this function fails and the socket gets closed
752 returns 0 on success, -1 on failure
753 the resulting file descriptors are symmetrical
754  ******************************************************************/
755 static int socketpair_tcp(int fd[2])
756 {
757         int listener;
758         struct sockaddr_in sock;
759         struct sockaddr_in sock2;
760         socklen_t socklen = sizeof(sock);
761         int connect_done = 0;
762         
763         fd[0] = fd[1] = listener = -1;
764
765         memset(&sock, 0, sizeof(sock));
766         
767         if ((listener = socket(PF_INET, SOCK_STREAM, 0)) == -1) goto failed;
768
769         memset(&sock2, 0, sizeof(sock2));
770 #ifdef HAVE_SOCK_SIN_LEN
771         sock2.sin_len = sizeof(sock2);
772 #endif
773         sock2.sin_family = PF_INET;
774
775         bind(listener, (struct sockaddr *)&sock2, sizeof(sock2));
776
777         if (listen(listener, 1) != 0) goto failed;
778
779         if (getsockname(listener, (struct sockaddr *)&sock, &socklen) != 0) goto failed;
780
781         if ((fd[1] = socket(PF_INET, SOCK_STREAM, 0)) == -1) goto failed;
782
783         set_nonblocking(fd[1]);
784
785         sock.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
786
787         if (connect(fd[1],(struct sockaddr *)&sock,sizeof(sock)) == -1) {
788                 if (errno != EINPROGRESS) goto failed;
789         } else {
790                 connect_done = 1;
791         }
792
793         if ((fd[0] = accept(listener, (struct sockaddr *)&sock, &socklen)) == -1) goto failed;
794
795         close(listener);
796         if (connect_done == 0) {
797                 if (connect(fd[1],(struct sockaddr *)&sock,sizeof(sock)) != 0
798                     && errno != EISCONN) goto failed;
799         }
800
801         set_blocking (fd[1]);
802
803         /* all OK! */
804         return 0;
805
806  failed:
807         if (fd[0] != -1) close(fd[0]);
808         if (fd[1] != -1) close(fd[1]);
809         if (listener != -1) close(listener);
810         return -1;
811 }
812
813
814 /*******************************************************************
815 run a program on a local tcp socket, this is used to launch smbd
816 when regression testing
817 the return value is a socket which is attached to a subprocess
818 running "prog". stdin and stdout are attached. stderr is left
819 attached to the original stderr
820  ******************************************************************/
821 int sock_exec(const char *prog)
822 {
823         int fd[2];
824         if (socketpair_tcp(fd) != 0) {
825                 rprintf (FERROR, RSYNC_NAME
826                          ": socketpair_tcp failed (%s)\n",
827                          strerror(errno));
828                 return -1;
829         }
830         if (fork() == 0) {
831                 close(fd[0]);
832                 close(0);
833                 close(1);
834                 dup(fd[1]);
835                 dup(fd[1]);
836                 if (verbose > 3)
837                         fprintf (stderr,
838                                  RSYNC_NAME ": execute socket program \"%s\"\n",
839                                  prog);
840                 exit (system (prog));
841         }
842         close (fd[1]);
843         return fd[0];
844 }
845
846
847