]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #1249 in SNORT/snort3 from perf_tcp_checksum to master
authorRuss Combs (rucombs) <rucombs@cisco.com>
Fri, 1 Jun 2018 16:45:51 +0000 (12:45 -0400)
committerRuss Combs (rucombs) <rucombs@cisco.com>
Fri, 1 Jun 2018 16:45:51 +0000 (12:45 -0400)
Squashed commit of the following:

commit d5fe88236b17cf464a65f68e5bad5b9451c43060
Author: davis mcpherson <davmcphe.cisco.com>
Date:   Fri May 25 09:11:56 2018 -0400

    decode: alternate checksum calculation to improve runtime performance

src/codecs/ip/checksum.h

index 90b0fb64fc5afc67717062c2a2b820d7c29c0b0c..b4095e2fecc28928942ae13411be0340a9be4761 100644 (file)
@@ -91,7 +91,20 @@ inline uint16_t cksum_add(const uint16_t* buf, std::size_t len, uint32_t cksum)
 {
     const uint16_t* sp = buf;
 
-    if (len > 1 )
+    // if pointer is 16 bit aligned calculate checksum in tight loop...
+    // gcc 5.4 -O3 generates unaligned quadword instructions that crash; fixed in gcc 8.0.1
+    if ( !( reinterpret_cast<std::uintptr_t>(sp) & 0x01 ) )
+    {
+        while ( len > 1 )
+        {
+            cksum += *sp++;
+            len -= 2;
+        }
+        // if len was odd, sum in the last byte...
+        if ( len )
+            cksum += (uint16_t) *(const uint8_t *)sp;
+    }
+    else if ( len > 1 )
     {
         std::size_t sn = ((len / 2) & 0xF);  // == len/2 % 16
         std::size_t n = (((len / 2) + 15) / 16);   // ceiling of (len / 2) / 16
@@ -155,11 +168,11 @@ inline uint16_t cksum_add(const uint16_t* buf, std::size_t len, uint32_t cksum)
             cksum += sp[15];
             sp += 16;
         }
+        // if len is odd, sum in the last byte...
+        if ( len & 0x01)
+            cksum += (uint16_t) *(const uint8_t *)sp;
     }
 
-    if (len & 1)
-        cksum += (*(const unsigned char*)sp);
-
     cksum  = (cksum >> 16) + (cksum & 0x0000ffff);
     cksum += (cksum >> 16);