chiark / gitweb /
sd-dhcp: avoid checksum calculation if possible
authorTom Gundersen <teg@jklm.no>
Sun, 30 Mar 2014 18:36:44 +0000 (20:36 +0200)
committerTom Gundersen <teg@jklm.no>
Sun, 30 Mar 2014 18:46:40 +0000 (20:46 +0200)
When receiving lots of packets that are not meant for us, we waste a relatively large amount
of cpu time computing their checksums before discarding them. Move the checksum calculation last
so we never compute it for packets which would otherwise be discarded.

src/libsystemd-network/dhcp-packet.c

index 3b62c2572f52608f7990b64bb20355319ca6a21a..4f90c283a21485a686b18704dbf1227b2a058d46 100644 (file)
@@ -155,11 +155,6 @@ int dhcp_packet_verify_headers(DHCPPacket *packet, size_t len, bool checksum) {
                 return -EINVAL;
         }
 
-        if (dhcp_packet_checksum(&packet->ip, hdrlen)) {
-                log_dhcp_client(client, "ignoring packet: invalid IP checksum");
-                return -EINVAL;
-        }
-
         /* UDP */
 
         if (packet->ip.protocol != IPPROTO_UDP) {
@@ -181,6 +176,22 @@ int dhcp_packet_verify_headers(DHCPPacket *packet, size_t len, bool checksum) {
                 return -EINVAL;
         }
 
+        if (be16toh(packet->udp.dest) != DHCP_PORT_CLIENT) {
+                log_dhcp_client(client, "ignoring packet: to port %u, which "
+                                "is not the DHCP client port (%u)",
+                                be16toh(packet->udp.dest), DHCP_PORT_CLIENT);
+                return -EINVAL;
+        }
+
+        /* checksums - computing these is relatively expensive, so only do it
+           if all the other checks have passed
+         */
+
+        if (dhcp_packet_checksum(&packet->ip, hdrlen)) {
+                log_dhcp_client(client, "ignoring packet: invalid IP checksum");
+                return -EINVAL;
+        }
+
         if (checksum && packet->udp.check) {
                 packet->ip.check = packet->udp.len;
                 packet->ip.ttl = 0;
@@ -192,12 +203,5 @@ int dhcp_packet_verify_headers(DHCPPacket *packet, size_t len, bool checksum) {
                 }
         }
 
-        if (be16toh(packet->udp.dest) != DHCP_PORT_CLIENT) {
-                log_dhcp_client(client, "ignoring packet: to port %u, which "
-                                "is not the DHCP client port (%u)",
-                                be16toh(packet->udp.dest), DHCP_PORT_CLIENT);
-                return -EINVAL;
-        }
-
         return 0;
 }