mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 14:48:21 +00:00
Switch one's complement checksum implementation
Borrows the `in_cksum` code from tcpdump, which borrowed from FreeBSD. It handles unaligned data better and also unrolls the inner loop to process 16 two-byte values at a time versus 2 one-byte values at a time in the previous version. Generally measured as ~1.5x faster in a release build. The new API should generally be more amenable to any future optimization explorations since all relevant data blocks are available within a single call rather than spread across multiple.
This commit is contained in:
parent
8feca7291b
commit
d070709c57
12 changed files with 283 additions and 74 deletions
|
@ -121,7 +121,54 @@ ZEEK_FORWARD_DECLARE_NAMESPACED(IP_Hdr, zeek);
|
|||
|
||||
namespace zeek {
|
||||
|
||||
// Returns the ones-complement checksum of a chunk of b short-aligned bytes.
|
||||
namespace detail {
|
||||
|
||||
struct checksum_block {
|
||||
const uint8_t* block;
|
||||
int len;
|
||||
};
|
||||
|
||||
struct ipv4_pseudo_hdr {
|
||||
in_addr src;
|
||||
in_addr dst;
|
||||
uint8_t zero;
|
||||
uint8_t next_proto;
|
||||
uint16_t len;
|
||||
};
|
||||
|
||||
struct ipv6_pseudo_hdr {
|
||||
in6_addr src;
|
||||
in6_addr dst;
|
||||
uint32_t len;
|
||||
uint8_t zero[3];
|
||||
uint8_t next_proto;
|
||||
};
|
||||
|
||||
extern uint16_t in_cksum(const checksum_block* blocks, int num_blocks);
|
||||
|
||||
inline uint16_t in_cksum(const uint8_t* data, int len)
|
||||
{
|
||||
checksum_block cb{data, len};
|
||||
return in_cksum(&cb, 1);
|
||||
}
|
||||
|
||||
extern uint16_t ip4_in_cksum(const IPAddr& src, const IPAddr& dst,
|
||||
uint8_t next_proto, const uint8_t* data, int len);
|
||||
|
||||
extern uint16_t ip6_in_cksum(const IPAddr& src, const IPAddr& dst,
|
||||
uint8_t next_proto, const uint8_t* data, int len);
|
||||
|
||||
inline uint16_t ip_in_cksum(bool is_ipv4, const IPAddr& src, const IPAddr& dst,
|
||||
uint8_t next_proto, const uint8_t* data, int len)
|
||||
{
|
||||
if ( is_ipv4 )
|
||||
return ip4_in_cksum(src, dst, next_proto, data, len);
|
||||
return ip6_in_cksum(src, dst, next_proto, data, len);
|
||||
}
|
||||
|
||||
} // namespace zeek::detail
|
||||
|
||||
// Returns the ones-complement checksum of a chunk of 'b' bytes.
|
||||
extern int ones_complement_checksum(const void* p, int b, uint32_t sum);
|
||||
|
||||
extern int ones_complement_checksum(const IPAddr& a, uint32_t sum);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue