Compare commits

...
20 Commits
Author SHA1 Message Date
Simon Désaulniers 502776aca3 version 0.6.2 2016-07-19 13:54:16 -04:00
Simon Désaulniers 7b4eac558a doc: clarify dhtnode usage 2016-07-19 13:47:01 -04:00
zorun 8f8905dfd1 doc: Fix install path of man page (#90)
Man pages go in /usr/share/man

  http://www.pathname.com/fhs/pub/fhs-2.3.html#USRSHAREMANMANUALPAGES
2016-07-18 18:13:45 -04:00
Simon Désaulniers 64b4d2fa4a doc: add missing CMakeLists.txt 2016-07-18 18:13:45 -04:00
Simon Désaulniers 574d1934c9 tools: specify optional arg syntax -o[ARG] 2016-07-18 18:13:45 -04:00
Simon Désaulniers b3ad031a97 build-tools: distribute dhtnode.1 manpage 2016-07-18 18:13:43 -04:00
Simon Désaulniers a0b9a1986c doc: fix typos in dhtnode manpage 2016-07-18 18:12:52 -04:00
Simon Désaulniers 97efe5b791 dhtnode: manpage and add all options in help text 2016-07-18 18:12:52 -04:00
Simon Désaulniers b6c1b6fdd2 dhtnode: fix getopt optional arg parsing 2016-07-18 18:12:49 -04:00
Adrien Béraud 7e2ae46870 dht: clear search before expiring it 2016-07-18 18:11:24 -04:00
Adrien Béraud ba5d60cebe autotools: handle case where DESTDIR is empty 2016-07-18 18:11:24 -04:00
Adrien Béraud 0dc158047a autotools: cleanup 2016-07-18 18:11:24 -04:00
Simon Désaulniers 1ab615096c dht: handle search expired before permanent put 2016-07-18 18:11:24 -04:00
Simon Désaulniers f8d26e8f9f securedht: permanent put of a certificate. 2016-07-18 18:11:24 -04:00
Simon Désaulniers c0b4bf8a46 dht,api: enable optional permanent put on dht
A permanent put is going to be executed once and every time the data expires on
each SearchNode.
2016-07-18 18:11:24 -04:00
Simon Désaulniers 8f26e30021 revert attempt to avoid securedht cert put fail 2016-07-18 18:11:23 -04:00
Simon Désaulniers c1e86b48f1 Revert "dht: wait for connection before running searches"
This reverts commit bd08506146.
2016-07-18 18:11:23 -04:00
Adrien Béraud b4b39f52dc dht: new insertNode algorithm 2016-07-18 18:11:23 -04:00
Simon Désaulniers c7a6e11a24 enable python make DESTDIR=$DIR install support 2016-07-18 18:11:23 -04:00
Simon Désaulniers d95eeb31e3 cmake: pass $DESTDIR environnement var to setup.py 2016-07-18 18:11:18 -04:00
19 changed files with 248 additions and 128 deletions

No files matched your search

+2 -1
View File
@@ -1,7 +1,7 @@
cmake_minimum_required (VERSION 2.8.6)
project (opendht)
set (opendht_VERSION_MAJOR 0)
set (opendht_VERSION_MINOR 6.1)
set (opendht_VERSION_MINOR 6.2)
set (opendht_VERSION ${opendht_VERSION_MAJOR}.${opendht_VERSION_MINOR})
set (PACKAGE_VERSION ${opendht_VERSION})
@@ -131,6 +131,7 @@ endif ()
if (OPENDHT_TOOLS)
add_subdirectory(tools)
endif ()
add_subdirectory(doc)
if (OPENDHT_PYTHON)
add_subdirectory(python)
-2
View File
@@ -10,9 +10,7 @@ if USE_CYTHON
SUBDIRS += python
endif
if HAVE_DOXYGEN
SUBDIRS += doc
endif
ACLOCAL_AMFLAGS = -I m4
+5 -5
View File
@@ -1,4 +1,4 @@
AC_INIT(opendht, 0.6.1)
AC_INIT(opendht, 0.6.2)
AC_CONFIG_AUX_DIR(ac)
AM_INIT_AUTOMAKE([foreign subdir-objects])
AC_CONFIG_HEADERS([config.h])
@@ -75,9 +75,9 @@ LT_LANG(C++)
AX_CXX_COMPILE_STDCXX(11,[noext],[mandatory])
PKG_PROG_PKG_CONFIG()
PKG_CHECK_MODULES([nettle], [nettle >= 2.4])
PKG_CHECK_MODULES([GNUTLS], [gnutls >= 3.1])
PKG_CHECK_MODULES([msgpack], [msgpack >= 1.2])
PKG_CHECK_MODULES([Nettle], [nettle >= 2.4])
PKG_CHECK_MODULES([GnuTLS], [gnutls >= 3.1])
PKG_CHECK_MODULES([MsgPack], [msgpack >= 1.2])
CXXFLAGS="${CXXFLAGS} -DMSGPACK_DISABLE_LEGACY_NIL -DMSGPACK_DISABLE_LEGACY_CONVERT"
AC_ARG_ENABLE([tools], AS_HELP_STRING([--disable-tools],[Disable tools (CLI DHT node)]),,build_tools=yes)
@@ -88,7 +88,7 @@ AM_COND_IF([ENABLE_TOOLS], [
])
])
AM_COND_IF([HAVE_DOXYGEN], [AC_CONFIG_FILES([doc/Doxyfile doc/Makefile])])
AC_CONFIG_FILES([doc/Doxyfile doc/Makefile])
dnl Configure setup.py if we build the python module
AM_COND_IF([USE_CYTHON], [
+3
View File
@@ -0,0 +1,3 @@
if (OPENDHT_TOOLS)
INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/dhtnode.1 DESTINATION ${CMAKE_INSTALL_PREFIX}/share/man/man1)
endif ()
+4
View File
@@ -1,3 +1,6 @@
dist_man1_MANS = dhtnode.1
if HAVE_DOXYGEN
doxyfile.stamp:
$(DOXYGEN) Doxyfile
echo stamp > doxyfile.stamp
@@ -7,3 +10,4 @@ CLEANFILES = doxyfile.stamp
all-local: doxyfile.stamp
clean-local:
rm -rf $(top_srcdir)/doc/man $(top_srcdir)/doc/html
endif
+85
View File
@@ -0,0 +1,85 @@
.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>
+28 -8
View File
@@ -163,16 +163,35 @@ public:
* reannounced on a regular basis.
* User can call #cancelPut(InfoHash, Value::Id) to cancel a put operation.
*/
void put(const InfoHash& key, std::shared_ptr<Value>, DoneCallback cb=nullptr, time_point created=time_point::max());
void put(const InfoHash& key, const std::shared_ptr<Value>& v, DoneCallbackSimple cb, time_point created=time_point::max()) {
put(key, v, bindDoneCb(cb), created);
void put(const InfoHash& key,
std::shared_ptr<Value>,
DoneCallback cb=nullptr,
time_point created=time_point::max(),
bool permanent = false);
void put(const InfoHash& key,
const std::shared_ptr<Value>& v,
DoneCallbackSimple cb,
time_point created=time_point::max(),
bool permanent = false)
{
put(key, v, bindDoneCb(cb), created, permanent);
}
void put(const InfoHash& key, Value&& v, DoneCallback cb=nullptr, time_point created=time_point::max()) {
put(key, std::make_shared<Value>(std::move(v)), cb, created);
void put(const InfoHash& key,
Value&& v,
DoneCallback cb=nullptr,
time_point created=time_point::max(),
bool permanent = false)
{
put(key, std::make_shared<Value>(std::move(v)), cb, created, permanent);
}
void put(const InfoHash& key, Value&& v, DoneCallbackSimple cb, time_point created=time_point::max()) {
put(key, std::forward<Value>(v), bindDoneCb(cb), created);
void put(const InfoHash& key,
Value&& v,
DoneCallbackSimple cb,
time_point created=time_point::max(),
bool permanent = false)
{
put(key, std::forward<Value>(v), bindDoneCb(cb), created, permanent);
}
/**
@@ -302,6 +321,7 @@ private:
* A single "put" operation data
*/
struct Announce {
bool permanent;
std::shared_ptr<Value> value;
time_point created;
DoneCallback callback;
@@ -453,7 +473,7 @@ private:
* The values can be filtered by an arbitrary provided filter.
*/
std::shared_ptr<Search> search(const InfoHash& id, sa_family_t af, GetCallback = nullptr, DoneCallback = nullptr, Value::Filter = Value::AllFilter());
void announce(const InfoHash& id, sa_family_t af, std::shared_ptr<Value> value, DoneCallback callback, time_point created=time_point::max());
void announce(const InfoHash& id, sa_family_t af, std::shared_ptr<Value> value, DoneCallback callback, time_point created=time_point::max(), bool permanent = false);
size_t listenTo(const InfoHash& id, sa_family_t af, GetCallback cb, Value::Filter f = Value::AllFilter());
void bootstrapSearch(Search& sr);
+7 -7
View File
@@ -156,16 +156,16 @@ public:
void cancelListen(InfoHash h, size_t token);
void cancelListen(InfoHash h, std::shared_future<size_t> token);
void put(InfoHash hash, std::shared_ptr<Value> value, DoneCallback cb={});
void put(InfoHash hash, std::shared_ptr<Value> value, DoneCallbackSimple cb) {
put(hash, value, bindDoneCb(cb));
void put(InfoHash hash, std::shared_ptr<Value> value, DoneCallback cb={}, bool permanent = false);
void put(InfoHash hash, std::shared_ptr<Value> value, DoneCallbackSimple cb, bool permanent = false) {
put(hash, value, bindDoneCb(cb), permanent);
}
void put(InfoHash hash, Value&& value, DoneCallback cb={});
void put(InfoHash hash, Value&& value, DoneCallbackSimple cb) {
put(hash, std::forward<Value>(value), bindDoneCb(cb));
void put(InfoHash hash, Value&& value, DoneCallback cb={}, bool permanent = false);
void put(InfoHash hash, Value&& value, DoneCallbackSimple cb, bool permanent = false) {
put(hash, std::forward<Value>(value), bindDoneCb(cb), permanent);
}
void put(const std::string& key, Value&& value, DoneCallbackSimple cb={});
void put(const std::string& key, Value&& value, DoneCallbackSimple cb={}, bool permanent = false);
void cancelPut(const InfoHash& h, const Value::Id& id);
+6 -6
View File
@@ -101,9 +101,9 @@ public:
/**
* Will take ownership of the value, sign it using our private key and put it in the DHT.
*/
void putSigned(const InfoHash& hash, std::shared_ptr<Value> val, DoneCallback callback);
void putSigned(const InfoHash& hash, Value&& v, DoneCallback callback) {
putSigned(hash, std::make_shared<Value>(std::move(v)), callback);
void putSigned(const InfoHash& hash, std::shared_ptr<Value> val, DoneCallback callback, bool permanent = false);
void putSigned(const InfoHash& hash, Value&& v, DoneCallback callback, bool permanent = false) {
putSigned(hash, std::make_shared<Value>(std::move(v)), callback, permanent);
}
/**
@@ -111,9 +111,9 @@ public:
* and put it in the DHT.
* The operation will be immediate if the recipient' public key is known (otherwise it will be retrived first).
*/
void putEncrypted(const InfoHash& hash, const InfoHash& to, std::shared_ptr<Value> val, DoneCallback callback);
void putEncrypted(const InfoHash& hash, const InfoHash& to, Value&& v, DoneCallback callback) {
putEncrypted(hash, to, std::make_shared<Value>(std::move(v)), callback);
void putEncrypted(const InfoHash& hash, const InfoHash& to, std::shared_ptr<Value> val, DoneCallback callback, bool permanent = false);
void putEncrypted(const InfoHash& hash, const InfoHash& to, Value&& v, DoneCallback callback, bool permanent = false) {
putEncrypted(hash, to, std::make_shared<Value>(std::move(v)), callback, permanent);
}
/**
+1 -1
View File
@@ -8,4 +8,4 @@ add_custom_target(python ALL
COMMAND python3 setup.py build
DEPENDS opendht opendht_cpp.pxd opendht.pyx)
install(CODE "execute_process(COMMAND python3 setup.py install WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})")
install(CODE "execute_process(COMMAND python3 setup.py install --root=\$ENV{DESTDIR}/ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})")
+1 -1
View File
@@ -13,7 +13,7 @@ clean-local:
rm -rf $(builddir)/build $(builddir)/*.so $(PYTHON_INSTALL_RECORD)
install-exec-local:
$(PYTHON) setup.py install --record $(PYTHON_INSTALL_RECORD)
$(PYTHON) setup.py install --root=$(DESTDIR)/ --record $(PYTHON_INSTALL_RECORD)
rm -rf $(builddir)/build
if HAVE_PIP
+1 -1
View File
@@ -1,4 +1,4 @@
# Copyright (C) 2015-2016 Savoir-faire Linux Inc.
# Copyright (C) 2015-2016 Savoir-faire Linux Inc.
# Author: Guillaume Roguez <guillaume.roguez@savoirfairelinux.com>
# Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
#
+2 -3
View File
@@ -3,8 +3,7 @@ SUBDIRS = argon2
lib_LTLIBRARIES = libopendht.la
AM_CPPFLAGS = -I../include/opendht
libopendht_la_CXXFLAGS = @CXXFLAGS@
libopendht_la_LDFLAGS = @LDFLAGS@ @GNUTLS_LIBS@ @nettle_LIBS@
libopendht_la_LDFLAGS = @LDFLAGS@ @GnuTLS_LIBS@ @Nettle_LIBS@
libopendht_la_LIBADD = ./argon2/libargon2.la
libopendht_la_SOURCES = \
@@ -31,7 +30,7 @@ nobase_include_HEADERS = \
../include/opendht/dht.h \
../include/opendht/callbacks.h \
../include/opendht/node_cache.h \
../include/opendht/routing_table.h \
../include/opendht/routing_table.h \
../include/opendht/network_engine.h \
../include/opendht/scheduler.h \
../include/opendht/utils.h \
+80 -59
View File
@@ -163,6 +163,7 @@ private:
struct Dht::SearchNode {
SearchNode() : node() {}
SearchNode(std::shared_ptr<Node> node) : node(node) {}
using AnnounceStatusMap = std::map<Value::Id, std::shared_ptr<Request>>;
@@ -322,7 +323,7 @@ struct Dht::Search {
callbacks.clear();
listeners.clear();
nodes.clear();
nextSearchStep = {};
nextSearchStep.reset();
}
};
@@ -430,10 +431,10 @@ Dht::trySearchInsert(const std::shared_ptr<Node>& node)
auto family = node->getFamily();
auto& srs = family == AF_INET ? searches4 : searches6;
for (auto& srp : srs) {
auto& s = srp.second;
if (s->insertNode(node, now)) {
auto& s = *srp.second;
if (s.insertNode(node, now)) {
inserted = true;
scheduler.edit(s->nextSearchStep, s->getNextStepTime(types, now));
scheduler.edit(s.nextSearchStep, s.getNextStepTime(types, now));
}
}
return inserted;
@@ -570,37 +571,53 @@ Dht::Search::removeExpiredNode(time_point now)
bool
Dht::Search::insertNode(const std::shared_ptr<Node>& snode, time_point now, const Blob& token)
{
if (expired and nodes.empty())
return false;
auto& node = *snode;
const auto& nid = node.id;
if (node.getFamily() != af) {
//DHT_LOG.DEBUG("Attempted to insert node in the wrong family.");
return false;
}
// Fast track for the case where the node is not relevant for this search
if (node.isExpired() && nodes.size() >= SEARCH_NODES && id.xorCmp(nid, nodes.back().node->id) > 0)
if (node.getFamily() != af)
return false;
bool found = false;
auto n = std::find_if(nodes.begin(), nodes.end(), [&](const SearchNode& sn) {
if (sn.node == snode) {
auto n = nodes.end();
while (n != nodes.begin()) {
--n;
if (n->node == snode) {
found = true;
return true;
break;
}
return id.xorCmp(nid, sn.node->id) < 0;
});
if (id.xorCmp(nid, n->node->id) > 0) {
++n;
break;
}
}
bool new_search_node = false;
if (!found) {
// Be more restricitve if there are too many
// good or unknown nodes in this search,
unsigned num_bad_nodes = getNumberOfBadNodes();
if (nodes.size() - num_bad_nodes >= SEARCH_NODES) {
if (node.isExpired() or n == nodes.end())
// find if and where to trim excessive nodes
auto t = nodes.cend();
size_t bad = 0; // number of bad nodes (if search is not expired)
bool full {false}; // is the search full (has the maximum nodes)
if (expired) {
// if the search is expired, trim to SEARCH_NODES nodes
if (nodes.size() >= SEARCH_NODES) {
full = true;
t = nodes.begin() + SEARCH_NODES;
}
} else {
// otherwise, trim to SEARCH_NODES nodes, not counting bad nodes
bad = getNumberOfBadNodes();
full = nodes.size() - bad >= SEARCH_NODES;
while (std::distance(nodes.cbegin(), t) - bad > SEARCH_NODES) {
--t;
if (t->isBad())
bad--;
}
}
if (full) {
if (t != nodes.cend())
nodes.resize(std::distance(nodes.cbegin(), t));
if (n >= t)
return false;
}
@@ -608,24 +625,22 @@ Dht::Search::insertNode(const std::shared_ptr<Node>& snode, time_point now, cons
if (nodes.empty()) {
step_time = TIME_INVALID;
}
n = nodes.insert(n, SearchNode(snode));
node.time = now;
new_search_node = true;
if (node.isExpired()) {
if (not expired)
bad++;
} else if (expired) {
bad = nodes.size() - 1;
expired = false;
}
// trim good nodes
while (nodes.size() - num_bad_nodes > SEARCH_NODES) {
if (removeExpiredNode(now))
num_bad_nodes--;
auto to_remove = std::find_if(nodes.rbegin(), nodes.rend(),
[](const SearchNode& n) { return not n.isBad(); }
);
if (to_remove != nodes.rend()) {
nodes.erase(std::prev(to_remove.base()));
} // else, all nodes are expired.
while (nodes.size() - bad > SEARCH_NODES) {
if (not expired and nodes.back().isBad())
bad--;
nodes.pop_back();
}
expired = false;
}
if (not token.empty()) {
n->candidate = false;
@@ -634,6 +649,9 @@ Dht::Search::insertNode(const std::shared_ptr<Node>& snode, time_point now, cons
n->token = token;
expired = false;
}
if (new_search_node) {
removeExpiredNode(now);
}
return new_search_node;
}
@@ -652,10 +670,11 @@ Dht::expireSearches()
{
auto t = scheduler.time() - SEARCH_EXPIRE_TIME;
auto expired = [&](std::pair<const InfoHash, std::shared_ptr<Search>>& srp) {
auto& sr = srp.second;
auto b = sr->callbacks.empty() && sr->announce.empty() && sr->listeners.empty() && sr->step_time < t;
auto& sr = *srp.second;
auto b = sr.callbacks.empty() && sr.announce.empty() && sr.listeners.empty() && sr.step_time < t;
if (b) {
DHT_LOG.DEBUG("Removing search %s ", srp.first.toString().c_str());
DHT_LOG.DEBUG("Removing search %s", srp.first.toString().c_str());
sr.clear();
return b;
} else { return false; }
};
@@ -722,17 +741,11 @@ void
Dht::searchStep(std::shared_ptr<Search> sr)
{
if (not sr or sr->expired or sr->done) return;
if (sr->nodes.empty() and (sr->af == AF_INET ? buckets : buckets6).isEmpty())
return; // wait for connection
const auto& now = scheduler.time();
DHT_LOG.DEBUG("[search %s IPv%c] step (%d requests)", sr->id.toString().c_str(), sr->af == AF_INET ? '4' : '6', sr->currentGetRequests());
sr->step_time = now;
/*
* The accurate delay between two refills has not been strongly determined.
* TODO: Emprical analysis over refill timeout.
*/
if (sr->refill_time + Node::NODE_EXPIRE_TIME < now and sr->nodes.size()-sr->getNumberOfBadNodes() < SEARCH_NODES) {
if (auto added = sr->refill(sr->af == AF_INET ? buckets : buckets6, now)) {
sr->refill_time = now;
@@ -815,8 +828,10 @@ Dht::searchStep(std::shared_ptr<Search> sr)
a.callback(true, sr->getNodes());
a.callback = nullptr;
}
ait = sr->announce.erase(ait);
continue;
if (not a.permanent) {
ait = sr->announce.erase(ait);
continue;
}
}
if (in) storageStore(sr->id, a.value, a.created);
unsigned i = 0;
@@ -883,13 +898,17 @@ Dht::searchStep(std::shared_ptr<Search> sr)
g.done_cb(false, {});
}
}
if (not sr->nodes.empty()) {
{
std::vector<DoneCallback> a_cbs;
a_cbs.reserve(sr->announce.size());
for (const auto& a : sr->announce)
if (a.callback)
a_cbs.emplace_back(std::move(a.callback));
sr->announce.clear();
for (auto ait = sr->announce.begin() ; ait != sr->announce.end(); ) {
if (ait->callback)
a_cbs.emplace_back(std::move(ait->callback));
if (not ait->permanent)
ait = sr->announce.erase(ait);
else
ait++;
}
for (const auto& a : a_cbs)
a(false, {});
}
@@ -1207,7 +1226,8 @@ Dht::search(const InfoHash& id, sa_family_t af, GetCallback callback, DoneCallba
}
void
Dht::announce(const InfoHash& id, sa_family_t af, std::shared_ptr<Value> value, DoneCallback callback, time_point created)
Dht::announce(const InfoHash& id, sa_family_t af, std::shared_ptr<Value> value, DoneCallback callback,
time_point created, bool permanent)
{
const auto& now = scheduler.time();
if (!value) {
@@ -1229,7 +1249,7 @@ Dht::announce(const InfoHash& id, sa_family_t af, std::shared_ptr<Value> value,
return a.value->id == value->id;
});
if (a_sr == sr->announce.end()) {
sr->announce.emplace_back(Announce {value, std::min(now, created), callback});
sr->announce.emplace_back(Announce {permanent, value, std::min(now, created), callback});
for (auto& n : sr->nodes)
n.acked[value->id] = {};
}
@@ -1384,7 +1404,7 @@ Dht::cancelListen(const InfoHash& id, size_t token)
}
void
Dht::put(const InfoHash& id, std::shared_ptr<Value> val, DoneCallback callback, time_point created)
Dht::put(const InfoHash& id, std::shared_ptr<Value> val, DoneCallback callback, time_point created, bool permanent)
{
scheduler.syncTime();
@@ -1412,13 +1432,13 @@ Dht::put(const InfoHash& id, std::shared_ptr<Value> val, DoneCallback callback,
*done4 = true;
*ok |= ok4;
donecb(nodes);
}, created);
}, created, permanent);
announce(id, AF_INET6, val, [=](bool ok6, const std::vector<std::shared_ptr<Node>>& nodes) {
DHT_LOG.DEBUG("Announce done IPv6 %d", ok6);
*done6 = true;
*ok |= ok6;
donecb(nodes);
}, created);
}, created, permanent);
}
struct OpStatus {
@@ -2688,7 +2708,8 @@ Dht::onAnnounceDone(const Request&, NetworkEngine::RequestAnswer& answer,
a.callback(true, sr->getNodes());
a.callback = nullptr;
}
return true;
if (not a.permanent)
return true;
}
return false;
}), sr->announce.end());
+6 -6
View File
@@ -480,30 +480,30 @@ DhtRunner::cancelListen(InfoHash h, std::shared_future<size_t> token)
}
void
DhtRunner::put(InfoHash hash, Value&& value, DoneCallback cb)
DhtRunner::put(InfoHash hash, Value&& value, DoneCallback cb, bool permanent)
{
std::lock_guard<std::mutex> lck(storage_mtx);
auto sv = std::make_shared<Value>(std::move(value));
pending_ops.emplace([=](SecureDht& dht) {
dht.put(hash, sv, cb);
dht.put(hash, sv, cb, {}, permanent);
});
cv.notify_all();
}
void
DhtRunner::put(InfoHash hash, std::shared_ptr<Value> value, DoneCallback cb)
DhtRunner::put(InfoHash hash, std::shared_ptr<Value> value, DoneCallback cb, bool permanent)
{
std::lock_guard<std::mutex> lck(storage_mtx);
pending_ops.emplace([=](SecureDht& dht) {
dht.put(hash, value, cb);
dht.put(hash, value, cb, {}, permanent);
});
cv.notify_all();
}
void
DhtRunner::put(const std::string& key, Value&& value, DoneCallbackSimple cb)
DhtRunner::put(const std::string& key, Value&& value, DoneCallbackSimple cb, bool permanent)
{
put(InfoHash::get(key), std::forward<Value>(value), cb);
put(InfoHash::get(key), std::forward<Value>(value), cb, permanent);
}
void
+6 -6
View File
@@ -78,7 +78,7 @@ SecureDht::SecureDht(int s, int s6, SecureDht::Config conf)
DHT_LOG.DEBUG("SecureDht: public key announced successfully");
else
DHT_LOG.ERR("SecureDht: error while announcing public key!");
});
}, {}, true);
}
}
@@ -303,7 +303,7 @@ SecureDht::listen(const InfoHash& id, GetCallback cb, Value::Filter&& f)
}
void
SecureDht::putSigned(const InfoHash& hash, std::shared_ptr<Value> val, DoneCallback callback)
SecureDht::putSigned(const InfoHash& hash, std::shared_ptr<Value> val, DoneCallback callback, bool permanent)
{
if (val->id == Value::INVALID_ID) {
crypto::random_device rdev;
@@ -331,16 +331,16 @@ SecureDht::putSigned(const InfoHash& hash, std::shared_ptr<Value> val, DoneCallb
}
return true;
},
[hash,val,this,callback] (bool /* ok */) {
[hash,val,this,callback,permanent] (bool /* ok */) {
sign(*val);
put(hash, val, callback);
put(hash, val, callback, {}, permanent);
},
Value::IdFilter(val->id)
);
}
void
SecureDht::putEncrypted(const InfoHash& hash, const InfoHash& to, std::shared_ptr<Value> val, DoneCallback callback)
SecureDht::putEncrypted(const InfoHash& hash, const InfoHash& to, std::shared_ptr<Value> val, DoneCallback callback, bool permanent)
{
findPublicKey(to, [=](const std::shared_ptr<crypto::PublicKey> pk) {
if(!pk || !*pk) {
@@ -350,7 +350,7 @@ SecureDht::putEncrypted(const InfoHash& hash, const InfoHash& to, std::shared_pt
}
DHT_LOG.WARN("Encrypting data for PK: %s", pk->getId().toString().c_str());
try {
put(hash, encrypt(*val, *pk), callback);
put(hash, encrypt(*val, *pk), callback, {}, permanent);
} catch (const std::exception& e) {
DHT_LOG.ERR("Error putting encrypted data: %s", e.what());
if (callback)
+3 -3
View File
@@ -3,10 +3,10 @@ bin_PROGRAMS = dhtnode dhtchat dhtscanner
AM_CPPFLAGS = -I../include
dhtnode_SOURCES = dhtnode.cpp
dhtnode_LDFLAGS = -lopendht -lreadline -L../src/.libs @GNUTLS_LIBS@
dhtnode_LDFLAGS = -lopendht -lreadline -L../src/.libs @GnuTLS_LIBS@
dhtchat_SOURCES = dhtchat.cpp
dhtchat_LDFLAGS = -lopendht -lreadline -L../src/.libs @GNUTLS_LIBS@
dhtchat_LDFLAGS = -lopendht -lreadline -L../src/.libs @GnuTLS_LIBS@
dhtscanner_SOURCES = dhtscanner.cpp
dhtscanner_LDFLAGS = -lopendht -lreadline -L../src/.libs @GNUTLS_LIBS@
dhtscanner_LDFLAGS = -lopendht -lreadline -L../src/.libs @GnuTLS_LIBS@
+1 -1
View File
@@ -29,7 +29,7 @@ extern "C" {
using namespace dht;
void print_usage() {
std::cout << "Usage: dhtnode [-p local_port] [-b bootstrap_host:port]" << std::endl << std::endl;
std::cout << "Usage: dhtnode [-v[logfile]] [-i] [-d] [-n network_id] [-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;
}
+7 -18
View File
@@ -153,7 +153,7 @@ static const constexpr struct option long_options[] = {
{"port", required_argument, nullptr, 'p'},
{"bootstrap", optional_argument, nullptr, 'b'},
{"identity", no_argument , nullptr, 'i'},
{"verbose", no_argument , nullptr, 'v'},
{"verbose", optional_argument, nullptr, 'v'},
{"daemonize", no_argument , nullptr, 'd'},
{nullptr, 0, nullptr, 0}
};
@@ -162,14 +162,14 @@ dht_params
parseArgs(int argc, char **argv) {
dht_params params;
int opt;
while ((opt = getopt_long(argc, argv, ":hidv:p:b:", long_options, nullptr)) != -1) {
while ((opt = getopt_long(argc, argv, "hidv::p:n: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::cout << "Invalid port: " << port_arg << std::endl;
std::cerr << "Invalid port: " << port_arg << std::endl;
}
break;
case 'b':
@@ -180,8 +180,7 @@ parseArgs(int argc, char **argv) {
ss << DHT_DEFAULT_PORT;
params.bootstrap.second = ss.str();
}
}
else
} else
params.is_bootstrap_node = true;
break;
case 'h':
@@ -198,19 +197,9 @@ parseArgs(int argc, char **argv) {
case 'd':
params.daemonize = true;
break;
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;
case '?':
std::cerr << "unrecognized option -- '" << static_cast<char>(optopt) << '\'' << std::endl;
exit(EXIT_FAILURE);
default:
break;
}