Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

send discovered services to standard output #38

Merged
merged 15 commits into from
Oct 25, 2023
Merged
105 changes: 53 additions & 52 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,91 +11,91 @@ set(CMAKE_CXX_EXTENSIONS FALSE)

# Set BpfObject input parameters -- note this is usually not necessary unless
# you're in a highly vendored environment
if(${CMAKE_SYSTEM_PROCESSOR} MATCHES "x86_64")
set(ARCH "x86")
elseif(${CMAKE_SYSTEM_PROCESSOR} MATCHES "arm")
set(ARCH "arm")
elseif(${CMAKE_SYSTEM_PROCESSOR} MATCHES "aarch64")
set(ARCH "arm64")
elseif(${CMAKE_SYSTEM_PROCESSOR} MATCHES "ppc64le")
set(ARCH "powerpc")
elseif(${CMAKE_SYSTEM_PROCESSOR} MATCHES "mips")
set(ARCH "mips")
elseif(${CMAKE_SYSTEM_PROCESSOR} MATCHES "riscv64")
set(ARCH "riscv")
elseif(${CMAKE_SYSTEM_PROCESSOR} MATCHES "loongarch64")
set(ARCH "loongarch")
endif()
if (${CMAKE_SYSTEM_PROCESSOR} MATCHES "x86_64")
set(ARCH "x86")
elseif (${CMAKE_SYSTEM_PROCESSOR} MATCHES "arm")
set(ARCH "arm")
elseif (${CMAKE_SYSTEM_PROCESSOR} MATCHES "aarch64")
set(ARCH "arm64")
elseif (${CMAKE_SYSTEM_PROCESSOR} MATCHES "ppc64le")
set(ARCH "powerpc")
elseif (${CMAKE_SYSTEM_PROCESSOR} MATCHES "mips")
set(ARCH "mips")
elseif (${CMAKE_SYSTEM_PROCESSOR} MATCHES "riscv64")
set(ARCH "riscv")
elseif (${CMAKE_SYSTEM_PROCESSOR} MATCHES "loongarch64")
set(ARCH "loongarch")
endif ()

set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)

if(CMAKE_BUILD_TYPE STREQUAL "Release")
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
endif()
if (CMAKE_BUILD_TYPE STREQUAL "Release")
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
endif ()

if("${PROJECT_VERSION}" STREQUAL "")
message(FATAL_ERROR "Project version has not been provided\n Please, provide project version using -DPROJECT_VERSION")
endif()
if ("${PROJECT_VERSION}" STREQUAL "")
message(FATAL_ERROR "Project version has not been provided\n Please, provide project version using -DPROJECT_VERSION")
endif ()

string(REGEX MATCH "([0-9]+)\.([0-9]+)\.([0-9]+)" _ "${PROJECT_VERSION}")
if(NOT CMAKE_MATCH_COUNT EQUAL 3)
message(FATAL_ERROR "Incorrect project version number format: ${PROJECT_VERSION}. Please provide the project version number in the format major.minor.patch")
endif()
if (NOT CMAKE_MATCH_COUNT EQUAL 3)
message(FATAL_ERROR "Incorrect project version number format: ${PROJECT_VERSION}. Please provide the project version number in the format major.minor.patch")
endif ()

project(
${_project_name} VERSION "${PROJECT_VERSION}" LANGUAGES C CXX
${_project_name} VERSION "${PROJECT_VERSION}" LANGUAGES C CXX
)

set(BPF_C_FLAGS ${BPF_C_FLAGS} -DTARGET_BPF)

# Set DEBUG macro in debug build and add additional warnings
set(EXTRA_DEBUG_FLAGS -DDEBUG -Wall -Wextra -Wno-unused-parameter -Wno-unused-value -Wno-missing-field-initializers)
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
add_compile_options(${EXTRA_DEBUG_FLAGS})
set(BPF_C_FLAGS ${BPF_C_FLAGS} ${EXTRA_DEBUG_FLAGS})
endif()
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
add_compile_options(${EXTRA_DEBUG_FLAGS})
set(BPF_C_FLAGS ${BPF_C_FLAGS} ${EXTRA_DEBUG_FLAGS})
endif ()

