Skip to content
Snippets Groups Projects
  • Louis Maillard's avatar
    88a3c8cd
    packaging: disable postinst auto-setup · 88a3c8cd
    Louis Maillard authored
    Disabled keys generation because it could lead to change of certificate
    during an update => security issue.
    Reconfiguration of yaml is disabled because user will now have to run
    `dhtnet-crtmgr --interactive`, which create the file if needed.
    
    Change-Id: I388ab1cebf75d248600f070be4eb108766bfe993
    88a3c8cd
    History
    packaging: disable postinst auto-setup
    Louis Maillard authored
    Disabled keys generation because it could lead to change of certificate
    during an update => security issue.
    Reconfiguration of yaml is disabled because user will now have to run
    `dhtnet-crtmgr --interactive`, which create the file if needed.
    
    Change-Id: I388ab1cebf75d248600f070be4eb108766bfe993
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
CMakeLists.txt 15.99 KiB
cmake_minimum_required(VERSION 3.16)
project(dhtnet
    VERSION 0.0.1
    LANGUAGES CXX
    DESCRIPTION "A C++ library for NAT traversal and secure communication")

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
include(CTest)
include(GNUInstallDirs)
include(CheckIncludeFileCXX)
set (prefix ${CMAKE_INSTALL_PREFIX})
set (exec_prefix "\${prefix}")
set (libdir "${CMAKE_INSTALL_FULL_LIBDIR}")
set (includedir "${CMAKE_INSTALL_FULL_INCLUDEDIR}")
set (bindir "${CMAKE_INSTALL_FULL_BINDIR}")
set (sysconfdir "${CMAKE_INSTALL_FULL_SYSCONFDIR}")
set (docdir "${CMAKE_INSTALL_FULL_DOCDIR}")
set (top_srcdir "${CMAKE_CURRENT_SOURCE_DIR}")
set (VERSION ${CMAKE_PROJECT_VERSION})

option(DHTNET_PUPNP "Enable UPnP support" ON)
option(DHTNET_NATPMP "Enable NAT-PMP support" ON)
option(DHTNET_TESTABLE "Enable API for tests" ON)
option(BUILD_TOOLS "Build tools" ON)
option(BUILD_BENCHMARKS "Build benchmarks" ON)
option(BUILD_DEPENDENCIES "Build dependencies" ON)
option(DNC_SYSTEMD_UNIT_FILE_LOCATION "Where to install systemd unit file")
option(DNC_SYSTEMD "Enable dnc systemd integration" ON)
option(CODE_COVERAGE "Enable coverage reporting" OFF)

# Check if testing is enabled
if(BUILD_TESTING)
  if(CODE_COVERAGE)
    if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
      # Add the flags for coverage
      add_compile_options(-fprofile-arcs -ftest-coverage --coverage -O0)
      link_libraries(--coverage)
    endif()
  endif()
endif()

if (NOT MSVC)
    # Check if there's a recent enough version of msgpack installed on the system
    find_package(msgpack 5.0.0 QUIET CONFIG NAMES msgpack msgpackc-cxx)
    if (msgpack_FOUND)
        set(MSGPACK_TARGET "msgpackc-cxx")
    else()
        find_package(msgpack 5.0.0 QUIET CONFIG NAMES msgpack-cxx)
        if (msgpack_FOUND)
            set(MSGPACK_TARGET "msgpack-cxx")
        endif()
    endif()
    # If no suitable version of msgpack was found, build the one
    # included as a submodule in the dependencies folder
    if (NOT msgpack_FOUND)
        set(DEPENDENCIES_BUILD_ARGS "--build-msgpack")
    else()
        set(DEPENDENCIES_BUILD_ARGS "")
    endif()

    set(DEPENDENCIES_PATH ${CMAKE_CURRENT_SOURCE_DIR}/dependencies/install/${TARGET})
    message("dependencies path: ${DEPENDENCIES_PATH}")
    if (BUILD_DEPENDENCIES)
        find_package(Python3 COMPONENTS Interpreter)
        execute_process(
            COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/dependencies/build.py ${DEPENDENCIES_BUILD_ARGS}
            WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/dependencies
            RESULT_VARIABLE BUILD_RESULT
        )
        if (BUILD_RESULT)
            message(FATAL_ERROR "Failed to execute build.py script.")
        endif()
    endif()
    include (GNUInstallDirs)
    list(APPEND CMAKE_FIND_ROOT_PATH ${DEPENDENCIES_PATH})
    set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE BOTH)
    list(APPEND CMAKE_PREFIX_PATH ${DEPENDENCIES_PATH})
    find_package (PkgConfig REQUIRED)
    if(NOT BUILD_SHARED_LIBS)
        list(APPEND PKG_CONFIG_EXECUTABLE "--static")
    endif()

    if (BUILD_TOOLS)
        find_package(yaml-cpp REQUIRED)
    endif()

    include_directories(${YAML_CPP_INCLUDE_DIR})
    find_package(fmt)
    pkg_search_module (opendht REQUIRED IMPORTED_TARGET opendht)
    pkg_search_module (pjproject REQUIRED IMPORTED_TARGET libpjproject)
