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