Skip to content

Commit 1f918ce

Browse files
committed
ConnectivityStatus:
this will help getting more granular reporting of connectivity status from kernel. it is linux/android specific for now with possible future support for bsd/darwin. this is very much a prototype; cleaner interface and code will follow. it adds libnl (ships with android) dependency which is really not required, although expedited prototyping.
1 parent c5c4c21 commit 1f918ce

File tree

6 files changed

+451
-6
lines changed

6 files changed

+451
-6
lines changed

CMakeLists.txt

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ option (OPENDHT_PROXY_CLIENT "Enable DHT proxy client, use Restinio and jsoncpp"
2323
option (OPENDHT_PROXY_OPENSSL "Build DHT proxy with OpenSSL" ON)
2424
option (OPENDHT_PROXY_HTTP_PARSER_FORK "Build DHT proxy with custom http_parser to support old API" OFF)
2525
option (OPENDHT_PEER_DISCOVERY "Enable multicast peer discovery" ON)
26+
option (OPENDHT_CONNECTIVITY_STAT "Enable connectivity stat module" OFF)
2627
option (OPENDHT_INDEX "Build DHT indexation feature" OFF)
2728
option (OPENDHT_TESTS "Add unit tests executable" OFF)
2829
option (OPENDHT_C "Build C bindings" OFF)
@@ -91,6 +92,9 @@ endif()
9192
if (OPENDHT_PROXY_SERVER OR OPENDHT_PROXY_CLIENT OR OPENDHT_PEER_DISCOVERY)
9293
add_definitions(-DASIO_STANDALONE)
9394
endif()
95+
if (OPENDHT_CONNECTIVITY_STAT)
96+
find_package (NL REQUIRED)
97+
endif()
9498

9599
# Build flags
96100
set (CMAKE_CXX_STANDARD 14)
@@ -146,6 +150,10 @@ include_directories (
146150
include/opendht/
147151
${CMAKE_CURRENT_BINARY_DIR}/include/
148152
)
153+
if (OPENDHT_CONNECTIVITY_STAT)
154+
include_directories (SYSTEM "${NL_INCLUDE_DIRS}")
155+
link_directories (${NL_LIBRARIES})
156+
endif()
149157

150158
# Install dirs
151159
include (GNUInstallDirs)
@@ -282,6 +290,12 @@ if(OPENDHT_ARGON2)
282290
include_directories(argon2/include/)
283291
endif()
284292

293+
if (OPENDHT_CONNECTIVITY_STAT)
294+
list (APPEND opendht_SOURCES src/connstat.cpp)
295+
list (APPEND opendht_HEADERS include/opendht/connstat.hpp)
296+
add_definitions(-DOPENDHT_CONNECTIVITY_STAT)
297+
endif()
298+
285299
# Targets
286300
if (OPENDHT_STATIC)
287301
add_library (opendht-static STATIC
@@ -298,7 +312,7 @@ if (OPENDHT_STATIC)
298312
PRIVATE ${argon2_LIBRARIES}
299313
PUBLIC ${CMAKE_THREAD_LIBS_INIT} ${GNUTLS_LIBRARIES} ${Nettle_LIBRARIES}
300314
${Jsoncpp_LIBRARIES} ${FMT_LIBRARY} ${HTTP_PARSER_LIBRARY}
301-
${OPENSSL_LIBRARIES})
315+
${OPENSSL_LIBRARIES} ${NL_LIBRARIES})
302316
install (TARGETS opendht-static DESTINATION ${CMAKE_INSTALL_LIBDIR} EXPORT opendht)
303317
endif ()
304318

@@ -316,11 +330,12 @@ if (OPENDHT_SHARED)
316330
target_link_libraries(opendht PRIVATE ${argon2_LIBRARIES})
317331
target_include_directories(opendht SYSTEM PRIVATE ${argon2_INCLUDE_DIRS})
318332
endif ()
333+
# FIXME
319334
target_link_libraries(opendht
320335
PUBLIC ${CMAKE_THREAD_LIBS_INIT} ${OPENSSL_LIBRARIES}
321336
PRIVATE ${GNUTLS_LIBRARIES} ${Nettle_LIBRARIES}
322337
${Jsoncpp_LIBRARIES}
323-
${FMT_LIBRARY} ${HTTP_PARSER_LIBRARY})
338+
${FMT_LIBRARY} ${HTTP_PARSER_LIBRARY} ${NL_LIBRARIES})
324339

325340
install (TARGETS opendht DESTINATION ${CMAKE_INSTALL_LIBDIR} EXPORT opendht)
326341
endif ()