else()
    set (WIN32_DEP_DIR ${PROJECT_SOURCE_DIR}/../)
    include_directories(
        ${WIN32_DEP_DIR}/../msvc/include
        ${WIN32_DEP_DIR}/msgpack-c/include
        ${WIN32_DEP_DIR}/asio/asio/include
        ${WIN32_DEP_DIR}/fmt/include
        ${WIN32_DEP_DIR}/pjproject/pjlib/include
        ${WIN32_DEP_DIR}/pjproject/pjlib-util/include
        ${WIN32_DEP_DIR}/pjproject/pjnath/include
        ${WIN32_DEP_DIR}/opendht/include
        ${WIN32_DEP_DIR}/opendht/src/compat/msvc
        ${WIN32_DEP_DIR}/openssl/include
        ${WIN32_DEP_DIR}/restinio/dev
        ${WIN32_DEP_DIR}/http_parser
        ${WIN32_DEP_DIR}/pupnp/include
        ${WIN32_DEP_DIR}/natpmp/include
    )
    # windirent.h
    include_directories(include/compat/msvc)
endif()

if (NOT MSVC)
    set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} \
        -DMSGPACK_NO_BOOST \
        -DMSGPACK_DISABLE_LEGACY_NIL \
        -DMSGPACK_DISABLE_LEGACY_CONVERT")
else()
    set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} \
        -DGNUTLS_INTERNAL_BUILD \
        -D_USE_MATH_DEFINES \
        -D_SCL_SECURE_NO_WARNINGS \
        -D_CRT_SECURE_NO_WARNINGS \
        -D_WINSOCK_DEPRECATED_NO_WARNINGS \
        -DASIO_STANDALONE \
        -DWIN32_LEAN_AND_MEAN \
        -D_WIN32_WINNT=0x0601 \
        -DNATPMP_STATICLIB \
        -DMSGPACK_NO_BOOST \
        -DMSGPACK_DISABLE_LEGACY_NIL \
        -DMSGPACK_DISABLE_LEGACY_CONVERT \
        -DUNICODE \
        -D_UNICODE")
endif()

if (DNC_SYSTEMD AND BUILD_TOOLS AND NOT MSVC)
    if (NOT DEFINED DNC_SYSTEMD_UNIT_FILE_LOCATION OR NOT DNC_SYSTEMD_UNIT_FILE_LOCATION)
        execute_process(COMMAND ${PKG_CONFIG_EXECUTABLE} systemd --variable=systemdsystemunitdir
                        OUTPUT_VARIABLE SYSTEMD_UNIT_INSTALL_DIR)
        message("-- Using Systemd unit installation directory by pkg-config: " ${SYSTEMD_UNIT_INSTALL_DIR})
    else()
        message("-- Using Systemd unit installation directory requested: " ${DNC_SYSTEMD_UNIT_FILE_LOCATION})
        set(SYSTEMD_UNIT_INSTALL_DIR ${DNC_SYSTEMD_UNIT_FILE_LOCATION})
    endif()

    if (NOT DEFINED DNC_SYSTEMD_PRESET_FILE_LOCATION OR NOT DNC_SYSTEMD_PRESET_FILE_LOCATION)
        execute_process(COMMAND ${PKG_CONFIG_EXECUTABLE} systemd --variable=systemdsystempresetdir
                        OUTPUT_VARIABLE SYSTEMD_PRESET_INSTALL_DIR)
        message("-- Using Systemd preset installation directory by pkg-config: " ${SYSTEMD_PRESET_INSTALL_DIR})
    else()
        message("-- Using Systemd preset installation directory requested: " ${DNC_SYSTEMD_PRESET_FILE_LOCATION})
        set(SYSTEMD_PRESET_INSTALL_DIR ${DNC_SYSTEMD_PRESET_FILE_LOCATION})
    endif()

    configure_file (
        tools/dnc/systemd/dnc.service.in
        systemd/dnc.service
        @ONLY
    )
    if (SYSTEMD_UNIT_INSTALL_DIR)
        string(REGEX REPLACE "[ \t\n]+" "" SYSTEMD_UNIT_INSTALL_DIR "${SYSTEMD_UNIT_INSTALL_DIR}")
        set (systemdunitdir "${SYSTEMD_UNIT_INSTALL_DIR}")
        install (FILES ${CMAKE_CURRENT_BINARY_DIR}/systemd/dnc.service DESTINATION ${systemdunitdir})

        string(REGEX REPLACE "[ \t\n]+" "" SYSTEMD_PRESET_INSTALL_DIR "${SYSTEMD_PRESET_INSTALL_DIR}")
        set (systemdpresetdir "${SYSTEMD_PRESET_INSTALL_DIR}")
        install (FILES tools/dnc/systemd/dhtnet-dnc.preset DESTINATION ${systemdpresetdir})

        install (FILES tools/dnc/dnc.yaml DESTINATION ${sysconfdir}/dhtnet/)
    else()
        message(WARNING "Systemd unit installation directory not found. The systemd unit won't be installed.")
    endif()
