]> git.ipfire.org Git - thirdparty/chrony.git/commitdiff
cmdmon: fix responding to IPv4 addresses on FreeBSD
authorMiroslav Lichvar <mlichvar@redhat.com>
Tue, 2 Mar 2021 12:10:13 +0000 (13:10 +0100)
committerMiroslav Lichvar <mlichvar@redhat.com>
Thu, 4 Mar 2021 11:36:36 +0000 (12:36 +0100)
On FreeBSD, the source address cannot be specified when sending a
message on a socket bound to a non-any IPv4 address, e.g. in default
configuration 127.0.0.1. In this case, make the address unspecified.

This is similar to commit 6af39d63aa93 ("ntp: don't use IP_SENDSRCADDR
on bound socket").

Fixes: f06c1cfa97f8 ("cmdmon: respond from same address")
cmdmon.c

index afdfa6cd9334e3d5eff42c16bb3f510bcb138954..b85bae8ecf55e5220c976a1f82a4b0a00165315f 100644 (file)
--- a/cmdmon.c
+++ b/cmdmon.c
@@ -62,6 +62,9 @@ static int sock_fdu;
 static int sock_fd4;
 static int sock_fd6;
 
+/* Flag indicating the IPv4 socket is bound to an address */
+static int bound_sock_fd4;
+
 /* Flag indicating whether this module has been initialised or not */
 static int initialised = 0;
 
@@ -179,6 +182,9 @@ open_socket(int family)
         return INVALID_SOCK_FD;
       }
 
+      if (family == IPADDR_INET4)
+        bound_sock_fd4 = local_addr.ip_addr.addr.in4 != INADDR_ANY;
+
       break;
     case IPADDR_UNSPEC:
       local_path = CNF_GetBindCommandPath();
@@ -244,6 +250,8 @@ CAM_Initialise(void)
 
   initialised = 1;
 
+  bound_sock_fd4 = 0;
+
   sock_fdu = INVALID_SOCK_FD;
   sock_fd4 = open_socket(IPADDR_INET4);
   sock_fd6 = open_socket(IPADDR_INET6);
@@ -310,6 +318,12 @@ transmit_reply(int sock_fd, int request_length, SCK_Message *message)
       !SCK_IsLinkLocalIPAddress(&message->remote_addr.ip.ip_addr))
     message->if_index = INVALID_IF_INDEX;
 
+#if !defined(HAVE_IN_PKTINFO) && defined(IP_SENDSRCADDR)
+  /* On FreeBSD a local IPv4 address cannot be specified on bound socket */
+  if (message->local_addr.ip.family == IPADDR_INET4 && (sock_fd != sock_fd4 || bound_sock_fd4))
+    message->local_addr.ip.family = IPADDR_UNSPEC;
+#endif
+
   if (!SCK_SendMessage(sock_fd, message, 0))
     return;
 }