OpenVPN 3 Core Library
Loading...
Searching...
No Matches
test_csum.cpp
Go to the documentation of this file.
1#include <iostream>
2#include "test_common.hpp"
3
5
7#include <openvpn/ip/csum.hpp>
9
10using namespace openvpn;
11
12std::uint16_t ip_checksum_slow(const void *ip, size_t size)
13{
14 const std::uint16_t *buf = (const std::uint16_t *)ip;
15 std::uint32_t cksum = 0;
16
17 while (size >= sizeof(std::uint16_t))
18 {
19 cksum += *buf++;
20 size -= sizeof(std::uint16_t);
21 }
22
23 if (size)
24 cksum += *(uint8_t *)buf;
25
26 cksum = (cksum >> 16) + (cksum & 0xffff);
27 cksum += (cksum >> 16);
28 return static_cast<uint16_t>(~cksum);
29}
30
31TEST(misc, stress_csum)
32{
33 RandomAPI::Ptr prng(new MTRand);
34 BufferAllocated buf(256);
35
36 for (long i = 0; i < 1000000; ++i)
37 {
38 buf.init_headroom(0);
39 const size_t size = 16 + (prng->rand_get<std::uint8_t>() & 127);
40 std::uint8_t *raw = buf.write_alloc(size);
41 prng->rand_bytes(raw, size);
42 const std::uint16_t orig_csum = IPChecksum::checksum(raw, size);
43 ASSERT_EQ(orig_csum, ip_checksum_slow(raw, size)) << "checksum algorithm inconsistency #1";
44
45 std::uint8_t old_prefix[16];
46 std::memcpy(old_prefix, raw, 16);
47 const int n = (prng->rand_get<std::uint8_t>() & 7);
48 for (int j = 0; j < n; ++j)
49 {
50 const size_t idx = (prng->rand_get<std::uint8_t>() & 15);
51 const std::uint8_t newval = prng->rand_get<std::uint8_t>();
52 raw[idx] = newval;
53 }
54 const std::uint16_t updated_csum = IPChecksum::cfold(IPChecksum::diff16(old_prefix,
55 raw,
56 IPChecksum::cunfold(orig_csum)));
57 const std::uint16_t verify_csum = IPChecksum::checksum(raw, size);
58 ASSERT_EQ(verify_csum, ip_checksum_slow(raw, size)) << "checksum algorithm inconsistency #2";
59 ASSERT_EQ(updated_csum, verify_csum)
60 << i
61 << " size=" << size << " n=" << n
62 << " orig=" << orig_csum
63 << " updated=" << updated_csum
64 << " verify=" << verify_csum
65 << std::endl;
66 }
67}
void init_headroom(const size_t headroom)
Initializes the headroom (offset) of the buffer.
Definition buffer.hpp:1151
T * write_alloc(const size_t size)
Allocate space for writing data to the buffer.
Definition buffer.hpp:1587
T rand_get()
Create a data object filled with random bytes.
Definition randapi.hpp:86
virtual void rand_bytes(unsigned char *buf, size_t size)=0
Fill a buffer with random bytes.
std::uint32_t diff16(const std::uint32_t *old, const std::uint32_t *new_, const std::uint32_t oldsum)
Definition csum.hpp:124
std::uint32_t cunfold(const std::uint16_t sum)
Definition csum.hpp:41
std::uint16_t cfold(const std::uint32_t sum)
Definition csum.hpp:31
std::uint16_t checksum(const void *data, const size_t size)
Definition csum.hpp:158
TEST(misc, stress_csum)
Definition test_csum.cpp:31
std::uint16_t ip_checksum_slow(const void *ip, size_t size)
Definition test_csum.cpp:12