set(Boost_USE_STATIC_LIBS ON)
find_package(Boost REQUIRED COMPONENTS program_options)
if(Boost_FOUND)
include_directories(${Boost_INCLUDE_DIRS})
endif()
if (Boost_FOUND)
include_directories(${Boost_INCLUDE_DIRS})
endif ()

if(NOT TARGET fmt)
find_package(fmt REQUIRED)
endif(NOT TARGET fmt)
if(NOT TARGET spdlog)
find_package(spdlog REQUIRED)
endif(NOT TARGET spdlog)
if (NOT TARGET fmt)
find_package(fmt REQUIRED)
endif (NOT TARGET fmt)
if (NOT TARGET spdlog)
find_package(spdlog REQUIRED)
endif (NOT TARGET spdlog)

find_package(Protobuf REQUIRED)


find_package(Microsoft.GSL REQUIRED)
if(Microsoft.GSL_FOUND)
include_directories(${Microsoft.GSL_INCLUDE_DIRS})
endif()
if (Microsoft.GSL_FOUND)
include_directories(${Microsoft.GSL_INCLUDE_DIRS})
endif ()

set(INSTALL_GTEST OFF CACHE BOOL "Disable installation of googletest" FORCE)

if(BUILD_TESTS OR BUILD_BPF_TESTS)
include(FetchContent)
FetchContent_Declare(googletest URL https://github.com/google/googletest/archive/03597a01ee50ed33e9dfd640b249b4be3799d395.zip)
FetchContent_MakeAvailable(googletest)
if (BUILD_TESTS OR BUILD_BPF_TESTS)
include(FetchContent)
FetchContent_Declare(googletest URL https://github.com/google/googletest/archive/03597a01ee50ed33e9dfd640b249b4be3799d395.zip)
FetchContent_MakeAvailable(googletest)

include(CTest)
include(GoogleTest)
enable_testing()
include(CTest)
include(GoogleTest)
enable_testing()

add_custom_target(run-tests COMMAND ${CMAKE_CTEST_COMMAND} -T Test --no-compress-output --output-on-failure USES_TERMINAL)
endif()
add_custom_target(run-tests COMMAND ${CMAKE_CTEST_COMMAND} -T Test --no-compress-output --output-on-failure USES_TERMINAL)
endif ()

add_subdirectory(thirdparty)
execute_process(
COMMAND ${CMAKE_COMMAND} -DTHIRDPARTY_MAKE_JOBS_COUNT=${THIRDPARTY_MAKE_JOBS_COUNT} ${PROJECT_SOURCE_DIR}/thirdparty
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/thirdparty
COMMAND ${CMAKE_COMMAND} -DTHIRDPARTY_MAKE_JOBS_COUNT=${THIRDPARTY_MAKE_JOBS_COUNT} ${PROJECT_SOURCE_DIR}/thirdparty
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/thirdparty
)
execute_process(COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR}/thirdparty)

Expand All @@ -109,6 +109,7 @@ add_subdirectory(libebpfdiscoveryproto)
add_subdirectory(libebpfdiscoveryshared)
add_subdirectory(libebpfdiscoveryskel)
add_subdirectory(libhttpparser)
add_subdirectory(libservice)
add_subdirectory(liblogging)

include(GNUInstallDirs)
Expand Down
2 changes: 2 additions & 0 deletions ebpfdiscoverysrv/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,6 @@ add_executable(${TARGET} ${SOURCES})
target_link_libraries(${TARGET} Boost::program_options)
target_link_libraries(${TARGET} ebpfdiscovery)
target_link_libraries(${TARGET} logging)
target_link_libraries(${TARGET} service)
target_link_libraries(${TARGET} ebpfdiscoveryproto)
target_compile_definitions(${TARGET} PUBLIC PROJECT_VERSION="${PROJECT_VERSION}")
24 changes: 24 additions & 0 deletions ebpfdiscoverysrv/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include "ebpfdiscovery/Discovery.h"
#include "ebpfdiscovery/DiscoveryBpf.h"
#include "ebpfdiscovery/DiscoveryBpfLoader.h"
#include "ebpfdiscoveryproto/Translator.h"
#include "logging/Logger.h"

#include <boost/program_options.hpp>
Expand Down Expand Up @@ -41,6 +42,7 @@ static po::options_description getProgramOptions() {
("log-level", po::value<logging::LogLevel>()->default_value(logging::LogLevel::Err, "error"), "Set log level {trace,debug,info,warning,error,critical,off}")
("log-no-stdout", po::bool_switch()->default_value(false), "Disable logging to stdout")
("version", "Display program version")
("interval", po::value<int>()->default_value(60), "Services reporting time interval (in seconds)")
;
// clang-format on

Expand Down Expand Up @@ -110,6 +112,23 @@ static void initLibbpf() {
libbpf_set_print(libbpfPrintFn);
}

bool isProgramRunning() {
std::lock_guard<std::mutex> lock(programStatusMutex);
return programStatus == ProgramStatus::Running;
}

void servicesProvidingLoop(ebpfdiscovery::Discovery& discoveryInstance, std::chrono::seconds interval) {
while (isProgramRunning()) {
if (auto services = discoveryInstance.popServices(); !services.empty()) {
auto servicesProto = proto::internalToProto(services);
LOG_DEBUG("Services list:\n{}\n", servicesProto.DebugString());
auto servicesJson = proto::protoToJson(servicesProto);
std::cout << servicesJson << std::endl;
}
std::this_thread::sleep_for(interval);
przsus marked this conversation as resolved.
Show resolved Hide resolved
}
}

int main(int argc, char** argv) {
po::options_description desc{getProgramOptions()};
po::variables_map vm;
Expand Down Expand Up @@ -172,6 +191,7 @@ int main(int argc, char** argv) {
}

if (!isLaunchTest) {
std::thread servicesProvider(servicesProvidingLoop, std::ref(instance), std::chrono::seconds(vm["interval"].as<int>()));
std::thread unixSignalThread(runUnixSignalHandlerLoop);
{
std::unique_lock<std::mutex> programStatusLock(programStatusMutex);
Expand All @@ -182,6 +202,10 @@ int main(int argc, char** argv) {
if (unixSignalThread.joinable()) {
unixSignalThread.join();
}
LOG_TRACE("Waiting for services providing thread to exit.");
if (servicesProvider.joinable()) {
servicesProvider.join();
}
}

LOG_DEBUG("Exiting the program.");
Expand Down
37 changes: 19 additions & 18 deletions libebpfdiscovery/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
list(
APPEND
SOURCES
src/Config.cpp
src/Discovery.cpp
src/DiscoveryBpf.cpp
src/DiscoveryBpfLoader.cpp
src/IpAddressChecker.cpp
src/NetlinkCalls.cpp
src/Session.cpp
src/StringFunctions.cpp
APPEND
SOURCES
src/Config.cpp
src/Discovery.cpp
src/DiscoveryBpf.cpp
src/DiscoveryBpfLoader.cpp
src/IpAddressChecker.cpp
src/NetlinkCalls.cpp
src/Session.cpp
src/StringFunctions.cpp
)
set(TARGET ebpfdiscovery)

Expand All @@ -24,13 +24,14 @@ target_link_libraries(${TARGET} fmt::fmt)
target_link_libraries(${TARGET} httpparser)
target_link_libraries(${TARGET} logging)
target_link_libraries(${TARGET} spdlog::spdlog)
target_link_libraries(${TARGET} service)

if(BUILD_TESTS)
list(APPEND TEST_SOURCES test/StringFunctionsTest.cpp test/LRUCacheTest.cpp test/IpAddressCheckerTest.cpp)
set(TEST_TARGET test${TARGET})
if (BUILD_TESTS)
list(APPEND TEST_SOURCES test/StringFunctionsTest.cpp test/LRUCacheTest.cpp test/IpAddressCheckerTest.cpp)
set(TEST_TARGET test${TARGET})

add_executable(${TEST_TARGET} ${TEST_SOURCES})
target_link_libraries(${TEST_TARGET} GTest::gtest_main GTest::gmock_main ${TARGET})
target_include_directories(${TEST_TARGET} PRIVATE src)
gtest_discover_tests(${TEST_TARGET})
endif()
add_executable(${TEST_TARGET} ${TEST_SOURCES})
target_link_libraries(${TEST_TARGET} GTest::gtest_main GTest::gmock_main ${TARGET})
target_include_directories(${TEST_TARGET} PRIVATE src)
gtest_discover_tests(${TEST_TARGET})
endif ()
8 changes: 7 additions & 1 deletion libebpfdiscovery/headers/ebpfdiscovery/Discovery.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "ebpfdiscovery/Session.h"
#include "ebpfdiscoveryshared/Types.h"
#include "httpparser/HttpRequestParser.h"
#include "service/Aggregator.h"

#include <atomic>
#include <chrono>
Expand Down Expand Up @@ -35,8 +36,10 @@ class Discovery {
void stop();
void wait();

std::vector<service::Service> popServices();

private:
typedef LRUCache<DiscoverySavedSessionKey, Session, DiscoverySavedSessionKeyHash> SavedSessionsCacheType;
using SavedSessionsCacheType = LRUCache<DiscoverySavedSessionKey, Session, DiscoverySavedSessionKeyHash>;

void run();

Expand Down Expand Up @@ -64,6 +67,9 @@ class Discovery {
DiscoveryConfig config;
DiscoveryBpf discoveryBpf;
SavedSessionsCacheType savedSessions;
ebpfdiscovery::NetlinkCalls netlinkCalls;
ebpfdiscovery::IpAddressChecker ipChecker{{}, netlinkCalls};
service::Aggregator serviceAggregator{ipChecker};

std::atomic<bool> running{false};
bool stopReceived{false};
Expand Down
17 changes: 11 additions & 6 deletions libebpfdiscovery/headers/ebpfdiscovery/IpAddressChecker.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
#include <initializer_list>
#include <vector>


namespace ebpfdiscovery {

using IPv4int = uint32_t;
Expand All @@ -17,7 +16,12 @@ struct IpIfce {
bool isLocalBridge;
};

class IpAddressChecker {
class IpAddressCheckerInerface {
public:
virtual bool isAddressExternalLocal(IPv4int addr) = 0;
};

class IpAddressChecker : public IpAddressCheckerInerface {
std::vector<IpIfce> interfaces;
std::vector<IpIfce>::iterator bridgeEnd = interfaces.end();
const NetlinkCalls& netlink;
Expand All @@ -27,13 +31,14 @@ class IpAddressChecker {
bool isLoopback(const IpIfce&);
void addIpIfce(IpIfce&& ifce);
void markBridge(int idx);

protected:
void moveBridges();

public:
IpAddressChecker(const NetlinkCalls &calls);
IpAddressChecker(std::initializer_list<IpIfce> config, const NetlinkCalls &calls);
bool isAddressExternalLocal(IPv4int addr);
IpAddressChecker(const NetlinkCalls& calls);
IpAddressChecker(std::initializer_list<IpIfce> config, const NetlinkCalls& calls);
bool isAddressExternalLocal(IPv4int addr) override;
bool readNetworks();
};
} // namespace ebpfdiscovery

1 change: 0 additions & 1 deletion libebpfdiscovery/src/Config.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// SPDX-License-Identifier: Apache-2.0

#include "ebpfdiscovery/Config.h"
#include "ebpfdiscoveryproto/example.pb.h"

namespace ebpfdiscovery {

Expand Down
7 changes: 6 additions & 1 deletion libebpfdiscovery/src/Discovery.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// SPDX-License-Identifier: Apache-2.0
#include "ebpfdiscovery/Discovery.h"

#include "StringFunctions.h"
#include "ebpfdiscovery/Session.h"
#include "ebpfdiscovery/StringFunctions.h"
#include "logging/Logger.h"

#include <algorithm>
Expand Down Expand Up @@ -174,6 +174,11 @@ void Discovery::handleNewRequest(const Session& session, const DiscoverySessionM
request.xForwardedFor,
meta.pid);
}
serviceAggregator.newRequest(request, meta);
}

std::vector<service::Service> Discovery::popServices() {
return serviceAggregator.popServices();
}

void Discovery::handleCloseEvent(DiscoveryEvent& event) {
Expand Down
Loading
Loading