mirror of
https://github.com/savoirfairelinux/opendht.git
synced 2026-11-08 20:37:23 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
83f8a92e5e | ||
|
|
f41685b864 | ||
|
|
84adbddd6f | ||
|
|
fa9730dd07 | ||
|
|
33f29e95f4 | ||
|
|
fdfa10bd2e | ||
|
|
f200f9dfc2 | ||
|
|
9615774114 | ||
|
|
c6b0e531c2 | ||
|
|
8e5f12dbf1 | ||
|
|
5bcf1da505 | ||
|
|
97d88fcfed | ||
|
|
963dd6779e | ||
|
|
54a4327039 | ||
|
|
10e5439048 | ||
|
|
dcca94aab7 | ||
|
|
173a9ee642 | ||
|
|
ed1ca6db8f | ||
|
|
7367158284 | ||
|
|
cf8d9ccd0d | ||
|
|
fdbdc91d55 | ||
|
|
cf9c63abb7 | ||
|
|
475b26048f | ||
|
|
df1615e8d1 | ||
|
|
9e461e0960 |
No files matched your search
+5
-31
@@ -1,44 +1,18 @@
|
||||
sudo: false
|
||||
sudo: required
|
||||
|
||||
services:
|
||||
- docker
|
||||
|
||||
language: cpp
|
||||
|
||||
compiler:
|
||||
- gcc
|
||||
- clang
|
||||
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
packages:
|
||||
- gcc-6
|
||||
- g++-6
|
||||
- libgnutls28-dev
|
||||
- cmake
|
||||
|
||||
before_install:
|
||||
- if [ $TRAVIS_OS_NAME == linux ] && [ $CXX == g++ ]; then export CXX=/usr/bin/g++-6 && export CC=/usr/bin/gcc-6; fi
|
||||
- if [ $TRAVIS_OS_NAME == linux ]; then git clone https://github.com/msgpack/msgpack-c.git; fi
|
||||
- if [ $TRAVIS_OS_NAME == linux ]; then cd msgpack-c && git checkout cpp-1.2.0 && mkdir build && mkdir -p $HOME/usr && cd build; fi
|
||||
- if [ $TRAVIS_OS_NAME == linux ]; then cmake -DCMAKE_INSTALL_PREFIX=$HOME/usr -DMSGPACK_CXX11=ON -DMSGPACK_BUILD_EXAMPLES=OFF .. && make -j && make install && cd ../.. && pwd; fi
|
||||
- if [ $TRAVIS_OS_NAME == osx ]; then brew update && brew install llvm36 && brew install msgpack && brew install gnutls && brew link --force llvm36; fi
|
||||
|
||||
before_script:
|
||||
- if [ $TRAVIS_OS_NAME == linux ]; then travis_retry ./autogen.sh && ./configure --prefix=$HOME/usr; fi
|
||||
- if [ $TRAVIS_OS_NAME == osx ]; then travis_retry ./autogen.sh && ./configure; fi
|
||||
- docker pull aberaud/opendht-deps
|
||||
- docker pull aberaud/opendht-deps-llvm
|
||||
|
||||
script:
|
||||
- make -j
|
||||
- docker build -f docker/DockerfileTravis .
|
||||
- docker build -f docker/DockerfileTravisLlvm .
|
||||
|
||||
notifications:
|
||||
email:
|
||||
- adrien.beraud@savoirfairelinux.com
|
||||
|
||||
env:
|
||||
- LANG="en_US.UTF-8"
|
||||
|
||||
os:
|
||||
- osx
|
||||
+1
-2
@@ -1,7 +1,7 @@
|
||||
cmake_minimum_required (VERSION 2.8.6)
|
||||
project (opendht)
|
||||
set (opendht_VERSION_MAJOR 0)
|
||||
set (opendht_VERSION_MINOR 6.3)
|
||||
set (opendht_VERSION_MINOR 6.1)
|
||||
set (opendht_VERSION ${opendht_VERSION_MAJOR}.${opendht_VERSION_MINOR})
|
||||
set (PACKAGE_VERSION ${opendht_VERSION})
|
||||
set (VERSION "${opendht_VERSION}")
|
||||
@@ -132,7 +132,6 @@ endif ()
|
||||
if (OPENDHT_TOOLS)
|
||||
add_subdirectory(tools)
|
||||
endif ()
|
||||
add_subdirectory(doc)
|
||||
|
||||
if (OPENDHT_PYTHON)
|
||||
add_subdirectory(python)
|
||||
|
||||
@@ -10,7 +10,9 @@ if USE_CYTHON
|
||||
SUBDIRS += python
|
||||
endif
|
||||
|
||||
if HAVE_DOXYGEN
|
||||
SUBDIRS += doc
|
||||
endif
|
||||
|
||||
ACLOCAL_AMFLAGS = -I m4
|
||||
|
||||
|
||||
@@ -97,11 +97,7 @@ Licence
|
||||
-
|
||||
Copyright (C) 2014-2016 Savoir-faire Linux Inc.
|
||||
|
||||
OpenDHT 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.
|
||||
|
||||
See COPYING or https://www.gnu.org/licenses/gpl-3.0.en.html for the full GPLv3 licence.
|
||||
Licenced under the GNU General Public License version 3 (see COPYING for the full licence).
|
||||
|
||||
This project is independent from another project called OpenDHT (Sean Rhea. Ph.D. Thesis, 2005), now extinct.
|
||||
|
||||
|
||||
+2
-13
@@ -1,21 +1,10 @@
|
||||
dnl define macros
|
||||
m4_define([opendht_major_version], 0)
|
||||
m4_define([opendht_minor_version], 6)
|
||||
m4_define([opendht_patch_version], 3)
|
||||
m4_define([opendht_version],
|
||||
[opendht_major_version.opendht_minor_version.opendht_patch_version])
|
||||
|
||||
AC_INIT(opendht, [opendht_version])
|
||||
AC_INIT(opendht, 0.6.1)
|
||||
AC_CONFIG_AUX_DIR(ac)
|
||||
AM_INIT_AUTOMAKE([foreign subdir-objects])
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
AC_CANONICAL_HOST
|
||||
|
||||
AC_SUBST(OPENDHT_MAJOR_VERSION, opendht_major_version)
|
||||
AC_SUBST(OPENDHT_MINOR_VERSION, opendht_minor_version)
|
||||
AC_SUBST(OPENDHT_PATCH_VERSION, opendht_patch_version)
|
||||
|
||||
AC_ARG_ENABLE([debug], AS_HELP_STRING([--enable-debug], [Build in debug mode, adds stricter warnings, disables optimization]))
|
||||
AS_IF([test "x$enable_debug" = "xyes"],
|
||||
[CXXFLAGS="${CXXFLAGS} -g -Wno-return-type -Wall -Wextra -Wnon-virtual-dtor -O0"],
|
||||
@@ -99,7 +88,7 @@ AM_COND_IF([ENABLE_TOOLS], [
|
||||
])
|
||||
])
|
||||
|
||||
AC_CONFIG_FILES([doc/Doxyfile doc/Makefile])
|
||||
AM_COND_IF([HAVE_DOXYGEN], [AC_CONFIG_FILES([doc/Doxyfile doc/Makefile])])
|
||||
|
||||
dnl Configure setup.py if we build the python module
|
||||
AM_COND_IF([USE_CYTHON], [
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
if (OPENDHT_TOOLS)
|
||||
INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/dhtnode.1 DESTINATION ${CMAKE_INSTALL_PREFIX}/share/man/man1)
|
||||
endif ()
|
||||
@@ -1,6 +1,3 @@
|
||||
dist_man1_MANS = dhtnode.1
|
||||
|
||||
if HAVE_DOXYGEN
|
||||
doxyfile.stamp:
|
||||
$(DOXYGEN) Doxyfile
|
||||
echo stamp > doxyfile.stamp
|
||||
@@ -10,4 +7,3 @@ CLEANFILES = doxyfile.stamp
|
||||
all-local: doxyfile.stamp
|
||||
clean-local:
|
||||
rm -rf $(top_srcdir)/doc/man $(top_srcdir)/doc/html
|
||||
endif
|
||||
@@ -1,85 +0,0 @@
|
||||
.TH DHTNODE 1 2016-06-27
|
||||
|
||||
.SH NAME
|
||||
.B dhtnode
|
||||
- a simple OpenDHT command line node runner.
|
||||
|
||||
.SH SYNOPSIS
|
||||
.B dhtnode [-h]
|
||||
|
||||
.B dhtnode [-v[\fIlogfile\fP]] [-i] [-d] [-n \fInetwork_id\fP] [-p \fIlocal_port\fP] [-b[\fIbootstrap_host\fP[:\fIport\fP]]]
|
||||
|
||||
.SH DESCRIPTION
|
||||
|
||||
This program runs a simple OpenDHT node in an interactive way. If you rather
|
||||
want to run the node in daemon mode, option \fB'-d'\fP is provided. When running
|
||||
in the interactive shell, you benefit from the readline capabilities for writing
|
||||
your commands such as command history. Here are the available commands in the
|
||||
interactive shell:
|
||||
|
||||
.EE
|
||||
h, help Print this help message.
|
||||
q, quit Quit the program.
|
||||
log Start/stop printing DHT logs.
|
||||
|
||||
Node information:
|
||||
ll Print basic information and stats about the current node.
|
||||
ls Print basic information about current searches.
|
||||
ld Print basic information about currenty stored values on this node.
|
||||
lr Print the full current routing table of this node
|
||||
|
||||
Operations on the DHT:
|
||||
b ip:port Ping potential node at given IP address/port.
|
||||
g [key] Get values at [key].
|
||||
l [key] Listen for value changes at [key].
|
||||
p [key] [str] Put string value at [key].
|
||||
s [key] [str] Put string value at [key], signed with our generated
|
||||
private key.
|
||||
e [key] [dest] [str] Put string value at [key], encrypted for [dest] with
|
||||
its public key (if found).
|
||||
|
||||
.SH OPTIONS
|
||||
|
||||
.TP
|
||||
\fB-h\fP
|
||||
Prints some help.
|
||||
|
||||
.TP
|
||||
\fB-v\fP[\fIlogfile\fP]
|
||||
Enable the verbose mode. Optionally provide a log file.
|
||||
|
||||
.TP
|
||||
\fB-i\fP
|
||||
Generate cryptographic identity for the node.
|
||||
|
||||
.TP
|
||||
\fB-d\fP
|
||||
Run the program in daemon mode (will fork in the background).
|
||||
|
||||
.TP
|
||||
\fB-n\fP \fInetwork_id\fP
|
||||
Specify the network id. This let you connect to distinct networks and prevents
|
||||
the merge of two different networks (available since OpenDHT v0.6.1).
|
||||
|
||||
.TP
|
||||
\fB-p\fP \fIlocal_port\fP
|
||||
Use port \fIlocal_port\fP for the program to bind to.
|
||||
|
||||
.TP
|
||||
\fB-b\fP[\fIbootstrap_host\fP[:\fIport\fP]]
|
||||
The program needs to be given a node to connect to the network. You use this
|
||||
option to provide the ip address of that node. If no argument is provided, the
|
||||
node runs in \fBbootstrap mode\fP, i.e. it will especially serve as entry point
|
||||
in the network.
|
||||
|
||||
.SH AUTHORS
|
||||
.TP
|
||||
Program written by
|
||||
.IP \(bu
|
||||
.\}
|
||||
Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
.TP
|
||||
Man page written by
|
||||
.IP \(bu
|
||||
.\}
|
||||
Simon Désaulniers <sim.desaulniers@gmail.com>
|
||||
@@ -0,0 +1,6 @@
|
||||
FROM aberaud/opendht-deps
|
||||
MAINTAINER Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
RUN git clone https://github.com/savoirfairelinux/opendht.git \
|
||||
&& cd opendht && mkdir build && cd build \
|
||||
&& cmake .. -DCMAKE_INSTALL_PREFIX=/usr && make -j8 && make install \
|
||||
&& cd ../.. && rm -rf opendht
|
||||
@@ -0,0 +1,9 @@
|
||||
FROM ubuntu:16.04
|
||||
MAINTAINER Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
RUN apt-get update && apt-get install -y build-essential cmake git wget libncurses5-dev libreadline-dev nettle-dev libgnutls-dev cython3 python3-dev python3-setuptools
|
||||
RUN wget https://github.com/msgpack/msgpack-c/releases/download/cpp-1.4.2/msgpack-1.4.2.tar.gz \
|
||||
&& tar -xzf msgpack-1.4.2.tar.gz \
|
||||
&& cd msgpack-1.4.2 && mkdir build && cd build \
|
||||
&& cmake -DMSGPACK_CXX11=ON -DMSGPACK_BUILD_EXAMPLES=OFF -DCMAKE_INSTALL_PREFIX=/usr .. \
|
||||
&& make -j8 && make install \
|
||||
&& cd ../.. && rm -rf msgpack-1.4.2
|
||||
@@ -0,0 +1,11 @@
|
||||
FROM ubuntu:16.04
|
||||
MAINTAINER Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y llvm clang make cmake git wget libncurses5-dev libreadline-dev nettle-dev libgnutls-dev cython3 python3-dev python3-setuptools \
|
||||
&& apt-get remove -y gcc g++ && apt-get autoremove -y && apt-get clean
|
||||
RUN wget https://github.com/msgpack/msgpack-c/releases/download/cpp-1.4.2/msgpack-1.4.2.tar.gz \
|
||||
&& tar -xzf msgpack-1.4.2.tar.gz \
|
||||
&& cd msgpack-1.4.2 && mkdir build && cd build \
|
||||
&& cmake -DMSGPACK_CXX11=ON -DMSGPACK_BUILD_EXAMPLES=OFF -DCMAKE_INSTALL_PREFIX=/usr .. \
|
||||
&& make -j8 && make install \
|
||||
&& cd ../.. && rm -rf msgpack-1.4.2
|
||||
@@ -0,0 +1,6 @@
|
||||
FROM aberaud/opendht-deps-llvm
|
||||
MAINTAINER Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
RUN git clone https://github.com/savoirfairelinux/opendht.git \
|
||||
&& cd opendht && mkdir build && cd build \
|
||||
&& cmake .. -DCMAKE_INSTALL_PREFIX=/usr && make -j8 && make install \
|
||||
&& cd ../.. && rm -rf opendht
|
||||
@@ -0,0 +1,6 @@
|
||||
FROM aberaud/opendht-deps
|
||||
MAINTAINER Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
COPY . /root/opendht
|
||||
RUN cd /root/opendht && mkdir build && cd build \
|
||||
&& cmake -DCMAKE_INSTALL_PREFIX=/usr .. && make -j8 && make install \
|
||||
&& cd ../.. && rm -rf opendht
|
||||
@@ -0,0 +1,6 @@
|
||||
FROM aberaud/opendht-deps-llvm
|
||||
MAINTAINER Adrien Béraud <adrien.beraud@savoirfairelinux.com>
|
||||
COPY . /root/opendht
|
||||
RUN cd /root/opendht && mkdir build && cd build \
|
||||
&& cmake -DCMAKE_INSTALL_PREFIX=/usr .. && make -j8 && make install \
|
||||
&& cd ../.. && rm -rf opendht
|
||||
@@ -30,44 +30,23 @@ namespace dht {
|
||||
|
||||
struct Node;
|
||||
|
||||
/**
|
||||
* Current status of a DHT node.
|
||||
*/
|
||||
enum class NodeStatus {
|
||||
Disconnected, // 0 nodes
|
||||
Connecting, // 1+ nodes
|
||||
Connected // 1+ good nodes
|
||||
};
|
||||
|
||||
/**
|
||||
* Dht configuration.
|
||||
*/
|
||||
struct Config {
|
||||
/** DHT node ID */
|
||||
InfoHash node_id;
|
||||
|
||||
/**
|
||||
* DHT network ID. A node will only talk with other nodes having
|
||||
* the same network ID.
|
||||
* Network ID 0 (default) represents the main public network.
|
||||
*/
|
||||
NetId network;
|
||||
|
||||
/** For testing purposes only, enables bootstrap mode */
|
||||
bool is_bootstrap;
|
||||
};
|
||||
|
||||
/**
|
||||
* SecureDht configuration.
|
||||
*/
|
||||
struct SecureDhtConfig
|
||||
{
|
||||
Config node_config;
|
||||
crypto::Identity id;
|
||||
};
|
||||
|
||||
static constexpr size_t DEFAULT_STORAGE_LIMIT {1024 * 1024 * 64};
|
||||
|
||||
using ValuesExport = std::pair<InfoHash, Blob>;
|
||||
|
||||
using GetCallback = std::function<bool(const std::vector<std::shared_ptr<Value>>& values)>;
|
||||
@@ -78,6 +57,8 @@ using CertificateStoreQuery = std::function<std::vector<std::shared_ptr<crypto::
|
||||
|
||||
typedef bool (*GetCallbackRaw)(std::shared_ptr<Value>, void *user_data);
|
||||
|
||||
static constexpr size_t DEFAULT_STORAGE_LIMIT {1024 * 1024 * 64};
|
||||
|
||||
GetCallbackSimple bindGetCb(GetCallbackRaw raw_cb, void* user_data);
|
||||
GetCallback bindGetCb(GetCallbackSimple cb);
|
||||
|
||||
|
||||
@@ -392,7 +392,7 @@ private:
|
||||
RoutingTable buckets {};
|
||||
RoutingTable buckets6 {};
|
||||
|
||||
std::vector<std::unique_ptr<Storage>> store;
|
||||
std::vector<Storage> store;
|
||||
size_t total_values {0};
|
||||
size_t total_store_size {0};
|
||||
size_t max_store_size {DEFAULT_STORAGE_LIMIT};
|
||||
|
||||
@@ -268,13 +268,12 @@ public:
|
||||
* @param threaded: If false, ::loop() must be called periodically. Otherwise a thread is launched.
|
||||
* @param cb: Optional callback to receive general state information.
|
||||
*/
|
||||
void run(in_port_t port, const crypto::Identity identity, bool threaded = false, NetId network = 0) {
|
||||
void run(in_port_t port, const crypto::Identity identity, bool threaded = false, bool is_bootstrap = false) {
|
||||
run(port, {
|
||||
/*.dht_config = */{
|
||||
/*.node_config = */{
|
||||
/*.node_id = */{},
|
||||
/*.network = */network,
|
||||
/*.is_bootstrap = */false
|
||||
/*.is_bootstrap = */is_bootstrap
|
||||
},
|
||||
/*.id = */identity
|
||||
},
|
||||
|
||||
@@ -256,7 +256,7 @@ public:
|
||||
using RequestExpiredCb = std::function<void(const Request&, bool)>;
|
||||
|
||||
NetworkEngine(Logger& log, Scheduler& scheduler) : myid(zeroes), DHT_LOG(log), scheduler(scheduler) {}
|
||||
NetworkEngine(InfoHash& myid, NetId net, int s, int s6, Logger& log, Scheduler& scheduler,
|
||||
NetworkEngine(InfoHash& myid, int s, int s6, Logger& log, Scheduler& scheduler,
|
||||
decltype(NetworkEngine::onError) onError,
|
||||
decltype(NetworkEngine::onNewNode) onNewNode,
|
||||
decltype(NetworkEngine::onReportedAddr) onReportedAddr,
|
||||
@@ -266,7 +266,7 @@ public:
|
||||
decltype(NetworkEngine::onListen) onListen,
|
||||
decltype(NetworkEngine::onAnnounce) onAnnounce) :
|
||||
onError(onError), onNewNode(onNewNode), onReportedAddr(onReportedAddr), onPing(onPing), onFindNode(onFindNode),
|
||||
onGetValues(onGetValues), onListen(onListen), onAnnounce(onAnnounce), myid(myid), network(net),
|
||||
onGetValues(onGetValues), onListen(onListen), onAnnounce(onAnnounce), myid(myid),
|
||||
dht_socket(s), dht_socket6(s6), DHT_LOG(log), scheduler(scheduler)
|
||||
{
|
||||
transaction_id = std::uniform_int_distribution<decltype(transaction_id)>{1}(rd_device);
|
||||
@@ -376,7 +376,6 @@ private:
|
||||
|
||||
/* DHT info */
|
||||
const InfoHash& myid;
|
||||
const NetId network {0};
|
||||
const int dht_socket {-1};
|
||||
const int dht_socket6 {-1};
|
||||
const Logger& DHT_LOG;
|
||||
|
||||
@@ -23,8 +23,6 @@
|
||||
|
||||
namespace dht {
|
||||
|
||||
static constexpr unsigned TARGET_NODES {8};
|
||||
|
||||
struct Bucket {
|
||||
Bucket() : cached() {}
|
||||
Bucket(sa_family_t af, const InfoHash& f = {}, time_point t = time_point::min())
|
||||
|
||||
@@ -40,8 +40,9 @@
|
||||
|
||||
namespace dht {
|
||||
|
||||
static constexpr unsigned TARGET_NODES {8};
|
||||
|
||||
using Address = std::pair<sockaddr_storage, socklen_t>;
|
||||
using NetId = uint32_t;
|
||||
using want_t = int_fast8_t;
|
||||
|
||||
std::string print_addr(const sockaddr* sa, socklen_t slen);
|
||||
|
||||
+13
-10
@@ -208,23 +208,23 @@ class DhtFeatureTest(FeatureTest):
|
||||
FeatureTest.lock.notify()
|
||||
|
||||
def _dhtPut(self, producer, _hash, *values):
|
||||
for val in values:
|
||||
with FeatureTest.lock:
|
||||
vstr = val.__str__()[:100]
|
||||
DhtNetwork.log('[PUT]:', _hash.toString(), '->', vstr + ("..." if len(vstr) > 100 else ""))
|
||||
FeatureTest.done += 1
|
||||
while FeatureTest.done > 0:
|
||||
with FeatureTest.lock:
|
||||
for val in values:
|
||||
vstr = val.__str__()[:100]
|
||||
DhtNetwork.log('[PUT]:', _hash.toString(), '->', vstr + ("..." if len(vstr) > 100 else ""))
|
||||
FeatureTest.done += 1
|
||||
producer.put(_hash, val, DhtFeatureTest.putDoneCb)
|
||||
FeatureTest.lock.wait()
|
||||
while FeatureTest.done > 0:
|
||||
FeatureTest.lock.wait()
|
||||
|
||||
def _dhtGet(self, consumer, _hash):
|
||||
DhtFeatureTest.foreignValues = []
|
||||
DhtFeatureTest.foreignNodes = []
|
||||
with FeatureTest.lock:
|
||||
FeatureTest.done += 1
|
||||
DhtNetwork.log('[GET]:', _hash.toString())
|
||||
consumer.get(_hash, DhtFeatureTest.getcb, DhtFeatureTest.getDoneCb)
|
||||
while FeatureTest.done > 0:
|
||||
DhtNetwork.log('[GET]:', _hash.toString())
|
||||
consumer.get(_hash, DhtFeatureTest.getcb, DhtFeatureTest.getDoneCb)
|
||||
FeatureTest.lock.wait()
|
||||
|
||||
def _gottaGetThemAllPokeNodes(self, consumer, hashes, nodes=None):
|
||||
@@ -356,7 +356,7 @@ class PersistenceTest(DhtFeatureTest):
|
||||
bootstrap = self.bootstrap
|
||||
# Value representing an ICE packet. Each ICE packet is around 1KB.
|
||||
VALUE_SIZE = 1024
|
||||
NUM_VALUES = self._num_values/wb.node_num if self._num_values else 50
|
||||
NUM_VALUES = self._num_values/wb.node_num if self._num_values else 5
|
||||
nr_values = NUM_VALUES * wb.node_num
|
||||
nr_nodes = wb.node_num
|
||||
nr_nodes_cv = threading.Condition()
|
||||
@@ -365,8 +365,11 @@ class PersistenceTest(DhtFeatureTest):
|
||||
hashes = [random_hash() for _ in range(wb.node_num)]
|
||||
|
||||
# initial set of values
|
||||
i = 0
|
||||
for h in hashes:
|
||||
self._dhtPut(bootstrap.front(), h, *[Value(v) for v in values])
|
||||
print("at: ", i)
|
||||
i += 1
|
||||
|
||||
def normalBehavior(do, t, log=None):
|
||||
nonlocal nr_values
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@ SUBDIRS = argon2
|
||||
lib_LTLIBRARIES = libopendht.la
|
||||
|
||||
AM_CPPFLAGS = -I../include/opendht
|
||||
libopendht_la_LDFLAGS = @LDFLAGS@ @GnuTLS_LIBS@ @Nettle_LIBS@ -version-number @OPENDHT_MAJOR_VERSION@:@OPENDHT_MINOR_VERSION@:@OPENDHT_PATCH_VERSION@
|
||||
libopendht_la_LDFLAGS = @LDFLAGS@ @GnuTLS_LIBS@ @Nettle_LIBS@
|
||||
libopendht_la_LIBADD = ./argon2/libargon2.la
|
||||
|
||||
libopendht_la_SOURCES = \
|
||||
|
||||
+45
-45
@@ -170,10 +170,9 @@ private:
|
||||
size_t total_size {};
|
||||
};
|
||||
|
||||
|
||||
struct Dht::SearchNode {
|
||||
SearchNode() : node() {}
|
||||
SearchNode(std::shared_ptr<Node> node) : node(node) {}
|
||||
SearchNode(const std::shared_ptr<Node>& node) : node(node) {}
|
||||
|
||||
using AnnounceStatusMap = std::map<Value::Id, std::shared_ptr<Request>>;
|
||||
|
||||
@@ -396,7 +395,7 @@ Dht::shutdown(ShutdownCallback cb) {
|
||||
};
|
||||
|
||||
for (const auto& str : store) {
|
||||
*remaining += maintainStorage(str->id, true, str_donecb);
|
||||
*remaining += maintainStorage(str.id, true, str_donecb);
|
||||
}
|
||||
DHT_LOG.WARN("Shuting down node: %u ops remaining.", *remaining);
|
||||
if (!*remaining && cb) { cb(); }
|
||||
@@ -1370,12 +1369,12 @@ Dht::listen(const InfoHash& id, GetCallback cb, Value::Filter&& f)
|
||||
auto st = findStorage(id);
|
||||
size_t tokenlocal = 0;
|
||||
if (st == store.end() && store.size() < MAX_HASHES) {
|
||||
store.emplace_back(new Storage(id, scheduler.time()));
|
||||
store.emplace_back(id, scheduler.time());
|
||||
st = std::prev(store.end());
|
||||
}
|
||||
if (st != store.end()) {
|
||||
if (not (*st)->empty()) {
|
||||
std::vector<std::shared_ptr<Value>> newvals = (*st)->get(f);
|
||||
if (not st->empty()) {
|
||||
std::vector<std::shared_ptr<Value>> newvals = st->get(f);
|
||||
if (not newvals.empty()) {
|
||||
if (!cb(newvals))
|
||||
return 0;
|
||||
@@ -1386,8 +1385,8 @@ Dht::listen(const InfoHash& id, GetCallback cb, Value::Filter&& f)
|
||||
}
|
||||
}
|
||||
}
|
||||
tokenlocal = ++(*st)->listener_token;
|
||||
(*st)->local_listeners.emplace(tokenlocal, LocalListener{f, gcb});
|
||||
tokenlocal = ++st->listener_token;
|
||||
st->local_listeners.emplace(tokenlocal, LocalListener{f, gcb});
|
||||
}
|
||||
|
||||
auto token4 = Dht::listenTo(id, AF_INET, gcb, f);
|
||||
@@ -1412,7 +1411,7 @@ Dht::cancelListen(const InfoHash& id, size_t token)
|
||||
auto st = findStorage(id);
|
||||
auto tokenlocal = std::get<0>(it->second);
|
||||
if (st != store.end() && tokenlocal)
|
||||
(*st)->local_listeners.erase(tokenlocal);
|
||||
st->local_listeners.erase(tokenlocal);
|
||||
|
||||
auto searches_cancel_listen = [&](std::map<InfoHash, std::shared_ptr<Search>> srs) {
|
||||
for (auto& sp : srs) {
|
||||
@@ -1488,6 +1487,7 @@ Dht::get(const InfoHash& id, GetCallback getcb, DoneCallback donecb, Value::Filt
|
||||
auto status = std::make_shared<OpStatus>();
|
||||
auto status4 = std::make_shared<OpStatus>();
|
||||
auto status6 = std::make_shared<OpStatus>();
|
||||
|
||||
auto vals = std::make_shared<std::vector<std::shared_ptr<Value>>>();
|
||||
auto all_nodes = std::make_shared<std::vector<std::shared_ptr<Node>>>();
|
||||
|
||||
@@ -1545,7 +1545,7 @@ Dht::getLocal(const InfoHash& id, Value::Filter f) const
|
||||
{
|
||||
auto s = findStorage(id);
|
||||
if (s == store.end()) return {};
|
||||
return (*s)->get(f);
|
||||
return s->get(f);
|
||||
}
|
||||
|
||||
std::shared_ptr<Value>
|
||||
@@ -1553,7 +1553,7 @@ Dht::getLocalById(const InfoHash& id, Value::Id vid) const
|
||||
{
|
||||
auto s = findStorage(id);
|
||||
if (s != store.end())
|
||||
return (*s)->getById(vid);
|
||||
return s->getById(vid);
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -1626,15 +1626,15 @@ Dht::cancelPut(const InfoHash& id, const Value::Id& vid)
|
||||
decltype(Dht::store)::iterator
|
||||
Dht::findStorage(const InfoHash& id)
|
||||
{
|
||||
return std::find_if(store.begin(), store.end(), [&](const std::unique_ptr<Storage>& st) {
|
||||
return st->id == id;
|
||||
return std::find_if(store.begin(), store.end(), [&](const Storage& st) {
|
||||
return st.id == id;
|
||||
});
|
||||
}
|
||||
decltype(Dht::store)::const_iterator
|
||||
Dht::findStorage(const InfoHash& id) const
|
||||
{
|
||||
return std::find_if(store.cbegin(), store.cend(), [&](const std::unique_ptr<Storage>& st) {
|
||||
return st->id == id;
|
||||
return std::find_if(store.cbegin(), store.cend(), [&](const Storage& st) {
|
||||
return st.id == id;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1674,15 +1674,15 @@ Dht::storageStore(const InfoHash& id, const std::shared_ptr<Value>& value, time_
|
||||
if (st == store.end()) {
|
||||
if (store.size() >= MAX_HASHES)
|
||||
return false;
|
||||
store.emplace_back(new Storage(id, now));
|
||||
store.emplace_back(id, now);
|
||||
st = std::prev(store.end());
|
||||
}
|
||||
|
||||
auto store = (*st)->store(value, created, max_store_size - total_store_size);
|
||||
auto store = st->store(value, created, max_store_size - total_store_size);
|
||||
if (std::get<0>(store)) {
|
||||
total_store_size += std::get<1>(store);
|
||||
total_values += std::get<2>(store);
|
||||
storageChanged(*(*st), *std::get<0>(store));
|
||||
storageChanged(*st, *std::get<0>(store));
|
||||
}
|
||||
return std::get<0>(store);
|
||||
}
|
||||
@@ -1731,12 +1731,12 @@ Dht::storageAddListener(const InfoHash& id, const std::shared_ptr<Node>& node, s
|
||||
if (st == store.end()) {
|
||||
if (store.size() >= MAX_HASHES)
|
||||
return;
|
||||
store.emplace_back(new Storage(id, now));
|
||||
store.emplace_back(id, now);
|
||||
st = std::prev(store.end());
|
||||
}
|
||||
auto l = (*st)->listeners.find(node);
|
||||
if (l == (*st)->listeners.end()) {
|
||||
const auto& stvalues = (*st)->getValues();
|
||||
auto l = st->listeners.find(node);
|
||||
if (l == st->listeners.end()) {
|
||||
const auto& stvalues = st->getValues();
|
||||
if (not stvalues.empty()) {
|
||||
std::vector<std::shared_ptr<Value>> values(stvalues.size());
|
||||
std::transform(stvalues.begin(), stvalues.end(), values.begin(), [=](const ValueStorage& vs) { return vs.data; });
|
||||
@@ -1745,7 +1745,7 @@ Dht::storageAddListener(const InfoHash& id, const std::shared_ptr<Node>& node, s
|
||||
buckets.findClosestNodes(id, now, TARGET_NODES), buckets6.findClosestNodes(id, now, TARGET_NODES),
|
||||
values);
|
||||
}
|
||||
(*st)->listeners.emplace(node, Listener {rid, now});
|
||||
st->listeners.emplace(node, Listener {rid, now});
|
||||
}
|
||||
else
|
||||
l->second.refresh(rid, now);
|
||||
@@ -1757,21 +1757,21 @@ Dht::expireStorage()
|
||||
const auto& now = scheduler.time();
|
||||
auto i = store.begin();
|
||||
while (i != store.end()) {
|
||||
for (auto l = (*i)->listeners.cbegin(); l != (*i)->listeners.cend();){
|
||||
for (auto l = i->listeners.cbegin(); l != i->listeners.cend();){
|
||||
bool expired = l->second.time + Node::NODE_EXPIRE_TIME < now;
|
||||
if (expired) {
|
||||
DHT_LOG.DEBUG("Discarding expired listener %s", l->first->id.toString().c_str());
|
||||
(*i)->listeners.erase(l++);
|
||||
i->listeners.erase(l++);
|
||||
} else
|
||||
++l;
|
||||
}
|
||||
|
||||
auto stats = (*i)->expire(types, now);
|
||||
auto stats = i->expire(types, now);
|
||||
total_store_size += stats.first;
|
||||
total_values += stats.second;
|
||||
|
||||
if ((*i)->empty() && (*i)->listeners.empty() && (*i)->local_listeners.empty()) {
|
||||
DHT_LOG.DEBUG("Discarding expired value %s", (*i)->id.toString().c_str());
|
||||
if (i->empty() && i->listeners.empty() && i->local_listeners.empty()) {
|
||||
DHT_LOG.DEBUG("Discarding expired value %s", i->id.toString().c_str());
|
||||
i = store.erase(i);
|
||||
}
|
||||
else
|
||||
@@ -2052,10 +2052,10 @@ Dht::getStorageLog() const
|
||||
using namespace std::chrono;
|
||||
std::stringstream out;
|
||||
for (const auto& st : store) {
|
||||
out << "Storage " << (*st).id << " " << (*st).listeners.size() << " list., " << (*st).valueCount() << " values (" << (*st).totalSize() << " bytes)" << std::endl;
|
||||
if (not (*st).local_listeners.empty())
|
||||
out << " " << (*st).local_listeners.size() << " local listeners" << std::endl;
|
||||
for (const auto& l : (*st).listeners) {
|
||||
out << "Storage " << st.id << " " << st.listeners.size() << " list., " << st.valueCount() << " values (" << st.totalSize() << " bytes)" << std::endl;
|
||||
if (not st.local_listeners.empty())
|
||||
out << " " << st.local_listeners.size() << " local listeners" << std::endl;
|
||||
for (const auto& l : st.listeners) {
|
||||
out << " " << "Listener " << l.first->toString();
|
||||
auto since = duration_cast<seconds>(now - l.second.time);
|
||||
auto expires = duration_cast<seconds>(l.second.time + Node::NODE_EXPIRE_TIME - now);
|
||||
@@ -2102,7 +2102,7 @@ Dht::Dht() : store(), network_engine(DHT_LOG, scheduler) {}
|
||||
|
||||
Dht::Dht(int s, int s6, Config config)
|
||||
: myid(config.node_id), is_bootstrap(config.is_bootstrap), store(),
|
||||
network_engine(myid, config.network, s, s6, DHT_LOG, scheduler,
|
||||
network_engine(myid, s, s6, DHT_LOG, scheduler,
|
||||
std::bind(&Dht::onError, this, _1, _2),
|
||||
std::bind(&Dht::onNewNode, this, _1, _2),
|
||||
std::bind(&Dht::onReportedAddr, this, _1, _2, _3),
|
||||
@@ -2238,11 +2238,11 @@ Dht::dataPersistence() {
|
||||
const auto& now = scheduler.time();
|
||||
auto storage_maintenance_time = time_point::max();
|
||||
for (auto &str : store) {
|
||||
if (now > str->maintenance_time) {
|
||||
maintainStorage(str->id);
|
||||
str->maintenance_time = now + MAX_STORAGE_MAINTENANCE_EXPIRE_TIME;
|
||||
if (now > str.maintenance_time) {
|
||||
maintainStorage(str.id);
|
||||
str.maintenance_time = now + MAX_STORAGE_MAINTENANCE_EXPIRE_TIME;
|
||||
}
|
||||
storage_maintenance_time = std::min(storage_maintenance_time, str->maintenance_time);
|
||||
storage_maintenance_time = std::min(storage_maintenance_time, str.maintenance_time);
|
||||
}
|
||||
scheduler.add(storage_maintenance_time, std::bind(&Dht::dataPersistence, this));
|
||||
}
|
||||
@@ -2259,7 +2259,7 @@ Dht::maintainStorage(InfoHash id, bool force, DoneCallback donecb) {
|
||||
auto nodes = buckets.findClosestNodes(id, now);
|
||||
if (!nodes.empty()) {
|
||||
if (force || id.xorCmp(nodes.back()->id, myid) < 0) {
|
||||
for (auto &value : (*local_storage)->getValues()) {
|
||||
for (auto &value : local_storage->getValues()) {
|
||||
const auto& vt = getType(value.data->type);
|
||||
if (force || value.time + vt.expiration > now + MAX_STORAGE_MAINTENANCE_EXPIRE_TIME) {
|
||||
// gotta put that value there
|
||||
@@ -2275,7 +2275,7 @@ Dht::maintainStorage(InfoHash id, bool force, DoneCallback donecb) {
|
||||
auto nodes6 = buckets6.findClosestNodes(id, now);
|
||||
if (!nodes6.empty()) {
|
||||
if (force || id.xorCmp(nodes6.back()->id, myid) < 0) {
|
||||
for (auto &value : (*local_storage)->getValues()) {
|
||||
for (auto &value : local_storage->getValues()) {
|
||||
const auto& vt = getType(value.data->type);
|
||||
if (force || value.time + vt.expiration > now + MAX_STORAGE_MAINTENANCE_EXPIRE_TIME) {
|
||||
// gotta put that value there
|
||||
@@ -2290,7 +2290,7 @@ Dht::maintainStorage(InfoHash id, bool force, DoneCallback donecb) {
|
||||
|
||||
if (not want4 and not want6) {
|
||||
DHT_LOG.DEBUG("Discarding storage values %s", id.toString().c_str());
|
||||
(*local_storage)->clear();
|
||||
local_storage->clear();
|
||||
}
|
||||
|
||||
return announce_per_af;
|
||||
@@ -2383,12 +2383,12 @@ Dht::exportValues() const
|
||||
e.reserve(store.size());
|
||||
for (const auto& h : store) {
|
||||
ValuesExport ve;
|
||||
ve.first = h->id;
|
||||
ve.first = h.id;
|
||||
|
||||
msgpack::sbuffer buffer;
|
||||
msgpack::packer<msgpack::sbuffer> pk(&buffer);
|
||||
pk.pack_array(h->getValues().size());
|
||||
for (const auto& v : h->getValues()) {
|
||||
pk.pack_array(h.getValues().size());
|
||||
for (const auto& v : h.getValues()) {
|
||||
pk.pack_array(2);
|
||||
pk.pack(v.time.time_since_epoch().count());
|
||||
v.data->msgpack_pack(pk);
|
||||
@@ -2551,8 +2551,8 @@ Dht::onGetValues(std::shared_ptr<Node> node, InfoHash& hash, want_t)
|
||||
answer.ntoken = makeToken((sockaddr*)&node->ss, false);
|
||||
answer.nodes4 = buckets.findClosestNodes(hash, now, TARGET_NODES);
|
||||
answer.nodes6 = buckets6.findClosestNodes(hash, now, TARGET_NODES);
|
||||
if (st != store.end() && not (*st)->empty()) {
|
||||
auto values = (*st)->getValues();
|
||||
if (st != store.end() && not st->empty()) {
|
||||
auto values = st->getValues();
|
||||
answer.values.resize(values.size());
|
||||
std::transform(values.begin(), values.end(), answer.values.begin(), [](const ValueStorage& vs) {
|
||||
return vs.data;
|
||||
|
||||
+14
-53
@@ -49,7 +49,6 @@ static const uint8_t v4prefix[16] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
constexpr unsigned SEND_NODES {8};
|
||||
|
||||
enum class MessageType {
|
||||
Error = 0,
|
||||
@@ -64,7 +63,6 @@ enum class MessageType {
|
||||
struct ParsedMessage {
|
||||
MessageType type;
|
||||
InfoHash id; /* the id of the sender */
|
||||
NetId network {0}; /* network id */
|
||||
InfoHash info_hash; /* hash for which values are requested */
|
||||
InfoHash target; /* target id around which to find nodes */
|
||||
NetworkEngine::TransId tid; /* transaction id */
|
||||
@@ -295,11 +293,6 @@ NetworkEngine::processMessage(const uint8_t *buf, size_t buflen, const sockaddr*
|
||||
return;
|
||||
}
|
||||
|
||||
if (msg.network != network) {
|
||||
DHT_LOG.DEBUG("Received message from other network %u.", msg.network);
|
||||
return;
|
||||
}
|
||||
|
||||
if (msg.id == myid || msg.id == zeroes) {
|
||||
DHT_LOG.DEBUG("Received message from self.");
|
||||
return;
|
||||
@@ -458,10 +451,9 @@ packToken(msgpack::packer<msgpack::sbuffer>& pk, Blob token)
|
||||
}
|
||||
|
||||
void
|
||||
insertAddr(msgpack::packer<msgpack::sbuffer>& pk, const sockaddr *sa, socklen_t sa_len)
|
||||
insertAddr(msgpack::packer<msgpack::sbuffer>& pk, const sockaddr *sa, socklen_t)
|
||||
{
|
||||
size_t addr_len = std::min<size_t>(sa_len,
|
||||
(sa->sa_family == AF_INET) ? sizeof(in_addr) : sizeof(in6_addr));
|
||||
size_t addr_len = (sa->sa_family == AF_INET) ? sizeof(in_addr) : sizeof(in6_addr);
|
||||
void* addr_ptr = (sa->sa_family == AF_INET) ? (void*)&((sockaddr_in*)sa)->sin_addr
|
||||
: (void*)&((sockaddr_in6*)sa)->sin6_addr;
|
||||
pk.pack("sa");
|
||||
@@ -493,7 +485,7 @@ NetworkEngine::sendPing(std::shared_ptr<Node> node, RequestCb on_done, RequestEx
|
||||
auto tid = TransId {TransPrefix::PING, getNewTid()};
|
||||
msgpack::sbuffer buffer;
|
||||
msgpack::packer<msgpack::sbuffer> pk(&buffer);
|
||||
pk.pack_map(5+(network?1:0));
|
||||
pk.pack_map(5);
|
||||
|
||||
pk.pack(std::string("a")); pk.pack_map(1);
|
||||
pk.pack(std::string("id")); pk.pack(myid);
|
||||
@@ -503,9 +495,6 @@ NetworkEngine::sendPing(std::shared_ptr<Node> node, RequestCb on_done, RequestEx
|
||||
pk.pack_bin_body((const char*)tid.data(), tid.size());
|
||||
pk.pack(std::string("y")); pk.pack(std::string("q"));
|
||||
pk.pack(std::string("v")); pk.pack(my_v);
|
||||
if (network) {
|
||||
pk.pack(std::string("n")); pk.pack(network);
|
||||
}
|
||||
|
||||
Blob b {buffer.data(), buffer.data() + buffer.size()};
|
||||
std::shared_ptr<Request> req(new Request {tid.getTid(), node, std::move(b),
|
||||
@@ -530,7 +519,7 @@ void
|
||||
NetworkEngine::sendPong(const sockaddr* sa, socklen_t salen, TransId tid) {
|
||||
msgpack::sbuffer buffer;
|
||||
msgpack::packer<msgpack::sbuffer> pk(&buffer);
|
||||
pk.pack_map(4+(network?1:0));
|
||||
pk.pack_map(4);
|
||||
|
||||
pk.pack(std::string("r")); pk.pack_map(2);
|
||||
pk.pack(std::string("id")); pk.pack(myid);
|
||||
@@ -540,9 +529,6 @@ NetworkEngine::sendPong(const sockaddr* sa, socklen_t salen, TransId tid) {
|
||||
pk.pack_bin_body((const char*)tid.data(), tid.size());
|
||||
pk.pack(std::string("y")); pk.pack(std::string("r"));
|
||||
pk.pack(std::string("v")); pk.pack(my_v);
|
||||
if (network) {
|
||||
pk.pack(std::string("n")); pk.pack(network);
|
||||
}
|
||||
|
||||
send(buffer.data(), buffer.size(), 0, sa, salen);
|
||||
}
|
||||
@@ -553,7 +539,7 @@ NetworkEngine::sendFindNode(std::shared_ptr<Node> n, const InfoHash& target, wan
|
||||
auto tid = TransId {TransPrefix::FIND_NODE, getNewTid()};
|
||||
msgpack::sbuffer buffer;
|
||||
msgpack::packer<msgpack::sbuffer> pk(&buffer);
|
||||
pk.pack_map(5+(network?1:0));
|
||||
pk.pack_map(5);
|
||||
|
||||
pk.pack(std::string("a")); pk.pack_map(2 + (want>0?1:0));
|
||||
pk.pack(std::string("id")); pk.pack(myid);
|
||||
@@ -570,9 +556,7 @@ NetworkEngine::sendFindNode(std::shared_ptr<Node> n, const InfoHash& target, wan
|
||||
pk.pack_bin_body((const char*)tid.data(), tid.size());
|
||||
pk.pack(std::string("y")); pk.pack(std::string("q"));
|
||||
pk.pack(std::string("v")); pk.pack(my_v);
|
||||
if (network) {
|
||||
pk.pack(std::string("n")); pk.pack(network);
|
||||
}
|
||||
|
||||
|
||||
Blob b {buffer.data(), buffer.data() + buffer.size()};
|
||||
std::shared_ptr<Request> req(new Request {tid.getTid(), n, std::move(b),
|
||||
@@ -599,7 +583,7 @@ NetworkEngine::sendGetValues(std::shared_ptr<Node> n, const InfoHash& info_hash,
|
||||
auto tid = TransId {TransPrefix::GET_VALUES, getNewTid()};
|
||||
msgpack::sbuffer buffer;
|
||||
msgpack::packer<msgpack::sbuffer> pk(&buffer);
|
||||
pk.pack_map(5+(network?1:0));
|
||||
pk.pack_map(5);
|
||||
|
||||
pk.pack(std::string("a")); pk.pack_map(2 + (want>0?1:0));
|
||||
pk.pack(std::string("id")); pk.pack(myid);
|
||||
@@ -616,9 +600,6 @@ NetworkEngine::sendGetValues(std::shared_ptr<Node> n, const InfoHash& info_hash,
|
||||
pk.pack_bin_body((const char*)tid.data(), tid.size());
|
||||
pk.pack(std::string("y")); pk.pack(std::string("q"));
|
||||
pk.pack(std::string("v")); pk.pack(my_v);
|
||||
if (network) {
|
||||
pk.pack(std::string("n")); pk.pack(network);
|
||||
}
|
||||
|
||||
Blob b {buffer.data(), buffer.data() + buffer.size()};
|
||||
std::shared_ptr<Request> req(new Request {tid.getTid(), n, std::move(b),
|
||||
@@ -683,7 +664,7 @@ NetworkEngine::sendNodesValues(const sockaddr* sa, socklen_t salen, TransId tid,
|
||||
const std::vector<std::shared_ptr<Value>>& st, const Blob& token) {
|
||||
msgpack::sbuffer buffer;
|
||||
msgpack::packer<msgpack::sbuffer> pk(&buffer);
|
||||
pk.pack_map(4+(network?1:0));
|
||||
pk.pack_map(4);
|
||||
|
||||
pk.pack(std::string("r"));
|
||||
pk.pack_map(2 + (not st.empty()?1:0) + (nodes.size()>0?1:0) + (nodes6.size()>0?1:0) + (not token.empty()?1:0));
|
||||
@@ -734,9 +715,6 @@ NetworkEngine::sendNodesValues(const sockaddr* sa, socklen_t salen, TransId tid,
|
||||
pk.pack_bin_body((const char*)tid.data(), tid.size());
|
||||
pk.pack(std::string("y")); pk.pack(std::string("r"));
|
||||
pk.pack(std::string("v")); pk.pack(my_v);
|
||||
if (network) {
|
||||
pk.pack(std::string("n")); pk.pack(network);
|
||||
}
|
||||
|
||||
send(buffer.data(), buffer.size(), 0, sa, salen);
|
||||
}
|
||||
@@ -747,7 +725,7 @@ NetworkEngine::bufferNodes(sa_family_t af, const InfoHash& id, std::vector<std::
|
||||
std::sort(nodes.begin(), nodes.end(), [&](const std::shared_ptr<Node>& a, const std::shared_ptr<Node>& b){
|
||||
return id.xorCmp(a->id, b->id) < 0;
|
||||
});
|
||||
size_t nnode = std::min<size_t>(SEND_NODES, nodes.size());
|
||||
size_t nnode = std::min<size_t>(TARGET_NODES, nodes.size());
|
||||
Blob bnodes;
|
||||
if (af == AF_INET) {
|
||||
bnodes.resize(NODE4_INFO_BUF_LEN * nnode);
|
||||
@@ -799,7 +777,7 @@ NetworkEngine::sendListen(std::shared_ptr<Node> n, const InfoHash& infohash, con
|
||||
auto tid = TransId {TransPrefix::LISTEN, getNewTid()};
|
||||
msgpack::sbuffer buffer;
|
||||
msgpack::packer<msgpack::sbuffer> pk(&buffer);
|
||||
pk.pack_map(5+(network?1:0));
|
||||
pk.pack_map(5);
|
||||
|
||||
pk.pack(std::string("a")); pk.pack_map(3);
|
||||
pk.pack(std::string("id")); pk.pack(myid);
|
||||
@@ -811,9 +789,7 @@ NetworkEngine::sendListen(std::shared_ptr<Node> n, const InfoHash& infohash, con
|
||||
pk.pack_bin_body((const char*)tid.data(), tid.size());
|
||||
pk.pack(std::string("y")); pk.pack(std::string("q"));
|
||||
pk.pack(std::string("v")); pk.pack(my_v);
|
||||
if (network) {
|
||||
pk.pack(std::string("n")); pk.pack(network);
|
||||
}
|
||||
|
||||
|
||||
Blob b {buffer.data(), buffer.data() + buffer.size()};
|
||||
std::shared_ptr<Request> req(new Request {tid.getTid(), n, std::move(b),
|
||||
@@ -836,7 +812,7 @@ void
|
||||
NetworkEngine::sendListenConfirmation(const sockaddr* sa, socklen_t salen, TransId tid) {
|
||||
msgpack::sbuffer buffer;
|
||||
msgpack::packer<msgpack::sbuffer> pk(&buffer);
|
||||
pk.pack_map(4+(network?1:0));
|
||||
pk.pack_map(4);
|
||||
|
||||
pk.pack(std::string("r")); pk.pack_map(2);
|
||||
pk.pack(std::string("id")); pk.pack(myid);
|
||||
@@ -846,9 +822,6 @@ NetworkEngine::sendListenConfirmation(const sockaddr* sa, socklen_t salen, Trans
|
||||
pk.pack_bin_body((const char*)tid.data(), tid.size());
|
||||
pk.pack(std::string("y")); pk.pack(std::string("r"));
|
||||
pk.pack(std::string("v")); pk.pack(my_v);
|
||||
if (network) {
|
||||
pk.pack(std::string("n")); pk.pack(network);
|
||||
}
|
||||
|
||||
send(buffer.data(), buffer.size(), 0, sa, salen);
|
||||
}
|
||||
@@ -859,7 +832,7 @@ NetworkEngine::sendAnnounceValue(std::shared_ptr<Node> n, const InfoHash& infoha
|
||||
auto tid = TransId {TransPrefix::ANNOUNCE_VALUES, getNewTid()};
|
||||
msgpack::sbuffer buffer;
|
||||
msgpack::packer<msgpack::sbuffer> pk(&buffer);
|
||||
pk.pack_map(5+(network?1:0));
|
||||
pk.pack_map(5);
|
||||
|
||||
pk.pack(std::string("a")); pk.pack_map((created < scheduler.time() ? 5 : 4));
|
||||
pk.pack(std::string("id")); pk.pack(myid);
|
||||
@@ -876,9 +849,6 @@ NetworkEngine::sendAnnounceValue(std::shared_ptr<Node> n, const InfoHash& infoha
|
||||
pk.pack_bin_body((const char*)tid.data(), tid.size());
|
||||
pk.pack(std::string("y")); pk.pack(std::string("q"));
|
||||
pk.pack(std::string("v")); pk.pack(my_v);
|
||||
if (network) {
|
||||
pk.pack(std::string("n")); pk.pack(network);
|
||||
}
|
||||
|
||||
Blob b {buffer.data(), buffer.data() + buffer.size()};
|
||||
std::shared_ptr<Request> req(new Request {tid.getTid(), n, std::move(b),
|
||||
@@ -908,7 +878,7 @@ void
|
||||
NetworkEngine::sendValueAnnounced(const sockaddr* sa, socklen_t salen, TransId tid, Value::Id vid) {
|
||||
msgpack::sbuffer buffer;
|
||||
msgpack::packer<msgpack::sbuffer> pk(&buffer);
|
||||
pk.pack_map(4+(network?1:0));
|
||||
pk.pack_map(4);
|
||||
|
||||
pk.pack(std::string("r")); pk.pack_map(3);
|
||||
pk.pack(std::string("id")); pk.pack(myid);
|
||||
@@ -919,9 +889,6 @@ NetworkEngine::sendValueAnnounced(const sockaddr* sa, socklen_t salen, TransId t
|
||||
pk.pack_bin_body((const char*)tid.data(), tid.size());
|
||||
pk.pack(std::string("y")); pk.pack(std::string("r"));
|
||||
pk.pack(std::string("v")); pk.pack(my_v);
|
||||
if (network) {
|
||||
pk.pack(std::string("n")); pk.pack(network);
|
||||
}
|
||||
|
||||
send(buffer.data(), buffer.size(), 0, sa, salen);
|
||||
}
|
||||
@@ -950,9 +917,6 @@ NetworkEngine::sendError(const sockaddr* sa,
|
||||
pk.pack_bin_body((const char*)tid.data(), tid.size());
|
||||
pk.pack(std::string("y")); pk.pack(std::string("e"));
|
||||
pk.pack(std::string("v")); pk.pack(my_v);
|
||||
if (network) {
|
||||
pk.pack(std::string("n")); pk.pack(network);
|
||||
}
|
||||
|
||||
send(buffer.data(), buffer.size(), 0, sa, salen);
|
||||
}
|
||||
@@ -996,9 +960,6 @@ ParsedMessage::msgpack_unpack(msgpack::object msg)
|
||||
error_code = e->via.array.ptr[0].as<uint16_t>();
|
||||
}
|
||||
|
||||
if (auto netid = findMapValue(msg, "n"))
|
||||
network = netid->as<NetId>();
|
||||
|
||||
if (auto rid = findMapValue(req, "id"))
|
||||
id = {*rid};
|
||||
|
||||
|
||||
+1
-1
@@ -53,7 +53,7 @@ main(int argc, char **argv)
|
||||
throw std::runtime_error(std::string("Error initializing GnuTLS: ")+gnutls_strerror(rc));
|
||||
|
||||
DhtRunner dht;
|
||||
dht.run(params.port, dht::crypto::generateIdentity("DHT Chat Node"), true, params.network);
|
||||
dht.run(params.port, dht::crypto::generateIdentity("DHT Chat Node"), true);
|
||||
|
||||
if (not params.bootstrap.first.empty())
|
||||
dht.bootstrap(params.bootstrap.first.c_str(), params.bootstrap.second.c_str());
|
||||
|
||||
+2
-2
@@ -29,7 +29,7 @@ extern "C" {
|
||||
using namespace dht;
|
||||
|
||||
void print_usage() {
|
||||
std::cout << "Usage: dhtnode [-v[logfile]] [-i] [-d] [-n network_id] [-p local_port] [-b[bootstrap_host[:port]]]" << std::endl << std::endl;
|
||||
std::cout << "Usage: dhtnode [-p local_port] [-b bootstrap_host:port]" << std::endl << std::endl;
|
||||
std::cout << "dhtnode, a simple OpenDHT command line node runner." << std::endl;
|
||||
std::cout << "Report bugs to: http://opendht.net" << std::endl;
|
||||
}
|
||||
@@ -256,7 +256,7 @@ main(int argc, char **argv)
|
||||
crt = dht::crypto::generateIdentity("DHT Node", ca_tmp);
|
||||
}
|
||||
|
||||
dht.run(params.port, crt, true, params.network);
|
||||
dht.run(params.port, crt, true, params.is_bootstrap_node);
|
||||
|
||||
if (params.log) {
|
||||
if (not params.logfile.empty())
|
||||
|
||||
@@ -80,7 +80,7 @@ main(int argc, char **argv)
|
||||
auto crt_tmp = dht::crypto::generateIdentity("Scanner node", ca_tmp);
|
||||
|
||||
DhtRunner dht;
|
||||
dht.run(params.port, crt_tmp, true, params.network);
|
||||
dht.run(params.port, crt_tmp, true, [](dht::NodeStatus /* ipv4 */, dht::NodeStatus /* ipv6 */) {});
|
||||
|
||||
if (not params.bootstrap.first.empty())
|
||||
dht.bootstrap(params.bootstrap.first.c_str(), params.bootstrap.second.c_str());
|
||||
|
||||
+18
-12
@@ -142,7 +142,6 @@ struct dht_params {
|
||||
bool log {false};
|
||||
std::string logfile {};
|
||||
in_port_t port {0};
|
||||
dht::NetId network {0};
|
||||
bool is_bootstrap_node {false};
|
||||
bool generate_identity {false};
|
||||
bool daemonize {false};
|
||||
@@ -152,10 +151,9 @@ struct dht_params {
|
||||
static const constexpr struct option long_options[] = {
|
||||
{"help", no_argument, nullptr, 'h'},
|
||||
{"port", required_argument, nullptr, 'p'},
|
||||
{"net", required_argument, nullptr, 'n'},
|
||||
{"bootstrap", optional_argument, nullptr, 'b'},
|
||||
{"identity", no_argument , nullptr, 'i'},
|
||||
{"verbose", optional_argument, nullptr, 'v'},
|
||||
{"verbose", no_argument , nullptr, 'v'},
|
||||
{"daemonize", no_argument , nullptr, 'd'},
|
||||
{nullptr, 0, nullptr, 0}
|
||||
};
|
||||
@@ -164,19 +162,16 @@ dht_params
|
||||
parseArgs(int argc, char **argv) {
|
||||
dht_params params;
|
||||
int opt;
|
||||
while ((opt = getopt_long(argc, argv, "hidv::p:n:b::", long_options, nullptr)) != -1) {
|
||||
while ((opt = getopt_long(argc, argv, ":hidv:p:b:", long_options, nullptr)) != -1) {
|
||||
switch (opt) {
|
||||
case 'p': {
|
||||
int port_arg = atoi(optarg);
|
||||
if (port_arg >= 0 && port_arg < 0x10000)
|
||||
params.port = port_arg;
|
||||
else
|
||||
std::cerr << "Invalid port: " << port_arg << std::endl;
|
||||
std::cout << "Invalid port: " << port_arg << std::endl;
|
||||
}
|
||||
break;
|
||||
case 'n':
|
||||
params.network = strtoul(optarg, nullptr, 0);
|
||||
break;
|
||||
case 'b':
|
||||
if (optarg) {
|
||||
params.bootstrap = splitPort((optarg[0] == '=') ? optarg+1 : optarg);
|
||||
@@ -185,7 +180,8 @@ parseArgs(int argc, char **argv) {
|
||||
ss << DHT_DEFAULT_PORT;
|
||||
params.bootstrap.second = ss.str();
|
||||
}
|
||||
} else
|
||||
}
|
||||
else
|
||||
params.is_bootstrap_node = true;
|
||||
break;
|
||||
case 'h':
|
||||
@@ -202,9 +198,19 @@ parseArgs(int argc, char **argv) {
|
||||
case 'd':
|
||||
params.daemonize = true;
|
||||
break;
|
||||
case '?':
|
||||
std::cerr << "unrecognized option -- '" << static_cast<char>(optopt) << '\'' << std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
case ':':
|
||||
switch (optopt) {
|
||||
case 'b':
|
||||
params.is_bootstrap_node = true;
|
||||
break;
|
||||
case 'v':
|
||||
params.log = true;
|
||||
break;
|
||||
default:
|
||||
std::cout << "option requires an argument -- '" << optopt << '\'' << std::endl;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user