]> git.ipfire.org Git - thirdparty/ntp.git/commitdiff
Bug #629 Allow certain broadcast packets to be received on the wildcard socket
authorDanny Mayer <mayer@ntp.org>
Sat, 2 Jun 2007 22:30:39 +0000 (18:30 -0400)
committerDanny Mayer <mayer@ntp.org>
Sat, 2 Jun 2007 22:30:39 +0000 (18:30 -0400)
bk: 4661ef8fMY9mjHkM08KokcrZv7HqQg

include/ntp_io.h
include/ntp_request.h
ntpd/ntp_io.c
ntpd/ntp_request.c
ports/winnt/ntpd/ntp_iocompletionport.c

index 983c6c7dce85bb412c8da81b07d6e26f55d304f0..cff1b701f6b872444d255cb3e466f87ddc4fcb8d 100644 (file)
@@ -30,6 +30,7 @@
 # include "win32_io.h"
 #endif
 
+#include <isc/boolean.h>
 /*
  * Define FNDELAY and FASYNC using O_NONBLOCK and O_ASYNC if we need
  * to (and can).  This is here initially for QNX, but may help for
@@ -47,4 +48,6 @@
 # endif
 #endif
 
+isc_boolean_t get_broadcastclient_flag(void); /* Get the status of client broadcast */
+
 #endif
index eb13fadb8fecb87f99c8410ae3823d468bd41933..fe0a11990143d3fd47681715c76caa2fcd34c408 100644 (file)
@@ -6,6 +6,7 @@
 #define _NTP_REQUEST_H
 
 #include "ntp_types.h"
+#include "recvbuff.h"
 
 /*
  * A mode 7 packet is used exchanging data between an NTP server
@@ -923,4 +924,10 @@ struct info_dns_assoc {
        associd_t associd;      /* association ID */
        char hostname[NTP_MAXHOSTNAME]; /* hostname */
 };
+
+/*
+ * function declarations
+ */
+int get_packet_mode(struct recvbuf *rbufp); /* Return packet mode */
+
 #endif /* NTP_REQUEST_H */
index c2b266df608c48964740ffbde1934810ca75b556..44fb53f5c8e5d7c9fa5af80e82e05ea99aa29561 100644 (file)
@@ -133,6 +133,7 @@ struct interface *any_interface;    /* default ipv4 interface */
 struct interface *any6_interface;      /* default ipv6 interface */
 struct interface *loopback_interface;  /* loopback ipv4 interface */
 
+isc_boolean_t  broadcast_client_enabled = ISC_FALSE;   /* is broadcast client enabled */
 int ninterfaces;                       /* Total number of interfaces */
 
 volatile int disable_dynamic_updates;   /* when set to != 0 dynamic updates won't happen */
@@ -758,7 +759,7 @@ add_interface(struct interface *interface)
 }
 
 /*
- * remove interface from known interface list and clean up
+ * remove interface from knoen interface list and clean up
  * associated resources
  */
 static void
@@ -1548,6 +1549,7 @@ socket_broadcast_enable(struct interface *iface, SOCKET fd, struct sockaddr_stor
 #endif
        }
        iface->flags |= INT_BCASTOPEN;
+       broadcast_client_enabled = ISC_TRUE;
        return ISC_TRUE;
 #else
        return ISC_FALSE;
@@ -1575,6 +1577,7 @@ socket_broadcast_disable(struct interface *iface, struct sockaddr_storage *maddr
                }
        }
        iface->flags &= ~INT_BCASTOPEN;
+       broadcast_client_enabled = ISC_FALSE;
        return ISC_TRUE;
 #else
        return ISC_FALSE;
@@ -1582,6 +1585,15 @@ socket_broadcast_disable(struct interface *iface, struct sockaddr_storage *maddr
 }
 
 #endif /* OPEN_BCAST_SOCKET */
+
+/*
+ * return the broadcast client flag value
+ */
+isc_boolean_t
+get_broadcastclient_flag(void)
+{
+       return (broadcast_client_enabled);
+}
 /*
  * Check to see if the address is a multicast address
  */