endif()
# Sources
list (APPEND dhtnet_SOURCES
    src/connectionmanager.cpp
    src/ice_transport.cpp
    src/multiplexed_socket.cpp
    src/peer_connection.cpp
    src/string_utils.cpp
    src/fileutils.cpp
    src/ip_utils.cpp
    src/security/tls_session.cpp
    src/security/certstore.cpp
    src/security/threadloop.cpp
    src/security/diffie-hellman.cpp
    src/turn/turn_cache.cpp
    src/turn/turn_transport.cpp
    src/upnp/upnp_context.cpp
    src/upnp/upnp_control.cpp
    src/upnp/protocol/mapping.cpp
    src/upnp/protocol/igd.cpp
)

list (APPEND dhtnet_HEADERS
    include/connectionmanager.h
    include/multiplexed_socket.h
    include/tls_session.h
    include/certstore.h
    include/ice_options.h
    include/ice_transport.h
    include/ice_transport_factory.h
    include/ice_socket.h
    include/fileutils.h
    include/string_utils.h
    include/ip_utils.h
    include/upnp/mapping.h
    include/upnp/upnp_context.h
    include/upnp/upnp_control.h
)

# Port mapping dependencies - add sources and libraries
if (DHTNET_PUPNP AND NOT MSVC)
    pkg_search_module (upnp IMPORTED_TARGET upnp libupnp)
    if (NOT upnp_FOUND)
        message("libupnp not found: disabling")
        set(DHTNET_PUPNP Off)
    else()
        message("libupnp found")
        set(upnp_LIBRARIES PkgConfig::upnp)
        set (requiresprivate "${requiresprivate} libupnp")
    endif()
endif()
if (DHTNET_NATPMP AND NOT MSVC)
    pkg_search_module (natpmp IMPORTED_TARGET natpmp)
    if (NOT natpmp_FOUND)
        find_library(natpmp_LIBRARIES natpmp)
        if (NOT natpmp_LIBRARIES)
            message("NAT-PMP not found: disabling")
            set(DHTNET_NATPMP Off)
        else()
            message("NAT-PMP found: ${natpmp_LIBRARIES}")
            set (libsprivate "${libsprivate} -lnatpmp")
        endif()
    else()
        message("NAT-PMP found")
        set(natpmp_LIBRARIES PkgConfig::natpmp)
        set (requiresprivate "${requiresprivate} natpmp")
    endif()
endif()

if (DHTNET_PUPNP)
    list (APPEND dhtnet_PRIVATE_DEFS HAVE_LIBUPNP)
    list (APPEND dhtnet_SOURCES
        src/upnp/protocol/pupnp/pupnp.cpp
        src/upnp/protocol/pupnp/upnp_igd.cpp
    )
    list (APPEND dhtnet_PRIVATELIBS ${upnp_LIBRARIES})