cmake/FindNL.cmake

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
#
2+
# Find the native netlink includes and library
3+
#
4+
# If they exist, differentiate between versions 1, 2 and 3.
5+
# Version 1 does not have netlink/version.h
6+
# Version 2 started separating libraries (libnl{,-genl,-route}).
7+
# Version 3 (>= 3.2) started appending the major version number as suffix to
8+
# library names (libnl-3)
9+
#
10+
# NL_INCLUDE_DIRS - where to find libnl.h, etc.
11+
# NL_LIBRARIES - List of libraries when using libnl.
12+
# NL_FOUND - True if libnl found.
13+
14+
if(NL_LIBRARIES AND NL_INCLUDE_DIRS)
15+
# in cache already
16+
SET(NL_FOUND TRUE)
17+
else()
18+
SET( SEARCHPATHS
19+
/opt/local
20+
/sw
21+
/usr
22+
/usr/local
23+
)
24+
25+
find_package(PkgConfig)
26+
pkg_check_modules(NL3 libnl-3.0 libnl-genl-3.0 libnl-route-3.0)
27+
if(NOT NL3_FOUND)
28+
pkg_search_module(NL2 libnl-2.0)
29+
endif()
30+
31+
# Try to find NL 2.0, 3.0 or 3.1 (/usr/include/netlink/version.h) or
32+
# NL >= 3.2 (/usr/include/libnl3/netlink/version.h)
33+
find_path(NL3_INCLUDE_DIR
34+
PATH_SUFFIXES
35+
include/libnl3
36+
include
37+
NAMES
38+
netlink/version.h
39+
HINTS
40+
"${NL3_libnl-3.0_INCLUDEDIR}"
41+
"${NL2_INCLUDEDIR}"
42+
PATHS
43+
$(SEARCHPATHS)
44+
)
45+
# NL version >= 2
46+
if(NL3_INCLUDE_DIR)
47+
find_library(NL3_LIBRARY
48+
NAMES
49+
nl-3 nl
50+
PATH_SUFFIXES
51+
lib64 lib
52+
HINTS
53+
"${NL3_libnl-3.0_LIBDIR}"
54+
"${NL2_LIBDIR}"
55+
PATHS
56+
$(SEARCHPATHS)
57+
)
58+
find_library(NLGENL_LIBRARY
59+
NAMES
60+
nl-genl-3 nl-genl
61+
PATH_SUFFIXES
62+
lib64 lib
63+
HINTS
64+
"${NL3_libnl-genl-3.0_LIBDIR}"
65+
"${NL2_LIBDIR}"
66+
PATHS
67+
$(SEARCHPATHS)
68+
)
69+
find_library(NLROUTE_LIBRARY
70+
NAMES
71+
nl-route-3 nl-route
72+
PATH_SUFFIXES
73+
lib64 lib
74+
HINTS
75+
"${NL3_libnl-route-3.0_LIBDIR}"
76+
"${NL2_LIBDIR}"
77+
PATHS
78+
$(SEARCHPATHS)
79+
)
80+
#
81+
# If we don't have all of those libraries, we can't use libnl.
82+
#
83+
if(NL3_LIBRARY AND NLGENL_LIBRARY AND NLROUTE_LIBRARY)
84+
set(NL_LIBRARY ${NL3_LIBRARY})
85+
# NL2 and NL3 are similar and just affect how the version is reported in
86+
# the --version output. In cast of doubt, assume NL3 since a library
87+
# without version number could be any of 2.0, 3.0 or 3.1.
88+
if(NOT NL3_FOUND AND NL2_FOUND)
89+
set(HAVE_LIBNL2 1)
90+
else()
91+
set(HAVE_LIBNL3 1)
92+
endif()
93+
endif()
94+
set(NL_INCLUDE_DIR ${NL3_INCLUDE_DIR})
95+
endif()
96+
97+
# libnl-2 and libnl-3 not found, try NL version 1
98+
if(NOT (NL_LIBRARY AND NL_INCLUDE_DIR))
99+
pkg_search_module(NL1 libnl-1)
100+
find_path(NL1_INCLUDE_DIR
101+
NAMES
102+
netlink/netlink.h
103+
HINTS
104+
"${NL1_INCLUDEDIR}"
105+
PATHS
106+
$(SEARCHPATHS)
107+
)
108+
find_library(NL1_LIBRARY
109+
NAMES
110+
nl
111+
PATH_SUFFIXES
112+
lib64 lib
113+
HINTS
114+
"${NL1_LIBDIR}"
115+
PATHS
116+
$(SEARCHPATHS)
117+
)
118+
set(NL_LIBRARY ${NL1_LIBRARY})
119+
set(NL_INCLUDE_DIR ${NL1_INCLUDE_DIR})
120+
if(NL1_LIBRARY AND NL1_INCLUDE_DIR)
121+
set(HAVE_LIBNL1 1)
122+
endif()
123+
endif()
124+
endif()
125+
126+
# handle the QUIETLY and REQUIRED arguments and set NL_FOUND to TRUE if
127+
# all listed variables are TRUE
128+
INCLUDE(FindPackageHandleStandardArgs)
129+
FIND_PACKAGE_HANDLE_STANDARD_ARGS(NL DEFAULT_MSG NL_LIBRARY NL_INCLUDE_DIR)
130+
131+
IF(NL_FOUND)
132+
set(NL_LIBRARIES ${NLGENL_LIBRARY} ${NLROUTE_LIBRARY} ${NL_LIBRARY})
133+
set(NL_INCLUDE_DIRS ${NL_INCLUDE_DIR})
134+
set(HAVE_LIBNL 1)
135+
else()
136+
set(NL_LIBRARIES )
137+
set(NL_INCLUDE_DIRS)
138+
endif()
139+
140+
MARK_AS_ADVANCED( NL_LIBRARIES NL_INCLUDE_DIRS )

