Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 24 additions & 6 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
cmake_minimum_required (VERSION 3.1)
include(CMakePackageConfigHelpers)
include(CMakeDependentOption)

project (opendht)
set (opendht_VERSION_MAJOR 2)
set (opendht_VERSION_MINOR 0.0)
Expand All @@ -22,7 +25,9 @@ option (OPENDHT_PROXY_SERVER_IDENTITY "Allow clients to use the node identity" O
option (OPENDHT_PROXY_CLIENT "Enable DHT proxy client, use Restinio and jsoncpp" OFF)
option (OPENDHT_PROXY_OPENSSL "Build DHT proxy with OpenSSL" ON)
option (OPENDHT_PROXY_HTTP_PARSER_FORK "Build DHT proxy with custom http_parser to support old API" OFF)
CMAKE_DEPENDENT_OPTION(OPENDHT_HTTP "Build embedded http(s) client" OFF "NOT OPENDHT_PROXY_SERVER;NOT OPENDHT_PROXY_CLIENT" ON)
option (OPENDHT_PEER_DISCOVERY "Enable multicast peer discovery" ON)
option (OPENDHT_CONNECTIVITY_STAT "Enable connectivity stat module" OFF)
option (OPENDHT_INDEX "Build DHT indexation feature" OFF)
option (OPENDHT_TESTS "Add unit tests executable" OFF)
option (OPENDHT_C "Build C bindings" OFF)
Expand Down Expand Up @@ -61,7 +66,7 @@ if (Jsoncpp_FOUND)
)
endif()

if (OPENDHT_PROXY_SERVER OR OPENDHT_PROXY_CLIENT)
if (OPENDHT_HTTP)
find_package(Restinio REQUIRED)
if (Restinio_FOUND)
find_library(FMT_LIBRARY fmt)
Expand All @@ -88,9 +93,12 @@ if (OPENDHT_PROXY_SERVER OR OPENDHT_PROXY_CLIENT)
else()
set(OPENDHT_PROXY_OPENSSL OFF)
endif()
if (OPENDHT_PROXY_SERVER OR OPENDHT_PROXY_CLIENT OR OPENDHT_PEER_DISCOVERY)
if (OPENDHT_HTTP OR OPENDHT_PEER_DISCOVERY)
add_definitions(-DASIO_STANDALONE)
endif()
if (OPENDHT_CONNECTIVITY_STAT)
find_package (NL REQUIRED)
endif()

# Build flags
set (CMAKE_CXX_STANDARD 14)
Expand Down Expand Up @@ -146,6 +154,10 @@ include_directories (
include/opendht/
${CMAKE_CURRENT_BINARY_DIR}/include/
)
if (OPENDHT_CONNECTIVITY_STAT)
include_directories (SYSTEM "${NL_INCLUDE_DIRS}")
link_directories (${NL_LIBRARIES})
endif()

# Install dirs
include (GNUInstallDirs)
Expand Down Expand Up @@ -251,7 +263,7 @@ if (OPENDHT_PROXY_CLIENT)
)
endif ()

if (OPENDHT_PROXY_SERVER OR OPENDHT_PROXY_CLIENT)
if (OPENDHT_HTTP)
if (OPENDHT_PUSH_NOTIFICATIONS)
message("Using push notification")
add_definitions(-DOPENDHT_PUSH_NOTIFICATIONS)
Expand Down Expand Up @@ -282,6 +294,12 @@ if(OPENDHT_ARGON2)
include_directories(argon2/include/)
endif()

if (OPENDHT_CONNECTIVITY_STAT)
list (APPEND opendht_SOURCES src/connstat.cpp)
list (APPEND opendht_HEADERS include/opendht/connstat.h)
add_definitions(-DOPENDHT_CONNECTIVITY_STAT)
endif()

# Targets
if (OPENDHT_STATIC)
add_library (opendht-static STATIC
Expand All @@ -298,7 +316,7 @@ if (OPENDHT_STATIC)
PRIVATE ${argon2_LIBRARIES}
PUBLIC ${CMAKE_THREAD_LIBS_INIT} ${GNUTLS_LIBRARIES} ${Nettle_LIBRARIES}
${Jsoncpp_LIBRARIES} ${FMT_LIBRARY} ${HTTP_PARSER_LIBRARY}
${OPENSSL_LIBRARIES})
${OPENSSL_LIBRARIES} ${NL_LIBRARIES})
install (TARGETS opendht-static DESTINATION ${CMAKE_INSTALL_LIBDIR} EXPORT opendht)
endif ()

