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