1 /*
2 chronyd/chronyc - Programs for keeping computer clocks accurate.
3
4 **********************************************************************
5 * Copyright (C) Richard P. Curnow 1997-2003
6 * Copyright (C) Timo Teras 2009
7 * Copyright (C) Miroslav Lichvar 2009, 2013-2020
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 *
22 **********************************************************************
23
24 =======================================================================
25
26 This file implements socket operations.
27
28 */
29
30 #include "config.h"
31
32 #include "sysincl.h"
33
34 #ifdef HAVE_LINUX_TIMESTAMPING
35 #include <linux/errqueue.h>
36 #include <linux/net_tstamp.h>
37 #endif
38
39 #include "socket.h"
40 #include "array.h"
41 #include "logging.h"
42 #include "privops.h"
43 #include "ptp.h"
44 #include "util.h"
45
46 #define INVALID_SOCK_FD (-4)
47 #define CMSG_BUF_SIZE 256
48
49 union sockaddr_all {
50 struct sockaddr_in in4;
51 #ifdef FEAT_IPV6
52 struct sockaddr_in6 in6;
53 #endif
54 struct sockaddr_un un;
55 struct sockaddr sa;
56 };
57
58 struct Message {
59 union sockaddr_all name;
60 struct iovec iov;
61 /* Buffer of sufficient length for all expected messages */
62 struct {
63 /* Extra space for Ethernet, IPv4/IPv6, and UDP headers in
64 timestamped messages received from the Linux error queue */
65 uint8_t l234_headers[64];
66 union {
67 NTP_Packet ntp_msg;
68 PTP_NtpMessage ptp_msg;
69 CMD_Request cmd_request;
70 CMD_Reply cmd_reply;
71 } msg;
72 } msg_buf;
73 /* Aligned buffer for control messages */
74 struct cmsghdr cmsg_buf[CMSG_BUF_SIZE / sizeof (struct cmsghdr)];
75 };
76
77 #ifdef HAVE_RECVMMSG
78 #define MAX_RECV_MESSAGES 16
79 #define MessageHeader mmsghdr
80 #else
81 /* Compatible with mmsghdr */
82 struct MessageHeader {
83 struct msghdr msg_hdr;
84 unsigned int msg_len;
85 };
86
87 #define MAX_RECV_MESSAGES 1
88 #endif
89
90 static int initialised;
91
92 /* Flags indicating in which IP families sockets can be requested */
93 static int ip4_enabled;
94 static int ip6_enabled;
95
96 /* Flags supported by socket() */
97 static int supported_socket_flags;
98
99 /* Arrays of Message, MessageHeader, and SCK_Message */
100 static ARR_Instance recv_messages;
101 static ARR_Instance recv_headers;
102 static ARR_Instance recv_sck_messages;
103
104 static unsigned int received_messages;
105
106 static int (*priv_bind_function)(int sock_fd, struct sockaddr *address,
107 socklen_t address_len);
108
109 /* ================================================== */
110
111 static void
prepare_buffers(unsigned int n)112 prepare_buffers(unsigned int n)
113 {
114 struct MessageHeader *hdr;
115 struct Message *msg;
116 unsigned int i;
117
118 for (i = 0; i < n; i++) {
119 msg = ARR_GetElement(recv_messages, i);
120 hdr = ARR_GetElement(recv_headers, i);
121
122 msg->iov.iov_base = &msg->msg_buf;
123 msg->iov.iov_len = sizeof (msg->msg_buf);
124 hdr->msg_hdr.msg_name = &msg->name;
125 hdr->msg_hdr.msg_namelen = sizeof (msg->name);
126 hdr->msg_hdr.msg_iov = &msg->iov;
127 hdr->msg_hdr.msg_iovlen = 1;
128 hdr->msg_hdr.msg_control = msg->cmsg_buf;
129 hdr->msg_hdr.msg_controllen = sizeof (msg->cmsg_buf);
130 hdr->msg_hdr.msg_flags = 0;
131 hdr->msg_len = 0;
132 }
133 }
134
135 /* ================================================== */
136
137 static const char *
domain_to_string(int domain)138 domain_to_string(int domain)
139 {
140 switch (domain) {
141 case AF_INET:
142 return "IPv4";
143 #ifdef AF_INET6
144 case AF_INET6:
145 return "IPv6";
146 #endif
147 case AF_UNIX:
148 return "Unix";
149 case AF_UNSPEC:
150 return "UNSPEC";
151 default:
152 return "?";
153 }
154 }
155
156 /* ================================================== */
157
158 #if defined(SOCK_CLOEXEC) || defined(SOCK_NONBLOCK)
159 static int
check_socket_flag(int sock_flag,int fd_flag,int fs_flag)160 check_socket_flag(int sock_flag, int fd_flag, int fs_flag)
161 {
162 int sock_fd, fd_flags, fs_flags;
163
164 sock_fd = socket(AF_INET, SOCK_DGRAM | sock_flag, 0);
165 if (sock_fd < 0)
166 return 0;
167
168 fd_flags = fcntl(sock_fd, F_GETFD);
169 fs_flags = fcntl(sock_fd, F_GETFL);
170
171 close(sock_fd);
172
173 if (fd_flags == -1 || (fd_flags & fd_flag) != fd_flag ||
174 fs_flags == -1 || (fs_flags & fs_flag) != fs_flag)
175 return 0;
176
177 return 1;
178 }
179 #endif
180
181 /* ================================================== */
182
183 static int
set_socket_nonblock(int sock_fd)184 set_socket_nonblock(int sock_fd)
185 {
186 if (fcntl(sock_fd, F_SETFL, O_NONBLOCK) < 0) {
187 DEBUG_LOG("Could not set O_NONBLOCK : %s", strerror(errno));
188 return 0;
189 }
190
191 return 1;
192 }
193
194 /* ================================================== */
195
196 static int
get_open_flags(int flags)197 get_open_flags(int flags)
198 {
199 int r = supported_socket_flags;
200
201 #ifdef SOCK_NONBLOCK
202 if (flags & SCK_FLAG_BLOCK)
203 r &= ~SOCK_NONBLOCK;
204 #endif
205
206 return r;
207 }
208
209 /* ================================================== */
210
211 static int
set_socket_flags(int sock_fd,int flags)212 set_socket_flags(int sock_fd, int flags)
213 {
214 /* Close the socket automatically on exec */
215 if (
216 #ifdef SOCK_CLOEXEC
217 (supported_socket_flags & SOCK_CLOEXEC) == 0 &&
218 #endif
219 !UTI_FdSetCloexec(sock_fd))
220 return 0;
221
222 /* Enable non-blocking mode */
223 if ((flags & SCK_FLAG_BLOCK) == 0 &&
224 #ifdef SOCK_NONBLOCK
225 (supported_socket_flags & SOCK_NONBLOCK) == 0 &&
226 #endif
227 !set_socket_nonblock(sock_fd))
228 return 0;
229
230 return 1;
231 }
232
233 /* ================================================== */
234
235 static int
open_socket(int domain,int type,int flags)236 open_socket(int domain, int type, int flags)
237 {
238 int sock_fd;
239
240 sock_fd = socket(domain, type | get_open_flags(flags), 0);
241
242 if (sock_fd < 0) {
243 DEBUG_LOG("Could not open %s socket : %s",
244 domain_to_string(domain), strerror(errno));
245 return INVALID_SOCK_FD;
246 }
247
248 if (!set_socket_flags(sock_fd, flags)) {
249 close(sock_fd);
250 return INVALID_SOCK_FD;
251 }
252
253 return sock_fd;
254 }
255
256 /* ================================================== */
257
258 static int
open_socket_pair(int domain,int type,int flags,int * other_fd)259 open_socket_pair(int domain, int type, int flags, int *other_fd)
260 {
261 int sock_fds[2];
262
263 if (socketpair(domain, type | get_open_flags(flags), 0, sock_fds) < 0) {
264 DEBUG_LOG("Could not open %s socket : %s",
265 domain_to_string(domain), strerror(errno));
266 return INVALID_SOCK_FD;
267 }
268
269 if (!set_socket_flags(sock_fds[0], flags) || !set_socket_flags(sock_fds[1], flags)) {
270 close(sock_fds[0]);
271 close(sock_fds[1]);
272 return INVALID_SOCK_FD;
273 }
274
275 *other_fd = sock_fds[1];
276
277 return sock_fds[0];
278 }
279
280 /* ================================================== */
281
282 static int
set_socket_options(int sock_fd,int flags)283 set_socket_options(int sock_fd, int flags)
284 {
285 /* Make the socket capable of sending broadcast packets if requested */
286 if (flags & SCK_FLAG_BROADCAST && !SCK_SetIntOption(sock_fd, SOL_SOCKET, SO_BROADCAST, 1))
287 ;
288
289 return 1;
290 }
291
292 /* ================================================== */
293
294 static int
set_ip_options(int sock_fd,int family,int flags)295 set_ip_options(int sock_fd, int family, int flags)
296 {
297 #if defined(FEAT_IPV6) && defined(IPV6_V6ONLY)
298 /* Receive only IPv6 packets on an IPv6 socket */
299 if (family == IPADDR_INET6 && !SCK_SetIntOption(sock_fd, IPPROTO_IPV6, IPV6_V6ONLY, 1))
300 return 0;
301 #endif
302
303 /* Provide destination address of received packets if requested */
304 if (flags & SCK_FLAG_RX_DEST_ADDR) {
305 if (family == IPADDR_INET4) {
306 #ifdef HAVE_IN_PKTINFO
307 if (!SCK_SetIntOption(sock_fd, IPPROTO_IP, IP_PKTINFO, 1))
308 ;
309 #elif defined(IP_RECVDSTADDR)
310 if (!SCK_SetIntOption(sock_fd, IPPROTO_IP, IP_RECVDSTADDR, 1))
311 ;
312 #endif
313 }
314 #ifdef FEAT_IPV6
315 else if (family == IPADDR_INET6) {
316 #ifdef HAVE_IN6_PKTINFO
317 #ifdef IPV6_RECVPKTINFO
318 if (!SCK_SetIntOption(sock_fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, 1))
319 ;
320 #else
321 if (!SCK_SetIntOption(sock_fd, IPPROTO_IPV6, IPV6_PKTINFO, 1))
322 ;
323 #endif
324 #endif
325 }
326 #endif
327 }
328
329 return 1;
330 }
331
332 /* ================================================== */
333
334 static int
is_any_address(IPAddr * addr)335 is_any_address(IPAddr *addr)
336 {
337 IPAddr any_addr;
338
339 SCK_GetAnyLocalIPAddress(addr->family, &any_addr);
340
341 return UTI_CompareIPs(&any_addr, addr, NULL) == 0;
342 }
343
344 /* ================================================== */
345
346 static int
bind_device(int sock_fd,const char * iface)347 bind_device(int sock_fd, const char *iface)
348 {
349 #ifdef SO_BINDTODEVICE
350 if (setsockopt(sock_fd, SOL_SOCKET, SO_BINDTODEVICE, iface, strlen(iface) + 1) < 0) {
351 DEBUG_LOG("Could not bind socket to %s : %s", iface, strerror(errno));
352 return 0;
353 }
354 return 1;
355 #else
356 DEBUG_LOG("Could not bind socket to %s : %s", iface, "Not supported");
357 return 0;
358 #endif
359 }
360
361 /* ================================================== */
362
363 static int
bind_ip_address(int sock_fd,IPSockAddr * addr,int flags)364 bind_ip_address(int sock_fd, IPSockAddr *addr, int flags)
365 {
366 union sockaddr_all saddr;
367 socklen_t saddr_len;
368 int s;
369
370 /* Make the socket capable of re-using an old address if binding to a specific port */
371 if (addr->port > 0 && !SCK_SetIntOption(sock_fd, SOL_SOCKET, SO_REUSEADDR, 1))
372 ;
373
374 #if defined(LINUX) && defined(SO_REUSEPORT)
375 /* Allow multiple instances to bind to the same port in order to enable load
376 balancing. Don't enable this option on non-Linux systems as it has
377 a slightly different meaning there (with some important implications). */
378 if (addr->port > 0 && !SCK_SetIntOption(sock_fd, SOL_SOCKET, SO_REUSEPORT, 1))
379 ;
380 #endif
381
382 #ifdef IP_FREEBIND
383 /* Allow binding to an address that doesn't exist yet */
384 if (!SCK_SetIntOption(sock_fd, IPPROTO_IP, IP_FREEBIND, 1))
385 ;
386 #endif
387
388 saddr_len = SCK_IPSockAddrToSockaddr(addr, (struct sockaddr *)&saddr, sizeof (saddr));
389 if (saddr_len == 0)
390 return 0;
391
392 if (flags & SCK_FLAG_PRIV_BIND && priv_bind_function)
393 s = priv_bind_function(sock_fd, &saddr.sa, saddr_len);
394 else
395 s = bind(sock_fd, &saddr.sa, saddr_len);
396
397 if (s < 0) {
398 DEBUG_LOG("Could not bind socket to %s : %s",
399 UTI_IPSockAddrToString(addr), strerror(errno));
400 return 0;
401 }
402
403 return 1;
404 }
405
406 /* ================================================== */
407
408 static int
connect_ip_address(int sock_fd,IPSockAddr * addr)409 connect_ip_address(int sock_fd, IPSockAddr *addr)
410 {
411 union sockaddr_all saddr;
412 socklen_t saddr_len;
413
414 saddr_len = SCK_IPSockAddrToSockaddr(addr, (struct sockaddr *)&saddr, sizeof (saddr));
415 if (saddr_len == 0)
416 return 0;
417
418 if (connect(sock_fd, &saddr.sa, saddr_len) < 0 && errno != EINPROGRESS) {
419 DEBUG_LOG("Could not connect socket to %s : %s",
420 UTI_IPSockAddrToString(addr), strerror(errno));
421 return 0;
422 }
423
424 return 1;
425 }
426
427 /* ================================================== */
428
429 static int
open_ip_socket(IPSockAddr * remote_addr,IPSockAddr * local_addr,const char * iface,int type,int flags)430 open_ip_socket(IPSockAddr *remote_addr, IPSockAddr *local_addr, const char *iface,
431 int type, int flags)
432 {
433 int domain, family, sock_fd;
434
435 if (local_addr)
436 family = local_addr->ip_addr.family;
437 else if (remote_addr)
438 family = remote_addr->ip_addr.family;
439 else
440 family = IPADDR_INET4;
441
442 switch (family) {
443 case IPADDR_INET4:
444 if (!ip4_enabled)
445 return INVALID_SOCK_FD;
446 domain = AF_INET;
447 break;
448 #ifdef FEAT_IPV6
449 case IPADDR_INET6:
450 if (!ip6_enabled)
451 return INVALID_SOCK_FD;
452 domain = AF_INET6;
453 break;
454 #endif
455 default:
456 DEBUG_LOG("Unspecified family");
457 return INVALID_SOCK_FD;
458 }
459
460 sock_fd = open_socket(domain, type, flags);
461 if (sock_fd < 0)
462 return INVALID_SOCK_FD;
463
464 if (!set_socket_options(sock_fd, flags))
465 goto error;
466
467 if (!set_ip_options(sock_fd, family, flags))
468 goto error;
469
470 if (iface && !bind_device(sock_fd, iface))
471 goto error;
472
473 /* Bind the socket if a non-any local address/port was specified */
474 if (local_addr && local_addr->ip_addr.family != IPADDR_UNSPEC &&
475 (local_addr->port != 0 || !is_any_address(&local_addr->ip_addr)) &&
476 !bind_ip_address(sock_fd, local_addr, flags))
477 goto error;
478
479 /* Connect the socket if a remote address was specified */
480 if (remote_addr && remote_addr->ip_addr.family != IPADDR_UNSPEC &&
481 !connect_ip_address(sock_fd, remote_addr))
482 goto error;
483
484 if (remote_addr || local_addr)
485 DEBUG_LOG("Opened %s%s socket fd=%d%s%s%s%s",
486 type == SOCK_DGRAM ? "UDP" : type == SOCK_STREAM ? "TCP" : "?",
487 family == IPADDR_INET4 ? "v4" : "v6",
488 sock_fd,
489 remote_addr ? " remote=" : "",
490 remote_addr ? UTI_IPSockAddrToString(remote_addr) : "",
491 local_addr ? " local=" : "",
492 local_addr ? UTI_IPSockAddrToString(local_addr) : "");
493
494 return sock_fd;
495
496 error:
497 SCK_CloseSocket(sock_fd);
498 return INVALID_SOCK_FD;
499 }
500
501 /* ================================================== */
502
503 static int
bind_unix_address(int sock_fd,const char * addr,int flags)504 bind_unix_address(int sock_fd, const char *addr, int flags)
505 {
506 union sockaddr_all saddr;
507
508 memset(&saddr, 0, sizeof (saddr));
509
510 if (snprintf(saddr.un.sun_path, sizeof (saddr.un.sun_path), "%s", addr) >=
511 sizeof (saddr.un.sun_path)) {
512 DEBUG_LOG("Unix socket path %s too long", addr);
513 return 0;
514 }
515 saddr.un.sun_family = AF_UNIX;
516
517 if (unlink(addr) < 0)
518 DEBUG_LOG("Could not remove %s : %s", addr, strerror(errno));
519
520 /* PRV_BindSocket() doesn't support Unix sockets yet */
521 if (bind(sock_fd, &saddr.sa, sizeof (saddr.un)) < 0) {
522 DEBUG_LOG("Could not bind Unix socket to %s : %s", addr, strerror(errno));
523 return 0;
524 }
525
526 /* Allow access to everyone with access to the directory if requested */
527 if (flags & SCK_FLAG_ALL_PERMISSIONS && chmod(addr, 0666) < 0) {
528 DEBUG_LOG("Could not change permissions of %s : %s", addr, strerror(errno));
529 return 0;
530 }
531
532 return 1;
533 }
534
535 /* ================================================== */
536
537 static int
connect_unix_address(int sock_fd,const char * addr)538 connect_unix_address(int sock_fd, const char *addr)
539 {
540 union sockaddr_all saddr;
541
542 memset(&saddr, 0, sizeof (saddr));
543
544 if (snprintf(saddr.un.sun_path, sizeof (saddr.un.sun_path), "%s", addr) >=
545 sizeof (saddr.un.sun_path)) {
546 DEBUG_LOG("Unix socket path %s too long", addr);
547 return 0;
548 }
549 saddr.un.sun_family = AF_UNIX;
550
551 if (connect(sock_fd, &saddr.sa, sizeof (saddr.un)) < 0) {
552 DEBUG_LOG("Could not connect Unix socket to %s : %s", addr, strerror(errno));
553 return 0;
554 }
555
556 return 1;
557 }
558
559 /* ================================================== */
560
561 static int
open_unix_socket(const char * remote_addr,const char * local_addr,int type,int flags)562 open_unix_socket(const char *remote_addr, const char *local_addr, int type, int flags)
563 {
564 int sock_fd;
565
566 sock_fd = open_socket(AF_UNIX, type, flags);
567 if (sock_fd < 0)
568 return INVALID_SOCK_FD;
569
570 if (!set_socket_options(sock_fd, flags))
571 goto error;
572
573 /* Bind the socket if a local address was specified */
574 if (local_addr && !bind_unix_address(sock_fd, local_addr, flags))
575 goto error;
576
577 /* Connect the socket if a remote address was specified */
578 if (remote_addr && !connect_unix_address(sock_fd, remote_addr))
579 goto error;
580
581 DEBUG_LOG("Opened Unix socket fd=%d%s%s%s%s",
582 sock_fd,
583 remote_addr ? " remote=" : "", remote_addr ? remote_addr : "",
584 local_addr ? " local=" : "", local_addr ? local_addr : "");
585
586 return sock_fd;
587
588 error:
589 SCK_RemoveSocket(sock_fd);
590 SCK_CloseSocket(sock_fd);
591 return INVALID_SOCK_FD;
592 }
593
594 /* ================================================== */
595
596 static int
open_unix_socket_pair(int type,int flags,int * other_fd)597 open_unix_socket_pair(int type, int flags, int *other_fd)
598 {
599 int sock_fd;
600
601 sock_fd = open_socket_pair(AF_UNIX, type, flags, other_fd);
602 if (sock_fd < 0)
603 return INVALID_SOCK_FD;
604
605 DEBUG_LOG("Opened Unix socket pair fd1=%d fd2=%d", sock_fd, *other_fd);
606
607 return sock_fd;
608 }
609
610 /* ================================================== */
611
612 static int
get_recv_flags(int flags)613 get_recv_flags(int flags)
614 {
615 int recv_flags = 0;
616
617 if (flags & SCK_FLAG_MSG_ERRQUEUE) {
618 #ifdef MSG_ERRQUEUE
619 recv_flags |= MSG_ERRQUEUE;
620 #else
621 assert(0);
622 #endif
623 }
624
625 return recv_flags;
626 }
627
628 /* ================================================== */
629
630 static void
handle_recv_error(int sock_fd,int flags)631 handle_recv_error(int sock_fd, int flags)
632 {
633 #ifdef MSG_ERRQUEUE
634 /* If reading from the error queue failed, the select() exception should
635 be for a socket error. Clear the error to avoid a busy loop. */
636 if (flags & SCK_FLAG_MSG_ERRQUEUE) {
637 int error = 0;
638
639 if (SCK_GetIntOption(sock_fd, SOL_SOCKET, SO_ERROR, &error))
640 errno = error;
641 }
642 #endif
643
644 DEBUG_LOG("Could not receive message fd=%d : %s", sock_fd, strerror(errno));
645 }
646
647 /* ================================================== */
648
649 static void
log_message(int sock_fd,int direction,SCK_Message * message,const char * prefix,const char * error)650 log_message(int sock_fd, int direction, SCK_Message *message, const char *prefix,
651 const char *error)
652 {
653 const char *local_addr, *remote_addr;
654 char if_index[20], tss[10], tsif[20], tslen[20];
655
656 if (DEBUG <= 0 || log_min_severity > LOGS_DEBUG)
657 return;
658
659 remote_addr = NULL;
660 local_addr = NULL;
661 if_index[0] = '\0';
662 tss[0] = '\0';
663 tsif[0] = '\0';
664 tslen[0] = '\0';
665
666 switch (message->addr_type) {
667 case SCK_ADDR_IP:
668 if (message->remote_addr.ip.ip_addr.family != IPADDR_UNSPEC)
669 remote_addr = UTI_IPSockAddrToString(&message->remote_addr.ip);
670 if (message->local_addr.ip.family != IPADDR_UNSPEC)
671 local_addr = UTI_IPToString(&message->local_addr.ip);
672 break;
673 case SCK_ADDR_UNIX:
674 remote_addr = message->remote_addr.path;
675 break;
676 default:
677 break;
678 }
679
680 if (message->if_index != INVALID_IF_INDEX)
681 snprintf(if_index, sizeof (if_index), " if=%d", message->if_index);
682
683 if (direction > 0) {
684 if (!UTI_IsZeroTimespec(&message->timestamp.kernel) ||
685 !UTI_IsZeroTimespec(&message->timestamp.hw))
686 snprintf(tss, sizeof (tss), " tss=%s%s",
687 !UTI_IsZeroTimespec(&message->timestamp.kernel) ? "K" : "",
688 !UTI_IsZeroTimespec(&message->timestamp.hw) ? "H" : "");
689
690 if (message->timestamp.if_index != INVALID_IF_INDEX)
691 snprintf(tsif, sizeof (tsif), " tsif=%d", message->timestamp.if_index);
692
693 if (message->timestamp.l2_length != 0)
694 snprintf(tslen, sizeof (tslen), " tslen=%d", message->timestamp.l2_length);
695 }
696
697 DEBUG_LOG("%s message%s%s%s%s fd=%d len=%d%s%s%s%s%s%s",
698 prefix,
699 remote_addr ? (direction > 0 ? " from " : " to ") : "",
700 remote_addr ? remote_addr : "",
701 local_addr ? (direction > 0 ? " to " : " from ") : "",
702 local_addr ? local_addr : "",
703 sock_fd, message->length, if_index,
704 tss, tsif, tslen,
705 error ? " : " : "", error ? error : "");
706 }
707
708 /* ================================================== */
709
710 static void
init_message_addresses(SCK_Message * message,SCK_AddressType addr_type)711 init_message_addresses(SCK_Message *message, SCK_AddressType addr_type)
712 {
713 message->addr_type = addr_type;
714
715 switch (addr_type) {
716 case SCK_ADDR_UNSPEC:
717 break;
718 case SCK_ADDR_IP:
719 message->remote_addr.ip.ip_addr.family = IPADDR_UNSPEC;
720 message->remote_addr.ip.port = 0;
721 message->local_addr.ip.family = IPADDR_UNSPEC;
722 break;
723 case SCK_ADDR_UNIX:
724 message->remote_addr.path = NULL;
725 break;
726 default:
727 assert(0);
728 }
729 }
730
731 /* ================================================== */
732
733 static void
init_message_nonaddress(SCK_Message * message)734 init_message_nonaddress(SCK_Message *message)
735 {
736 message->data = NULL;
737 message->length = 0;
738 message->if_index = INVALID_IF_INDEX;
739
740 UTI_ZeroTimespec(&message->timestamp.kernel);
741 UTI_ZeroTimespec(&message->timestamp.hw);
742 message->timestamp.if_index = INVALID_IF_INDEX;
743 message->timestamp.l2_length = 0;
744 message->timestamp.tx_flags = 0;
745
746 message->descriptor = INVALID_SOCK_FD;
747 }
748
749 /* ================================================== */
750
751 static int
match_cmsg(struct cmsghdr * cmsg,int level,int type,size_t length)752 match_cmsg(struct cmsghdr *cmsg, int level, int type, size_t length)
753 {
754 if (cmsg->cmsg_type == type && cmsg->cmsg_level == level &&
755 (length == 0 || cmsg->cmsg_len == CMSG_LEN(length)))
756 return 1;
757 return 0;
758 }
759
760 /* ================================================== */
761
762 static int
process_header(struct msghdr * msg,int msg_length,int sock_fd,int flags,SCK_Message * message)763 process_header(struct msghdr *msg, int msg_length, int sock_fd, int flags,
764 SCK_Message *message)
765 {
766 struct cmsghdr *cmsg;
767 int r = 1;
768
769 if (msg->msg_namelen <= sizeof (union sockaddr_all) &&
770 msg->msg_namelen > sizeof (((struct sockaddr *)msg->msg_name)->sa_family)) {
771 switch (((struct sockaddr *)msg->msg_name)->sa_family) {
772 case AF_INET:
773 #ifdef FEAT_IPV6
774 case AF_INET6:
775 #endif
776 init_message_addresses(message, SCK_ADDR_IP);
777 SCK_SockaddrToIPSockAddr(msg->msg_name, msg->msg_namelen, &message->remote_addr.ip);
778 break;
779 case AF_UNIX:
780 init_message_addresses(message, SCK_ADDR_UNIX);
781 message->remote_addr.path = ((struct sockaddr_un *)msg->msg_name)->sun_path;
782 break;
783 default:
784 init_message_addresses(message, SCK_ADDR_UNSPEC);
785 DEBUG_LOG("Unexpected address");
786 r = 0;
787 break;
788 }
789 } else {
790 init_message_addresses(message, SCK_ADDR_UNSPEC);
791
792 if (msg->msg_namelen > sizeof (union sockaddr_all)) {
793 DEBUG_LOG("Truncated source address");
794 r = 0;
795 }
796 }
797
798 init_message_nonaddress(message);
799
800 if (msg->msg_iovlen == 1) {
801 message->data = msg->msg_iov[0].iov_base;
802 message->length = msg_length;
803 } else {
804 DEBUG_LOG("Unexpected iovlen");
805 r = 0;
806 }
807
808 if (msg->msg_flags & MSG_TRUNC) {
809 log_message(sock_fd, 1, message, "Truncated", NULL);
810 r = 0;
811 }
812
813 if (msg->msg_flags & MSG_CTRUNC) {
814 log_message(sock_fd, 1, message, "Truncated cmsg in", NULL);
815 r = 0;
816 }
817
818 for (cmsg = CMSG_FIRSTHDR(msg); cmsg; cmsg = CMSG_NXTHDR(msg, cmsg)) {
819 if (0) {
820 }
821 #ifdef HAVE_IN_PKTINFO
822 else if (match_cmsg(cmsg, IPPROTO_IP, IP_PKTINFO, sizeof (struct in_pktinfo))) {
823 struct in_pktinfo ipi;
824
825 if (message->addr_type != SCK_ADDR_IP)
826 init_message_addresses(message, SCK_ADDR_IP);
827
828 memcpy(&ipi, CMSG_DATA(cmsg), sizeof (ipi));
829 message->local_addr.ip.addr.in4 = ntohl(ipi.ipi_addr.s_addr);
830 message->local_addr.ip.family = IPADDR_INET4;
831 message->if_index = ipi.ipi_ifindex;
832 }
833 #elif defined(IP_RECVDSTADDR)
834 else if (match_cmsg(cmsg, IPPROTO_IP, IP_RECVDSTADDR, sizeof (struct in_addr))) {
835 struct in_addr addr;
836
837 if (message->addr_type != SCK_ADDR_IP)
838 init_message_addresses(message, SCK_ADDR_IP);
839
840 memcpy(&addr, CMSG_DATA(cmsg), sizeof (addr));
841 message->local_addr.ip.addr.in4 = ntohl(addr.s_addr);
842 message->local_addr.ip.family = IPADDR_INET4;
843 }
844 #endif
845 #ifdef HAVE_IN6_PKTINFO
846 else if (match_cmsg(cmsg, IPPROTO_IPV6, IPV6_PKTINFO, sizeof (struct in6_pktinfo))) {
847 struct in6_pktinfo ipi;
848
849 if (message->addr_type != SCK_ADDR_IP)
850 init_message_addresses(message, SCK_ADDR_IP);
851
852 memcpy(&ipi, CMSG_DATA(cmsg), sizeof (ipi));
853 memcpy(&message->local_addr.ip.addr.in6, &ipi.ipi6_addr.s6_addr,
854 sizeof (message->local_addr.ip.addr.in6));
855 message->local_addr.ip.family = IPADDR_INET6;
856 message->if_index = ipi.ipi6_ifindex;
857 }
858 #endif
859 #ifdef SCM_TIMESTAMP
860 else if (match_cmsg(cmsg, SOL_SOCKET, SCM_TIMESTAMP, sizeof (struct timeval))) {
861 struct timeval tv;
862
863 memcpy(&tv, CMSG_DATA(cmsg), sizeof (tv));
864 UTI_TimevalToTimespec(&tv, &message->timestamp.kernel);
865 }
866 #endif
867 #ifdef SCM_TIMESTAMPNS
868 else if (match_cmsg(cmsg, SOL_SOCKET, SCM_TIMESTAMPNS, sizeof (message->timestamp.kernel))) {
869 memcpy(&message->timestamp.kernel, CMSG_DATA(cmsg), sizeof (message->timestamp.kernel));
870 }
871 #endif
872 #ifdef HAVE_LINUX_TIMESTAMPING
873 #ifdef HAVE_LINUX_TIMESTAMPING_OPT_PKTINFO
874 else if (match_cmsg(cmsg, SOL_SOCKET, SCM_TIMESTAMPING_PKTINFO,
875 sizeof (struct scm_ts_pktinfo))) {
876 struct scm_ts_pktinfo ts_pktinfo;
877
878 memcpy(&ts_pktinfo, CMSG_DATA(cmsg), sizeof (ts_pktinfo));
879 message->timestamp.if_index = ts_pktinfo.if_index;
880 message->timestamp.l2_length = ts_pktinfo.pkt_length;
881 }
882 #endif
883 else if (match_cmsg(cmsg, SOL_SOCKET, SCM_TIMESTAMPING,
884 sizeof (struct scm_timestamping))) {
885 struct scm_timestamping ts3;
886
887 memcpy(&ts3, CMSG_DATA(cmsg), sizeof (ts3));
888 message->timestamp.kernel = ts3.ts[0];
889 message->timestamp.hw = ts3.ts[2];
890 }
891 else if ((match_cmsg(cmsg, SOL_IP, IP_RECVERR, 0) ||
892 match_cmsg(cmsg, SOL_IPV6, IPV6_RECVERR, 0)) &&
893 cmsg->cmsg_len >= CMSG_LEN(sizeof (struct sock_extended_err))) {
894 struct sock_extended_err err;
895
896 memcpy(&err, CMSG_DATA(cmsg), sizeof (err));
897
898 if (err.ee_errno != ENOMSG || err.ee_info != SCM_TSTAMP_SND ||
899 err.ee_origin != SO_EE_ORIGIN_TIMESTAMPING) {
900 log_message(sock_fd, 1, message, "Unexpected extended error in", NULL);
901 r = 0;
902 }
903 }
904 #endif
905 else if (match_cmsg(cmsg, SOL_SOCKET, SCM_RIGHTS, 0)) {
906 if (!(flags & SCK_FLAG_MSG_DESCRIPTOR) || cmsg->cmsg_len != CMSG_LEN(sizeof (int))) {
907 int i, fd;
908
909 DEBUG_LOG("Unexpected SCM_RIGHTS");
910 for (i = 0; CMSG_LEN((i + 1) * sizeof (int)) <= cmsg->cmsg_len; i++) {
911 memcpy(&fd, (char *)CMSG_DATA(cmsg) + i * sizeof (int), sizeof (fd));
912 close(fd);
913 }
914 r = 0;
915 } else {
916 memcpy(&message->descriptor, CMSG_DATA(cmsg), sizeof (message->descriptor));
917 }
918 }
919 else {
920 DEBUG_LOG("Unexpected control message level=%d type=%d len=%d",
921 cmsg->cmsg_level, cmsg->cmsg_type, (int)cmsg->cmsg_len);
922 }
923 }
924
925 if (!r && message->descriptor != INVALID_SOCK_FD)
926 close(message->descriptor);
927
928 return r;
929 }
930
931 /* ================================================== */
932
933 static SCK_Message *
receive_messages(int sock_fd,int flags,int max_messages,int * num_messages)934 receive_messages(int sock_fd, int flags, int max_messages, int *num_messages)
935 {
936 struct MessageHeader *hdr;
937 SCK_Message *messages;
938 unsigned int i, n, n_ok;
939 int ret, recv_flags = 0;
940
941 assert(initialised);
942
943 *num_messages = 0;
944
945 if (max_messages < 1)
946 return NULL;
947
948 /* Prepare used buffers for new messages */
949 prepare_buffers(received_messages);
950 received_messages = 0;
951
952 messages = ARR_GetElements(recv_sck_messages);
953
954 hdr = ARR_GetElements(recv_headers);
955 n = ARR_GetSize(recv_headers);
956 n = MIN(n, max_messages);
957
958 if (n < 1 || n > MAX_RECV_MESSAGES ||
959 n > ARR_GetSize(recv_messages) || n > ARR_GetSize(recv_sck_messages))
960 assert(0);
961
962 recv_flags = get_recv_flags(flags);
963
964 #ifdef HAVE_RECVMMSG
965 ret = recvmmsg(sock_fd, hdr, n, recv_flags, NULL);
966 if (ret >= 0)
967 n = ret;
968 #else
969 n = 1;
970 ret = recvmsg(sock_fd, &hdr[0].msg_hdr, recv_flags);
971 if (ret >= 0)
972 hdr[0].msg_len = ret;
973 #endif
974
975 if (ret < 0) {
976 handle_recv_error(sock_fd, flags);
977 return NULL;
978 }
979
980 received_messages = n;
981
982 for (i = n_ok = 0; i < n; i++) {
983 hdr = ARR_GetElement(recv_headers, i);
984 if (!process_header(&hdr->msg_hdr, hdr->msg_len, sock_fd, flags, &messages[n_ok]))
985 continue;
986
987 log_message(sock_fd, 1, &messages[n_ok],
988 flags & SCK_FLAG_MSG_ERRQUEUE ? "Received error" : "Received", NULL);
989
990 n_ok++;
991 }
992
993 *num_messages = n_ok;
994
995 return n_ok > 0 ? messages : NULL;
996 }
997
998 /* ================================================== */
999
1000 static void *
add_control_message(struct msghdr * msg,int level,int type,size_t length,size_t buf_length)1001 add_control_message(struct msghdr *msg, int level, int type, size_t length, size_t buf_length)
1002 {
1003 struct cmsghdr *cmsg;
1004 size_t cmsg_space;
1005
1006 /* Avoid using CMSG_NXTHDR as the one in glibc does not support adding
1007 control messages: https://sourceware.org/bugzilla/show_bug.cgi?id=13500 */
1008
1009 cmsg = msg->msg_control;
1010 cmsg_space = CMSG_SPACE(length);
1011
1012 if (!cmsg || length > buf_length || msg->msg_controllen + cmsg_space > buf_length) {
1013 DEBUG_LOG("Could not add control message level=%d type=%d", level, type);
1014 return NULL;
1015 }
1016
1017 cmsg = (struct cmsghdr *)((char *)cmsg + msg->msg_controllen);
1018
1019 memset(cmsg, 0, cmsg_space);
1020
1021 cmsg->cmsg_level = level;
1022 cmsg->cmsg_type = type;
1023 cmsg->cmsg_len = CMSG_LEN(length);
1024
1025 msg->msg_controllen += cmsg_space;
1026
1027 return CMSG_DATA(cmsg);
1028 }
1029
1030 /* ================================================== */
1031
1032 static int
send_message(int sock_fd,SCK_Message * message,int flags)1033 send_message(int sock_fd, SCK_Message *message, int flags)
1034 {
1035 struct cmsghdr cmsg_buf[CMSG_BUF_SIZE / sizeof (struct cmsghdr)];
1036 union sockaddr_all saddr;
1037 socklen_t saddr_len;
1038 struct msghdr msg;
1039 struct iovec iov;
1040
1041 switch (message->addr_type) {
1042 case SCK_ADDR_UNSPEC:
1043 saddr_len = 0;
1044 break;
1045 case SCK_ADDR_IP:
1046 saddr_len = SCK_IPSockAddrToSockaddr(&message->remote_addr.ip,
1047 (struct sockaddr *)&saddr, sizeof (saddr));
1048 break;
1049 case SCK_ADDR_UNIX:
1050 memset(&saddr, 0, sizeof (saddr));
1051 if (snprintf(saddr.un.sun_path, sizeof (saddr.un.sun_path), "%s",
1052 message->remote_addr.path) >= sizeof (saddr.un.sun_path)) {
1053 DEBUG_LOG("Unix socket path %s too long", message->remote_addr.path);
1054 return 0;
1055 }
1056 saddr.un.sun_family = AF_UNIX;
1057 saddr_len = sizeof (saddr.un);
1058 break;
1059 default:
1060 assert(0);
1061 }
1062
1063 if (saddr_len) {
1064 msg.msg_name = &saddr.un;
1065 msg.msg_namelen = saddr_len;
1066 } else {
1067 msg.msg_name = NULL;
1068 msg.msg_namelen = 0;
1069 }
1070
1071 if (message->length < 0) {
1072 DEBUG_LOG("Invalid length %d", message->length);
1073 return 0;
1074 }
1075
1076 iov.iov_base = message->data;
1077 iov.iov_len = message->length;
1078 msg.msg_iov = &iov;
1079 msg.msg_iovlen = 1;
1080 msg.msg_control = cmsg_buf;
1081 msg.msg_controllen = 0;
1082 msg.msg_flags = 0;
1083
1084 if (message->addr_type == SCK_ADDR_IP) {
1085 if (message->local_addr.ip.family == IPADDR_INET4) {
1086 #ifdef HAVE_IN_PKTINFO
1087 struct in_pktinfo *ipi;
1088
1089 ipi = add_control_message(&msg, IPPROTO_IP, IP_PKTINFO, sizeof (*ipi),
1090 sizeof (cmsg_buf));
1091 if (!ipi)
1092 return 0;
1093
1094 ipi->ipi_spec_dst.s_addr = htonl(message->local_addr.ip.addr.in4);
1095 if (message->if_index != INVALID_IF_INDEX)
1096 ipi->ipi_ifindex = message->if_index;
1097
1098 #elif defined(IP_SENDSRCADDR)
1099 struct in_addr *addr;
1100
1101 addr = add_control_message(&msg, IPPROTO_IP, IP_SENDSRCADDR, sizeof (*addr),
1102 sizeof (cmsg_buf));
1103 if (!addr)
1104 return 0;
1105
1106 addr->s_addr = htonl(message->local_addr.ip.addr.in4);
1107 #endif
1108 }
1109
1110 #ifdef HAVE_IN6_PKTINFO
1111 if (message->local_addr.ip.family == IPADDR_INET6) {
1112 struct in6_pktinfo *ipi;
1113
1114 ipi = add_control_message(&msg, IPPROTO_IPV6, IPV6_PKTINFO, sizeof (*ipi),
1115 sizeof (cmsg_buf));
1116 if (!ipi)
1117 return 0;
1118
1119 memcpy(&ipi->ipi6_addr.s6_addr, &message->local_addr.ip.addr.in6,
1120 sizeof(ipi->ipi6_addr.s6_addr));
1121 if (message->if_index != INVALID_IF_INDEX)
1122 ipi->ipi6_ifindex = message->if_index;
1123 }
1124 #endif
1125 }
1126
1127 #ifdef HAVE_LINUX_TIMESTAMPING
1128 if (message->timestamp.tx_flags) {
1129 int *ts_tx_flags;
1130
1131 /* Set timestamping flags for this message */
1132
1133 ts_tx_flags = add_control_message(&msg, SOL_SOCKET, SO_TIMESTAMPING,
1134 sizeof (*ts_tx_flags), sizeof (cmsg_buf));
1135 if (!ts_tx_flags)
1136 return 0;
1137
1138 *ts_tx_flags = message->timestamp.tx_flags;
1139 }
1140 #endif
1141
1142 if (flags & SCK_FLAG_MSG_DESCRIPTOR) {
1143 int *fd;
1144
1145 fd = add_control_message(&msg, SOL_SOCKET, SCM_RIGHTS, sizeof (*fd), sizeof (cmsg_buf));
1146 if (!fd)
1147 return 0;
1148
1149 *fd = message->descriptor;
1150 }
1151
1152 /* This is apparently required on some systems */
1153 if (msg.msg_controllen == 0)
1154 msg.msg_control = NULL;
1155
1156 if (sendmsg(sock_fd, &msg, 0) < 0) {
1157 log_message(sock_fd, -1, message, "Could not send", strerror(errno));
1158 return 0;
1159 }
1160
1161 log_message(sock_fd, -1, message, "Sent", NULL);
1162
1163 return 1;
1164 }
1165
1166 /* ================================================== */
1167
1168 void
SCK_Initialise(int family)1169 SCK_Initialise(int family)
1170 {
1171 ip4_enabled = family == IPADDR_INET4 || family == IPADDR_UNSPEC;
1172 #ifdef FEAT_IPV6
1173 ip6_enabled = family == IPADDR_INET6 || family == IPADDR_UNSPEC;
1174 #else
1175 ip6_enabled = 0;
1176 #endif
1177
1178 recv_messages = ARR_CreateInstance(sizeof (struct Message));
1179 ARR_SetSize(recv_messages, MAX_RECV_MESSAGES);
1180 recv_headers = ARR_CreateInstance(sizeof (struct MessageHeader));
1181 ARR_SetSize(recv_headers, MAX_RECV_MESSAGES);
1182 recv_sck_messages = ARR_CreateInstance(sizeof (SCK_Message));
1183 ARR_SetSize(recv_sck_messages, MAX_RECV_MESSAGES);
1184
1185 received_messages = MAX_RECV_MESSAGES;
1186
1187 priv_bind_function = NULL;
1188
1189 supported_socket_flags = 0;
1190 #ifdef SOCK_CLOEXEC
1191 if (check_socket_flag(SOCK_CLOEXEC, FD_CLOEXEC, 0))
1192 supported_socket_flags |= SOCK_CLOEXEC;
1193 #endif
1194 #ifdef SOCK_NONBLOCK
1195 if (check_socket_flag(SOCK_NONBLOCK, 0, O_NONBLOCK))
1196 supported_socket_flags |= SOCK_NONBLOCK;
1197 #endif
1198
1199 initialised = 1;
1200 }
1201
1202 /* ================================================== */
1203
1204 void
SCK_Finalise(void)1205 SCK_Finalise(void)
1206 {
1207 ARR_DestroyInstance(recv_sck_messages);
1208 ARR_DestroyInstance(recv_headers);
1209 ARR_DestroyInstance(recv_messages);
1210
1211 initialised = 0;
1212 }
1213
1214 /* ================================================== */
1215
1216 int
SCK_IsIpFamilyEnabled(int family)1217 SCK_IsIpFamilyEnabled(int family)
1218 {
1219 switch (family) {
1220 case IPADDR_INET4:
1221 return ip4_enabled;
1222 case IPADDR_INET6:
1223 return ip6_enabled;
1224 default:
1225 return 0;
1226 }
1227 }
1228
1229 /* ================================================== */
1230
1231 void
SCK_GetAnyLocalIPAddress(int family,IPAddr * local_addr)1232 SCK_GetAnyLocalIPAddress(int family, IPAddr *local_addr)
1233 {
1234 local_addr->family = family;
1235
1236 switch (family) {
1237 case IPADDR_INET4:
1238 local_addr->addr.in4 = INADDR_ANY;
1239 break;
1240 case IPADDR_INET6:
1241 #ifdef FEAT_IPV6
1242 memcpy(&local_addr->addr.in6, &in6addr_any, sizeof (local_addr->addr.in6));
1243 #else
1244 memset(&local_addr->addr.in6, 0, sizeof (local_addr->addr.in6));
1245 #endif
1246 break;
1247 }
1248 }
1249
1250 /* ================================================== */
1251
1252 void
SCK_GetLoopbackIPAddress(int family,IPAddr * local_addr)1253 SCK_GetLoopbackIPAddress(int family, IPAddr *local_addr)
1254 {
1255 local_addr->family = family;
1256
1257 switch (family) {
1258 case IPADDR_INET4:
1259 local_addr->addr.in4 = INADDR_LOOPBACK;
1260 break;
1261 case IPADDR_INET6:
1262 #ifdef FEAT_IPV6
1263 memcpy(&local_addr->addr.in6, &in6addr_loopback, sizeof (local_addr->addr.in6));
1264 #else
1265 memset(&local_addr->addr.in6, 0, sizeof (local_addr->addr.in6));
1266 local_addr->addr.in6[15] = 1;
1267 #endif
1268 break;
1269 }
1270 }
1271
1272 /* ================================================== */
1273
1274 int
SCK_IsLinkLocalIPAddress(IPAddr * addr)1275 SCK_IsLinkLocalIPAddress(IPAddr *addr)
1276 {
1277 switch (addr->family) {
1278 case IPADDR_INET4:
1279 /* 169.254.0.0/16 */
1280 return (addr->addr.in4 & 0xffff0000) == 0xa9fe0000;
1281 case IPADDR_INET6:
1282 /* fe80::/10 */
1283 return addr->addr.in6[0] == 0xfe && (addr->addr.in6[1] & 0xc0) == 0x80;
1284 default:
1285 return 0;
1286 }
1287 }
1288
1289 /* ================================================== */
1290
1291 void
SCK_SetPrivBind(int (* function)(int sock_fd,struct sockaddr * address,socklen_t address_len))1292 SCK_SetPrivBind(int (*function)(int sock_fd, struct sockaddr *address,
1293 socklen_t address_len))
1294 {
1295 priv_bind_function = function;
1296 }
1297
1298 /* ================================================== */
1299
1300 int
SCK_OpenUdpSocket(IPSockAddr * remote_addr,IPSockAddr * local_addr,const char * iface,int flags)1301 SCK_OpenUdpSocket(IPSockAddr *remote_addr, IPSockAddr *local_addr, const char *iface, int flags)
1302 {
1303 return open_ip_socket(remote_addr, local_addr, iface, SOCK_DGRAM, flags);
1304 }
1305
1306 /* ================================================== */
1307
1308 int
SCK_OpenTcpSocket(IPSockAddr * remote_addr,IPSockAddr * local_addr,const char * iface,int flags)1309 SCK_OpenTcpSocket(IPSockAddr *remote_addr, IPSockAddr *local_addr, const char *iface, int flags)
1310 {
1311 return open_ip_socket(remote_addr, local_addr, iface, SOCK_STREAM, flags);
1312 }
1313
1314 /* ================================================== */
1315
1316 int
SCK_OpenUnixDatagramSocket(const char * remote_addr,const char * local_addr,int flags)1317 SCK_OpenUnixDatagramSocket(const char *remote_addr, const char *local_addr, int flags)
1318 {
1319 return open_unix_socket(remote_addr, local_addr, SOCK_DGRAM, flags);
1320 }
1321
1322 /* ================================================== */
1323
1324 int
SCK_OpenUnixStreamSocket(const char * remote_addr,const char * local_addr,int flags)1325 SCK_OpenUnixStreamSocket(const char *remote_addr, const char *local_addr, int flags)
1326 {
1327 return open_unix_socket(remote_addr, local_addr, SOCK_STREAM, flags);
1328 }
1329
1330 /* ================================================== */
1331
1332 int
SCK_OpenUnixSocketPair(int flags,int * other_fd)1333 SCK_OpenUnixSocketPair(int flags, int *other_fd)
1334 {
1335 int sock_fd;
1336
1337 /* Prefer SEQPACKET sockets over DGRAM in order to receive a zero-length
1338 message (end of file) when the other end is unexpectedly closed */
1339 if (
1340 #ifdef SOCK_SEQPACKET
1341 (sock_fd = open_unix_socket_pair(SOCK_SEQPACKET, flags, other_fd)) < 0 &&
1342 #endif
1343 (sock_fd = open_unix_socket_pair(SOCK_DGRAM, flags, other_fd)) < 0)
1344 return INVALID_SOCK_FD;
1345
1346 return sock_fd;
1347 }
1348
1349 /* ================================================== */
1350
1351 int
SCK_SetIntOption(int sock_fd,int level,int name,int value)1352 SCK_SetIntOption(int sock_fd, int level, int name, int value)
1353 {
1354 if (setsockopt(sock_fd, level, name, &value, sizeof (value)) < 0) {
1355 DEBUG_LOG("setsockopt() failed fd=%d level=%d name=%d value=%d : %s",
1356 sock_fd, level, name, value, strerror(errno));
1357 return 0;
1358 }
1359
1360 return 1;
1361 }
1362
1363 /* ================================================== */
1364
1365 int
SCK_GetIntOption(int sock_fd,int level,int name,int * value)1366 SCK_GetIntOption(int sock_fd, int level, int name, int *value)
1367 {
1368 socklen_t len = sizeof (*value);
1369
1370 if (getsockopt(sock_fd, level, name, value, &len) < 0) {
1371 DEBUG_LOG("getsockopt() failed fd=%d level=%d name=%d : %s",
1372 sock_fd, level, name, strerror(errno));
1373 return 0;
1374 }
1375
1376 return 1;
1377 }
1378
1379 /* ================================================== */
1380
1381 int
SCK_EnableKernelRxTimestamping(int sock_fd)1382 SCK_EnableKernelRxTimestamping(int sock_fd)
1383 {
1384 #ifdef SO_TIMESTAMPNS
1385 if (SCK_SetIntOption(sock_fd, SOL_SOCKET, SO_TIMESTAMPNS, 1))
1386 return 1;
1387 #endif
1388 #ifdef SO_TIMESTAMP
1389 if (SCK_SetIntOption(sock_fd, SOL_SOCKET, SO_TIMESTAMP, 1))
1390 return 1;
1391 #endif
1392
1393 return 0;
1394 }
1395
1396 /* ================================================== */
1397
1398 int
SCK_ListenOnSocket(int sock_fd,int backlog)1399 SCK_ListenOnSocket(int sock_fd, int backlog)
1400 {
1401 if (listen(sock_fd, backlog) < 0) {
1402 DEBUG_LOG("listen() failed : %s", strerror(errno));
1403 return 0;
1404 }
1405
1406 return 1;
1407 }
1408
1409 /* ================================================== */
1410
1411 int
SCK_AcceptConnection(int sock_fd,IPSockAddr * remote_addr)1412 SCK_AcceptConnection(int sock_fd, IPSockAddr *remote_addr)
1413 {
1414 union sockaddr_all saddr;
1415 socklen_t saddr_len = sizeof (saddr);
1416 int conn_fd;
1417
1418 conn_fd = accept(sock_fd, &saddr.sa, &saddr_len);
1419 if (conn_fd < 0) {
1420 DEBUG_LOG("accept() failed : %s", strerror(errno));
1421 return INVALID_SOCK_FD;
1422 }
1423
1424 if (!UTI_FdSetCloexec(conn_fd) || !set_socket_nonblock(conn_fd)) {
1425 close(conn_fd);
1426 return INVALID_SOCK_FD;
1427 }
1428
1429 SCK_SockaddrToIPSockAddr(&saddr.sa, saddr_len, remote_addr);
1430
1431 return conn_fd;
1432 }
1433
1434 /* ================================================== */
1435
1436 int
SCK_ShutdownConnection(int sock_fd)1437 SCK_ShutdownConnection(int sock_fd)
1438 {
1439 if (shutdown(sock_fd, SHUT_RDWR) < 0) {
1440 DEBUG_LOG("shutdown() failed : %s", strerror(errno));
1441 return 0;
1442 }
1443
1444 return 1;
1445 }
1446
1447 /* ================================================== */
1448
1449 int
SCK_Receive(int sock_fd,void * buffer,int length,int flags)1450 SCK_Receive(int sock_fd, void *buffer, int length, int flags)
1451 {
1452 int r;
1453
1454 if (length < 0) {
1455 DEBUG_LOG("Invalid length %d", length);
1456 return -1;
1457 }
1458
1459 r = recv(sock_fd, buffer, length, get_recv_flags(flags));
1460
1461 if (r < 0) {
1462 handle_recv_error(sock_fd, flags);
1463 return r;
1464 }
1465
1466 DEBUG_LOG("Received data fd=%d len=%d", sock_fd, r);
1467
1468 return r;
1469 }
1470
1471 /* ================================================== */
1472
1473 int
SCK_Send(int sock_fd,const void * buffer,int length,int flags)1474 SCK_Send(int sock_fd, const void *buffer, int length, int flags)
1475 {
1476 int r;
1477
1478 assert(flags == 0);
1479
1480 if (length < 0) {
1481 DEBUG_LOG("Invalid length %d", length);
1482 return -1;
1483 }
1484
1485 r = send(sock_fd, buffer, length, 0);
1486
1487 if (r < 0) {
1488 DEBUG_LOG("Could not send data fd=%d len=%d : %s", sock_fd, length, strerror(errno));
1489 return r;
1490 }
1491
1492 DEBUG_LOG("Sent data fd=%d len=%d", sock_fd, r);
1493
1494 return r;
1495 }
1496
1497 /* ================================================== */
1498
1499 SCK_Message *
SCK_ReceiveMessage(int sock_fd,int flags)1500 SCK_ReceiveMessage(int sock_fd, int flags)
1501 {
1502 int num_messages;
1503
1504 return receive_messages(sock_fd, flags, 1, &num_messages);
1505 }
1506
1507 /* ================================================== */
1508
1509 SCK_Message *
SCK_ReceiveMessages(int sock_fd,int flags,int * num_messages)1510 SCK_ReceiveMessages(int sock_fd, int flags, int *num_messages)
1511 {
1512 return receive_messages(sock_fd, flags, MAX_RECV_MESSAGES, num_messages);
1513 }
1514
1515 /* ================================================== */
1516
1517 void
SCK_InitMessage(SCK_Message * message,SCK_AddressType addr_type)1518 SCK_InitMessage(SCK_Message *message, SCK_AddressType addr_type)
1519 {
1520 init_message_addresses(message, addr_type);
1521 init_message_nonaddress(message);
1522 }
1523
1524 /* ================================================== */
1525
1526 int
SCK_SendMessage(int sock_fd,SCK_Message * message,int flags)1527 SCK_SendMessage(int sock_fd, SCK_Message *message, int flags)
1528 {
1529 return send_message(sock_fd, message, flags);
1530 }
1531
1532 /* ================================================== */
1533
1534 int
SCK_RemoveSocket(int sock_fd)1535 SCK_RemoveSocket(int sock_fd)
1536 {
1537 union sockaddr_all saddr;
1538 socklen_t saddr_len;
1539
1540 saddr_len = sizeof (saddr);
1541
1542 if (getsockname(sock_fd, &saddr.sa, &saddr_len) < 0) {
1543 DEBUG_LOG("getsockname() failed : %s", strerror(errno));
1544 return 0;
1545 }
1546
1547 if (saddr_len > sizeof (saddr) || saddr_len <= sizeof (saddr.sa.sa_family) ||
1548 saddr.sa.sa_family != AF_UNIX)
1549 return 0;
1550
1551 if (unlink(saddr.un.sun_path) < 0) {
1552 DEBUG_LOG("Could not remove %s : %s", saddr.un.sun_path, strerror(errno));
1553 return 0;
1554 }
1555
1556 return 1;
1557 }
1558
1559 /* ================================================== */
1560
1561 void
SCK_CloseSocket(int sock_fd)1562 SCK_CloseSocket(int sock_fd)
1563 {
1564 close(sock_fd);
1565 }
1566
1567 /* ================================================== */
1568
1569 void
SCK_SockaddrToIPSockAddr(struct sockaddr * sa,int sa_length,IPSockAddr * ip_sa)1570 SCK_SockaddrToIPSockAddr(struct sockaddr *sa, int sa_length, IPSockAddr *ip_sa)
1571 {
1572 ip_sa->ip_addr.family = IPADDR_UNSPEC;
1573 ip_sa->port = 0;
1574
1575 switch (sa->sa_family) {
1576 case AF_INET:
1577 if (sa_length < (int)sizeof (struct sockaddr_in))
1578 return;
1579 ip_sa->ip_addr.family = IPADDR_INET4;
1580 ip_sa->ip_addr.addr.in4 = ntohl(((struct sockaddr_in *)sa)->sin_addr.s_addr);
1581 ip_sa->port = ntohs(((struct sockaddr_in *)sa)->sin_port);
1582 break;
1583 #ifdef FEAT_IPV6
1584 case AF_INET6:
1585 if (sa_length < (int)sizeof (struct sockaddr_in6))
1586 return;
1587 ip_sa->ip_addr.family = IPADDR_INET6;
1588 memcpy(&ip_sa->ip_addr.addr.in6, ((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr,
1589 sizeof (ip_sa->ip_addr.addr.in6));
1590 ip_sa->port = ntohs(((struct sockaddr_in6 *)sa)->sin6_port);
1591 break;
1592 #endif
1593 default:
1594 break;
1595 }
1596 }
1597
1598 /* ================================================== */
1599
1600 int
SCK_IPSockAddrToSockaddr(IPSockAddr * ip_sa,struct sockaddr * sa,int sa_length)1601 SCK_IPSockAddrToSockaddr(IPSockAddr *ip_sa, struct sockaddr *sa, int sa_length)
1602 {
1603 switch (ip_sa->ip_addr.family) {
1604 case IPADDR_INET4:
1605 if (sa_length < (int)sizeof (struct sockaddr_in))
1606 return 0;
1607 memset(sa, 0, sizeof (struct sockaddr_in));
1608 sa->sa_family = AF_INET;
1609 ((struct sockaddr_in *)sa)->sin_addr.s_addr = htonl(ip_sa->ip_addr.addr.in4);
1610 ((struct sockaddr_in *)sa)->sin_port = htons(ip_sa->port);
1611 #ifdef SIN6_LEN
1612 ((struct sockaddr_in *)sa)->sin_len = sizeof (struct sockaddr_in);
1613 #endif
1614 return sizeof (struct sockaddr_in);
1615 #ifdef FEAT_IPV6
1616 case IPADDR_INET6:
1617 if (sa_length < (int)sizeof (struct sockaddr_in6))
1618 return 0;
1619 memset(sa, 0, sizeof (struct sockaddr_in6));
1620 sa->sa_family = AF_INET6;
1621 memcpy(&((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr, ip_sa->ip_addr.addr.in6,
1622 sizeof (((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr));
1623 ((struct sockaddr_in6 *)sa)->sin6_port = htons(ip_sa->port);
1624 #ifdef SIN6_LEN
1625 ((struct sockaddr_in6 *)sa)->sin6_len = sizeof (struct sockaddr_in6);
1626 #endif
1627 return sizeof (struct sockaddr_in6);
1628 #endif
1629 default:
1630 if (sa_length < (int)sizeof (struct sockaddr))
1631 return 0;
1632 memset(sa, 0, sizeof (struct sockaddr));
1633 sa->sa_family = AF_UNSPEC;
1634 return 0;
1635 }
1636 }
1637