Expand All @@ -316,11 +334,12 @@ if (OPENDHT_SHARED)
target_link_libraries(opendht PRIVATE ${argon2_LIBRARIES})
target_include_directories(opendht SYSTEM PRIVATE ${argon2_INCLUDE_DIRS})
endif ()
# FIXME
target_link_libraries(opendht
PUBLIC ${CMAKE_THREAD_LIBS_INIT} ${OPENSSL_LIBRARIES}
PRIVATE ${GNUTLS_LIBRARIES} ${Nettle_LIBRARIES}
${Jsoncpp_LIBRARIES}
${FMT_LIBRARY} ${HTTP_PARSER_LIBRARY})
${FMT_LIBRARY} ${HTTP_PARSER_LIBRARY} ${NL_LIBRARIES})

install (TARGETS opendht DESTINATION ${CMAKE_INSTALL_LIBDIR} EXPORT opendht)
endif ()
Expand Down Expand Up @@ -357,7 +376,6 @@ if (OPENDHT_PYTHON)
endif ()

# CMake module
include(CMakePackageConfigHelpers)
write_basic_package_version_file("${CMAKE_CURRENT_BINARY_DIR}/opendhtConfigVersion.cmake"
VERSION ${opendht_VERSION}
COMPATIBILITY AnyNewerVersion
Expand Down
140 changes: 140 additions & 0 deletions cmake/FindNL.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
#
# Find the native netlink includes and library
#
# If they exist, differentiate between versions 1, 2 and 3.
# Version 1 does not have netlink/version.h
# Version 2 started separating libraries (libnl{,-genl,-route}).
# Version 3 (>= 3.2) started appending the major version number as suffix to
# library names (libnl-3)
#
# NL_INCLUDE_DIRS - where to find libnl.h, etc.
# NL_LIBRARIES - List of libraries when using libnl.
# NL_FOUND - True if libnl found.

if(NL_LIBRARIES AND NL_INCLUDE_DIRS)
# in cache already
SET(NL_FOUND TRUE)
else()
SET( SEARCHPATHS
/opt/local
/sw
/usr
/usr/local
)

find_package(PkgConfig)
pkg_check_modules(NL3 libnl-3.0 libnl-genl-3.0 libnl-route-3.0)
if(NOT NL3_FOUND)
pkg_search_module(NL2 libnl-2.0)
endif()

# Try to find NL 2.0, 3.0 or 3.1 (/usr/include/netlink/version.h) or
# NL >= 3.2 (/usr/include/libnl3/netlink/version.h)
find_path(NL3_INCLUDE_DIR
PATH_SUFFIXES
include/libnl3
include
NAMES
netlink/version.h
HINTS
"${NL3_libnl-3.0_INCLUDEDIR}"
"${NL2_INCLUDEDIR}"
PATHS
$(SEARCHPATHS)
)
# NL version >= 2
if(NL3_INCLUDE_DIR)
find_library(NL3_LIBRARY
NAMES
nl-3 nl
PATH_SUFFIXES
lib64 lib
HINTS
"${NL3_libnl-3.0_LIBDIR}"
"${NL2_LIBDIR}"
PATHS
$(SEARCHPATHS)
)
find_library(NLGENL_LIBRARY
NAMES
nl-genl-3 nl-genl
PATH_SUFFIXES
lib64 lib
HINTS
"${NL3_libnl-genl-3.0_LIBDIR}"
"${NL2_LIBDIR}"
PATHS
$(SEARCHPATHS)
)
find_library(NLROUTE_LIBRARY
NAMES
nl-route-3 nl-route
PATH_SUFFIXES
lib64 lib
HINTS
"${NL3_libnl-route-3.0_LIBDIR}"
"${NL2_LIBDIR}"
PATHS
$(SEARCHPATHS)
)
#
# If we don't have all of those libraries, we can't use libnl.
#
if(NL3_LIBRARY AND NLGENL_LIBRARY AND NLROUTE_LIBRARY)
set(NL_LIBRARY ${NL3_LIBRARY})
# NL2 and NL3 are similar and just affect how the version is reported in
# the --version output. In cast of doubt, assume NL3 since a library
# without version number could be any of 2.0, 3.0 or 3.1.
if(NOT NL3_FOUND AND NL2_FOUND)
set(HAVE_LIBNL2 1)
else()
set(HAVE_LIBNL3 1)
endif()
endif()
set(NL_INCLUDE_DIR ${NL3_INCLUDE_DIR})
endif()

# libnl-2 and libnl-3 not found, try NL version 1
if(NOT (NL_LIBRARY AND NL_INCLUDE_DIR))
pkg_search_module(NL1 libnl-1)
find_path(NL1_INCLUDE_DIR
NAMES
netlink/netlink.h
HINTS
"${NL1_INCLUDEDIR}"
PATHS
$(SEARCHPATHS)
)
find_library(NL1_LIBRARY
NAMES
nl
PATH_SUFFIXES
lib64 lib
HINTS
"${NL1_LIBDIR}"
PATHS
$(SEARCHPATHS)
)
set(NL_LIBRARY ${NL1_LIBRARY})
set(NL_INCLUDE_DIR ${NL1_INCLUDE_DIR})
if(NL1_LIBRARY AND NL1_INCLUDE_DIR)
set(HAVE_LIBNL1 1)
endif()
endif()
endif()

# handle the QUIETLY and REQUIRED arguments and set NL_FOUND to TRUE if
# all listed variables are TRUE
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(NL DEFAULT_MSG NL_LIBRARY NL_INCLUDE_DIR)

IF(NL_FOUND)
set(NL_LIBRARIES ${NLGENL_LIBRARY} ${NLROUTE_LIBRARY} ${NL_LIBRARY})
set(NL_INCLUDE_DIRS ${NL_INCLUDE_DIR})
set(HAVE_LIBNL 1)
else()
set(NL_LIBRARIES )
set(NL_INCLUDE_DIRS)
endif()

MARK_AS_ADVANCED( NL_LIBRARIES NL_INCLUDE_DIRS )
18 changes: 18 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,24 @@ AC_ARG_ENABLE([proxy_server_identity], AS_HELP_STRING([--enable-proxy-server-ide
AC_ARG_ENABLE([proxy_client], AS_HELP_STRING([--enable-proxy-client], [Enable proxy client ability]), proxy_client=yes, proxy_client=no)
AM_CONDITIONAL(ENABLE_PROXY_CLIENT, test x$proxy_client == xyes)

dnl connectivity status
AC_ARG_ENABLE([connstat],
AS_HELP_STRING([--disable-connstat],
[Disable native connectivity stat reports]))
AS_IF([test "$SYS" == "android"], [have_libnl=yes],
[test "$SYS" == "linux"], [PKG_CHECK_MODULES([NL3],
[libnl-3.0 libnl-genl-3.0 libnl-route-3.0],
[have_libnl=yes], [have_libnl=no])],
[have_libnl=no]
)
dnl assert on other hosts
AS_IF([test "x$enable_connstat" = "xyes" && "x$have_libnl" = "xno"], [
AC_MSG_ERROR(["libnl is required connectivity stat"])]
)
AM_CONDITIONAL([ENABLE_CONNSTAT], [test "x$have_libnl" == "xyes"])
AM_COND_IF([ENABLE_CONNSTAT], [AC_DEFINE([ENABLE_CONNSTAT], [1], [Enable connstat])])


AC_ARG_ENABLE([tests], AS_HELP_STRING([--enable-tests], [Enable tests]), build_tests=yes, build_tests=no)
AM_CONDITIONAL(ENABLE_TESTS, test x$build_tests == xyes)
AM_COND_IF([ENABLE_TESTS], [
Expand Down
102 changes: 102 additions & 0 deletions include/opendht/connstat.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/*
* Copyright (C) 2014-2020 Savoir-faire Linux Inc.
* Author(s) : Paymon <paymon@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

#pragma once

#include "log.h"

#include <functional>
#include <thread>
#include <mutex>
#include <atomic>

struct nl_sock;
struct nl_msg;
struct sockaddr_nl;
struct ucred;

namespace dht {
namespace net {

class OPENDHT_PUBLIC ConnectivityStatus
{
public:
enum class Event : long unsigned int {
NONE_EVENT = 0,
ADDR,
ROUTE,
LINK,
NEIGHT,
EVENTS_NEW,
NEWLINK,
NEWROUTE4,
NEWROUTE6,
NEWROUTE,
NEWADDR4,
NEWADDR6,
NEWADDR,
NEWNEIGH,
NEIGHTBL,
IPV4_MROUTE,
IPV6_MROUTE,
IP_MROUTE,
EVENTS_DEL,
DELLINK,
DELROUTE4,
DELROUTE6,
DELROUTE,
DELADDR4,
DELADDR6,
DELADDR,
DELNEIGH
};

ConnectivityStatus();
~ConnectivityStatus();

using ConnectionEventCb = std::function<void (Event)>;

void setEventListener (ConnectionEventCb ucb, Event);
void removeEventListener (Event);

private:

std::mutex mtx_;
std::unique_ptr<dht::Logger> logger_;

std::map<Event, ConnectionEventCb> event_cbs = {};

using NlMsgPtr = std::unique_ptr<nl_msg, void(*)(nl_msg *)>;
NlMsgPtr bye;
using NlPtr = std::unique_ptr<nl_sock, void(*)(nl_sock *)>;
NlPtr nlsk;
static NlPtr nlsk_init ();

void nlsk_setup (nl_sock*);
void nl_event_loop_thrd (nl_sock*);
void get_neigh_state (struct nl_msg*);
int nl_event_cb (struct nl_msg*);
void executer (Event);

std::atomic_bool stop {false};

std::thread thrd_;
};

} /* namespace net */
} /* namespace dht */
Loading