1 /* $Id: network.c 10396 2020-11-12 20:19:41Z iulius $
2  *
3  * Utility functions for network connections.
4  *
5  * This is a collection of utility functions for network connections and
6  * socket creation, encapsulating some of the complexities of IPv4 and IPv6
7  * support and abstracting operations common to most network code.
8  *
9  * All of the portability difficulties with supporting IPv4 and IPv6 should be
10  * encapsulated in the combination of this code and replacement
11  * implementations for functions that aren't found on some pre-IPv6 systems.
12  * No other part of the source tree should have to care about IPv4 vs. IPv6.
13  *
14  * In this file, casts through void * or const void * of struct sockaddr *
15  * parameters are to silence gcc warnings with -Wcast-align.  The specific
16  * address types often require stronger alignment than a struct sockaddr, and
17  * were originally allocated with that alignment.  GCC doesn't have a good way
18  * of knowing that this code is correct.
19  *
20  * The canonical version of this file is maintained in the rra-c-util package,
21  * which can be found at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
22  *
23  * Written by Russ Allbery <eagle@eyrie.org>
24  * Copyright 2014-2017 Russ Allbery <eagle@eyrie.org>
25  * Copyright 2009, 2011-2014
26  *     The Board of Trustees of the Leland Stanford Junior University
27  * Copyright 2004-2008 Internet Systems Consortium, Inc. ("ISC")
28  * Copyright 1991, 1994-2003 The Internet Software Consortium and Rich Salz
29  *
30  * This code is derived from software contributed to the Internet Software
31  * Consortium by Rich Salz.
32  *
33  * Permission to use, copy, modify, and distribute this software for any
34  * purpose with or without fee is hereby granted, provided that the above
35  * copyright notice and this permission notice appear in all copies.
36  *
37  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
38  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
39  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
40  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
41  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
42  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
43  * PERFORMANCE OF THIS SOFTWARE.
44  *
45  * SPDX-License-Identifier: ISC
46  */
47 
48 #include "config.h"
49 #include "portable/socket.h"
50 #include "clibrary.h"
51 
52 #include <errno.h>
53 #ifdef HAVE_SYS_SELECT_H
54 #    include <sys/select.h>
55 #endif
56 #ifdef HAVE_SYS_TIME_H
57 #    include <sys/time.h>
58 #endif
59 #include <time.h>
60 
61 #include "inn/fdflag.h"
62 #include "inn/innconf.h"
63 #include "inn/macros.h"
64 #include "inn/messages.h"
65 #include "inn/network.h"
66 #include "inn/xmalloc.h"
67 #include "inn/xwrite.h"
68 
69 /* Macros to set the len attribute of sockaddrs. */
70 #if HAVE_STRUCT_SOCKADDR_SA_LEN
71 #    define sin_set_length(s)  ((s)->sin_len = sizeof(struct sockaddr_in))
72 #    define sin6_set_length(s) ((s)->sin6_len = sizeof(struct sockaddr_in6))
73 #else
74 #    define sin_set_length(s)  /* empty */
75 #    define sin6_set_length(s) /* empty */
76 #endif
77 
78 /*
79  * Windows requires a different function when sending to sockets, but can't
80  * return short writes on blocking sockets.
81  */
82 #ifdef _WIN32
83 #    define socket_xwrite(fd, b, s) send((fd), (b), (s), 0)
84 #else
85 #    define socket_xwrite(fd, b, s) xwrite((fd), (b), (s))
86 #endif
87 
88 
89 /*
90  * Set SO_REUSEADDR on a socket if possible (so that something new can listen
91  * on the same port immediately if the daemon dies unexpectedly).
92  */
93 void
network_set_reuseaddr(socket_type fd UNUSED)94 network_set_reuseaddr(socket_type fd UNUSED)
95 {
96 #ifdef SO_REUSEADDR
97     int flag = 1;
98 
99     if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag)) < 0)
100         syswarn("cannot mark bind address reusable");
101 #endif
102 }
103 
104 
105 /*
106  * Set IPV6_V6ONLY on a socket if possible, since the IPv6 behavior is more
107  * consistent and easier to understand.
108  */
109 void
network_set_v6only(socket_type fd UNUSED)110 network_set_v6only(socket_type fd UNUSED)
111 {
112 #ifdef IPV6_V6ONLY
113     int flag = 1;
114 
115     if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &flag, sizeof(flag)) < 0)
116         syswarn("cannot set IPv6 socket to v6only");
117 #endif
118 }
119 
120 
121 /*
122  * Set IP_FREEBIND on a socket if possible, which allows binding servers to
123  * IPv6 addresses that may not have been set up yet.
124  */
125 void
network_set_freebind(socket_type fd UNUSED)126 network_set_freebind(socket_type fd UNUSED)
127 {
128 #ifdef IP_FREEBIND
129     int flag = 1;
130 
131     if (setsockopt(fd, IPPROTO_IP, IP_FREEBIND, &flag, sizeof(flag)) < 0)
132         syswarn("cannot set IPv6 socket to free binding");
133 #endif
134 }
135 
136 
137 /*
138  * Create an IPv4 socket and bind it, returning the resulting file descriptor
139  * (or INVALID_SOCKET on a failure).
140  */
141 socket_type
network_bind_ipv4(int type,const char * address,unsigned short port)142 network_bind_ipv4(int type, const char *address, unsigned short port)
143 {
144     socket_type fd;
145     struct sockaddr_in server;
146     struct in_addr addr;
147 
148     /* Create the socket. */
149     fd = socket(PF_INET, type, IPPROTO_IP);
150     if (fd == INVALID_SOCKET) {
151         syswarn("cannot create IPv4 socket for %s, port %hu", address, port);
152         return INVALID_SOCKET;
153     }
154     network_set_reuseaddr(fd);
155 
156     /* Accept "any" or "all" in the bind address to mean 0.0.0.0. */
157     if (!strcmp(address, "any") || !strcmp(address, "all"))
158         address = "0.0.0.0";
159 
160     /* Flesh out the socket and do the bind. */
161     memset(&server, 0, sizeof(server));
162     server.sin_family = AF_INET;
163     server.sin_port = htons(port);
164     if (!inet_aton(address, &addr)) {
165         warn("invalid IPv4 address %s", address);
166         socket_set_errno_einval();
167         return INVALID_SOCKET;
168     }
169     server.sin_addr = addr;
170     sin_set_length(&server);
171     if (bind(fd, (struct sockaddr *) &server, sizeof(server)) < 0) {
172         syswarn("cannot bind socket for %s, port %hu", address, port);
173         socket_close(fd);
174         return INVALID_SOCKET;
175     }
176     return fd;
177 }
178 
179 
180 /*
181  * Create an IPv6 socket and bind it, returning the resulting file descriptor
182  * (or INVALID_SOCKET on a failure).  This socket will be restricted to IPv6
183  * only if possible (as opposed to the standard behavior of binding IPv6
184  * sockets to both IPv6 and IPv4).
185  *
186  * Note that we don't warn (but still return failure) if the reason for the
187  * socket creation failure is that IPv6 isn't supported; this is to handle
188  * systems like many Linux hosts where IPv6 is available in userland but the
189  * kernel doesn't support it.
190  */
191 #if HAVE_INET6
192 
193 socket_type
network_bind_ipv6(int type,const char * address,unsigned short port)194 network_bind_ipv6(int type, const char *address, unsigned short port)
195 {
196     socket_type fd;
197     struct sockaddr_in6 server;
198     struct in6_addr addr;
199 
200     /* Create the socket. */
201     fd = socket(PF_INET6, type, IPPROTO_IP);
202     if (fd == INVALID_SOCKET) {
203         if (socket_errno != EAFNOSUPPORT && socket_errno != EPROTONOSUPPORT)
204             syswarn("cannot create IPv6 socket for %s, port %hu", address,
205                     port);
206         return INVALID_SOCKET;
207     }
208     network_set_reuseaddr(fd);
209 
210     /*
211      * Restrict the socket to IPv6 only if possible.  The default behavior is
212      * to bind IPv6 sockets to both IPv6 and IPv4 for backward compatibility,
213      * but this causes various other problems (such as with reusing sockets
214      * and requiring handling of mapped addresses).  Continue on if this
215      * fails, however.
216      */
217     network_set_v6only(fd);
218 
219     /* Accept "any" or "all" in the bind address to mean ::. */
220     if (!strcmp(address, "any") || !strcmp(address, "all"))
221         address = "::";
222 
223     /*
224      * If the address is not ::, use IP_FREEBIND if it's available.  This
225      * allows the network stack to bind to an address that isn't configured.
226      * We lose diagnosis of errors from specifying bind addresses that don't
227      * exist on the system, but we gain the ability to bind to IPv6 addresses
228      * that aren't yet configured.  Since IPv6 address configuration can take
229      * unpredictable amounts of time during system setup, this is more robust.
230      *
231      * Ensure there is always a block here to avoid compiler warnings, since
232      * network_set_freebind() may expand into nothing.
233      */
234     if (strcmp(address, "::") != 0) {
235         network_set_freebind(fd);
236     }
237 
238     /* Flesh out the socket and do the bind. */
239     memset(&server, 0, sizeof(server));
240     server.sin6_family = AF_INET6;
241     server.sin6_port = htons(port);
242     if (inet_pton(AF_INET6, address, &addr) < 1) {
243         warn("invalid IPv6 address %s", address);
244         socket_set_errno_einval();
245         return INVALID_SOCKET;
246     }
247     server.sin6_addr = addr;
248     sin6_set_length(&server);
249     if (bind(fd, (struct sockaddr *) &server, sizeof(server)) < 0) {
250         syswarn("cannot bind socket for %s, port %hu", address, port);
251         socket_close(fd);
252         return INVALID_SOCKET;
253     }
254     return fd;
255 }
256 
257 #else /* HAVE_INET6 */
258 
259 socket_type
network_bind_ipv6(int type UNUSED,const char * address,unsigned short port)260 network_bind_ipv6(int type UNUSED, const char *address, unsigned short port)
261 {
262     warn("cannot bind %s, port %hu: IPv6 not supported", address, port);
263     socket_set_errno(EPROTONOSUPPORT);
264     return INVALID_SOCKET;
265 }
266 
267 #endif /* HAVE_INET6 */
268 
269 
270 /*
271  * Create and bind sockets for every local address, as determined by
272  * getaddrinfo if IPv6 is available (otherwise, just use the IPv4 loopback
273  * address).  Takes the socket type and port number, and then a pointer to an
274  * array of integers and a pointer to a count of them.  Allocates a new array
275  * to hold the file descriptors and stores the count in the fourth argument.
276  */
277 #if HAVE_INET6
278 
279 bool
network_bind_all(int type,unsigned short port,socket_type ** fds,unsigned int * count)280 network_bind_all(int type, unsigned short port, socket_type **fds,
281                  unsigned int *count)
282 {
283     struct addrinfo hints, *addrs, *addr;
284     unsigned int size;
285     int status;
286     socket_type fd;
287     char service[16], name[INET6_ADDRSTRLEN];
288 
289     *count = 0;
290 
291     /* Do the query to find all the available addresses. */
292     memset(&hints, 0, sizeof(hints));
293     hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG;
294     hints.ai_family = AF_UNSPEC;
295     hints.ai_socktype = type;
296     status = snprintf(service, sizeof(service), "%hu", port);
297     if (status < 0 || (size_t) status >= sizeof(service)) {
298         warn("cannot convert port %hu to string", port);
299         socket_set_errno_einval();
300         return false;
301     }
302     status = getaddrinfo(NULL, service, &hints, &addrs);
303     if (status < 0) {
304         warn("getaddrinfo for %s failed: %s", service, gai_strerror(status));
305         socket_set_errno_einval();
306         return false;
307     }
308 
309     /*
310      * Now, try to bind each of them.  Start the fds array at two entries,
311      * assuming an IPv6 and IPv4 socket, and grow it by two when necessary.
312      */
313     size = 2;
314     *fds = xcalloc(size, sizeof(socket_type));
315     for (addr = addrs; addr != NULL; addr = addr->ai_next) {
316         network_sockaddr_sprint(name, sizeof(name), addr->ai_addr);
317         if (addr->ai_family == AF_INET)
318             fd = network_bind_ipv4(type, name, port);
319         else if (addr->ai_family == AF_INET6)
320             fd = network_bind_ipv6(type, name, port);
321         else
322             continue;
323         if (fd != INVALID_SOCKET) {
324             if (*count >= size) {
325                 size += 2;
326                 *fds = xreallocarray(*fds, size, sizeof(socket_type));
327             }
328             (*fds)[*count] = fd;
329             (*count)++;
330         }
331     }
332     freeaddrinfo(addrs);
333     return (*count > 0);
334 }
335 
336 #else /* HAVE_INET6 */
337 
338 bool
network_bind_all(int type,unsigned short port,socket_type ** fds,unsigned int * count)339 network_bind_all(int type, unsigned short port, socket_type **fds,
340                  unsigned int *count)
341 {
342     socket_type fd;
343 
344     fd = network_bind_ipv4(type, "0.0.0.0", port);
345     if (fd == INVALID_SOCKET) {
346         *fds = NULL;
347         *count = 0;
348         return false;
349     }
350     *fds = xmalloc(sizeof(socket_type));
351     *fds[0] = fd;
352     *count = 1;
353     return true;
354 }
355 
356 #endif /* HAVE_INET6 */
357 
358 
359 /*
360  * Free the array of file descriptors allocated by network_bind_all.  This is
361  * a simple wrapper around free, needed on platforms where libraries allocate
362  * memory from a different memory domain than programs (such as Windows).
363  */
364 void
network_bind_all_free(socket_type * fds)365 network_bind_all_free(socket_type *fds)
366 {
367     free(fds);
368 }
369 
370 
371 /*
372  * Given an array of file descriptors and the length of that array (the same
373  * data that's returned by network_bind_all), wait for an incoming connection
374  * on any of those sockets and return the file descriptor that selects ready
375  * for read.
376  *
377  * This is primarily intended for UDP services listening on multiple file
378  * descriptors, and also provides part of the code for network_accept_any.
379  * TCP services will probably want to use network_accept_any instead.
380  *
381  * Returns the new socket on success or INVALID_SOCKET on failure.  Note that
382  * INVALID_SOCKET may be returned if the timeout is interrupted by a signal,
383  * which is not, precisely speaking, an error condition.  In this case, errno
384  * will be set to EINTR.
385  *
386  * This is not intended to be a replacement for a full event loop, just some
387  * simple shared code for UDP services.
388  */
389 socket_type
network_wait_any(socket_type fds[],unsigned int count)390 network_wait_any(socket_type fds[], unsigned int count)
391 {
392     fd_set readfds;
393     socket_type maxfd, fd;
394     unsigned int i;
395     int status;
396 
397     FD_ZERO(&readfds);
398     maxfd = -1;
399     for (i = 0; i < count; i++) {
400         FD_SET(fds[i], &readfds);
401         if (fds[i] > maxfd)
402             maxfd = fds[i];
403     }
404     status = select(maxfd + 1, &readfds, NULL, NULL, NULL);
405     if (status < 0)
406         return INVALID_SOCKET;
407     fd = INVALID_SOCKET;
408     for (i = 0; i < count; i++)
409         if (FD_ISSET(fds[i], &readfds)) {
410             fd = fds[i];
411             break;
412         }
413     return fd;
414 }
415 
416 
417 /*
418  * Given an array of file descriptors and the length of that array (the same
419  * data that's returned by network_bind_all), wait for an incoming connection
420  * on any of those sockets, accept the connection with accept(), and return
421  * the new file descriptor.
422  *
423  * This is essentially a replacement for accept() with a single socket for
424  * daemons that are listening to multiple separate bound sockets, possibly
425  * because they need to listen to specific interfaces or possibly because
426  * they're listening for both IPv4 and IPv6 connections.
427  *
428  * Returns the new socket on success or INVALID_SOCKET on failure.  On
429  * success, fills out the arguments with the address and address length of the
430  * accepted client.  No error will be reported, so the caller should do that.
431  * Note that INVALID_SOCKET may be returned if the timeout is interrupted by a
432  * signal, which is not, precisely speaking, an error condition.  In this
433  * case, errno will be set to EINTR.
434  */
435 socket_type
network_accept_any(socket_type fds[],unsigned int count,struct sockaddr * addr,socklen_t * addrlen)436 network_accept_any(socket_type fds[], unsigned int count,
437                    struct sockaddr *addr, socklen_t *addrlen)
438 {
439     socket_type fd;
440 
441     fd = network_wait_any(fds, count);
442     if (fd == INVALID_SOCKET)
443         return INVALID_SOCKET;
444     else
445         return accept(fd, addr, addrlen);
446 }
447 
448 
449 /*
450  * Binds the given socket to an appropriate source address for its family
451  * using the provided source address.  Returns true on success and false on
452  * failure.
453  */
454 static bool
network_source(socket_type fd,int family,const char * source)455 network_source(socket_type fd, int family, const char *source)
456 {
457     if (source == NULL && innconf == NULL)
458         return true;
459     if (family == AF_INET) {
460         struct sockaddr_in saddr;
461 
462         if (source == NULL && innconf != NULL)
463             source = innconf->sourceaddress;
464         if (source == NULL ||
465             strcmp(source, "all") == 0 || strcmp(source, "any") == 0)
466               return true;
467 
468         memset(&saddr, 0, sizeof(saddr));
469         saddr.sin_family = AF_INET;
470         if (!inet_aton(source, &saddr.sin_addr)) {
471             socket_set_errno_einval();
472             return false;
473         }
474         return bind(fd, (struct sockaddr *) &saddr, sizeof(saddr)) == 0;
475     }
476 #ifdef HAVE_INET6
477     else if (family == AF_INET6) {
478         struct sockaddr_in6 saddr;
479 
480         memset(&saddr, 0, sizeof(saddr));
481         if (source == NULL && innconf != NULL)
482             source = innconf->sourceaddress6;
483         if (source == NULL ||
484             strcmp(source, "all") == 0 || strcmp(source, "any") == 0)
485               return true;
486 
487         saddr.sin6_family = AF_INET6;
488         if (inet_pton(AF_INET6, source, &saddr.sin6_addr) < 1) {
489             socket_set_errno_einval();
490             return false;
491         }
492         return bind(fd, (struct sockaddr *) &saddr, sizeof(saddr)) == 0;
493     }
494 #endif
495     else {
496         socket_set_errno(EAFNOSUPPORT);
497         return false;
498     }
499 }
500 
501 
502 /*
503  * Internal helper function that waits for a non-blocking connect to complete
504  * on a socket.  Takes the file descriptor and the timeout.  Returns 0 on a
505  * successful completion of the connect within the timeout and -1 on failure.
506  * On failure, sets the socket errno.
507  */
508 static int
connect_wait(socket_type fd,time_t timeout)509 connect_wait(socket_type fd, time_t timeout)
510 {
511     int status, err;
512     socklen_t length;
513     struct timeval tv;
514     fd_set set;
515 
516     /*
517      * Use select to poll the file descriptor.  Loop if interrupted by a
518      * caught signal.  This means we could wait for longer than the timeout
519      * when interrupted, but there's no good way of recovering the elapsed
520      * time that's worth the hassle.
521      */
522     do {
523         tv.tv_sec = timeout;
524         tv.tv_usec = 0;
525         FD_ZERO(&set);
526         FD_SET(fd, &set);
527         status = select(fd + 1, NULL, &set, NULL, &tv);
528     } while (status < 0 && socket_errno == EINTR);
529 
530     /*
531      * If we timed out, set errno appropriately.  If the connection completes,
532      * retrieve the actual status from the socket.
533      */
534     if (status == 0 && !FD_ISSET(fd, &set)) {
535         status = -1;
536         socket_set_errno(ETIMEDOUT);
537     } else if (status > 0 && FD_ISSET(fd, &set)) {
538         length = sizeof(err);
539         status = getsockopt(fd, SOL_SOCKET, SO_ERROR, &err, &length);
540         if (status == 0) {
541             status = (err == 0) ? 0 : -1;
542             socket_set_errno(err);
543         }
544     }
545     return status;
546 }
547 
548 
549 /*
550  * Given a linked list of addrinfo structs representing the remote service,
551  * try to create a local socket and connect to that service.  Takes an
552  * optional source address.  Try each address in turn until one of them
553  * connects.  Returns the file descriptor of the open socket on success, or
554  * INVALID_SOCKET on failure.  Tries to leave the reason for the failure in
555  * errno.
556  */
557 socket_type
network_connect(const struct addrinfo * ai,const char * source,time_t timeout)558 network_connect(const struct addrinfo *ai, const char *source, time_t timeout)
559 {
560     socket_type fd = INVALID_SOCKET;
561     int oerrno, status;
562 
563     for (status = -1; status != 0 && ai != NULL; ai = ai->ai_next) {
564         if (fd != INVALID_SOCKET)
565             socket_close(fd);
566         fd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
567         if (fd == INVALID_SOCKET)
568             continue;
569         if (!network_source(fd, ai->ai_family, source))
570             continue;
571         if (timeout == 0)
572             status = connect(fd, ai->ai_addr, ai->ai_addrlen);
573         else {
574             fdflag_nonblocking(fd, true);
575             status = connect(fd, ai->ai_addr, ai->ai_addrlen);
576             if (status < 0 && socket_errno == EINPROGRESS)
577                 status = connect_wait(fd, timeout);
578             oerrno = socket_errno;
579             fdflag_nonblocking(fd, false);
580             socket_set_errno(oerrno);
581         }
582     }
583     if (status == 0)
584         return fd;
585     else {
586         if (fd != INVALID_SOCKET) {
587             oerrno = socket_errno;
588             socket_close(fd);
589             socket_set_errno(oerrno);
590         }
591         return INVALID_SOCKET;
592     }
593 }
594 
595 
596 /*
597  * Like network_connect, but takes a host and a port instead of an addrinfo
598  * struct list.  Returns the file descriptor of the open socket on success, or
599  * INVALID_SOCKET on failure.  If getaddrinfo fails, errno may not be set to
600  * anything useful.
601  */
602 socket_type
network_connect_host(const char * host,unsigned short port,const char * source,time_t timeout)603 network_connect_host(const char *host, unsigned short port, const char *source,
604                      time_t timeout)
605 {
606     struct addrinfo hints, *ai;
607     char portbuf[16];
608     socket_type fd;
609     int status, oerrno;
610 
611     memset(&hints, 0, sizeof(hints));
612     hints.ai_family = AF_UNSPEC;
613     hints.ai_socktype = SOCK_STREAM;
614     status = snprintf(portbuf, sizeof(portbuf), "%hu", port);
615     if (status > 0 && (size_t) status >= sizeof(portbuf)) {
616         status = -1;
617         socket_set_errno_einval();
618     }
619     if (status < 0)
620         return INVALID_SOCKET;
621     if (getaddrinfo(host, portbuf, &hints, &ai) != 0)
622         return INVALID_SOCKET;
623     fd = network_connect(ai, source, timeout);
624     oerrno = socket_errno;
625     freeaddrinfo(ai);
626     socket_set_errno(oerrno);
627     return fd;
628 }
629 
630 
631 /*
632  * Create a new socket of the specified domain and type and do the binding as
633  * if we were a regular client socket, but then return before connecting.
634  * Returns the file descriptor of the open socket on success, or
635  * INVALID_SOCKET on failure.  Intended primarily for the use of clients that
636  * will then go on to do a non-blocking connect.
637  */
638 socket_type
network_client_create(int domain,int type,const char * source)639 network_client_create(int domain, int type, const char *source)
640 {
641     socket_type fd;
642     int oerrno;
643 
644     fd = socket(domain, type, 0);
645     if (fd == INVALID_SOCKET)
646         return INVALID_SOCKET;
647     if (!network_source(fd, domain, source)) {
648         oerrno = socket_errno;
649         socket_close(fd);
650         socket_set_errno(oerrno);
651         return INVALID_SOCKET;
652     }
653     return fd;
654 }
655 
656 
657 /*
658  * Equivalent to read, but reads all the available data up to the buffer
659  * length, using multiple reads if needed and handling EINTR and EAGAIN.  If
660  * we get EOF before we get enough data, set the socket errno to EPIPE.
661  */
662 static ssize_t
socket_xread(socket_type fd,void * buffer,size_t size)663 socket_xread(socket_type fd, void *buffer, size_t size)
664 {
665     size_t total;
666     ssize_t status;
667     unsigned int count = 0;
668 
669     /* Abort the read if we try 100 times with no forward progress. */
670     for (total = 0, status = 0; total < size; total += status) {
671         if (++count > 100)
672             break;
673         status = socket_read(fd, (char *) buffer + total, size - total);
674         if (status > 0)
675             count = 0;
676         else if (status == 0)
677             break;
678         else {
679             if ((socket_errno != EINTR) && (socket_errno != EAGAIN))
680                 break;
681             status = 0;
682         }
683     }
684     if (status == 0 && total < size)
685         socket_set_errno(EPIPE);
686     return (total < size) ? -1 : (ssize_t) total;
687 }
688 
689 
690 /*
691  * Read the specified number of bytes from the network, enforcing a timeout
692  * (in seconds).  We use select to wait for data to become available and then
693  * keep reading until either we time out or we've gotten all the data we're
694  * looking for.  timeout may be 0 to never time out.  Return true on success
695  * and false (setting socket_errno) on failure.
696  */
697 bool
network_read(socket_type fd,void * buffer,size_t total,time_t timeout)698 network_read(socket_type fd, void *buffer, size_t total, time_t timeout)
699 {
700     time_t start, now;
701     fd_set set;
702     struct timeval tv;
703     size_t got = 0;
704     ssize_t status;
705 
706     /* If there's no timeout, do this the easy way. */
707     if (timeout == 0)
708         return (socket_xread(fd, buffer, total) >= 0);
709 
710     /*
711      * The hard way.  We try to apply the timeout on the whole read.  If
712      * either select or read fails with EINTR, restart the loop, and rely on
713      * the overall timeout to limit how long we wait without forward
714      * progress.
715      */
716     start = time(NULL);
717     now = start;
718     do {
719         FD_ZERO(&set);
720         FD_SET(fd, &set);
721         tv.tv_sec = timeout - (now - start);
722         if (tv.tv_sec < 1)
723             tv.tv_sec = 1;
724         tv.tv_usec = 0;
725         status = select(fd + 1, &set, NULL, NULL, &tv);
726         if (status < 0) {
727             if (socket_errno == EINTR)
728                 continue;
729             return false;
730         } else if (status == 0) {
731             socket_set_errno(ETIMEDOUT);
732             return false;
733         }
734         status = socket_read(fd, (char *) buffer + got, total - got);
735         if (status < 0) {
736             if (socket_errno == EINTR)
737                 continue;
738             return false;
739         } else if (status == 0) {
740             socket_set_errno(EPIPE);
741             return false;
742         }
743         got += status;
744         if (got == total)
745             return true;
746         now = time(NULL);
747     } while (now - start < timeout);
748     socket_set_errno(ETIMEDOUT);
749     return false;
750 }
751 
752 
753 /*
754  * Write the specified number of bytes from the network, enforcing a timeout
755  * (in seconds).  We use select to wait for the socket to become available and
756  * then keep reading until either we time out or we've sent all the data.
757  * timeout may be 0 to never time out.  Return true on success and false
758  * (setting socket_errno) on failure.
759  */
760 bool
network_write(socket_type fd,const void * buffer,size_t total,time_t timeout)761 network_write(socket_type fd, const void *buffer, size_t total, time_t timeout)
762 {
763     time_t start, now;
764     fd_set set;
765     struct timeval tv;
766     size_t sent = 0;
767     ssize_t status;
768     int err;
769 
770     /* If there's no timeout, do this the easy way. */
771     if (timeout == 0)
772         return (socket_xwrite(fd, buffer, total) >= 0);
773 
774     /* The hard way.  We try to apply the timeout on the whole write.  If
775      * either select or read fails with EINTR, restart the loop, and rely on
776      * the overall timeout to limit how long we wait without forward progress.
777      */
778     fdflag_nonblocking(fd, true);
779     start = time(NULL);
780     now = start;
781     do {
782         FD_ZERO(&set);
783         FD_SET(fd, &set);
784         tv.tv_sec = timeout - (now - start);
785         if (tv.tv_sec < 1)
786             tv.tv_sec = 1;
787         tv.tv_usec = 0;
788         status = select(fd + 1, NULL, &set, NULL, &tv);
789         if (status < 0) {
790             if (socket_errno == EINTR)
791                 continue;
792             goto fail;
793         } else if (status == 0) {
794             socket_set_errno(ETIMEDOUT);
795             goto fail;
796         }
797         status = socket_write(fd, (const char *) buffer + sent, total - sent);
798         if (status < 0) {
799             if (socket_errno == EINTR)
800                 continue;
801             goto fail;
802         }
803         sent += status;
804         if (sent == total) {
805             fdflag_nonblocking(fd, false);
806             return true;
807         }
808         now = time(NULL);
809     } while (now - start < timeout);
810     socket_set_errno(ETIMEDOUT);
811 
812 fail:
813     err = socket_errno;
814     fdflag_nonblocking(fd, false);
815     socket_set_errno(err);
816     return false;
817 }
818 
819 
820 /*
821  * Print an ASCII representation of the address of the given sockaddr into the
822  * provided buffer.  This buffer must hold at least INET_ADDRSTRLEN characters
823  * for IPv4 addresses and INET6_ADDRSTRLEN characters for IPv6, so generally
824  * it should always be as large as the latter.  Returns success or failure.
825  */
826 bool
network_sockaddr_sprint(char * dst,socklen_t size,const struct sockaddr * addr)827 network_sockaddr_sprint(char *dst, socklen_t size, const struct sockaddr *addr)
828 {
829     const char *result;
830 
831 #ifdef HAVE_INET6
832     if (addr->sa_family == AF_INET6) {
833         const struct sockaddr_in6 *sin6;
834 
835         sin6 = (const struct sockaddr_in6 *) (const void *) addr;
836         if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
837             struct in_addr in;
838 
839             memcpy(&in, sin6->sin6_addr.s6_addr + 12, sizeof(in));
840             result = inet_ntop(AF_INET, &in, dst, size);
841         } else
842             result = inet_ntop(AF_INET6, &sin6->sin6_addr, dst, size);
843         return (result != NULL);
844     }
845 #endif
846     if (addr->sa_family == AF_INET) {
847         const struct sockaddr_in *sin;
848 
849         sin = (const struct sockaddr_in *) (const void *) addr;
850         result = inet_ntop(AF_INET, &sin->sin_addr, dst, size);
851         return (result != NULL);
852     } else {
853         socket_set_errno(EAFNOSUPPORT);
854         return false;
855     }
856 }
857 
858 
859 /*
860  * Compare the addresses from two sockaddrs and see whether they're equal.
861  * IPv4 addresses that have been mapped to IPv6 addresses compare equal to the
862  * corresponding IPv4 address.
863  */
864 bool
network_sockaddr_equal(const struct sockaddr * a,const struct sockaddr * b)865 network_sockaddr_equal(const struct sockaddr *a, const struct sockaddr *b)
866 {
867     const struct sockaddr_in *a4;
868     const struct sockaddr_in *b4;
869 #ifdef HAVE_INET6
870     const struct sockaddr_in6 *a6;
871     const struct sockaddr_in6 *b6;
872     const struct sockaddr *tmp;
873 #endif
874 
875     a4 = (const struct sockaddr_in *) (const void *) a;
876     b4 = (const struct sockaddr_in *) (const void *) b;
877 
878 #ifdef HAVE_INET6
879     a6 = (const struct sockaddr_in6 *) (const void *) a;
880     b6 = (const struct sockaddr_in6 *) (const void *) b;
881     if (a->sa_family == AF_INET && b->sa_family == AF_INET6) {
882         tmp = a;
883         a = b;
884         b = tmp;
885         a6 = (const struct sockaddr_in6 *) (const void *) a;
886         b4 = (const struct sockaddr_in *) (const void *) b;
887     }
888     if (a->sa_family == AF_INET6) {
889         if (b->sa_family == AF_INET6)
890             return IN6_ARE_ADDR_EQUAL(&a6->sin6_addr, &b6->sin6_addr);
891         else if (b->sa_family != AF_INET)
892             return false;
893         else if (!IN6_IS_ADDR_V4MAPPED(&a6->sin6_addr))
894             return false;
895         else {
896             struct in_addr in;
897 
898             memcpy(&in, a6->sin6_addr.s6_addr + 12, sizeof(in));
899             return (in.s_addr == b4->sin_addr.s_addr);
900         }
901     }
902 #endif
903 
904     if (a->sa_family != AF_INET || b->sa_family != AF_INET)
905         return false;
906     return (a4->sin_addr.s_addr == b4->sin_addr.s_addr);
907 }
908 
909 
910 /*
911  * Returns the port of a sockaddr or 0 on error.
912  */
913 unsigned short
network_sockaddr_port(const struct sockaddr * sa)914 network_sockaddr_port(const struct sockaddr *sa)
915 {
916     const struct sockaddr_in *sin;
917 
918 #ifdef HAVE_INET6
919     const struct sockaddr_in6 *sin6;
920 
921     if (sa->sa_family == AF_INET6) {
922         sin6 = (const struct sockaddr_in6 *) (const void *) sa;
923         return htons(sin6->sin6_port);
924     }
925 #endif
926     if (sa->sa_family != AF_INET)
927         return 0;
928     else {
929         sin = (const struct sockaddr_in *) (const void *) sa;
930         return htons(sin->sin_port);
931     }
932 }
933 
934 
935 /*
936  * Compare two addresses given as strings, applying an optional mask.  Returns
937  * true if the addresses are equal modulo the mask and false otherwise,
938  * including on syntax errors in the addresses or mask specification.
939  */
940 bool
network_addr_match(const char * a,const char * b,const char * mask)941 network_addr_match(const char *a, const char *b, const char *mask)
942 {
943     struct in_addr a4, b4, tmp;
944     unsigned long cidr;
945     char *end;
946     unsigned int i;
947     uint32_t bits, addr_mask;
948 #ifdef HAVE_INET6
949     struct in6_addr a6, b6;
950 #endif
951 
952     /*
953      * AIX 7.1 treats the empty string as equivalent to 0.0.0.0 and allows it
954      * to match, but it's too easy to get the empty string from some sort of
955      * syntax error.  Special-case the empty string to always return false.
956      */
957     if (a[0] == '\0' || b[0] == '\0')
958         return false;
959 
960     /*
961      * If the addresses are IPv4, the mask may be in one of two forms.  It can
962      * either be a traditional mask, like 255.255.0.0, or it can be a CIDR
963      * subnet designation, like 16.  (The caller should have already removed
964      * the slash separating it from the address.)
965      */
966     if (inet_aton(a, &a4) && inet_aton(b, &b4)) {
967         if (mask == NULL)
968             addr_mask = htonl(0xffffffffUL);
969         else if (strchr(mask, '.') == NULL) {
970             cidr = strtoul(mask, &end, 10);
971             if (cidr > 32 || *end != '\0')
972                 return false;
973             for (bits = 0, i = 0; i < cidr; i++)
974                 bits |= (1U << (31 - i));
975             addr_mask = htonl(bits);
976         } else if (inet_aton(mask, &tmp))
977             addr_mask = tmp.s_addr;
978         else
979             return false;
980         return (a4.s_addr & addr_mask) == (b4.s_addr & addr_mask);
981     }
982 
983 #ifdef HAVE_INET6
984     /*
985      * Otherwise, if the address is IPv6, the mask is required to be a CIDR
986      * subnet designation.
987      */
988     if (!inet_pton(AF_INET6, a, &a6) || !inet_pton(AF_INET6, b, &b6))
989         return false;
990     if (mask == NULL)
991         cidr = 128;
992     else {
993         cidr = strtoul(mask, &end, 10);
994         if (cidr > 128 || *end != '\0')
995             return false;
996     }
997     for (i = 0; i * 8 < cidr; i++) {
998         if ((i + 1) * 8 <= cidr) {
999             if (a6.s6_addr[i] != b6.s6_addr[i])
1000                 return false;
1001         } else {
1002             for (addr_mask = 0, bits = 0; bits < cidr % 8; bits++)
1003                 addr_mask |= (1U << (7 - bits));
1004             if ((a6.s6_addr[i] & addr_mask) != (b6.s6_addr[i] & addr_mask))
1005                 return false;
1006         }
1007     }
1008     return true;
1009 #else
1010     return false;
1011 #endif
1012 }
1013