@@ -2833,6 +2845,7 @@ read_network_packet(SOCKET fd, struct interface *itf, l_fp ts)
 {
        GETSOCKNAME_SOCKLEN_TYPE fromlen;
        int buflen;
+       isc_boolean_t ignore_this;
        register struct recvbuf *rb;
 #ifdef HAVE_TIMESTAMP
        struct msghdr msghdr;
@@ -2849,7 +2862,19 @@ read_network_packet(SOCKET fd, struct interface *itf, l_fp ts)
 
        rb = get_free_recv_buffer();
 
-       if (rb == NULL || itf->ignore_packets == ISC_TRUE)
+       /* For broadcast packet received on the IPv4 wildcard socket
+        * we carve out an exception but only if the client has requested
+        * to receive wildcard sockets
+        */
+       ignore_this = itf->ignore_packets;
+       if (ignore_this == ISC_TRUE && itf->family == AF_INET &&
+           itf->flags == (INT_BROADCAST | INT_WILDCARD) &&
+           get_packet_mode(rb) == MODE_BROADCAST &&
+           get_broadcastclient_flag() == ISC_TRUE
+           )
+           ignore_this = ISC_FALSE;
+
+       if (rb == NULL || ignore_this == ISC_TRUE)
        {
                char buf[RX_BUFF_SIZE];
                struct sockaddr_storage from;
index d9a486c6294480888ecc5730bb2591d186d0afc6..f1cd4bfc69bb0e885c8981a4636f6c4388a5afc4 100644 (file)
@@ -400,6 +400,15 @@ flush_pkt(void)
 
 
 
+/*
+ * Given a buffer, return the packet mode
+ */
+int
+get_packet_mode(struct recvbuf *rbufp)
+{
+       struct req_pkt *inpkt = (struct req_pkt *)&rbufp->recv_pkt;
+       return (INFO_MODE(inpkt->rm_vn_mode));
+}
 /*
  * process_private - process private mode (7) packets
  */
index 39ae4f15ae9363e356fed23a90b3771e4d89d58b..026d5044f91fc73cb9beb08ce1cc30baf0db7cbe 100644 (file)
@@ -16,6 +16,8 @@
 #include "ntp_refclock.h"
 #include "ntp_iocompletionport.h"
 #include "transmitbuff.h"
+#include "ntp_request.h"
+#include "ntp_io.h"
 
 /*
  * Request types
@@ -456,8 +458,12 @@ OnSocketRecv(DWORD i, IoCompletionInfo *lpo, DWORD Bytes, int errstatus)
 {
        struct recvbuf *buff = NULL;
        recvbuf_t *newbuff;
+       isc_boolean_t ignore_this;
+       l_fp arrival_time;
        struct interface * inter = (struct interface *) i;
        
+       get_systime(&arrival_time);     
+
        /*  Convert the overlapped pointer back to a recvbuf pointer.
        */
        
@@ -501,11 +507,23 @@ OnSocketRecv(DWORD i, IoCompletionInfo *lpo, DWORD Bytes, int errstatus)
        }
        else 
        {
+               /* For broadcast packet received on the IPv4 wildcard socket
+                * we carve out an exception but only if the client has requested
+                * to receive wildcard sockets
+                */
+               ignore_this = inter->ignore_packets;
+               if (ignore_this == ISC_TRUE && inter->family == AF_INET &&
+                   inter->flags == (INT_BROADCAST | INT_WILDCARD) &&
+                   get_packet_mode(buff) == MODE_BROADCAST &&
+                   get_broadcastclient_flag() == ISC_TRUE
+                   )
+                       ignore_this = ISC_FALSE;
+
                /*
                 * If we keep it add some info to the structure
                 */
-               if (Bytes > 0 && inter->ignore_packets == ISC_FALSE) {
-                       get_systime(&buff->recv_time);  
+               if (Bytes > 0 && ignore_this == ISC_FALSE) {
+                       memcpy(&buff->recv_time, &arrival_time, sizeof(arrival_time));  
                        buff->recv_length = (int) Bytes;
                        buff->receiver = receive; 
                        buff->dstadr = inter;