Improved how NAT-T keepalives are handled in sockets/receiver.
authorTobias Brunner <tobias@strongswan.org>
Fri, 24 Feb 2012 10:19:53 +0000 (11:19 +0100)
committerTobias Brunner <tobias@strongswan.org>
Wed, 8 Aug 2012 13:12:24 +0000 (15:12 +0200)
src/libcharon/network/receiver.c
src/libcharon/plugins/socket_default/socket_default_socket.c
src/libcharon/plugins/socket_dynamic/socket_dynamic_socket.c
src/libcharon/plugins/socket_raw/socket_raw_socket.c

index 81dfb70..8240c2a 100644 (file)
@@ -417,6 +417,7 @@ static job_requeue_t receive_packets(private_receiver_t *this)
        host_t *src, *dst;
        status_t status;
        bool supported = TRUE;
+       chunk_t data, marker = chunk_from_chars(0x00, 0x00, 0x00, 0x00);
 
        /* read in a packet */
        status = charon->socket->receive(charon->socket, &packet);
@@ -430,6 +431,19 @@ static job_requeue_t receive_packets(private_receiver_t *this)
                return JOB_REQUEUE_FAIR;
        }
 
+       data = packet->get_data(packet);
+       if (data.len == 1 && data.ptr[0] == 0xFF)
+       {       /* silently drop NAT-T keepalives */
+               packet->destroy(packet);
+               return JOB_REQUEUE_DIRECT;
+       }
+       else if (data.len < marker.len)
+       {       /* drop packets that are too small */
+               DBG3(DBG_NET, "received packet is too short (%d bytes)", data.len);
+               packet->destroy(packet);
+               return JOB_REQUEUE_DIRECT;
+       }
+
        /* if neither source nor destination port is 500 we assume an IKE packet
         * with Non-ESP marker or an ESP packet */
        dst = packet->get_destination(packet);
@@ -437,9 +451,6 @@ static job_requeue_t receive_packets(private_receiver_t *this)
        if (dst->get_port(dst) != IKEV2_UDP_PORT &&
                src->get_port(src) != IKEV2_UDP_PORT)
        {
-               chunk_t marker = chunk_from_chars(0x00, 0x00, 0x00, 0x00), data;
-
-               data = packet->get_data(packet);
                if (memeq(data.ptr, marker.ptr, marker.len))
                {       /* remove Non-ESP marker */
                        data = chunk_skip(data, marker.len);
index b035d57..8da574a 100644 (file)
@@ -48,9 +48,6 @@
 /* Maximum size of a packet */
 #define MAX_PACKET 10000
 
-/* length of non-esp marker */
-#define MARKER_LEN sizeof(u_int32_t)
-
 /* these are not defined on some platforms */
 #ifndef SOL_IP
 #define SOL_IP IPPROTO_IP
@@ -207,13 +204,6 @@ METHOD(socket_t, receiver, status_t,
                }
                DBG3(DBG_NET, "received packet %b", buffer, bytes_read);
 
-               if (bytes_read < MARKER_LEN)
-               {
-                       DBG3(DBG_NET, "received packet too short (%d bytes)",
-                                bytes_read);
-                       return FAILED;
-               }
-
                /* read ancillary data to get destination address */
                for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULL;
                         cmsgptr = CMSG_NXTHDR(&msg, cmsgptr))
index 787f6f4..3c3b17b 100644 (file)
@@ -45,9 +45,6 @@
 /* Maximum size of a packet */
 #define MAX_PACKET 10000
 
-/* length of non-esp marker */
-#define MARKER_LEN sizeof(u_int32_t)
-
 /* these are not defined on some platforms */
 #ifndef SOL_IP
 #define SOL_IP IPPROTO_IP
@@ -225,12 +222,6 @@ static packet_t *receive_packet(private_socket_dynamic_socket_t *this,
        }
        DBG3(DBG_NET, "received packet %b", buffer, (u_int)len);
 
-       if (len < MARKER_LEN)
-       {
-               DBG3(DBG_NET, "received packet too short (%d bytes)", len);
-               return NULL;
-       }
-
        /* read ancillary data to get destination address */
        for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULL;
                 cmsgptr = CMSG_NXTHDR(&msg, cmsgptr))
index 8d0b422..37d13f1 100644 (file)
@@ -172,7 +172,7 @@ METHOD(socket_t, receiver, status_t,
                DBG3(DBG_NET, "received IPv4 packet %b", buffer, bytes_read);
 
                /* read source/dest from raw IP/UDP header */
-               if (bytes_read < IP_LEN + UDP_LEN + MARKER_LEN)
+               if (bytes_read < IP_LEN + UDP_LEN)
                {
                        DBG1(DBG_NET, "received IPv4 packet too short (%d bytes)",
                                 bytes_read);
@@ -226,7 +226,7 @@ METHOD(socket_t, receiver, status_t,
                }
                DBG3(DBG_NET, "received IPv6 packet %b", buffer, bytes_read);
 
-               if (bytes_read < IP_LEN + UDP_LEN + MARKER_LEN)
+               if (bytes_read < IP_LEN + UDP_LEN)
                {
                        DBG3(DBG_NET, "received IPv6 packet too short (%d bytes)",
                                 bytes_read);