]> git.ipfire.org Git - thirdparty/chrony.git/commitdiff
ntp: create new socket for each client request
authorMiroslav Lichvar <mlichvar@redhat.com>
Wed, 13 Aug 2014 16:11:34 +0000 (18:11 +0200)
committerMiroslav Lichvar <mlichvar@redhat.com>
Fri, 15 Aug 2014 08:58:43 +0000 (10:58 +0200)
Create a new connected client socket before each request and close it
when a valid reply is received.

This is useful when the network configuration is changed and the client
socket should be reconnected, but the old bound address remains valid
and sendmsg() doesn't return with an error.

ntp_core.c

index 54e152f3c9d78c816283b747a462ce7a59763d0b..983f7bdf7611cf1dfc8b05070bf5f4b810eb7fd3 100644 (file)
@@ -279,12 +279,17 @@ start_initial_timeout(NCR_Instance inst)
 
     /* Mark source active */
     SRC_SetActive(inst->source);
+  }
+}
 
-    /* Open client socket */
-    if (inst->mode == MODE_CLIENT) {
-      assert(inst->local_addr.sock_fd == INVALID_SOCK_FD);
-      inst->local_addr.sock_fd = NIO_GetClientSocket(&inst->remote_addr);
-    }
+/* ================================================== */
+
+static void
+close_client_socket(NCR_Instance inst)
+{
+  if (inst->mode == MODE_CLIENT && inst->local_addr.sock_fd != INVALID_SOCK_FD) {
+    NIO_CloseClientSocket(inst->local_addr.sock_fd);
+    inst->local_addr.sock_fd = INVALID_SOCK_FD;
   }
 }
 
@@ -305,11 +310,7 @@ take_offline(NCR_Instance inst)
   /* And inactive */
   SRC_UnsetActive(inst->source);
 
-  /* Close client socket */
-  if (inst->mode == MODE_CLIENT && inst->local_addr.sock_fd != INVALID_SOCK_FD) {
-    NIO_CloseClientSocket(inst->local_addr.sock_fd);
-    inst->local_addr.sock_fd = INVALID_SOCK_FD;
-  }
+  close_client_socket(inst);
 
   NCR_ResetInstance(inst);
 }
@@ -328,7 +329,7 @@ NCR_GetInstance(NTP_Remote_Address *remote_addr, NTP_Source_Type type, SourcePar
 
   switch (type) {
     case NTP_SERVER:
-      /* Client socket will be obtained when timer is started */
+      /* Client socket will be obtained when sending request */
       result->local_addr.sock_fd = INVALID_SOCK_FD;
       result->mode = MODE_CLIENT;
       break;
@@ -758,6 +759,13 @@ transmit_timeout(void *arg)
   DEBUG_LOG(LOGF_NtpCore, "Transmit timeout for [%s:%d]",
       UTI_IPToString(&inst->remote_addr.ip_addr), inst->remote_addr.port);
 
+  /* Open new client socket */
+  if (inst->mode == MODE_CLIENT) {
+    close_client_socket(inst);
+    assert(inst->local_addr.sock_fd == INVALID_SOCK_FD);
+    inst->local_addr.sock_fd = NIO_GetClientSocket(&inst->remote_addr);
+  }
+
   /* Check whether we need to 'warm up' the link to the other end by
      sending an echo exchange to ensure both ends' ARP caches are
      primed.  On loaded systems this might also help ensure that bits
@@ -1257,6 +1265,10 @@ receive_packet(NTP_Packet *message, struct timeval *now, double now_err, NCR_Ins
       adjust_poll(inst, 0.1);
     }
 
+    /* If in client mode, no more packets are expected to be coming from the
+       server and the socket can be closed */
+    close_client_socket(inst);
+
     requeue_transmit = 1;
   }