endif()
if (DHTNET_NATPMP)
    list (APPEND dhtnet_PRIVATE_DEFS HAVE_LIBNATPMP)
    list (APPEND dhtnet_SOURCES
        src/upnp/protocol/natpmp/nat_pmp.cpp
        src/upnp/protocol/natpmp/pmp_igd.cpp
    )
    list (APPEND dhtnet_PRIVATELIBS ${natpmp_LIBRARIES})
endif()

add_library(dhtnet ${dhtnet_SOURCES})
if (NOT MSVC)
    target_link_libraries(dhtnet PUBLIC PkgConfig::opendht PkgConfig::pjproject fmt::fmt ${MSGPACK_LIB})
else()
    target_link_libraries(dhtnet PUBLIC
        ${WIN32_DEP_DIR}/../msvc/lib/libopendht.lib
        ${WIN32_DEP_DIR}/../msvc/lib/libpjproject.lib
        ${WIN32_DEP_DIR}/../msvc/lib/libfmt.lib
        ${WIN32_DEP_DIR}/../msvc/lib/libmsgpackc-cxx.lib)
endif()
if (msgpack_FOUND)
    target_link_libraries(dhtnet PUBLIC ${MSGPACK_TARGET})
endif()
if (APPLE)
    target_link_libraries(dhtnet PRIVATE "-framework CoreFoundation" "-framework Security" "resolv")
endif()

target_include_directories(dhtnet PUBLIC
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
    $<INSTALL_INTERFACE:include>
)

target_compile_definitions(dhtnet PRIVATE ${dhtnet_PRIVATE_DEFS})
target_link_libraries(dhtnet PRIVATE ${dhtnet_PRIVATELIBS})
if (MSVC)
    target_compile_definitions(dhtnet PRIVATE
        _CRT_SECURE_NO_WARNINGS
        _WINSOCK_DEPRECATED_NO_WARNINGS
        ASIO_STANDALONE
        _WIN32_WINNT=0x0601
        MSGPACK_NO_BOOST
        MSGPACK_DISABLE_LEGACY_NIL
        MSGPACK_DISABLE_LEGACY_CONVERT
        DHTNET_STATIC
        DHTNET_STATIC_DEFINE
        DHTNET_EXPORTS
        DHTNET_BUILDING
        DHT)
    target_compile_options(dhtnet PRIVATE
        /O2; /Oi; ${DEFAULT_CXX_RUNTIME_LIBRARY}; /Gy; /MP; /Oy-; /sdl-; /W0;
        /FC; /FS; /nologo; /Zi; /wd4996; /wd4503; /wd4180; /wd4244; /wd4267;
        /Zc:__cplusplus;
        ${DEFAULT_CXX_EXCEPTION_HANDLING})
else()
    target_compile_definitions(dhtnet PUBLIC PJ_AUTOCONF=1)
endif()

if (BUILD_TESTING AND NOT MSVC)
    target_compile_definitions(dhtnet PUBLIC DHTNET_TESTABLE)
endif()

configure_file(dhtnet.pc.in dhtnet.pc @ONLY)

# Install targets
install(TARGETS dhtnet)
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/dhtnet)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/dhtnet.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)

