The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
socket.c
Go to the documentation of this file.
1 /*
2  * This program is is free software; you can redistribute it and/or modify
3  * it under the terms of the GNU General Public License as published by
4  * the Free Software Foundation; either version 2 of the License, or (at
5  * your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
15  */
16 
17 /** Functions for establishing and managing low level sockets
18  *
19  * @file src/lib/util/socket.c
20  *
21  * @author Arran Cudbard-Bell (a.cudbardb@freeradius.org)
22  * @author Alan DeKok (aland@freeradius.org)
23  *
24  * @copyright 2015 The FreeRADIUS project
25  */
26 
27 #include <freeradius-devel/util/debug.h>
28 #include <freeradius-devel/util/misc.h>
29 #include <freeradius-devel/util/socket.h>
30 #include <freeradius-devel/util/strerror.h>
31 #include <freeradius-devel/util/syserror.h>
32 #include <freeradius-devel/util/udpfromto.h>
33 #include <freeradius-devel/util/value.h>
34 #include <freeradius-devel/util/cap.h>
35 
36 #include <fcntl.h>
37 #include <sys/socket.h>
38 #include <ifaddrs.h>
39 
40 /** Resolve a named service to a port
41  *
42  * @param[in] proto The protocol. Either IPPROTO_TCP or IPPROTO_UDP.
43  * @param[in] port_name The service name, i.e. "radius".
44  * @return
45  * - > 0 the port port_name resolves to.
46  * - < 0 on error.
47  */
48 static int socket_port_from_service(int proto, char const *port_name)
49 {
50  struct servent *service;
51  char const *proto_name;
52 
53  if (!port_name) {
54  fr_strerror_const("No port specified");
55  return -1;
56  }
57 
58  switch (proto) {
59  case IPPROTO_UDP:
60  proto_name = "udp";
61  break;
62 
63  case IPPROTO_TCP:
64  proto_name = "tcp";
65  break;
66 
67 #ifdef IPPROTO_SCTP
68  case IPPROTO_SCTP:
69  proto_name = "sctp";
70  break;
71 #endif
72 
73  default:
74  fr_strerror_printf("Unrecognised proto %i", proto);
75  return -1;
76  }
77 
78  service = getservbyname(port_name, proto_name);
79  if (!service) {
80  fr_strerror_printf("Unknown service %s", port_name);
81  return -1;
82  }
83 
84  return ntohs(service->s_port);
85 }
86 
87 #ifdef FD_CLOEXEC
88 static int socket_dont_inherit(int sockfd)
89 {
90  int ret;
91 
92  /*
93  * We don't want child processes inheriting these
94  * file descriptors.
95  */
96  ret = fcntl(sockfd, F_GETFD);
97  if (ret >= 0) {
98  if (fcntl(sockfd, F_SETFD, ret | FD_CLOEXEC) < 0) {
99  fr_strerror_printf("Failed setting close on exec: %s", fr_syserror(errno));
100  return -1;
101  }
102  }
103 
104  return 0;
105 }
106 #else
108 {
109  return 0;
110 }
111 #endif
112 
113 #ifdef HAVE_STRUCT_SOCKADDR_IN6
114 /** Restrict wildcard sockets to v6 only
115  *
116  * If we don't do this we get v4 and v6 packets coming in on the same
117  * socket, which is weird.
118  *
119  * @param[in] sockfd to modify.
120  * @param[in] ipaddr we will be binding to.
121  * @return
122  * - 0 on success.
123  * - -1 on failure.
124  */
125 static int socket_inaddr_any_v6only(int sockfd, fr_ipaddr_t const *ipaddr)
126 {
127  /*
128  * Listening on '::' does NOT get you IPv4 to
129  * IPv6 mapping. You've got to listen on an IPv4
130  * address, too. This makes the rest of the server
131  * design a little simpler.
132  */
133  if (ipaddr->af == AF_INET6) {
134 # ifdef IPV6_V6ONLY
135  /* unconst for emscripten/musl */
136  if (IN6_IS_ADDR_UNSPECIFIED(UNCONST(struct in6_addr *, &ipaddr->addr.v6))) {
137  int on = 1;
138 
139  if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_V6ONLY,
140  (char *)&on, sizeof(on)) < 0) {
141  fr_strerror_printf("Failed setting socket to IPv6 only: %s", fr_syserror(errno));
142  close(sockfd);
143  return -1;
144  }
145  }
146 # endif /* IPV6_V6ONLY */
147  }
148  return 0;
149 }
150 #else
152 {
153  return 0;
154 }
155 #endif
156 
157 #if (defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)) || defined(IP_DONTFRAG)
158 /** Set the don't fragment bit
159  *
160  * @param[in] sockfd to set don't fragment bit for.
161  * @param[in] af of the socket.
162  * @return
163  * - 0 on success.
164  * - -1 on failure.
165  */
166 static int socket_dont_fragment(int sockfd, int af)
167 {
168  /*
169  * Set the "don't fragment" flag on UDP sockets. Most
170  * routers don't have good support for fragmented UDP
171  * packets.
172  */
173  if (af == AF_INET) {
174  int flag;
175 
176 # if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
177  /*
178  * Disable PMTU discovery. On Linux, this
179  * also makes sure that the "don't fragment"
180  * flag is zero.
181  */
182  flag = IP_PMTUDISC_DONT;
183 
184  if (setsockopt(sockfd, IPPROTO_IP, IP_MTU_DISCOVER, &flag, sizeof(flag)) < 0) {
185  fr_strerror_printf("Failed disabling PMTU discovery: %s", fr_syserror(errno));
186  return -1;
187  }
188 # endif
189 
190 # if defined(IP_DONTFRAG)
191  /*
192  * Ensure that the "don't fragment" flag is zero.
193  */
194  flag = 0;
195 
196  if (setsockopt(sockfd, IPPROTO_IP, IP_DONTFRAG, &flag, sizeof(flag)) < 0) {
197  fr_strerror_printf("Failed setting don't fragment flag: %s", fr_syserror(errno));
198  return -1;
199  }
200 # endif
201  }
202 
203  return 0;
204 }
205 #else
206 static int socket_dont_fragment(UNUSED int sockfd, UNUSED int af)
207 {
208  return 0;
209 }
210 #endif /* lots of things */
211 
212 /** Bind a UDP/TCP v4/v6 socket to a given ipaddr src port, and interface.
213  *
214  * Use one of:
215  * - fr_socket_server_udp - for non-connected socket.
216  * - fr_socket_server_tcp
217  * ...to open a file descriptor, then call this function to bind the socket to an IP address.
218  *
219  * @param[in] sockfd the socket which opened by fr_socket_server_*.
220  * @param[in] ifname to bind to.
221  * @param[in,out] src_ipaddr The IP address to bind to. Will be updated to the IP address
222  * that was actually bound to. Pass NULL to just bind to an interface.
223  * @param[in] src_port the port to bind to. NULL if any port is allowed.
224 
225  * @return
226  * - 0 on success
227  * - -1 on failure.
228  */
229 int fr_socket_bind(int sockfd, char const *ifname, fr_ipaddr_t *src_ipaddr, uint16_t *src_port)
230 {
231  int ret;
232  uint16_t my_port = 0;
234  struct sockaddr_storage salocal;
235  socklen_t salen;
236 
237  /*
238  * Clear the thread local error stack as we may
239  * push multiple errors onto the stack, and this
240  * is likely to be the function which returns
241  * the "original" error.
242  */
244 
245  if (src_port) my_port = *src_port;
246  if (src_ipaddr) {
247  my_ipaddr = *src_ipaddr;
248  } else {
249  my_ipaddr = (fr_ipaddr_t) {
250  .af = AF_UNSPEC
251  };
252  }
253 
254 #ifdef HAVE_CAPABILITY_H
255  /*
256  * If we're binding to a special port as non-root, then
257  * check capabilities. If we're root, we already have
258  * equivalent capabilities so we don't need to check.
259  */
260  if (src_port && (*src_port < 1024) && (geteuid() != 0)) {
261  (void)fr_cap_enable(CAP_NET_BIND_SERVICE, CAP_EFFECTIVE); /* Sets error on failure, which will be seen if the bind fails */
262  }
263 #endif
264 
265  /*
266  * Bind to a device BEFORE touching IP addresses.
267  */
268  if (ifname) {
269 #ifdef HAVE_NET_IF_H
270  unsigned int scope_id;
271 
272  scope_id = if_nametoindex(ifname);
273  if (!scope_id) {
274  fr_strerror_printf_push("Failed finding interface %s: %s", ifname, fr_syserror(errno));
275  return -1;
276  }
277 
278  /*
279  * If the scope ID hasn't already been set, then
280  * set it. This allows us to get the scope from the interface name.
281  */
282  if ((my_ipaddr.scope_id != 0) && (scope_id != my_ipaddr.scope_id)) {
283  fr_strerror_printf_push("Cannot bind to interface %s: Socket is already bound "
284  "to another interface", ifname);
285  return -1;
286  }
287 #endif
288 
289 #ifdef SO_BINDTODEVICE
290  /*
291  * The caller didn't specify a scope_id, but we
292  * have one from above. Call "bind to device",
293  * and set the scope_id.
294  */
295  if (!my_ipaddr.scope_id) {
296  /*
297  * The internet hints that CAP_NET_RAW
298  * is required to use SO_BINDTODEVICE.
299  *
300  * This function also sets fr_strerror()
301  * on failure, which will be seen if the
302  * bind fails. If the bind succeeds,
303  * then we don't really care that the
304  * capability change has failed. We must
305  * already have that capability.
306  */
307 #ifdef HAVE_CAPABILITY_H
308  (void)fr_cap_enable(CAP_NET_RAW, CAP_EFFECTIVE);
309 #endif
310  ret = setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE, ifname, strlen(ifname));
311  if (ret < 0) {
312  fr_strerror_printf_push("Failed binding socket to interface %s: %s",
313  ifname, fr_syserror(errno));
314  return -1;
315  } /* else it worked. */
316 
317  /*
318  * Set the scope ID.
319  */
320  my_ipaddr.scope_id = scope_id;
321  }
322 
323  /*
324  * SO_BINDTODEVICE succeeded, so we're always
325  * bound to the socket.
326  */
327 
328 #elif defined(IP_BOUND_IF) || defined(IPV6_BOUND_IF)
329  {
330  int idx = scope_id;
331 
332  if (my_ipaddr.af == AF_INET) {
333  if (unlikely(setsockopt(sockfd, IPPROTO_IP, IP_BOUND_IF, &idx, sizeof(idx)) < 0)) {
334  error:
335  fr_strerror_printf_push("Failed binding socket to interface %s: %s",
336  ifname, fr_syserror(errno));
337  return -1;
338  }
339 
340  } else if (my_ipaddr.af == AF_INET6) {
341  if (unlikely(setsockopt(sockfd, IPPROTO_IPV6, IPV6_BOUND_IF, &idx, sizeof(idx)) < 0)) goto error;
342 
343  } else {
344  fr_strerror_printf("Invalid address family for 'interface = ...'");
345  return -1;
346  }
347 
348  my_ipaddr.scope_id = scope_id;
349  }
350 
351 #else
352  {
353  struct ifaddrs *list = NULL;
354  bool bound = false;
355 
356  /*
357  * Troll through all interfaces to see if there's
358  */
359  if (getifaddrs(&list) == 0) {
360  struct ifaddrs *i;
361 
362  for (i = list; i != NULL; i = i->ifa_next) {
363  if (i->ifa_addr && i->ifa_name && (strcmp(i->ifa_name, ifname) == 0)) {
364  /*
365  * IPv4, and there's either no src_ip, OR src_ip is INADDR_ANY,
366  * it's a match.
367  *
368  * We also update my_ipaddr to point to this particular IP,
369  * so that we can later bind() to it. This gets us the same
370  * effect as SO_BINDTODEVICE.
371  */
372  if ((i->ifa_addr->sa_family == AF_INET) &&
373  (!src_ipaddr || fr_ipaddr_is_inaddr_any(src_ipaddr))) {
374  (void) fr_ipaddr_from_sockaddr(&my_ipaddr, NULL,
375  (struct sockaddr_storage *) i->ifa_addr,
376  sizeof(struct sockaddr_in));
377  my_ipaddr.scope_id = scope_id;
378  bound = true;
379  break;
380  }
381 
382  /*
383  * The caller specified a source IP, and we find a matching
384  * address family. Allow it.
385  *
386  * Note that we do NOT check for matching IPs here. If we did,
387  * then binding to an interface and the *wrong* IP would get us
388  * a "bind to device is unsupported" message.
389  *
390  * Instead we say "yes, we found a matching interface", and then
391  * allow the bind() call below to run. If that fails, we get a
392  * "Can't assign requested address" error, which is more informative.
393  */
394  if (src_ipaddr && (src_ipaddr->af == i->ifa_addr->sa_family)) {
395  my_ipaddr.scope_id = scope_id;
396  bound = true;
397  break;
398  }
399  }
400  }
401 
402  freeifaddrs(list);
403 
404  if (!bound) {
405  /*
406  * IPv4: no link local addresses,
407  * and no bind to device.
408  */
409  fr_strerror_printf_push("Bind to interface %s failed: Unable to match "
410  "interface with the given IP address.", ifname);
411  return -1;
412  }
413  } else {
414  fr_strerror_printf_push("Bind to interface %s failed, unable to get list of interfaces: %s",
415  ifname, fr_syserror(errno));
416  return -1;
417  }
418  }
419 #endif
420  } /* else no interface was passed in */
421 
422  /*
423  * Don't bind to an IP address if there's no src IP address.
424  */
425  if (my_ipaddr.af == AF_UNSPEC) goto done;
426 
427  /*
428  * Set up sockaddr stuff.
429  */
430  if (fr_ipaddr_to_sockaddr(&salocal, &salen, &my_ipaddr, my_port) < 0) return -1;
431 
432  ret = bind(sockfd, (struct sockaddr *) &salocal, salen);
433  if (ret < 0) {
434  fr_strerror_printf_push("Bind failed with source address %pV:%pV on interface %s: %s",
435  src_ipaddr ? fr_box_ipaddr(*src_ipaddr) : fr_box_strvalue("*"),
436  src_port ? fr_box_int16(*src_port) : fr_box_strvalue("*"),
437  ifname ? ifname : "*",
438  fr_syserror(errno));
439  return ret;
440  }
441 
442  if (!src_port) goto done;
443 
444  /*
445  * FreeBSD jail issues. We bind to 0.0.0.0, but the
446  * kernel instead binds us to a 1.2.3.4. So once the
447  * socket is bound, ask it what it's IP address is.
448  */
449  salen = sizeof(salocal);
450  memset(&salocal, 0, salen);
451  if (getsockname(sockfd, (struct sockaddr *) &salocal, &salen) < 0) {
452  fr_strerror_printf_push("Failed getting socket name: %s", fr_syserror(errno));
453  return -1;
454  }
455 
456  if (fr_ipaddr_from_sockaddr(&my_ipaddr, &my_port, &salocal, salen) < 0) return -1;
457  *src_port = my_port;
458  *src_ipaddr = my_ipaddr;
459 
460 done:
461 #ifdef HAVE_CAPABILITY_H
462  /*
463  * Clear any errors we may have produced in the
464  * capabilities check.
465  */
467 #endif
468  return 0;
469 }
470 
471 #ifdef HAVE_SYS_UN_H
472 /** Open a Unix socket
473  *
474  * @note If the file doesn't exist then errno will be set to ENOENT.
475  *
476  * The following code demonstrates using this function with a connection timeout:
477  @code {.c}
478  sockfd = fr_socket_client_unix(path, true);
479  if (sockfd < 0) {
480  fr_perror();
481  fr_exit_now(1);
482  }
483  if ((errno == EINPROGRESS) && (fr_socket_wait_for_connect(sockfd, timeout) < 0)) {
484  error:
485  fr_perror();
486  close(sockfd);
487  goto error;
488  }
489  //Optionally, if blocking operation is required
490  if (fr_blocking(sockfd) < 0) goto error;
491  @endcode
492  *
493  * @param path to the file bound to the unix socket.
494  * @param async Whether to set the socket to nonblocking, allowing use of
495  * #fr_socket_wait_for_connect.
496  * @return
497  * - Socket FD on success.
498  * - -1 on failure.
499  */
500 int fr_socket_client_unix(char const *path, bool async)
501 {
502  int sockfd = -1;
503  size_t len;
504  socklen_t socklen;
505  struct sockaddr_un saremote;
506 
507  len = strlen(path);
508  if (len >= sizeof(saremote.sun_path)) {
509  fr_strerror_printf("Path too long, maximum length is %zu", sizeof(saremote.sun_path) - 1);
510  errno = EINVAL;
511  return -1;
512  }
513 
514  sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
515  if (sockfd < 0) {
516  fr_strerror_printf("Failed creating UNIX socket: %s", fr_syserror(errno));
517  return -1;
518  }
519 
520  if (async && (fr_nonblock(sockfd) < 0)) {
521  close(sockfd);
522  return -1;
523  }
524 
525  saremote.sun_family = AF_UNIX;
526  memcpy(saremote.sun_path, path, len + 1); /* SUN_LEN does strlen */
527 
528  socklen = SUN_LEN(&saremote);
529 
530  /*
531  * Although we ignore SIGPIPE, some operating systems
532  * like BSD and OSX ignore the ignoring.
533  *
534  * Fortunately, those operating systems usually support
535  * SO_NOSIGPIPE, to prevent them raising the signal in
536  * the first place.
537  */
538 #ifdef SO_NOSIGPIPE
539  {
540  int set = 1;
541 
542  setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, (void *)&set, sizeof(int));
543  }
544 #endif
545 
546  if (connect(sockfd, (struct sockaddr *)&saremote, socklen) < 0) {
547  /*
548  * POSIX says the only time we will get this,
549  * is if the socket has been marked as
550  * nonblocking. This is not an error, the caller
551  * must check the state of errno, and wait for
552  * the connection to complete.
553  */
554  if (errno == EINPROGRESS) return sockfd;
555 
556  close(sockfd);
557  fr_strerror_printf("Failed connecting to %s: %s", path, fr_syserror(errno));
558 
559  return -1;
560  }
561  return sockfd;
562 }
563 #else
564 int fr_socket_client_unix(UNUSED char const *path, UNUSED bool async)
565 {
566  fprintf(stderr, "Unix domain sockets not supported on this system");
567  return -1;
568 }
569 #endif /* WITH_SYS_UN_H */
570 
571 #if defined SO_BINDTODEVICE || defined IP_BOUND_IF
572 static inline CC_HINT(always_inline) int socket_bind_ifname(int sockfd, char const *ifname)
573 #else
574 static inline CC_HINT(always_inline) int socket_bind_ifname(UNUSED int sockfd, UNUSED char const *ifname)
575 #endif
576 {
577 #if defined(SO_BINDTODEVICE)
578  if (setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE, ifname, strlen(ifname)) < 0) {
579  fr_strerror_printf("Failed binding socket to %s: %s", ifname, fr_syserror(errno));
580  return -1;
581  }
582 #elif defined(IP_BOUND_IF)
583  {
584  int idx = if_nametoindex(ifname);
585  if (idx == 0) {
586  error:
587  fr_strerror_printf("Failed binding socket to %s: %s", ifname, fr_syserror(errno));
588  return -1;
589  }
590  if (unlikely(setsockopt(sockfd, IPPROTO_IP, IP_BOUND_IF, &idx, sizeof(idx)) < 0)) goto error;
591  }
592 #else
593  fr_strerror_const("Binding sockets to interfaces not supported on this platform");
594  return -1;
595 #endif
596 
597  return 0;
598 }
599 
600 /** Establish a connected UDP socket
601  *
602  * Connected UDP sockets can be used with write(), unlike unconnected sockets
603  * which must be used with sendto and recvfrom.
604  *
605  * The following code demonstrates using this function with a connection timeout:
606  @code {.c}
607  sockfd = fr_socket_client_udp(NULL, NULL, NULL, ipaddr, port, true);
608  if (sockfd < 0) {
609  fr_perror();
610  fr_exit_now(1);
611  }
612  if ((errno == EINPROGRESS) && (fr_socket_wait_for_connect(sockfd, timeout) < 0)) {
613  error:
614  fr_perror();
615  close(sockfd);
616  goto error;
617  }
618  //Optionally, if blocking operation is required
619  if (fr_blocking(sockfd) < 0) goto error;
620  @endcode
621  *
622  * @param[in] ifname If non-NULL, bind the socket to this interface.
623  * @param[in,out] src_ipaddr to bind socket to, may be NULL if socket is not bound to any specific
624  * address. If non-null, the bound IP is copied here, too.
625  * @param[out] src_port The source port we were bound to, may be NULL.
626  * @param[in] dst_ipaddr Where to send datagrams.
627  * @param[in] dst_port Where to send datagrams.
628  * @param[in] async Whether to set the socket to nonblocking, allowing use of
629  * #fr_socket_wait_for_connect.
630  * @return
631  * - FD on success.
632  * - -1 on failure.
633  */
634 int fr_socket_client_udp(char const *ifname, fr_ipaddr_t *src_ipaddr, uint16_t *src_port,
635  fr_ipaddr_t const *dst_ipaddr, uint16_t dst_port, bool async)
636 {
637  int sockfd;
638  struct sockaddr_storage salocal;
639  socklen_t salen;
640 
641  if (!dst_ipaddr) return -1;
642 
643  sockfd = socket(dst_ipaddr->af, SOCK_DGRAM, 0);
644  if (sockfd < 0) {
645  fr_strerror_printf("Error creating UDP socket: %s", fr_syserror(errno));
646  return -1;
647  }
648 
649  if (async && (fr_nonblock(sockfd) < 0)) {
650  error:
651  close(sockfd);
652  return -1;
653  }
654 
655  /*
656  * Although we ignore SIGPIPE, some operating systems
657  * like BSD and OSX ignore the ignoring.
658  *
659  * Fortunately, those operating systems usually support
660  * SO_NOSIGPIPE, to prevent them raising the signal in
661  * the first place.
662  */
663 #ifdef SO_NOSIGPIPE
664  {
665  int set = 1;
666 
667  setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, (void *)&set, sizeof(int));
668  }
669 #endif
670 
671  if (unlikely(fr_socket_bind(sockfd, ifname, src_ipaddr, src_port) < 0)) goto error;
672 
673  /*
674  * And now get our destination
675  */
676  if (fr_ipaddr_to_sockaddr(&salocal, &salen, dst_ipaddr, dst_port) < 0) {
677  close(sockfd);
678  return -1;
679  }
680 
681  if (connect(sockfd, (struct sockaddr *) &salocal, salen) < 0) {
682  /*
683  * POSIX says the only time we will get this,
684  * is if the socket has been marked as
685  * nonblocking. This is not an error, the caller
686  * must check the state of errno, and wait for
687  * the connection to complete.
688  */
689  if (errno == EINPROGRESS) return sockfd;
690 
691  fr_strerror_printf("Failed connecting socket: %s", fr_syserror(errno));
692  close(sockfd);
693  return -1;
694  }
695 
696  return sockfd;
697 }
698 
699 /** Establish a connected TCP socket
700  *
701  * The following code demonstrates using this function with a connection timeout:
702  @code {.c}
703  sockfd = fr_socket_client_tcp(NULL, NULL, ipaddr, port, true);
704  if (sockfd < 0) {
705  fr_perror();
706  fr_exit_now(1);
707  }
708  if ((errno == EINPROGRESS) && (fr_socket_wait_for_connect(sockfd, timeout) < 0)) {
709  error:
710  fr_perror();
711  close(sockfd);
712  goto error;
713  }
714  //Optionally, if blocking operation is required
715  if (fr_blocking(sockfd) < 0) goto error;
716  @endcode
717  *
718  * @param[in] ifname If non-NULL, bind the socket to this interface.
719  * @param src_ipaddr to bind socket to, may be NULL if socket is not bound to any specific
720  * address.
721  * @param dst_ipaddr Where to connect to.
722  * @param dst_port Where to connect to.
723  * @param async Whether to set the socket to nonblocking, allowing use of
724  * #fr_socket_wait_for_connect.
725  * @return
726  * - FD on success
727  * - -1 on failure.
728  */
729 int fr_socket_client_tcp(char const *ifname, fr_ipaddr_t *src_ipaddr,
730  fr_ipaddr_t const *dst_ipaddr, uint16_t dst_port, bool async)
731 {
732  int sockfd;
733  struct sockaddr_storage salocal;
734  socklen_t salen;
735 
736  if (!dst_ipaddr) return -1;
737 
738  sockfd = socket(dst_ipaddr->af, SOCK_STREAM, 0);
739  if (sockfd < 0) {
740  fr_strerror_printf("Error creating TCP socket: %s", fr_syserror(errno));
741  return sockfd;
742  }
743 
744  if (async && (fr_nonblock(sockfd) < 0)) {
745  error:
746  close(sockfd);
747  return -1;
748  }
749 
750  if (unlikely(fr_socket_bind(sockfd, ifname, src_ipaddr, NULL) < 0)) goto error;
751 
752  if (fr_ipaddr_to_sockaddr(&salocal, &salen, dst_ipaddr, dst_port) < 0) {
753  close(sockfd);
754  return -1;
755  }
756 
757  /*
758  * Although we ignore SIGPIPE, some operating systems
759  * like BSD and OSX ignore the ignoring.
760  *
761  * Fortunately, those operating systems usually support
762  * SO_NOSIGPIPE, to prevent them raising the signal in
763  * the first place.
764  */
765 #ifdef SO_NOSIGPIPE
766  {
767  int set = 1;
768 
769  setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, (void *)&set, sizeof(int));
770  }
771 #endif
772 
773  if (connect(sockfd, (struct sockaddr *) &salocal, salen) < 0) {
774  /*
775  * POSIX says the only time we will get this,
776  * is if the socket has been marked as
777  * nonblocking. This is not an error, the caller
778  * must check the state of errno, and wait for
779  * the connection to complete.
780  */
781  if (errno == EINPROGRESS) return sockfd;
782 
783  fr_strerror_printf("Failed connecting socket: %s", fr_syserror(errno));
784  close(sockfd);
785  return -1;
786  }
787 
788  return sockfd;
789 }
790 
791 /** Wait for a socket to be connected, with an optional timeout
792  *
793  * @note On error the caller is expected to ``close(sockfd)``.
794  *
795  * @param sockfd the socket to wait on.
796  * @param timeout How long to wait for socket to open.
797  * @return
798  * - 0 on success.
799  * - -1 on connection error.
800  * - -2 on timeout.
801  * - -3 on select error.
802  */
804 {
805  int ret;
806  fd_set error_set;
807  fd_set write_set; /* POSIX says sockets are open when they become writable */
808 
809  FD_ZERO(&error_set);
810  FD_ZERO(&write_set);
811 
812  FD_SET(sockfd, &error_set);
813  FD_SET(sockfd, &write_set);
814 
815  /* Don't let signals mess up the select */
816  do {
817  ret = select(sockfd + 1, NULL, &write_set, &error_set, &fr_time_delta_to_timeval(timeout));
818  } while ((ret == -1) && (errno == EINTR));
819 
820  switch (ret) {
821  case 1: /* ok (maybe) */
822  {
823  int error;
824  socklen_t socklen = sizeof(error);
825 
826  if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (void *)&error, &socklen)) {
827  fr_strerror_printf("Failed connecting socket: %s", fr_syserror(errno));
828  return -1;
829  }
830 
831  if (FD_ISSET(sockfd, &error_set)) {
832  fr_strerror_const("Failed connecting socket: Unknown error");
833  return -1;
834  }
835  }
836  return 0;
837 
838  case 0: /* timeout */
839  if (!fr_cond_assert(fr_time_delta_ispos(timeout))) return -1;
840  fr_strerror_printf("Connection timed out after %pVs", fr_box_time_delta(timeout));
841  return -2;
842 
843  case -1: /* select error */
844  fr_strerror_printf("Failed waiting for connection: %s", fr_syserror(errno));
845  return -3;
846 
847  default:
848  (void)fr_cond_assert(0);
849  return -1;
850  }
851 }
852 
853 /** Open an IPv4/IPv6 unconnected UDP socket
854  *
855  * Function name is a bit of a misnomer as it can also be used to create client sockets too,
856  * such is the nature of UDP.
857  *
858  * @param[in] src_ipaddr The IP address to listen on
859  * @param[in,out] src_port the port to listen on. If *port == 0, the resolved
860  * service port will be written here.
861  * @param[in] port_name if *port == 0, the name of the port
862  * @param[in] async whether we block or not on reads and writes
863  * @return
864  * - Socket FD on success.
865  * - -1 on failure.
866  */
867 int fr_socket_server_udp(fr_ipaddr_t const *src_ipaddr, uint16_t *src_port, char const *port_name, bool async)
868 {
869  int sockfd;
870  uint16_t my_port = 0;
871 
872  if (src_port) my_port = *src_port;
873 
874  /*
875  * Check IP looks OK
876  */
877  if (!src_ipaddr || ((src_ipaddr->af != AF_INET) && (src_ipaddr->af != AF_INET6))) {
878  fr_strerror_const("No address specified");
879  return -1;
880  }
881 
882  /*
883  * Check we have a port value or stuff we can resolve to a port
884  */
885  if (!my_port && port_name) {
886  int ret;
887 
888  ret = socket_port_from_service(IPPROTO_UDP, port_name);
889  if (ret < 0) return -1;
890 
891  my_port = ret;
892  }
893 
894  /*
895  * Open the socket
896  */
897  sockfd = socket(src_ipaddr->af, SOCK_DGRAM, IPPROTO_UDP);
898  if (sockfd < 0) {
899  fr_strerror_printf("Failed creating UDP socket: %s", fr_syserror(errno));
900  return -1;
901  }
902 
903  /*
904  * Make it non-blocking if asked
905  */
906  if (async && (fr_nonblock(sockfd) < 0)) {
907  error:
908  close(sockfd);
909  return -1;
910  }
911 
912  /*
913  * Don't allow child processes to inherit the socket
914  */
915  if (socket_dont_inherit(sockfd) < 0) goto error;
916 
917  /*
918  * Initialize udpfromto for UDP sockets.
919  */
920  if (udpfromto_init(sockfd, src_ipaddr->af) != 0) {
921  fr_strerror_printf("Failed initializing udpfromto: %s", fr_syserror(errno));
922  goto error;
923  }
924 
925  /*
926  * Make sure we don't get v4 and v6 packets on inaddr_any sockets.
927  */
928  if (socket_inaddr_any_v6only(sockfd, src_ipaddr) < 0) goto error;
929 
930  /*
931  * Ensure don't fragment bit is set
932  */
933  if (socket_dont_fragment(sockfd, src_ipaddr->af) < 0) goto error;
934 
935 #ifdef SO_TIMESTAMP
936  {
937  int on = 1;
938 
939  /*
940  * Enable receive timestamps, these should reflect
941  * when the packet was received, not when it was read
942  * from the socket.
943  */
944  if (setsockopt(sockfd, SOL_SOCKET, SO_TIMESTAMP, &on, sizeof(int)) < 0) {
945  close(sockfd);
946  fr_strerror_printf("Failed enabling socket timestamps: %s", fr_syserror(errno));
947  return -1;
948  }
949  }
950 #endif
951 
952  if (src_port) *src_port = my_port;
953 
954  return sockfd;
955 }
956 
957 /** Open an IPv4/IPv6 TCP socket
958  *
959  * @param[in] src_ipaddr The IP address to listen on
960  * @param[in,out] src_port the port to listen on. If *port == 0, the resolved
961  * service port will be written here.
962  * NULL if any port is allowed.
963  * @param[in] port_name if *port == 0, the name of the port
964  * @param[in] async whether we block or not on reads and writes
965  * @return
966  * - Socket FD on success.
967  * - -1 on failure.
968  */
969 int fr_socket_server_tcp(fr_ipaddr_t const *src_ipaddr, uint16_t *src_port, char const *port_name, bool async)
970 {
971  int sockfd;
972  uint16_t my_port = 0;
973 
974  if (src_port) my_port = *src_port;
975 
976  /*
977  * Check IP looks OK
978  */
979  if (!src_ipaddr || ((src_ipaddr->af != AF_INET) && (src_ipaddr->af != AF_INET6))) {
980  fr_strerror_const("No address specified");
981  return -1;
982  }
983 
984  /*
985  * Check we have a port value or stuff we can resolve to a port
986  */
987  if (!my_port && port_name) {
988  int ret;
989 
990  ret = socket_port_from_service(IPPROTO_TCP, port_name);
991  if (ret < 0) return -1;
992 
993  my_port = ret;
994  }
995 
996  /*
997  * Open the socket
998  */
999  sockfd = socket(src_ipaddr->af, SOCK_STREAM, IPPROTO_TCP);
1000  if (sockfd < 0) {
1001  fr_strerror_printf("Failed creating TCP socket: %s", fr_syserror(errno));
1002  return -1;
1003  }
1004 
1005  /*
1006  * Make it non-blocking if asked
1007  */
1008  if (async && (fr_nonblock(sockfd) < 0)) {
1009  error:
1010  close(sockfd);
1011  return -1;
1012  }
1013 
1014  /*
1015  * Don't allow child processes to inherit the socket
1016  */
1017  if (socket_dont_inherit(sockfd) < 0) goto error;
1018 
1019  /*
1020  * Make sure we don't get v4 and v6 packets on inaddr_any sockets.
1021  */
1022  if (socket_inaddr_any_v6only(sockfd, src_ipaddr) < 0) goto error;
1023 
1024  {
1025  int on = 1;
1026 
1027  if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) {
1028  close(sockfd);
1029  fr_strerror_printf("Failed to reuse address: %s", fr_syserror(errno));
1030  return -1;
1031  }
1032  }
1033 
1034  if (src_port) *src_port = my_port;
1035 
1036  return sockfd;
1037 }
#define UNCONST(_type, _ptr)
Remove const qualification from a pointer.
Definition: build.h:165
#define unlikely(_x)
Definition: build.h:378
#define UNUSED
Definition: build.h:313
#define fr_cond_assert(_x)
Calls panic_action ifndef NDEBUG, else logs error and evaluates to value of _x.
Definition: debug.h:137
static int sockfd
Definition: dhcpclient.c:56
static fr_time_delta_t timeout
Definition: dhcpclient.c:54
int fr_ipaddr_from_sockaddr(fr_ipaddr_t *ipaddr, uint16_t *port, struct sockaddr_storage const *sa, socklen_t salen)
Convert sockaddr to our internal ip address representation.
Definition: inet.c:1427
int fr_ipaddr_is_inaddr_any(fr_ipaddr_t const *ipaddr)
Determine if an address is the INADDR_ANY address for its address family.
Definition: inet.c:62
int fr_ipaddr_to_sockaddr(struct sockaddr_storage *sa, socklen_t *salen, fr_ipaddr_t const *ipaddr, uint16_t port)
Convert our internal ip address representation to a sockaddr.
Definition: inet.c:1378
int af
Address family.
Definition: inet.h:64
union fr_ipaddr_t::@121 addr
uint32_t scope_id
A host may have multiple link-local interfaces the scope ID allows the application to specify which o...
Definition: inet.h:70
IPv4/6 prefix.
Definition: merged_model.c:272
unsigned short uint16_t
Definition: merged_model.c:31
int fr_nonblock(UNUSED int fd)
Definition: misc.c:284
static bool done
Definition: radclient.c:80
static uint16_t my_port
Definition: radius1_test.c:74
static fr_ipaddr_t my_ipaddr
Definition: radius1_test.c:73
static char const * proto(int id, int porttype)
Definition: radwho.c:85
#define FD_CLOEXEC
static socket_dont_inherit(UNUSED int sockfd)
Definition: socket.c:107
static int socket_inaddr_any_v6only(UNUSED int sockfd, UNUSED fr_ipaddr_t const *ipaddr)
Definition: socket.c:151
static int socket_port_from_service(int proto, char const *port_name)
Resolve a named service to a port.
Definition: socket.c:48
static int socket_bind_ifname(UNUSED int sockfd, UNUSED char const *ifname)
Definition: socket.c:574
int fr_socket_server_tcp(fr_ipaddr_t const *src_ipaddr, uint16_t *src_port, char const *port_name, bool async)
Open an IPv4/IPv6 TCP socket.
Definition: socket.c:969
int fr_socket_client_udp(char const *ifname, fr_ipaddr_t *src_ipaddr, uint16_t *src_port, fr_ipaddr_t const *dst_ipaddr, uint16_t dst_port, bool async)
Establish a connected UDP socket.
Definition: socket.c:634
int fr_socket_server_udp(fr_ipaddr_t const *src_ipaddr, uint16_t *src_port, char const *port_name, bool async)
Open an IPv4/IPv6 unconnected UDP socket.
Definition: socket.c:867
int fr_socket_client_tcp(char const *ifname, fr_ipaddr_t *src_ipaddr, fr_ipaddr_t const *dst_ipaddr, uint16_t dst_port, bool async)
Establish a connected TCP socket.
Definition: socket.c:729
static int socket_dont_fragment(UNUSED int sockfd, UNUSED int af)
Definition: socket.c:206
int fr_socket_bind(int sockfd, char const *ifname, fr_ipaddr_t *src_ipaddr, uint16_t *src_port)
Bind a UDP/TCP v4/v6 socket to a given ipaddr src port, and interface.
Definition: socket.c:229
int fr_socket_wait_for_connect(int sockfd, fr_time_delta_t timeout)
Wait for a socket to be connected, with an optional timeout.
Definition: socket.c:803
int fr_socket_client_unix(UNUSED char const *path, UNUSED bool async)
Definition: socket.c:564
char const * fr_syserror(int num)
Guaranteed to be thread-safe version of strerror.
Definition: syserror.c:243
#define fr_time_delta_ispos(_a)
Definition: time.h:288
#define fr_time_delta_to_timeval(_delta)
Convert a delta to a timeval.
Definition: time.h:654
A time delta, a difference in time measured in nanoseconds.
Definition: time.h:80
close(uq->fd)
int udpfromto_init(int s, int af)
Definition: udpfromto.c:92
void fr_strerror_clear(void)
Clears all pending messages from the talloc pools.
Definition: strerror.c:577
#define fr_strerror_printf(_fmt,...)
Log to thread local error buffer.
Definition: strerror.h:64
#define fr_strerror_printf_push(_fmt,...)
Add a message to an existing stack of messages at the tail.
Definition: strerror.h:84
#define fr_strerror_const(_msg)
Definition: strerror.h:223
#define fr_box_ipaddr(_val)
Definition: value.h:287
#define fr_box_strvalue(_val)
Definition: value.h:278
#define fr_box_int16(_val)
Definition: value.h:310
#define fr_box_time_delta(_val)
Definition: value.h:336