configure.ac

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,9 @@ AC_SUBST(OPENDHT_PATCH_VERSION, opendht_patch_version)
1818

1919
AC_ARG_ENABLE([debug], AS_HELP_STRING([--enable-debug], [Build in debug mode, adds stricter warnings, disables optimization]))
2020
AS_IF([test "x$enable_debug" = "xyes"],
21-
[CXXFLAGS="${CXXFLAGS} -g -Wno-return-type -Wall -Wextra -Wnon-virtual-dtor -O0 -pedantic-errors"],
22-
[CXXFLAGS="${CXXFLAGS} -O3 -pedantic-errors"])
21+
[
22+
CXXFLAGS="${CXXFLAGS} -g -Wno-return-type -Wall -Wextra -Wnon-virtual-dtor -O0 -pedantic-errors -pedantic -ggdb -fsanitize=address"],
23+
[CXXFLAGS="${CXXFLAGS} -O3 -pedantic-errors"])
2324

2425
AC_PROG_CXX
2526
AM_PROG_AR
@@ -121,6 +122,24 @@ AC_ARG_ENABLE([proxy_server_identity], AS_HELP_STRING([--enable-proxy-server-ide
121122
AC_ARG_ENABLE([proxy_client], AS_HELP_STRING([--enable-proxy-client], [Enable proxy client ability]), proxy_client=yes, proxy_client=no)
122123
AM_CONDITIONAL(ENABLE_PROXY_CLIENT, test x$proxy_client == xyes)
123124

125+
dnl connectivity status
126+
AC_ARG_ENABLE([connstat],
127+
AS_HELP_STRING([--disable-connstat],
128+
[Disable native connectivity stat reports]))
129+
AS_IF([test "$SYS" == "android"], [have_libnl=yes],
130+
[test "$SYS" == "linux"], [PKG_CHECK_MODULES([NL3],
131+
[libnl-3.0 libnl-genl-3.0 libnl-route-3.0],
132+
[have_libnl=yes], [have_libnl=no])],
133+
[have_libnl=no]
134+
)
135+
dnl assert on other hosts
136+
AS_IF([test "x$enable_connstat" = "xyes" && "x$have_libnl" = "xno"], [
137+
AC_MSG_ERROR(["libnl is required connectivity stat"])]
138+
)
139+
AM_CONDITIONAL([ENABLE_CONNSTAT], [test "x$have_libnl" == "xyes"])
140+
AM_COND_IF([ENABLE_CONNSTAT], [AC_DEFINE([ENABLE_CONNSTAT], [1], [Enable connstat])])
141+
142+
124143
AC_ARG_ENABLE([tests], AS_HELP_STRING([--enable-tests], [Enable tests]), build_tests=yes, build_tests=no)
125144
AM_CONDITIONAL(ENABLE_TESTS, test x$build_tests == xyes)
126145
AM_COND_IF([ENABLE_TESTS], [

include/opendht/connstat.h

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
/*
2+
* Copyright (C) 2014-2020 Savoir-faire Linux Inc.
3+
* Author(s) : Paymon <[email protected]>
4+
*
5+
* This program is free software; you can redistribute it and/or modify
6+
* it under the terms of the GNU General Public License as published by
7+
* the Free Software Foundation; either version 3 of the License, or
8+
* (at your option) any later version.
9+
*
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU General Public License
16+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
17+
*/
18+
19+
#pragma once
20+
21+
#include "log.h"
22+
23+
#include <functional>
24+
#include <thread>
25+
26+
struct nl_sock;
27+
struct nl_msg;
28+
29+
namespace dht {
30+
namespace net {
31+
32+
class OPENDHT_PUBLIC ConnectivityStatus
33+
{
34+
public:
35+
enum class topic : const long unsigned int {
36+
NONE_TOPIC = 0,
37+
ADDR,
38+
ROUTE,
39+
LINK,
40+
NEIGHT,
41+
TOPICS_NEW,
42+
NEWLINK,
43+
NEWROUTE4,
44+
NEWROUTE6,
45+
NEWROUTE,
46+
NEWADDR4,
47+
NEWADDR6,
48+
NEWADDR,
49+
NEWNEIGH,
50+
NEIGHTBL,
51+
IPV4_MROUTE,
52+
IPV6_MROUTE,
53+
IP_MROUTE,
54+
TOPICS_DEL,
55+
DELLINK,
56+
DELROUTE4,
57+
DELROUTE6,
58+
DELROUTE,
59+
DELADDR4,
60+
DELADDR6,
61+
DELADDR,
62+
DELNEIGH,
63+
TOPICS_MAX
64+
};
65+
66+
ConnectivityStatus();
67+
68+
using connstat_event_cb = std::function<void (unsigned int)>;
69+
70+
void setTopicListener (connstat_event_cb ucb, topic);
71+
void removeTopicListener (topic);
72+
73+
bool nl_event_cb (struct nl_msg*);
74+
75+
private:
76+
bool SUCCESS, FAILURE;
77+
78+
static const std::size_t topics_max = static_cast<std::size_t>(topic::TOPICS_MAX);
79+
std::array<connstat_event_cb, topics_max> topic_cbs = {};
80+
81+
using NlPtr = std::unique_ptr<nl_sock, void(*)(nl_sock *)>;
82+
NlPtr nlsk;
83+
static NlPtr nlsk_init ();
84+
85+
bool nlsk_setup (nl_sock*);
86+
void nl_event_loop_thrd (nl_sock*);
87+
bool get_neigh_state (struct nl_msg*);
88+
void executer (topic);
89+
90+
std::unique_ptr<dht::Logger> logger_;
91+
92+
std::thread thrd_;
93+
94+
};
95+
96+
} /* namespace net */
97+
} /* namespace dht */

src/Makefile.am

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
lib_LTLIBRARIES = libopendht.la
22

3-
libopendht_la_CPPFLAGS = @CPPFLAGS@ -I$(top_srcdir)/include/opendht @Argon2_CFLAGS@ @JsonCpp_CFLAGS@ @MsgPack_CFLAGS@ @OpenSSL_CFLAGS@ @Fmt_CFLAGS@
4-
libopendht_la_LIBADD = @Argon2_LIBS@ @JsonCpp_LIBS@ @GnuTLS_LIBS@ @Nettle_LIBS@ @OpenSSL_LIBS@ @Fmt_LIBS@
3+
libopendht_la_CPPFLAGS = @CPPFLAGS@ -I$(top_srcdir)/include/opendht @Argon2_CFLAGS@ @JsonCpp_CFLAGS@ @MsgPack_CFLAGS@ @OpenSSL_CFLAGS@ @Fmt_CFLAGS@ @NL3_CFLAGS@
4+
libopendht_la_LIBADD = @Argon2_LIBS@ @JsonCpp_LIBS@ @GnuTLS_LIBS@ @Nettle_LIBS@ @OpenSSL_LIBS@ @Fmt_LIBS@ @Nettle_LIBS@ @NL3_LIBS@
55
libopendht_la_LDFLAGS = @LDFLAGS@ @Argon2_LDFLAGS@ -version-number @OPENDHT_MAJOR_VERSION@:@OPENDHT_MINOR_VERSION@:@OPENDHT_PATCH_VERSION@
66
libopendht_la_SOURCES = \
77
dht.cpp \
@@ -80,6 +80,11 @@ libopendht_la_SOURCES += peer_discovery.cpp
8080
nobase_include_HEADERS += ../include/opendht/peer_discovery.h
8181
endif
8282

83+
if ENABLE_CONNSTAT
84+
libopendht_la_SOURCES += connstat.cpp
85+
nobase_include_HEADERS += ../include/opendht/connstat.h
86+
endif
87+
8388
if ENABLE_INDEXATION
8489
libopendht_la_SOURCES += indexation/pht.cpp
8590
nobase_include_HEADERS += ../include/opendht/indexation/pht.h

0 commit comments

Comments
 (0)