diff --git a/ebpfdiscoverysrv/src/main.cpp b/ebpfdiscoverysrv/src/main.cpp index 7d692f18..473ef25f 100644 --- a/ebpfdiscoverysrv/src/main.cpp +++ b/ebpfdiscoverysrv/src/main.cpp @@ -11,13 +11,13 @@ static ebpfdiscovery::Discovery discoveryInstance; -std::atomic is_shutting_down; +std::atomic isShuttingDown; static void handleUnixExitSignal(int signo) { - if (is_shutting_down) { + if (isShuttingDown) { return; } - is_shutting_down = true; + isShuttingDown = true; discoveryInstance.stopRun(); } diff --git a/libebpfdiscovery/CMakeLists.txt b/libebpfdiscovery/CMakeLists.txt index 8cf81a6d..6888c764 100644 --- a/libebpfdiscovery/CMakeLists.txt +++ b/libebpfdiscovery/CMakeLists.txt @@ -3,7 +3,6 @@ list( SOURCES src/Config.cpp src/Discovery.cpp - src/Log.cpp src/Session.cpp src/StringFunctions.cpp ) diff --git a/libebpfdiscovery/headers/ebpfdiscovery/Discovery.h b/libebpfdiscovery/headers/ebpfdiscovery/Discovery.h index 4bed4497..427c6f16 100644 --- a/libebpfdiscovery/headers/ebpfdiscovery/Discovery.h +++ b/libebpfdiscovery/headers/ebpfdiscovery/Discovery.h @@ -25,6 +25,7 @@ class Discovery { Discovery(const DiscoveryConfig config); ~Discovery(); + bool isLoaded() noexcept; void load(); void unload() noexcept; @@ -43,21 +44,22 @@ class Discovery { void handleNewEvent(DiscoveryEvent event); void handleNewDataEvent(DiscoveryEvent& event); - void handleBufferLookupSuccess(DiscoverySavedBuffer& saved_buffer, DiscoveryEvent& event); - void handleExistingSession(SavedSessionsCacheType::iterator it, std::string_view& buffer_view, DiscoveryEvent& event); - void handleNewSession(std::string_view& buffer_view, DiscoveryEvent& event); + void handleBufferLookupSuccess(DiscoverySavedBuffer& savedBuffer, DiscoveryEvent& event); + void handleExistingSession(SavedSessionsCacheType::iterator it, std::string_view& bufferView, DiscoveryEvent& event); + void handleNewSession(std::string_view& bufferView, DiscoveryEvent& event); void handleCloseEvent(DiscoveryEvent& event); - void handleSuccessfulParse(const Session& session, const DiscoverySessionMeta& session_meta); + void handleSuccessfulParse(const Session& session, const DiscoverySessionMeta& sessionMeta); int bpfDiscoveryResetConfig(); int bpfDiscoveryResumeCollecting(); - int bpfDiscoveryDeleteSession(const DiscoveryTrackedSessionKey& tracked_session_key); + int bpfDiscoveryDeleteSession(const DiscoveryTrackedSessionKey& trackedSessionKey); DiscoveryConfig config; std::atomic running; - bpf_object_open_opts bpf_open_opts; - discovery_bpf* bpf_obj; + std::atomic loaded; + discovery_bpf* discoverySkel; + bpf_object_open_opts discoverySkelOpenOpts; SavedSessionsCacheType savedSessions; }; diff --git a/libebpfdiscovery/headers/ebpfdiscovery/Log.h b/libebpfdiscovery/headers/ebpfdiscovery/Log.h deleted file mode 100644 index d15efe07..00000000 --- a/libebpfdiscovery/headers/ebpfdiscovery/Log.h +++ /dev/null @@ -1,14 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -#pragma once - -#include "ebpfdiscovery/Session.h" -#include "ebpfdiscoveryshared/Types.h" - -#include -#include - -namespace ebpfdiscovery { - -void printSession(const Session& session, const DiscoverySessionMeta& meta); - -} // namespace ebpfdiscovery diff --git a/libebpfdiscovery/src/Discovery.cpp b/libebpfdiscovery/src/Discovery.cpp index 50be5162..b0af007c 100644 --- a/libebpfdiscovery/src/Discovery.cpp +++ b/libebpfdiscovery/src/Discovery.cpp @@ -2,7 +2,7 @@ #include "ebpfdiscovery/Discovery.h" -#include "ebpfdiscovery/Log.h" +#include "StringFunctions.h" #include "ebpfdiscovery/Session.h" extern "C" { @@ -24,10 +24,27 @@ extern "C" { namespace ebpfdiscovery { +static void printSession(const Session& session, const DiscoverySessionMeta& meta) { + const auto& request{session.parser.result}; + std::cout << request.method << " " << request.host << request.url; + + if (const auto& xForwardedFor{request.xForwardedFor}; !xForwardedFor.empty()) { + std::cout << " X-Forwarded-For: " << '"' << xForwardedFor << '"'; + } else if (discoverySessionFlagsIsIPv4(meta.flags)) { + if (auto srcIpv4{ipv4ToString(meta.sourceIPData)}; !srcIpv4.empty()) + std::cout << " srcIpv4: " << '"' << srcIpv4 << '"'; + } else if (discoverySessionFlagsIsIPv6(meta.flags)) { + if (auto srcIpv6{ipv6ToString(meta.sourceIPData)}; !srcIpv6.empty()) + std::cout << " srcIpv6: " << '"' << srcIpv6 << '"'; + } + + std::cout << '\n'; +} + Discovery::Discovery() : Discovery(DiscoveryConfig{}) { } -Discovery::Discovery(const DiscoveryConfig config) : bpf_open_opts{.sz = sizeof(bpf_open_opts)}, savedSessions(MAX_SESSIONS) { +Discovery::Discovery(const DiscoveryConfig config) : savedSessions(DISCOVERY_MAX_SESSIONS) { } Discovery::~Discovery() { @@ -35,7 +52,7 @@ Discovery::~Discovery() { } int Discovery::run() { - if (bpf_obj == nullptr) { + if (!isLoaded()) { return -1; } @@ -51,7 +68,7 @@ int Discovery::run() { void Discovery::fetchEvents() { DiscoveryEvent event; - while (bpf_map__lookup_and_delete_elem(bpf_obj->maps.eventsToUserspaceQueueMap, NULL, 0, &event, sizeof(event), BPF_ANY) == 0) { + while (bpf_map__lookup_and_delete_elem(discoverySkel->maps.eventsToUserspaceQueueMap, NULL, 0, &event, sizeof(event), BPF_ANY) == 0) { handleNewEvent(std::move(event)); } } @@ -68,7 +85,12 @@ void Discovery::handleNewEvent(DiscoveryEvent event) { void Discovery::handleNewDataEvent(DiscoveryEvent& event) { DiscoverySavedBuffer savedBuffer; auto lookup_result{bpf_map__lookup_elem( - bpf_obj->maps.savedBuffersMap, &event.dataKey, sizeof(DiscoverySavedBufferKey), &savedBuffer, sizeof(savedBuffer), BPF_ANY)}; + discoverySkel->maps.savedBuffersMap, + &event.dataKey, + sizeof(DiscoverySavedBufferKey), + &savedBuffer, + sizeof(savedBuffer), + BPF_ANY)}; if (lookup_result != 0) { return; } @@ -76,28 +98,28 @@ void Discovery::handleNewDataEvent(DiscoveryEvent& event) { handleBufferLookupSuccess(savedBuffer, event); } -void Discovery::handleBufferLookupSuccess(DiscoverySavedBuffer& saved_buffer, DiscoveryEvent& event) { - std::string_view buffer_view(saved_buffer.data, saved_buffer.length); - bpf_map__delete_elem(bpf_obj->maps.savedBuffersMap, &event.dataKey, sizeof(DiscoverySavedBufferKey), BPF_ANY); +void Discovery::handleBufferLookupSuccess(DiscoverySavedBuffer& savedBuffer, DiscoveryEvent& event) { + std::string_view bufferView(savedBuffer.data, savedBuffer.length); + bpf_map__delete_elem(discoverySkel->maps.savedBuffersMap, &event.dataKey, sizeof(DiscoverySavedBufferKey), BPF_ANY); auto it{savedSessions.find(event.dataKey)}; if (it != savedSessions.end()) { - handleExistingSession(it, buffer_view, event); + handleExistingSession(it, bufferView, event); return; } - handleNewSession(buffer_view, event); + handleNewSession(bufferView, event); } -void Discovery::handleExistingSession(SavedSessionsCacheType::iterator it, std::string_view& buffer_view, DiscoveryEvent& event) { - savedSessions.update(it, [buffer_view = std::move(buffer_view)](auto& session) { session.parser.parse(std::move(buffer_view)); }); - if (it->second.parser.is_invalid_state()) { +void Discovery::handleExistingSession(SavedSessionsCacheType::iterator it, std::string_view& bufferView, DiscoveryEvent& event) { + savedSessions.update(it, [bufferView = std::move(bufferView)](auto& session) { session.parser.parse(std::move(bufferView)); }); + if (it->second.parser.isInvalidState()) { bpfDiscoveryDeleteSession(event.dataKey); savedSessions.erase(it); return; } - if (!it->second.parser.is_finished()) { + if (!it->second.parser.isFinished()) { // We expect more data buffers to come return; } @@ -106,20 +128,20 @@ void Discovery::handleExistingSession(SavedSessionsCacheType::iterator it, std:: savedSessions.update(it, [](auto& session) { session.reset(); }); } -void Discovery::handleNewSession(std::string_view& buffer_view, DiscoveryEvent& event) { +void Discovery::handleNewSession(std::string_view& bufferView, DiscoveryEvent& event) { Session session; - session.parser.parse(std::move(buffer_view)); - if (session.parser.is_invalid_state()) { + session.parser.parse(std::move(bufferView)); + if (session.parser.isInvalidState()) { bpfDiscoveryDeleteSession(event.dataKey); return; } - if (!session.parser.is_finished() && !discoveryEventFlagsIsNoMoreData(event.flags)) { + if (!session.parser.isFinished() && !discoveryEventFlagsIsNoMoreData(event.flags)) { saveSession(event.dataKey, std::move(session)); return; } - if (!session.parser.is_finished()) { + if (!session.parser.isFinished()) { return; } @@ -134,43 +156,54 @@ void Discovery::handleCloseEvent(DiscoveryEvent& event) { int Discovery::bpfDiscoveryResumeCollecting() { static uint32_t zero{0}; - DiscoveryGlobalState shared_global_state; + DiscoveryGlobalState discoveryGlobalState{}; return bpf_map__update_elem( - bpf_obj->maps.globalStateMap, &zero, sizeof(zero), &shared_global_state, sizeof(shared_global_state), BPF_EXIST); + discoverySkel->maps.globalStateMap, &zero, sizeof(zero), &discoveryGlobalState, sizeof(discoveryGlobalState), BPF_EXIST); } int Discovery::bpfDiscoveryResetConfig() { return bpfDiscoveryResumeCollecting(); } +bool Discovery::isLoaded() noexcept { + return discoverySkel != nullptr && loaded; +} + void Discovery::load() { - if (int res{ensure_core_btf(&bpf_open_opts)}) { + LIBBPF_OPTS(bpf_object_open_opts, openOpts); + discoverySkelOpenOpts = openOpts; + + if (int res{ensure_core_btf(&openOpts)}) { throw std::runtime_error("Failed to fetch necessary BTF for CO-RE: " + std::string(strerror(-res))); } - bpf_obj = discovery_bpf__open_opts(&bpf_open_opts); - if (bpf_obj == nullptr) { + discoverySkel = discovery_bpf__open_opts(&openOpts); + if (discoverySkel == nullptr) { throw std::runtime_error("Failed to open BPF object."); } - if (int res{discovery_bpf__load(bpf_obj)}) { + if (int res{discovery_bpf__load(discoverySkel)}) { throw std::runtime_error("Failed to load BPF object: " + std::to_string(res)); } - if (int res{discovery_bpf__attach(bpf_obj)}) { + if (int res{discovery_bpf__attach(discoverySkel)}) { throw std::runtime_error("Failed to attach BPF object: " + std::to_string(res)); } if (int res{bpfDiscoveryResumeCollecting()}) { throw std::runtime_error("Failed to set config of BPF program: " + std::to_string(res)); } + + loaded = true; } void Discovery::unload() noexcept { - if (bpf_obj != nullptr) { - discovery_bpf__destroy(bpf_obj); + stopRun(); + loaded = false; + if (discoverySkel != nullptr) { + discovery_bpf__destroy(discoverySkel); } - cleanup_core_btf(&bpf_open_opts); + cleanup_core_btf(&discoverySkelOpenOpts); } void Discovery::stopRun() { @@ -181,12 +214,12 @@ void Discovery::handleSuccessfulParse(const Session& session, const DiscoverySes printSession(session, meta); } -void Discovery::saveSession(const DiscoverySavedSessionKey& session_key, const Session& session) { - savedSessions.insert(session_key, session); +void Discovery::saveSession(const DiscoverySavedSessionKey& sessionKey, const Session& session) { + savedSessions.insert(sessionKey, session); } -int Discovery::bpfDiscoveryDeleteSession(const DiscoveryTrackedSessionKey& tracked_session_key) { - return bpf_map__delete_elem(bpf_obj->maps.trackedSessionsMap, &tracked_session_key, sizeof(tracked_session_key), BPF_ANY); +int Discovery::bpfDiscoveryDeleteSession(const DiscoveryTrackedSessionKey& trackedSessionKey) { + return bpf_map__delete_elem(discoverySkel->maps.trackedSessionsMap, &trackedSessionKey, sizeof(trackedSessionKey), BPF_ANY); } } // namespace ebpfdiscovery diff --git a/libebpfdiscovery/src/Log.cpp b/libebpfdiscovery/src/Log.cpp deleted file mode 100644 index aef40064..00000000 --- a/libebpfdiscovery/src/Log.cpp +++ /dev/null @@ -1,27 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -#include "ebpfdiscovery/Log.h" - -#include "StringFunctions.h" - -#include - -namespace ebpfdiscovery { - -void printSession(const Session& session, const DiscoverySessionMeta& meta) { - const auto& request{session.parser.result}; - std::cout << request.method << " " << request.host << request.url; - - if (const auto& x_forwarded_for{request.x_forwarded_for}; !x_forwarded_for.empty()) { - std::cout << " X-Forwarded-For: " << '"' << x_forwarded_for << '"'; - } else if (discoverySessionFlagsIsIPv4(meta.flags)) { - if (auto src_ipv4{ipv4ToString(meta.sourceIPData)}; !src_ipv4.empty()) - std::cout << " src_ipv4: " << '"' << src_ipv4 << '"'; - } else if (discoverySessionFlagsIsIPv6(meta.flags)) { - if (auto src_ipv6{ipv6ToString(meta.sourceIPData)}; !src_ipv6.empty()) - std::cout << " src_ipv6: " << '"' << src_ipv6 << '"'; - } - - std::cout << '\n'; -} - -} // namespace ebpfdiscovery diff --git a/libebpfdiscoveryshared/headers/ebpfdiscoveryshared/Constants.h b/libebpfdiscoveryshared/headers/ebpfdiscoveryshared/Constants.h index ea4d5df0..6184f910 100644 --- a/libebpfdiscoveryshared/headers/ebpfdiscoveryshared/Constants.h +++ b/libebpfdiscoveryshared/headers/ebpfdiscoveryshared/Constants.h @@ -1,9 +1,9 @@ // SPDX-License-Identifier: GPL-2.0 #pragma once -#define BUFFER_MAX_DATA_SIZE 10240 // 10 KiB -#define MAX_SESSIONS 8192 -#define EVENT_QUEUE_SIZE 512 +#define DISCOVERY_BUFFER_MAX_DATA_SIZE 10240 // 10 KiB +#define DISCOVERY_MAX_SESSIONS 8192 +#define DISCOVERY_EVENT_QUEUE_SIZE 512 -#define MAX_HTTP_REQUEST_LENGTH BUFFER_MAX_DATA_SIZE -#define MIN_HTTP_REQUEST_LENGTH 16 +#define DISCOVERY_MAX_HTTP_REQUEST_LENGTH DISCOVERY_BUFFER_MAX_DATA_SIZE +#define DISCOVERY_MIN_HTTP_REQUEST_LENGTH 16 diff --git a/libebpfdiscoveryshared/headers/ebpfdiscoveryshared/Types.h b/libebpfdiscoveryshared/headers/ebpfdiscoveryshared/Types.h index 1a0fd5be..29ac5b66 100644 --- a/libebpfdiscoveryshared/headers/ebpfdiscoveryshared/Types.h +++ b/libebpfdiscoveryshared/headers/ebpfdiscoveryshared/Types.h @@ -42,7 +42,7 @@ struct DiscoverySockIPv6 { struct DiscoverySavedBuffer { __u32 length; - char data[BUFFER_MAX_DATA_SIZE]; + char data[DISCOVERY_BUFFER_MAX_DATA_SIZE]; }; /* diff --git a/libebpfdiscoveryskel/src/DataFunctions.h b/libebpfdiscoveryskel/src/DataFunctions.h new file mode 100644 index 00000000..e4c7579c --- /dev/null +++ b/libebpfdiscoveryskel/src/DataFunctions.h @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: GPL-2.0 +#pragma once + +#include "ebpfdiscoveryshared/Constants.h" + +#include "vmlinux.h" + +#include + +__attribute__((always_inline)) inline static int dataProbeIsEqualToString(const char* src, const char* str, size_t len) { + char ch; + for (size_t i = 0; i < len; ++i) { + int result = bpf_probe_read(&ch, sizeof(char), (char*)src + i); + if (result < 0) { + return result; + } + + if (ch != str[i] || ch == '\0') { + return i + 1; + } + } + return len; +} + +__attribute__((always_inline)) inline static bool dataProbeIsBeginningOfHttpRequest(const char* ptr, size_t len) { + // We expect only GET and POST requests. We expect request URI's to start with a slash as absolute urls are mainly used in + // requests to proxy servers. + return len >= DISCOVERY_MIN_HTTP_REQUEST_LENGTH && + (dataProbeIsEqualToString(ptr, "GET /", 5) || dataProbeIsEqualToString(ptr, "POST /", 6)); +} diff --git a/libebpfdiscoveryskel/src/DataReading.h b/libebpfdiscoveryskel/src/DataReading.h deleted file mode 100644 index 27ef4fe4..00000000 --- a/libebpfdiscoveryskel/src/DataReading.h +++ /dev/null @@ -1,17 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#pragma once - -#include "vmlinux.h" - -#include - -__attribute__((always_inline)) inline static int dataReadingStreq(const char* src, const char* str, size_t len) { - char ch; - for (int i = 0; i < len; ++i) { - bpf_probe_read(&ch, sizeof(char), (char*)src + i); - if (ch != str[i]) { - return i + 1; - } - } - return 0; -} diff --git a/libebpfdiscoveryskel/src/GlobalData.h b/libebpfdiscoveryskel/src/GlobalData.h index c456e2c0..f4f6ee9d 100644 --- a/libebpfdiscoveryskel/src/GlobalData.h +++ b/libebpfdiscoveryskel/src/GlobalData.h @@ -12,13 +12,13 @@ struct { __uint(type, BPF_MAP_TYPE_ARRAY); __type(key, __u32); - __type(value, struct DiscoveryAllSessionState); + __type(value, struct DiscoveryGlobalState); __uint(max_entries, 1); -} allSessionStateMap SEC(".maps"); +} globalStateMap SEC(".maps"); -__attribute__((always_inline)) inline static struct DiscoveryAllSessionState* getAllSessionState() { +__attribute__((always_inline)) inline static struct DiscoveryGlobalState* getGlobalState() { __u32 zero = 0; - return (struct DiscoveryAllSessionState*)bpf_map_lookup_elem(&allSessionStateMap, &zero); + return (struct DiscoveryGlobalState*)bpf_map_lookup_elem(&globalStateMap, &zero); } __attribute__((always_inline)) inline static void disableDiscoveryCollecting(struct DiscoveryGlobalState* discoveryGlobalStatePtr) { @@ -27,34 +27,34 @@ __attribute__((always_inline)) inline static void disableDiscoveryCollecting(str } struct { - __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY); + __uint(type, BPF_MAP_TYPE_ARRAY); __type(key, __u32); - __type(value, struct DiscoverySavedBuffer); + __type(value, struct DiscoveryAllSessionState); __uint(max_entries, 1); -} oneSavedBufferHeapMap SEC(".maps"); +} allSessionStateMap SEC(".maps"); -__attribute__((always_inline)) inline static struct DiscoverySavedBuffer* newSavedBuffer() { +__attribute__((always_inline)) inline static struct DiscoveryAllSessionState* getAllSessionState() { __u32 zero = 0; - return (struct DiscoverySavedBuffer*)bpf_map_lookup_elem(&oneSavedBufferHeapMap, &zero); + return (struct DiscoveryAllSessionState*)bpf_map_lookup_elem(&allSessionStateMap, &zero); } struct { - __uint(type, BPF_MAP_TYPE_ARRAY); + __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY); __type(key, __u32); - __type(value, struct DiscoveryGlobalState); + __type(value, struct DiscoverySavedBuffer); __uint(max_entries, 1); -} globalStateMap SEC(".maps"); +} oneSavedBufferHeapMap SEC(".maps"); -__attribute__((always_inline)) inline static struct DiscoveryGlobalState* getGlobalState() { +__attribute__((always_inline)) inline static struct DiscoverySavedBuffer* newSavedBuffer() { __u32 zero = 0; - return (struct DiscoveryGlobalState*)bpf_map_lookup_elem(&globalStateMap, &zero); + return (struct DiscoverySavedBuffer*)bpf_map_lookup_elem(&oneSavedBufferHeapMap, &zero); } struct { __uint(type, BPF_MAP_TYPE_HASH); __type(key, struct DiscoverySavedBufferKey); __type(value, struct DiscoverySavedBuffer); - __uint(max_entries, MAX_SESSIONS); + __uint(max_entries, DISCOVERY_MAX_SESSIONS); } savedBuffersMap SEC(".maps"); __attribute__((always_inline)) inline static void deleteSavedSession(struct DiscoverySavedSessionKey* savedSessionKeyPtr) { @@ -64,7 +64,7 @@ __attribute__((always_inline)) inline static void deleteSavedSession(struct Disc struct { __uint(type, BPF_MAP_TYPE_QUEUE); __type(value, struct DiscoveryEvent); - __uint(max_entries, EVENT_QUEUE_SIZE); + __uint(max_entries, DISCOVERY_EVENT_QUEUE_SIZE); } eventsToUserspaceQueueMap SEC(".maps"); __attribute__((always_inline)) inline static int pushEventToUserspace( diff --git a/libebpfdiscoveryskel/src/Handlers.h b/libebpfdiscoveryskel/src/Handlers.h index 8502b16f..b870810b 100644 --- a/libebpfdiscoveryskel/src/Handlers.h +++ b/libebpfdiscoveryskel/src/Handlers.h @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 #pragma once -#include "DataReading.h" +#include "DataFunctions.h" #include "GlobalData.h" #include "Log.h" #include "Pid.h" @@ -17,24 +17,24 @@ #include __attribute__((always_inline)) inline static void handleAcceptIPv4Session( - const struct DiscoveryTrackedSessionKey tracked_session_key, const struct AcceptArgs* acceptArgsPtr, int addrlen) { + const struct DiscoveryTrackedSessionKey trackedSessionKey, const struct AcceptArgs* acceptArgsPtr, int addrlen) { if (acceptArgsPtr->addrSize < sizeof(struct sockaddr_in) || addrlen != sizeof(struct sockaddr_in)) { return; } struct DiscoverySession session = {}; discoverySessionFlagsSetIPv4(&session.meta.flags); - // session.timestamp will be initialized on the first read() call + // Session fields are initialized on session's first read() call struct DiscoverySockIPv4 sockIPv4 = {}; bpf_probe_read(&sockIPv4.addr, sizeof(struct sockaddr_in), acceptArgsPtr->addr); - bpf_map_update_elem(&trackedSessionSockIPv4Map, &tracked_session_key, &sockIPv4, BPF_ANY); - bpf_map_update_elem(&trackedSessionsMap, &tracked_session_key, &session, BPF_ANY); + bpf_map_update_elem(&trackedSessionSockIPv4Map, &trackedSessionKey, &sockIPv4, BPF_ANY); + bpf_map_update_elem(&trackedSessionsMap, &trackedSessionKey, &session, BPF_ANY); } __attribute__((always_inline)) inline static void handleAcceptIPv6Session( - const struct DiscoveryTrackedSessionKey tracked_session_key, const struct AcceptArgs* acceptArgsPtr, int addrlen) { + const struct DiscoveryTrackedSessionKey trackedSessionKey, const struct AcceptArgs* acceptArgsPtr, int addrlen) { if (acceptArgsPtr->addrSize < sizeof(struct sockaddr_in6) || addrlen != sizeof(struct sockaddr_in6)) { return; } @@ -46,11 +46,11 @@ __attribute__((always_inline)) inline static void handleAcceptIPv6Session( struct DiscoverySockIPv6 sockIPv6 = {}; bpf_probe_read(&sockIPv6.addr, sizeof(struct sockaddr_in6), acceptArgsPtr->addr); - bpf_map_update_elem(&trackedSessionSockIPv6Map, &tracked_session_key, &sockIPv6, BPF_ANY); - bpf_map_update_elem(&trackedSessionsMap, &tracked_session_key, &session, BPF_ANY); + bpf_map_update_elem(&trackedSessionSockIPv6Map, &trackedSessionKey, &sockIPv6, BPF_ANY); + bpf_map_update_elem(&trackedSessionsMap, &trackedSessionKey, &session, BPF_ANY); } -__attribute__((always_inline)) inline static void discoveryHandleAccept(struct AcceptArgs* acceptArgsPtr, int fd) { +__attribute__((always_inline)) inline static void handleAccept(struct AcceptArgs* acceptArgsPtr, int fd) { // Size of returned sockaddr struct int addrlen = 0; bpf_probe_read(&addrlen, sizeof(addrlen), (acceptArgsPtr->addrlen)); @@ -79,50 +79,44 @@ __attribute__((always_inline)) inline static void discoveryHandleAccept(struct A } } -__attribute__((always_inline)) inline static int session_init_fill_saddr_ipv4( +__attribute__((always_inline)) inline static int sessionFillIPv4( struct DiscoveryTrackedSessionKey* sessionKeyPtr, struct DiscoverySession* sessionPtr) { - struct sockaddr_in* addrPtr = (struct sockaddr_in*)bpf_map_lookup_elem(&trackedSessionSockIPv4Map, sessionKeyPtr); - if (addrPtr == NULL) { + struct sockaddr_in* sockipPtr = (struct sockaddr_in*)bpf_map_lookup_elem(&trackedSessionSockIPv4Map, sessionKeyPtr); + if (sockipPtr == NULL) { DEBUG_PRINT("No IPv4 of tracked session. (id: %d)\n", sessionPtr->id); return 1; } - BPF_CORE_READ_INTO(&sessionPtr->meta.sourceIPData, addrPtr, sin_addr); + BPF_CORE_READ_INTO(&sessionPtr->meta.sourceIPData, sockipPtr, sin_addr); bpf_map_delete_elem(&trackedSessionSockIPv4Map, sessionKeyPtr); return 0; } -__attribute__((always_inline)) inline static int session_init_fill_saddr_ipv6( +__attribute__((always_inline)) inline static int sessionFillIPv6( struct DiscoveryTrackedSessionKey* sessionKeyPtr, struct DiscoverySession* sessionPtr) { - struct sockaddr_in6* addr_ptr = (struct sockaddr_in6*)bpf_map_lookup_elem(&trackedSessionSockIPv6Map, sessionKeyPtr); - if (addr_ptr == NULL) { + struct sockaddr_in6* sockipPtr = (struct sockaddr_in6*)bpf_map_lookup_elem(&trackedSessionSockIPv6Map, sessionKeyPtr); + if (sockipPtr == NULL) { DEBUG_PRINT("No IPv6 of tracked session. (id: %d)\n", sessionPtr->id); return 1; } - BPF_CORE_READ_INTO(&sessionPtr->meta.sourceIPData, addr_ptr, sin6_addr); + BPF_CORE_READ_INTO(&sessionPtr->meta.sourceIPData, sockipPtr, sin6_addr); bpf_map_delete_elem(&trackedSessionSockIPv6Map, sessionKeyPtr); return 0; } -__attribute__((always_inline)) inline static int session_init_fill_saddr( - struct DiscoveryTrackedSessionKey* session_key_ptr, struct DiscoverySession* sessionPtr) { +__attribute__((always_inline)) inline static int sessionFillIP( + struct DiscoveryTrackedSessionKey* sessionKeyPtr, struct DiscoverySession* sessionPtr) { if (discoverySessionFlagsIsIPv4(sessionPtr->meta.flags)) { - return session_init_fill_saddr_ipv4(session_key_ptr, sessionPtr); + return sessionFillIPv4(sessionKeyPtr, sessionPtr); } else if (discoverySessionFlagsIsIPv6(sessionPtr->meta.flags)) { - return session_init_fill_saddr_ipv6(session_key_ptr, sessionPtr); + return sessionFillIPv6(sessionKeyPtr, sessionPtr); } return -1; } -__attribute__((always_inline)) inline static bool probe_buf_and_check_is_http_beginning(const char* buf, size_t length) { - // We collect only GET and POST requests. We expect request URI's to start with a slash as absolute urls are mainly used in - // requests to proxy servers. - return length >= MIN_HTTP_REQUEST_LENGTH && (dataReadingStreq(buf, "GET /", 5) || dataReadingStreq(buf, "POST /", 6)); -} - -__attribute__((always_inline)) inline static void discoveryHandleRead( +__attribute__((always_inline)) inline static void handleRead( struct DiscoveryGlobalState* globalStatePtr, struct DiscoveryAllSessionState* allSessionStatePtr, struct ReadArgs* readArgsPtr, @@ -144,7 +138,7 @@ __attribute__((always_inline)) inline static void discoveryHandleRead( } if (sessionPtr->bufferCount == 0) { - if (!probe_buf_and_check_is_http_beginning(readArgsPtr->buf, bytesCount)) { + if (!dataProbeIsBeginningOfHttpRequest(readArgsPtr->buf, bytesCount)) { deleteTrackedSession((struct DiscoveryTrackedSessionKey*)&event.dataKey, sessionPtr); DEBUG_PRINT( "Received data from session. Ignoring the session, as it doesn't look like an HTTP request. pid: `%d`, fd: `%d`, " @@ -157,7 +151,7 @@ __attribute__((always_inline)) inline static void discoveryHandleRead( sessionPtr->id = allSessionStatePtr->sessionCounter; allSessionStatePtr->sessionCounter++; - session_init_fill_saddr((struct DiscoveryTrackedSessionKey*)&event.dataKey, sessionPtr); + sessionFillIP((struct DiscoveryTrackedSessionKey*)&event.dataKey, sessionPtr); } else { event.dataKey.bufferSeq = sessionPtr->bufferCount; } @@ -170,7 +164,7 @@ __attribute__((always_inline)) inline static void discoveryHandleRead( return; } - if (bytesCount <= sizeof(savedBufferPtr->data)) { + if ((size_t)bytesCount <= sizeof(savedBufferPtr->data)) { savedBufferPtr->length = bytesCount; } else { savedBufferPtr->length = sizeof(savedBufferPtr->data); @@ -191,7 +185,7 @@ __attribute__((always_inline)) inline static void discoveryHandleRead( sessionPtr->bufferCount++; } -__attribute__((always_inline)) inline static void discoveryHandleClose( +__attribute__((always_inline)) inline static void handleClose( struct DiscoveryGlobalState* globalStatePtr, struct DiscoveryAllSessionState* allSessionStatePtr, int fd) { struct DiscoveryTrackedSessionKey trackedSessionKey = {}; trackedSessionKey.pid = pidTgidToPid(bpf_get_current_pid_tgid()); diff --git a/libebpfdiscoveryskel/src/Log.h b/libebpfdiscoveryskel/src/Log.h index 790303fa..d0bb0600 100644 --- a/libebpfdiscoveryskel/src/Log.h +++ b/libebpfdiscoveryskel/src/Log.h @@ -1,6 +1,8 @@ // SPDX-License-Identifier: GPL-2.0 #pragma once +#include "vmlinux.h" + #include #include diff --git a/libebpfdiscoveryskel/src/SysTypes.h b/libebpfdiscoveryskel/src/SysTypes.h index 5ef8c82d..4850d8d5 100644 --- a/libebpfdiscoveryskel/src/SysTypes.h +++ b/libebpfdiscoveryskel/src/SysTypes.h @@ -32,7 +32,7 @@ struct AcceptArgs { socklen_t* addrlen; // Size of sockaddr struct allocated by calling program - int addrSize; + size_t addrSize; }; struct ReadArgs { diff --git a/libebpfdiscoveryskel/src/SyscallProbes.h b/libebpfdiscoveryskel/src/SyscallProbes.h index 04cb9137..1e8fd457 100644 --- a/libebpfdiscoveryskel/src/SyscallProbes.h +++ b/libebpfdiscoveryskel/src/SyscallProbes.h @@ -1,7 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 #pragma once -#include "DataReading.h" #include "GlobalData.h" #include "Handlers.h" #include "SysPrefixMacro.h" @@ -23,14 +22,14 @@ struct { __uint(type, BPF_MAP_TYPE_HASH); __type(key, __u64); // pid_tgid __type(value, struct AcceptArgs); - __uint(max_entries, MAX_SESSIONS); + __uint(max_entries, DISCOVERY_MAX_SESSIONS); } runningAcceptArgsMap SEC(".maps"); struct { __uint(type, BPF_MAP_TYPE_HASH); __type(key, __u64); // pid_tgid __type(value, struct ReadArgs); - __uint(max_entries, MAX_SESSIONS); + __uint(max_entries, DISCOVERY_MAX_SESSIONS); } runningReadArgsMap SEC(".maps"); /* @@ -94,7 +93,7 @@ __attribute__((always_inline)) inline static int handleSysAcceptExit(int fd) { return 0; } - discoveryHandleAccept(acceptArgsPtr, fd); + handleAccept(acceptArgsPtr, fd); bpf_map_delete_elem(&runningAcceptArgsMap, &pidTgid); return 0; @@ -154,7 +153,7 @@ __attribute__((always_inline)) inline static int handleSysReadExit(ssize_t bytes return 0; } - discoveryHandleRead(globalStatePtr, allSessionStatePtr, readArgsPtr, bytesCount); + handleRead(globalStatePtr, allSessionStatePtr, readArgsPtr, bytesCount); bpf_map_delete_elem(&runningReadArgsMap, &pidTgid); return 0; @@ -171,7 +170,7 @@ __attribute__((always_inline)) inline static int handleSysCloseEntry(int fd) { return 0; }; - discoveryHandleClose(globalStatePtr, allSessionStatePtr, fd); + handleClose(globalStatePtr, allSessionStatePtr, fd); return 0; } diff --git a/libebpfdiscoveryskel/src/TrackedSession.h b/libebpfdiscoveryskel/src/TrackedSession.h index 840b35ad..69ffc5e3 100644 --- a/libebpfdiscoveryskel/src/TrackedSession.h +++ b/libebpfdiscoveryskel/src/TrackedSession.h @@ -16,21 +16,21 @@ struct { __uint(type, BPF_MAP_TYPE_LRU_HASH); __type(key, struct DiscoveryTrackedSessionKey); __type(value, struct DiscoverySession); - __uint(max_entries, MAX_SESSIONS); + __uint(max_entries, DISCOVERY_MAX_SESSIONS); } trackedSessionsMap SEC(".maps"); struct { __uint(type, BPF_MAP_TYPE_LRU_HASH); __type(key, struct DiscoveryTrackedSessionKey); __type(value, struct DiscoverySockIPv4); - __uint(max_entries, MAX_SESSIONS); + __uint(max_entries, DISCOVERY_MAX_SESSIONS); } trackedSessionSockIPv4Map SEC(".maps"); struct { __uint(type, BPF_MAP_TYPE_LRU_HASH); __type(key, struct DiscoveryTrackedSessionKey); __type(value, struct DiscoverySockIPv6); - __uint(max_entries, MAX_SESSIONS); + __uint(max_entries, DISCOVERY_MAX_SESSIONS); } trackedSessionSockIPv6Map SEC(".maps"); __attribute__((always_inline)) inline static void deleteTrackedSession( diff --git a/libhttpparser/headers/httpparser/HttpRequestParser.h b/libhttpparser/headers/httpparser/HttpRequestParser.h index a617096a..dcccf0e5 100644 --- a/libhttpparser/headers/httpparser/HttpRequestParser.h +++ b/libhttpparser/headers/httpparser/HttpRequestParser.h @@ -13,7 +13,7 @@ struct HttpRequest { std::string url; std::string protocol; std::string host; - std::string x_forwarded_for; + std::string xForwardedFor; HttpRequest(); void clear(); @@ -26,8 +26,8 @@ class HttpRequestParser { // Parse passed data while advancing the state machine size_t parse(std::string_view data); - bool is_invalid_state() const; - bool is_finished() const; + bool isInvalidState() const; + bool isFinished() const; void reset(); @@ -51,26 +51,26 @@ class HttpRequestParser { private: State state; - void set_invalid_state(); - void set_finished_state(); + void setInvalidState(); + void setFinishedState(); - void handle_char(const char ch); - void handle_char_method(const char ch); - void handle_char_space_before_url(const char ch); - void handle_char_url(const char ch); - void handle_char_space_before_protocol(const char ch); - void handle_char_protocol(const char ch); - void handle_char_header_newline(const char ch); - void handle_char_header_key(const char ch); - void handle_char_space_before_header_value(const char ch); - void handle_char_header_value(const char ch); - void handle_char_headers_end(const char ch); + void handleChar(const char ch); + void handleCharMethod(const char ch); + void handleCharSpaceBeforeUrl(const char ch); + void handleCharUrl(const char ch); + void handleCharSpaceBeforeProtocol(const char ch); + void handleCharProtocol(const char ch); + void handleCharHeaderNewline(const char ch); + void handleCharHeaderKey(const char ch); + void handleCharSpaceBeforeHeaderValue(const char ch); + void handleCharHeaderValue(const char ch); + void handleCharHeadersEnd(const char ch); - bool is_current_header_key_host(); - bool is_current_header_key_x_forwarded_for(); + bool isCurrentHeaderKeyHost(); + bool isCurrentHeaderKeyXForwardedFor(); std::string currentHeaderKey; - size_t _length; + size_t length; }; } // namespace httpparser diff --git a/libhttpparser/src/HttpRequestParser.cpp b/libhttpparser/src/HttpRequestParser.cpp index 885a7915..5502a687 100644 --- a/libhttpparser/src/HttpRequestParser.cpp +++ b/libhttpparser/src/HttpRequestParser.cpp @@ -26,23 +26,23 @@ static constexpr std::string_view X_FORWARDED_FOR{"X-Forwarded-For"}; static constexpr std::string_view X_FORWARDED_FOR_LOWER{"x-forwarded-for"}; } // namespace constants -inline static bool is_valid_url_char(const char ch) { +inline static bool isValidUrlChar(const char ch) { return std::isalnum(ch) || constants::VALID_URL_SPECIAL_CHARS.find(ch) != std::string_view::npos; } -inline static bool is_valid_header_key_char(const char ch) { +inline static bool isValidHeaderKeyChar(const char ch) { return std::isalnum(ch) || constants::VALID_HEADER_KEY_SPECIAL_CHARS.find(ch) != std::string_view::npos; } -inline static bool is_valid_header_value_char(const char ch) { +inline static bool isValidHeaderValueChar(const char ch) { return std::isalnum(ch) || constants::VALID_HEADER_VALUE_SPECIAL_CHARS.find(ch) != std::string_view::npos; } -inline static bool is_valid_host_header_value_char(const char ch) { +inline static bool isValidHostHeaderValueChar(const char ch) { return std::isalnum(ch) || constants::VALID_HOST_HEADER_VALUE_SPECIAL_CHARS.find(ch) != std::string_view::npos; } -inline static bool is_valid_x_forwarded_for_header_value_char(const char ch) { +inline static bool isValidXForwardedForHeaderValueChar(const char ch) { return std::isalnum(ch) || constants::VALID_X_FORWARDED_FOR_HEADER_VALUE_SPECIAL_CHARS.find(ch) != std::string_view::npos; } @@ -56,24 +56,24 @@ void HttpRequest::clear() { url.clear(); protocol.clear(); host.clear(); - x_forwarded_for.clear(); + xForwardedFor.clear(); } -HttpRequestParser::HttpRequestParser() : state{State::METHOD}, _length{0} { +HttpRequestParser::HttpRequestParser() : state{State::METHOD}, length{0} { } size_t HttpRequestParser::parse(std::string_view data) { size_t i{0}; while (i < data.size()) { - if (_length > MAX_HTTP_REQUEST_LENGTH) { - set_invalid_state(); + if (length > DISCOVERY_MAX_HTTP_REQUEST_LENGTH) { + setInvalidState(); return i; } - handle_char(data[i]); + handleChar(data[i]); i++; - _length++; + length++; if (state == State::FINISHED || state == State::INVALID) { return i; @@ -84,53 +84,53 @@ size_t HttpRequestParser::parse(std::string_view data) { return i; } -bool HttpRequestParser::is_invalid_state() const { +bool HttpRequestParser::isInvalidState() const { return state == State::INVALID; } -bool HttpRequestParser::is_finished() const { +bool HttpRequestParser::isFinished() const { return state == State::FINISHED || state == State::INVALID; } -void HttpRequestParser::set_invalid_state() { +void HttpRequestParser::setInvalidState() { state = State::INVALID; } -void HttpRequestParser::set_finished_state() { +void HttpRequestParser::setFinishedState() { state = State::FINISHED; } -void HttpRequestParser::handle_char(const char ch) { +void HttpRequestParser::handleChar(const char ch) { switch (state) { case State::METHOD: - handle_char_method(ch); + handleCharMethod(ch); break; case State::SPACE_BEFORE_URL: - handle_char_space_before_url(ch); + handleCharSpaceBeforeUrl(ch); break; case State::URL: - handle_char_url(ch); + handleCharUrl(ch); break; case State::SPACE_BEFORE_PROTOCOL: - handle_char_space_before_protocol(ch); + handleCharSpaceBeforeProtocol(ch); break; case State::PROTOCOL: - handle_char_protocol(ch); + handleCharProtocol(ch); break; case State::HEADER_NEWLINE: - handle_char_header_newline(ch); + handleCharHeaderNewline(ch); break; case State::HEADER_KEY: - handle_char_header_key(ch); + handleCharHeaderKey(ch); break; case State::SPACE_BEFORE_HEADER_VALUE: - handle_char_space_before_header_value(ch); + handleCharSpaceBeforeHeaderValue(ch); break; case State::HEADER_VALUE: - handle_char_header_value(ch); + handleCharHeaderValue(ch); break; case State::HEADERS_END: - handle_char_headers_end(ch); + handleCharHeadersEnd(ch); break; case State::FINISHED: case State::INVALID: @@ -138,7 +138,7 @@ void HttpRequestParser::handle_char(const char ch) { } } -void HttpRequestParser::handle_char_method(const char ch) { +void HttpRequestParser::handleCharMethod(const char ch) { if (std::isupper(ch)) { result.method.push_back(ch); @@ -147,29 +147,29 @@ void HttpRequestParser::handle_char_method(const char ch) { bool isMaybePost{constants::POST.substr(0, result.method.length()) == result.method}; if (!isMaybeGet && !isMaybePost) { - set_invalid_state(); + setInvalidState(); return; } return; } if (ch != ' ') { - set_invalid_state(); + setInvalidState(); return; } if (result.method != constants::GET && result.method != constants::POST) { - set_invalid_state(); + setInvalidState(); return; } state = State::SPACE_BEFORE_URL; } -void HttpRequestParser::handle_char_space_before_url(const char ch) { +void HttpRequestParser::handleCharSpaceBeforeUrl(const char ch) { if (ch != '/') { // We expect every HTTP request URI to start with / - set_invalid_state(); + setInvalidState(); return; } @@ -177,10 +177,10 @@ void HttpRequestParser::handle_char_space_before_url(const char ch) { state = State::URL; } -void HttpRequestParser::handle_char_url(const char ch) { +void HttpRequestParser::handleCharUrl(const char ch) { if (ch != ' ') { - if (!is_valid_url_char(ch)) { - set_invalid_state(); + if (!isValidUrlChar(ch)) { + setInvalidState(); return; } @@ -191,10 +191,10 @@ void HttpRequestParser::handle_char_url(const char ch) { state = State::SPACE_BEFORE_PROTOCOL; } -void HttpRequestParser::handle_char_space_before_protocol(const char ch) { +void HttpRequestParser::handleCharSpaceBeforeProtocol(const char ch) { if (ch != 'H') { // First letter of HTTP/x.x - set_invalid_state(); + setInvalidState(); return; } @@ -202,7 +202,7 @@ void HttpRequestParser::handle_char_space_before_protocol(const char ch) { state = State::PROTOCOL; } -void HttpRequestParser::handle_char_protocol(const char ch) { +void HttpRequestParser::handleCharProtocol(const char ch) { if (ch != '\r') { result.protocol.push_back(ch); @@ -210,23 +210,23 @@ void HttpRequestParser::handle_char_protocol(const char ch) { bool isMaybe1_1{constants::HTTP_1_1.substr(0, result.protocol.length()) == result.protocol}; if (!isMaybe1_0 && !isMaybe1_1) { - set_invalid_state(); + setInvalidState(); return; } return; } if (result.protocol != constants::HTTP_1_0 && result.protocol != constants::HTTP_1_1) { - set_invalid_state(); + setInvalidState(); return; } state = State::HEADER_NEWLINE; } -void HttpRequestParser::handle_char_header_newline(const char ch) { +void HttpRequestParser::handleCharHeaderNewline(const char ch) { if (ch != '\n') { - set_invalid_state(); + setInvalidState(); return; } @@ -234,7 +234,7 @@ void HttpRequestParser::handle_char_header_newline(const char ch) { state = State::HEADER_KEY; } -void HttpRequestParser::handle_char_header_key(const char ch) { +void HttpRequestParser::handleCharHeaderKey(const char ch) { if (ch == '\r') { state = State::HEADERS_END; return; @@ -245,8 +245,8 @@ void HttpRequestParser::handle_char_header_key(const char ch) { } if (ch != ':') { - if (!is_valid_header_key_char(ch)) { - set_invalid_state(); + if (!isValidHeaderKeyChar(ch)) { + setInvalidState(); return; } @@ -257,41 +257,41 @@ void HttpRequestParser::handle_char_header_key(const char ch) { return; } - if (is_current_header_key_host() && !result.host.empty()) { + if (isCurrentHeaderKeyHost() && !result.host.empty()) { state = State::INVALID; return; } - if (is_current_header_key_x_forwarded_for() && !result.x_forwarded_for.empty()) { - result.x_forwarded_for.push_back(','); + if (isCurrentHeaderKeyXForwardedFor() && !result.xForwardedFor.empty()) { + result.xForwardedFor.push_back(','); } state = State::SPACE_BEFORE_HEADER_VALUE; } -void HttpRequestParser::handle_char_space_before_header_value(const char ch) { +void HttpRequestParser::handleCharSpaceBeforeHeaderValue(const char ch) { if (ch == ' ') { return; } - if (!is_valid_header_value_char(ch)) { - set_invalid_state(); + if (!isValidHeaderValueChar(ch)) { + setInvalidState(); return; } - if (is_current_header_key_host()) { + if (isCurrentHeaderKeyHost()) { result.host.push_back(ch); - } else if (is_current_header_key_x_forwarded_for()) { - result.x_forwarded_for.push_back(ch); + } else if (isCurrentHeaderKeyXForwardedFor()) { + result.xForwardedFor.push_back(ch); } state = State::HEADER_VALUE; } -void HttpRequestParser::handle_char_header_value(const char ch) { - if (ch != '\r' && is_current_header_key_host()) { - if (!is_valid_host_header_value_char(ch)) { - set_invalid_state(); +void HttpRequestParser::handleCharHeaderValue(const char ch) { + if (ch != '\r' && isCurrentHeaderKeyHost()) { + if (!isValidHostHeaderValueChar(ch)) { + setInvalidState(); return; } @@ -299,18 +299,18 @@ void HttpRequestParser::handle_char_header_value(const char ch) { return; } - if (ch != '\r' && is_current_header_key_x_forwarded_for()) { - if (!is_valid_x_forwarded_for_header_value_char(ch)) { - set_invalid_state(); + if (ch != '\r' && isCurrentHeaderKeyXForwardedFor()) { + if (!isValidXForwardedForHeaderValueChar(ch)) { + setInvalidState(); return; } - result.x_forwarded_for.push_back(ch); + result.xForwardedFor.push_back(ch); return; } - if (ch != '\r' && !is_valid_header_value_char(ch)) { - set_invalid_state(); + if (ch != '\r' && !isValidHeaderValueChar(ch)) { + setInvalidState(); return; } @@ -321,30 +321,30 @@ void HttpRequestParser::handle_char_header_value(const char ch) { state = State::HEADER_NEWLINE; } -void HttpRequestParser::handle_char_headers_end(const char ch) { +void HttpRequestParser::handleCharHeadersEnd(const char ch) { if (ch != '\n') { - set_invalid_state(); + setInvalidState(); return; } // At this stage there may be additional POST data. It's fine to ignore it. // We also don't handle pipelined HTTP requests as they are uncommon. - set_finished_state(); + setFinishedState(); return; } -inline bool HttpRequestParser::is_current_header_key_host() { +inline bool HttpRequestParser::isCurrentHeaderKeyHost() { return currentHeaderKey == constants::HOST_LOWER; } -inline bool HttpRequestParser::is_current_header_key_x_forwarded_for() { +inline bool HttpRequestParser::isCurrentHeaderKeyXForwardedFor() { return currentHeaderKey == constants::X_FORWARDED_FOR_LOWER; } void HttpRequestParser::reset() { state = State::METHOD; currentHeaderKey.clear(); - _length = 0; + length = 0; result.clear(); } diff --git a/libhttpparser/test/HttpRequestParserTest.cpp b/libhttpparser/test/HttpRequestParserTest.cpp index f87c85b6..1bb32f63 100644 --- a/libhttpparser/test/HttpRequestParserTest.cpp +++ b/libhttpparser/test/HttpRequestParserTest.cpp @@ -23,35 +23,33 @@ std::vector chunkString(const std::string_view str, int chunkSize) } struct HttpRequestTestData { - std::vector request_chunks; + std::vector requestChunks; std::string method; std::string url; std::string protocol; std::string host; - std::string x_forwarded_for; - bool expect_finished; - size_t expect_total_bytes_parsed; + std::string xForwardedFor; + bool expectFinished; + size_t expectTotalBytesParsed; HttpRequestTestData( - std::vector request_chunks_ = {}, + std::vector requestChunks_ = {}, std::string method = "", std::string url = "", std::string protocol = "", std::string host = "", - std::string x_forwarded_for = "", - bool expect_finished = true, - std::optional expect_total_bytes_parsed_ = std::nullopt) - : request_chunks(std::move(request_chunks_)), + std::string xForwardedFor = "", + bool expectFinished = true, + std::optional expectTotalBytesParsed_ = std::nullopt) + : requestChunks(std::move(requestChunks_)), method(std::move(method)), url(std::move(url)), protocol(std::move(protocol)), host(std::move(host)), - x_forwarded_for(std::move(x_forwarded_for)), - expect_finished(expect_finished), - expect_total_bytes_parsed(expect_total_bytes_parsed_.value_or( - std::accumulate(request_chunks.begin(), request_chunks.end(), 0, [](int sum, const std::string& str) { - return sum + str.length(); - }))) { + xForwardedFor(std::move(xForwardedFor)), + expectFinished(expectFinished), + expectTotalBytesParsed(expectTotalBytesParsed_.value_or(std::accumulate( + requestChunks.begin(), requestChunks.end(), 0, [](int sum, const std::string& str) { return sum + str.length(); }))) { } }; @@ -61,23 +59,23 @@ TEST_P(HttpRequestParserTest, TestValidRequest) { const auto& testData{GetParam()}; HttpRequestParser parser; size_t totalBytesParsed{0}; - for (const auto& chunk : testData.request_chunks) { + for (const auto& chunk : testData.requestChunks) { totalBytesParsed += parser.parse(chunk); } - EXPECT_EQ(parser.is_finished(), testData.expect_finished); - EXPECT_FALSE(parser.is_invalid_state()); - EXPECT_EQ(totalBytesParsed, testData.expect_total_bytes_parsed); + EXPECT_EQ(parser.isFinished(), testData.expectFinished); + EXPECT_FALSE(parser.isInvalidState()); + EXPECT_EQ(totalBytesParsed, testData.expectTotalBytesParsed); EXPECT_EQ(parser.result.method, testData.method); EXPECT_EQ(parser.result.url, testData.url); EXPECT_EQ(parser.result.protocol, testData.protocol); EXPECT_EQ(parser.result.host, testData.host); - EXPECT_EQ(parser.result.x_forwarded_for, testData.x_forwarded_for); + EXPECT_EQ(parser.result.xForwardedFor, testData.xForwardedFor); } struct HttpRequestTestInvalidData { - std::vector request_chunks; - size_t expect_total_bytes_parsed; + std::vector requestChunks; + size_t expectTotalBytesParsed; }; class HttpRequestParserTestInvalid : public ::testing::TestWithParam {}; @@ -86,13 +84,13 @@ TEST_P(HttpRequestParserTestInvalid, testInvalidRequest) { const auto& testData{GetParam()}; HttpRequestParser parser; size_t totalBytesParsed{0}; - for (const auto& chunk : testData.request_chunks) { + for (const auto& chunk : testData.requestChunks) { totalBytesParsed += parser.parse(chunk); } - EXPECT_TRUE(parser.is_finished()); - EXPECT_TRUE(parser.is_invalid_state()); - EXPECT_EQ(totalBytesParsed, testData.expect_total_bytes_parsed); + EXPECT_TRUE(parser.isFinished()); + EXPECT_TRUE(parser.isInvalidState()); + EXPECT_EQ(totalBytesParsed, testData.expectTotalBytesParsed); } INSTANTIATE_TEST_CASE_P(