if (BUILD_TOOLS AND NOT MSVC)
    add_executable(dnc
        tools/dnc/main.cpp
        tools/dnc/dnc.cpp
        tools/common.cpp
        tools/dhtnet_crtmgr/dhtnet_crtmgr.cpp)
    target_link_libraries(dnc PRIVATE dhtnet fmt::fmt yaml-cpp)
    target_include_directories(dnc PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/tools)
    install(TARGETS dnc RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})

    add_executable(dsh
        tools/dsh/main.cpp
        tools/dsh/dsh.cpp
        tools/common.cpp
        tools/dhtnet_crtmgr/dhtnet_crtmgr.cpp)
    target_link_libraries(dsh PRIVATE dhtnet fmt::fmt yaml-cpp)
    target_include_directories(dsh PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/tools)
    install(TARGETS dsh RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})

    # dvpn is a Linux-only tool
    if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
        add_executable(dvpn
            tools/dvpn/main.cpp
            tools/dvpn/dvpn.cpp
            tools/common.cpp
            tools/dhtnet_crtmgr/dhtnet_crtmgr.cpp)
        target_link_libraries(dvpn PRIVATE dhtnet fmt::fmt yaml-cpp)
        target_include_directories(dvpn PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/tools)
        install(TARGETS dvpn RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
    endif()

    find_library(READLINE_LIBRARIES readline)
    find_path(READLINE_INCLUDE_DIR readline/readline.h)
    add_library(readline STATIC IMPORTED)
    set_target_properties(readline PROPERTIES
        IMPORTED_LOCATION "${READLINE_LIBRARIES}"
        INTERFACE_INCLUDE_DIRECTORIES "${READLINE_INCLUDE_DIR}")
    add_executable(upnpctrl
        tools/upnp/upnpctrl.cpp)
    target_link_libraries(upnpctrl PRIVATE dhtnet fmt::fmt readline)
    target_include_directories(upnpctrl PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/tools)
    install(TARGETS upnpctrl RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})

    add_executable(dhtnet-crtmgr
        tools/dhtnet_crtmgr/main.cpp
        tools/dhtnet_crtmgr/dhtnet_crtmgr.cpp)
    target_link_libraries(dhtnet-crtmgr PRIVATE dhtnet fmt::fmt)
    target_include_directories(dhtnet-crtmgr PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/tools)
    install(TARGETS dhtnet-crtmgr RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})

    add_executable(peerDiscovery
        tools/peerdiscovery/peerDiscovery.cpp)
    target_link_libraries(peerDiscovery PRIVATE dhtnet fmt::fmt readline)
    target_include_directories(peerDiscovery PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/tools/peerdiscovery)
    install(TARGETS peerDiscovery RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})

    install(FILES
        tools/dnc/dnc.1
        tools/dsh/dsh.1
        tools/dvpn/dvpn.1
        tools/dhtnet_crtmgr/dhtnet-crtmgr.1
    DESTINATION ${CMAKE_INSTALL_MANDIR}/man1)

    install(FILES README.md DESTINATION ${docdir})
    install(FILES tools/dnc/README.md RENAME DNC.md DESTINATION ${docdir})
    install(FILES tools/dsh/README.md RENAME DSH.md DESTINATION ${docdir})
    install(FILES tools/dvpn/README.md RENAME DVPN.md DESTINATION ${docdir})
    install(FILES tools/dhtnet_crtmgr/README.md RENAME DHTNET_CRTMGR.md DESTINATION ${docdir})
endif()

if (BUILD_BENCHMARKS)
    add_executable(bench
        tools/benchmark/main.cpp
        tools/common.cpp)
    target_link_libraries(bench PRIVATE dhtnet fmt::fmt)
    target_include_directories(bench PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/tools)
    install(TARGETS bench RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
endif()

if (BUILD_TESTING AND NOT MSVC)
    pkg_search_module(Cppunit REQUIRED IMPORTED_TARGET cppunit)
    add_executable(tests_certstore tests/certstore.cpp)
    target_link_libraries(tests_certstore PRIVATE dhtnet fmt::fmt PkgConfig::Cppunit)
    add_test(NAME tests_certstore COMMAND tests_certstore)

    add_executable(tests_connectionManager tests/connectionManager.cpp)
    target_link_libraries(tests_connectionManager PRIVATE dhtnet fmt::fmt PkgConfig::Cppunit)
    add_test(NAME tests_connectionManager COMMAND tests_connectionManager)

    add_executable(tests_fileutils tests/testFileutils.cpp)
    target_link_libraries(tests_fileutils PRIVATE dhtnet fmt::fmt PkgConfig::Cppunit)
    add_test(NAME tests_fileutils COMMAND tests_fileutils)

    add_executable(tests_ice tests/ice.cpp)
    target_link_libraries(tests_ice PRIVATE dhtnet fmt::fmt PkgConfig::Cppunit)
    add_test(NAME tests_ice COMMAND tests_ice)

    add_executable(tests_turnCache tests/turnCache.cpp)
    target_link_libraries(tests_turnCache PRIVATE dhtnet fmt::fmt PkgConfig::Cppunit)
    add_test(NAME tests_turnCache  COMMAND tests_turnCache)

    add_executable(tests_peerDiscovery tests/peerDiscovery.cpp)
    target_link_libraries(tests_peerDiscovery PRIVATE dhtnet fmt::fmt PkgConfig::Cppunit)
    add_test(NAME tests_peerDiscovery  COMMAND tests_peerDiscovery)

    #add_executable(tests_stringutils tests/testString_utils.cpp)
    #target_link_libraries(tests_stringutils PRIVATE dhtnet fmt::fmt PkgConfig::Cppunit)
    #add_test(NAME tests_stringutils COMMAND tests_stringutils)

endif()