srdusr
aboutsummaryrefslogtreecommitdiffstats
path: root/tests/test_dissector.cpp
blob: 9dd4135e22dbc30d6f651526d619bc2f4cbaab7b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#include <doctest/doctest.h>

#include "packeteer/l7/dissector.hpp"

using namespace packeteer::net;

namespace {

// A dissector that claims a port but never actually matches any
// payload - stands in for e.g. TlsSniDissector receiving QUIC bytes
// on port 443: same port, wrong protocol, never succeeds.
class NeverMatchesDissector : public L7Dissector {
public:
    explicit NeverMatchesDissector(std::uint16_t port) : port_(port) {}
    std::uint16_t port() const override { return port_; }
    std::optional<std::string> summarize(std::span<const unsigned char>) const override {
        return std::nullopt;
    }

private:
    std::uint16_t port_;
};

class AlwaysMatchesDissector : public L7Dissector {
public:
    AlwaysMatchesDissector(std::uint16_t port, std::string label)
        : port_(port), label_(std::move(label)) {}
    std::uint16_t port() const override { return port_; }
    std::optional<std::string> summarize(std::span<const unsigned char>) const override {
        return label_;
    }

private:
    std::uint16_t port_;
    std::string label_;
};

}  // namespace

TEST_CASE("L7Registry falls through to a later dissector on the same port "
          "when an earlier one fails to match") {
    NeverMatchesDissector tls_like(443);
    AlwaysMatchesDissector quic_like(443, "QUIC something");

    L7Registry registry;
    registry.add(&tls_like);
    registry.add(&quic_like);

    auto result = registry.dissect(443, {});
    REQUIRE(result.has_value());
    CHECK(*result == "QUIC something");
}

TEST_CASE("L7Registry still returns the first dissector to succeed, not the last") {
    AlwaysMatchesDissector first(80, "first");
    AlwaysMatchesDissector second(80, "second");

    L7Registry registry;
    registry.add(&first);
    registry.add(&second);

    auto result = registry.dissect(80, {});
    REQUIRE(result.has_value());
    CHECK(*result == "first");
}

TEST_CASE("L7Registry returns nullopt when no dissector on the port matches") {
    NeverMatchesDissector only(443);

    L7Registry registry;
    registry.add(&only);

    CHECK_FALSE(registry.dissect(443, {}).has_value());
}