25 #include "ibrcommon/net/vsocket.h"
31 #include <ibrcommon/Logger.h>
32 #include <ibrcommon/thread/MutexLock.h>
34 #include <sys/socket.h>
35 #include <arpa/inet.h>
44 _exiting(false), _initialized(false), _announced(false), _foundNodes(-1),
46 _config(daemon::Configuration::getInstance().getDHT()) {
54 return "DHT Naming Service";
60 bool dtn::dht::DHTNameService::setNonBlockingInterruptPipe() {
61 for (
int i = 0; i < 2; ++i) {
63 opts = fcntl(_interrupt_pipe[i], F_GETFL);
68 if (fcntl(_interrupt_pipe[i], F_SETFL, opts) < 0) {
80 if (pipe(_interrupt_pipe) < 0) {
81 IBRCOMMON_LOGGER_TAG(
"DHTNameService", error) <<
"Error " << errno <<
" creating pipe"
82 << IBRCOMMON_LOGGER_ENDL;
86 if (!this->setNonBlockingInterruptPipe()) {
87 IBRCOMMON_LOGGER_TAG(
"DHTNameService", error) <<
"Error " << errno
88 <<
" setting pipe to non-blocking mode"
89 << IBRCOMMON_LOGGER_ENDL;
93 int rc = dtn_dht_initstruct(&_context);
95 IBRCOMMON_LOGGER_TAG(
"DHTNameService", error) <<
"DHT Context creation failed: " << rc
96 << IBRCOMMON_LOGGER_ENDL;
99 if (_config.randomPort()) {
101 _context.port = rand() % 64000 + 1024;
103 _context.port = _config.getPort();
105 if (_config.getIPv4Binding().size() > 0) {
106 _context.bind = _config.getIPv4Binding().c_str();
108 if (_config.getIPv6Binding().size() > 0) {
109 _context.bind6 = _config.getIPv6Binding().c_str();
111 if (_config.isIPv4Enabled() && _config.isIPv6Enabled()) {
112 _context.type = BINDBOTH;
113 }
else if (_config.isIPv4Enabled()) {
114 _context.type = IPV4ONLY;
115 }
else if (_config.isIPv6Enabled()) {
116 _context.type = IPV6ONLY;
118 _context.type = BINDNONE;
120 string myid = _config.getID();
121 if (!_config.randomID()) {
122 dtn_dht_build_id_from_str(_context.id, myid.c_str(), myid.size());
125 rc = dtn_dht_init_sockets(&_context);
127 if(_context.type == BINDBOTH) {
129 IBRCOMMON_LOGGER_TAG(
"DHTNameService", warning) <<
"DHT IPv6 socket couldn't be initialized"
130 <<IBRCOMMON_LOGGER_ENDL;
132 IBRCOMMON_LOGGER_TAG(
"DHTNameService", warning) <<
"DHT socket(s) couldn't be initialized"
133 <<IBRCOMMON_LOGGER_ENDL;
135 dtn_dht_close_sockets(&_context);
137 _context.type = IPV4ONLY;
138 rc = dtn_dht_init_sockets(&_context);
140 IBRCOMMON_LOGGER_TAG(
"DHTNameService", warning) <<
"DHT IPv4 socket couldn't be initialized"
141 <<IBRCOMMON_LOGGER_ENDL;
142 dtn_dht_close_sockets(&_context);
144 _context.type = IPV6ONLY;
145 rc = dtn_dht_init_sockets(&_context);
147 IBRCOMMON_LOGGER_TAG(
"DHTNameService", warning) <<
"DHT IPv6 socket couldn't be initialized"
148 <<IBRCOMMON_LOGGER_ENDL;
149 IBRCOMMON_LOGGER_TAG(
"DHTNameService", error) <<
"DHT Sockets couldn't be initialized"
150 <<IBRCOMMON_LOGGER_ENDL;
151 dtn_dht_close_sockets(&_context);
156 IBRCOMMON_LOGGER_TAG(
"DHTNameService", error) <<
"DHT Sockets couldn't be initialized"
157 <<IBRCOMMON_LOGGER_ENDL;
158 dtn_dht_close_sockets(&_context);
162 IBRCOMMON_LOGGER_DEBUG_TAG(
"DHTNameService", 50) <<
"Sockets for DHT initialized"
163 <<IBRCOMMON_LOGGER_ENDL;
164 if (!_config.isBlacklistEnabled()) {
165 IBRCOMMON_LOGGER_DEBUG_TAG(
"DHTNameService", 50) <<
"DHT Blacklist disabled"
166 <<IBRCOMMON_LOGGER_ENDL;
167 dtn_dht_blacklist(0);
169 IBRCOMMON_LOGGER_DEBUG_TAG(
"DHTNameService", 50) <<
"DHT Blacklist enabled"
170 <<IBRCOMMON_LOGGER_ENDL;
173 ibrcommon::MutexLock l(this->_libmutex);
174 rc = dtn_dht_init(&_context);
177 IBRCOMMON_LOGGER_TAG(
"DHTNameService", error) <<
"DHT initialization failed"
178 << IBRCOMMON_LOGGER_ENDL;
181 IBRCOMMON_LOGGER_TAG(
"DHTNameService", info) <<
"DHT initialized on Port: " << _context.port
182 <<
" with ID: " << myid << IBRCOMMON_LOGGER_ENDL;
183 this->_initialized =
true;
185 if(_config.isNeighbourAnnouncementEnabled() &&
187 IBRCOMMON_LOGGER_TAG(
"DHTNameService", warning) <<
"DHT will not announce neighbor nodes: "
188 <<
"announcement enabled but routing forwarding is disabled"
189 << IBRCOMMON_LOGGER_ENDL;
194 if (!this->_initialized) {
195 IBRCOMMON_LOGGER_TAG(
"DHTNameService", error) <<
"DHT is not initialized"
196 <<IBRCOMMON_LOGGER_ENDL;
201 const std::list<dtn::daemon::Configuration::NetConfig>
206 for (std::list<dtn::daemon::Configuration::NetConfig>::const_iterator iter =
207 nets.begin(); iter != nets.end(); ++iter) {
209 cltype_ = getConvergenceLayerName((*iter));
210 std::stringstream ss;
213 struct dtn_convergence_layer * clstruct =
214 (
struct dtn_convergence_layer*) malloc(
215 sizeof(
struct dtn_convergence_layer));
216 clstruct->clname = (
char*) malloc(cltype_.size());
217 clstruct->clnamelen = cltype_.size();
218 memcpy(clstruct->clname, cltype_.c_str(), cltype_.size());
219 struct dtn_convergence_layer_arg * arg =
220 (
struct dtn_convergence_layer_arg*) malloc(
221 sizeof(
struct dtn_convergence_layer_arg));
222 arg->key = (
char*) malloc(5);
226 if(cltype_ ==
"email") {
227 memcpy(arg->key,
"email", 5);
229 const std::string &email =
231 arg->value = (
char*) malloc(email.size());
232 memcpy(arg->value, email.c_str(), email.size());
233 arg->valuelen = email.size();
237 memcpy(arg->key,
"port", 4);
239 arg->value = (
char*) malloc(port_.size());
240 memcpy(arg->value, port_.c_str(), port_.size());
241 arg->valuelen = port_.size();
248 clstruct->args = arg;
249 clstruct->next = _context.clayer;
250 _context.clayer = clstruct;
251 }
catch (
const std::exception&) {
257 int rc, numberOfRandomRequests = 0;
263 struct sockaddr_storage from;
264 socklen_t fromlen =
sizeof(sockaddr_storage);
265 ::memset(&from, 0, fromlen);
267 while (!this->_exiting) {
268 if (this->_foundNodes == 0) {
272 if (!this->_announced && dtn_dht_ready_for_work(&_context) > 2) {
273 this->_announced =
true;
274 if (!_config.isSelfAnnouncingEnabled())
281 std::set<dtn::data::EID>::iterator iterator;
282 for (iterator = eids_.begin(); iterator != eids_.end(); ++iterator) {
286 std::set<dtn::core::Node>::iterator neighbouriterator;
287 for (neighbouriterator = neighbours_.begin(); neighbouriterator
288 != neighbours_.end(); ++neighbouriterator) {
289 if (isNeighbourAnnouncable(*neighbouriterator))
290 announce(*neighbouriterator, NEIGHBOUR);
292 while (!this->cachedLookups.empty()) {
293 lookup(this->cachedLookups.front());
294 this->cachedLookups.pop_front();
298 if (dtn_dht_ready_for_work(&_context) > 0 && dtn_dht_ready_for_work(
299 &_context) <= 2 && numberOfRandomRequests < 40) {
300 dtn_dht_start_random_lookup(&_context);
301 numberOfRandomRequests++;
306 tv.tv_usec = random() % 1000000;
307 int high_fd = _interrupt_pipe[0];
309 FD_SET(_interrupt_pipe[0], &readfds);
310 if (_context.ipv4socket >= 0) {
311 FD_SET(_context.ipv4socket, &readfds);
312 high_fd = max(high_fd, _context.ipv4socket);
314 if (_context.ipv6socket >= 0) {
315 FD_SET(_context.ipv6socket, &readfds);
316 high_fd = max(high_fd, _context.ipv6socket);
318 rc = select(high_fd + 1, &readfds, NULL, NULL, &tv);
320 if (errno != EINTR) {
321 IBRCOMMON_LOGGER_TAG(
"DHTNameService", error)
322 <<
"select of DHT Sockets failed with error: "
323 << errno << IBRCOMMON_LOGGER_ENDL;
324 ibrcommon::Thread::sleep(1000);
327 if (FD_ISSET(_interrupt_pipe[0], &readfds)) {
328 IBRCOMMON_LOGGER_DEBUG_TAG(
"DHTNameService", 25) <<
"unblocked by self-pipe-trick"
329 << IBRCOMMON_LOGGER_ENDL;
332 int read = ::read(_interrupt_pipe[0], buf, 2);
333 if (read <= 2 || _exiting)
337 fromlen =
sizeof(from);
338 if (_context.ipv4socket >= 0 && FD_ISSET(_context.ipv4socket,
340 rc = recvfrom(_context.ipv4socket, _buf,
sizeof(_buf) - 1, 0,
341 (
struct sockaddr*) &from, &fromlen);
342 else if (_context.ipv6socket >= 0 && FD_ISSET(_context.ipv6socket,
344 rc = recvfrom(_context.ipv6socket, _buf,
sizeof(_buf) - 1, 0,
345 (
struct sockaddr*) &from, &fromlen);
350 ibrcommon::MutexLock l(this->_libmutex);
351 rc = dtn_dht_periodic(&_context, _buf, rc,
352 (
struct sockaddr*) &from, fromlen, &tosleep);
356 ibrcommon::MutexLock l(this->_libmutex);
357 rc = dtn_dht_periodic(&_context, NULL, 0, NULL, 0, &tosleep);
360 int numberOfHosts = 0;
361 int numberOfGoodHosts = 0;
362 int numberOfGood6Hosts = 0;
363 unsigned int numberOfBlocksHosts = 0;
364 unsigned int numberOfBlocksHostsIPv4 = 0;
365 unsigned int numberOfBlocksHostsIPv6 = 0;
367 ibrcommon::MutexLock l(this->_libmutex);
368 if (_context.ipv4socket >= 0)
370 = dtn_dht_nodes(AF_INET, &numberOfGoodHosts, NULL);
371 if (_context.ipv6socket >= 0)
372 numberOfHosts += dtn_dht_nodes(AF_INET6, &numberOfGood6Hosts,
374 numberOfBlocksHosts = dtn_dht_blacklisted_nodes(
375 &numberOfBlocksHostsIPv4, &numberOfBlocksHostsIPv6);
377 if (this->_foundNodes != numberOfHosts) {
378 if (_config.isBlacklistEnabled()) {
379 IBRCOMMON_LOGGER_DEBUG_TAG(
"DHTNameService", 42) <<
"DHT Nodes available: "
380 << numberOfHosts <<
"(Good:" << numberOfGoodHosts
381 <<
"+" << numberOfGood6Hosts <<
") Blocked: "
382 << numberOfBlocksHosts <<
"("
383 << numberOfBlocksHostsIPv4 <<
"+"
384 << numberOfBlocksHostsIPv6 <<
")"
385 << IBRCOMMON_LOGGER_ENDL;
388 IBRCOMMON_LOGGER_DEBUG_TAG(
"DHTNameService", 42) <<
"DHT Nodes available: "
389 << numberOfHosts <<
"(Good:" << numberOfGoodHosts
390 <<
"+" << numberOfGood6Hosts <<
")"
391 << IBRCOMMON_LOGGER_ENDL;
394 this->_foundNodes = numberOfHosts;
397 if (errno == EINTR) {
400 IBRCOMMON_LOGGER_TAG(
"DHTNameService", error) <<
"dtn_dht_periodic failed"
401 << IBRCOMMON_LOGGER_ENDL;
402 if (rc == EINVAL || rc == EFAULT) {
403 IBRCOMMON_LOGGER_TAG(
"DHTNameService", error) <<
"DHT failed -> stopping DHT"
404 << IBRCOMMON_LOGGER_ENDL;
413 this->_initialized =
false;
414 if (_config.getPathToNodeFiles().size() > 0) {
415 ibrcommon::MutexLock l(this->_libmutex);
416 int save = dtn_dht_save_conf(_config.getPathToNodeFiles().c_str());
418 IBRCOMMON_LOGGER_TAG(
"DHTNameService", warning) <<
"DHT could not save nodes"
419 << IBRCOMMON_LOGGER_ENDL;
421 IBRCOMMON_LOGGER_DEBUG_TAG(
"DHTNameService", 25) <<
"DHT saved nodes"
422 << IBRCOMMON_LOGGER_ENDL;
425 if (this->_announced && _config.isSelfAnnouncingEnabled())
428 IBRCOMMON_LOGGER_TAG(
"DHTNameService", info) <<
"DHT shut down" << IBRCOMMON_LOGGER_ENDL;
430 dtn_dht_close_sockets(&_context);
432 dtn_dht_free_convergence_layer_struct(_context.clayer);
434 IBRCOMMON_LOGGER_DEBUG_TAG(
"DHTNameService", 25) <<
"DHT sockets are closed"
435 << IBRCOMMON_LOGGER_ENDL;
436 ::close(_interrupt_pipe[0]);
437 ::close(_interrupt_pipe[1]);
444 this->_exiting =
true;
445 IBRCOMMON_LOGGER_DEBUG_TAG(
"DHTNameService", 25) <<
"DHT will be shut down"
446 << IBRCOMMON_LOGGER_ENDL;
447 ssize_t written = ::write(_interrupt_pipe[1],
"i", 1);
449 IBRCOMMON_LOGGER_DEBUG_TAG(
"DHTNameService", 25) <<
"DHT pipeline trick failed"
450 << IBRCOMMON_LOGGER_ENDL;
454 void dtn::dht::DHTNameService::lookup(
const dtn::data::EID &eid) {
456 if (this->_announced) {
458 IBRCOMMON_LOGGER_DEBUG_TAG(
"DHTNameService", 30) <<
"DHT Lookup: " << eid_
459 << IBRCOMMON_LOGGER_ENDL;
460 ibrcommon::MutexLock l(this->_libmutex);
461 dtn_dht_lookup(&_context, eid_.c_str(), eid_.size());
463 this->cachedLookups.push_front(eid);
472 enum dtn_dht_lookup_type type) {
473 if (this->_announced) {
475 ibrcommon::MutexLock l(this->_libmutex);
476 int rc = dtn_dht_announce(&_context, eid_.c_str(), eid_.size(), type);
478 IBRCOMMON_LOGGER_TAG(
"DHTNameService", info) <<
"DHT Announcing: " << eid_
479 << IBRCOMMON_LOGGER_ENDL;
484 bool dtn::dht::DHTNameService::isNeighbourAnnouncable(
486 if (!_config.isNeighbourAnnouncementEnabled())
503 std::set<dtn::core::Node::Type> types = n.
getTypes();
510 std::list<dtn::core::Node::Attribute> services = n.
get(
"dhtns");
511 if (!services.empty()) {
512 for (std::list<dtn::core::Node::Attribute>::const_iterator service =
513 services.begin(); service != services.end(); ++service) {
516 ";", (*service).value);
517 std::vector<string>::const_iterator param_iter = parameters.begin();
519 while (param_iter != parameters.end()) {
522 if (p[0].compare(
"proxy") == 0) {
523 std::stringstream proxy_stream;
524 proxy_stream << p[1];
525 proxy_stream >> proxy;
543 ibrcommon::MutexLock l(this->_libmutex);
544 dtn_dht_deannounce(eid_.c_str(), eid_.size());
545 IBRCOMMON_LOGGER_DEBUG_TAG(
"DHTNameService", 25) <<
"DHT Deannounced: " << eid_
546 << IBRCOMMON_LOGGER_ENDL;
549 std::string dtn::dht::DHTNameService::getConvergenceLayerName(
551 std::string cltype_ =
"";
566 throw ibrcommon::Exception(
"type of convergence layer not supported");
574 && !
event.bundle.destination.isNone()) {
575 lookup(event.bundle.destination);
583 switch (nodeevent.getAction()) {
585 if (isNeighbourAnnouncable(n))
586 announce(n, NEIGHBOUR);
599 std::list<dtn::core::Node::Attribute> services = n.
get(
"dhtns");
600 unsigned int port = 9999;
601 if (!services.empty()) {
602 for (std::list<dtn::core::Node::Attribute>::const_iterator service =
603 services.begin(); service != services.end(); ++service) {
605 ";", (*service).value);
606 std::vector<string>::const_iterator param_iter = parameters.begin();
607 bool portFound =
false;
608 while (param_iter != parameters.end()) {
611 if (p[0].compare(
"port") == 0) {
612 std::stringstream port_stream;
623 IBRCOMMON_LOGGER_DEBUG_TAG(
"DHTNameService", 25) <<
"trying to ping node "
624 << n.
toString() << IBRCOMMON_LOGGER_ENDL;
625 const std::list<std::string> ips = getAllIPAddresses(n);
626 IBRCOMMON_LOGGER_DEBUG_TAG(
"DHTNameService", 25) << ips.size() <<
" IP Addresses found!"
627 << IBRCOMMON_LOGGER_ENDL;
628 std::string lastip =
"";
629 for (std::list<std::string>::const_iterator iter = ips.begin(); iter
630 != ips.end(); ++iter) {
631 const std::string ip = (*iter);
637 struct sockaddr_in sin;
638 memset(&sin, 0,
sizeof(sin));
639 sin.sin_family = AF_INET;
640 sin.sin_port = htons(port);
641 IBRCOMMON_LOGGER_DEBUG_TAG(
"DHTNameService", 26) <<
" --- Using IP address: " << ip
642 <<IBRCOMMON_LOGGER_ENDL;
643 rc = inet_pton(AF_INET, ip.c_str(), &(sin.sin_addr));
645 IBRCOMMON_LOGGER_DEBUG_TAG(
"DHTNameService", 26) <<
"Pinging node "
646 << n.
toString() <<
" on " << ip <<
":" << port
647 << IBRCOMMON_LOGGER_ENDL;
648 ibrcommon::MutexLock l(this->_libmutex);
649 dtn_dht_ping_node((
struct sockaddr*) &sin,
sizeof(sin));
651 IBRCOMMON_LOGGER_TAG(
"DHTNameService", error) <<
" --- ERROR pton: " << rc
652 <<IBRCOMMON_LOGGER_ENDL;
660 std::list<std::string> dtn::dht::DHTNameService::getAllIPAddresses(
662 std::string address =
"0.0.0.0";
663 unsigned int port = 0;
664 std::list < std::string > ret;
665 const std::list<dtn::core::Node::URI> uri_list = n.
get(
667 for (std::list<dtn::core::Node::URI>::const_iterator iter =
668 uri_list.begin(); iter != uri_list.end(); ++iter) {
670 uri.
decode(address, port);
671 ret.push_front(address);
673 const std::list<dtn::core::Node::URI> udp_uri_list = n.
get(
675 for (std::list<dtn::core::Node::URI>::const_iterator iter =
676 udp_uri_list.begin(); iter != udp_uri_list.end(); ++iter) {
678 udp_uri.
decode(address, port);
679 ret.push_front(address);
684 void dtn::dht::DHTNameService::bootstrapping() {
685 if (this->_bootstrapped > time(NULL) + 30) {
688 this->_bootstrapped = time(NULL);
689 if (_config.getPathToNodeFiles().size() > 0) {
692 if (_config.isDNSBootstrappingEnabled()) {
695 if (_config.isIPBootstrappingEnabled()) {
700 void dtn::dht::DHTNameService::bootstrappingFile() {
703 ibrcommon::MutexLock l(this->_libmutex);
704 rc = dtn_dht_load_prev_conf(_config.getPathToNodeFiles().c_str());
707 IBRCOMMON_LOGGER_TAG(
"DHTNameService", warning) <<
"DHT loading of saved nodes failed"
708 << IBRCOMMON_LOGGER_ENDL;
710 IBRCOMMON_LOGGER_DEBUG_TAG(
"DHTNameService", 25) <<
"DHT loading of saved nodes done"
711 << IBRCOMMON_LOGGER_ENDL;
715 void dtn::dht::DHTNameService::bootstrappingDNS() {
717 std::vector < string > dns = _config.getDNSBootstrappingNames();
719 std::vector<string>::const_iterator dns_iter = dns.begin();
720 while (dns_iter != dns.end()) {
721 const string &dn = (*dns_iter);
723 ibrcommon::MutexLock l(this->_libmutex);
724 rc = dtn_dht_dns_bootstrap(&_context, dn.c_str(), NULL);
727 IBRCOMMON_LOGGER_TAG(
"DHTNameService", warning) <<
"bootstrapping from domain " << dn
728 <<
" failed with error: " << rc
729 << IBRCOMMON_LOGGER_ENDL;
731 IBRCOMMON_LOGGER_DEBUG_TAG(
"DHTNameService", 25)
732 <<
"DHT Bootstrapping done for domain" << dn
733 << IBRCOMMON_LOGGER_ENDL;
739 ibrcommon::MutexLock l(this->_libmutex);
740 rc = dtn_dht_dns_bootstrap(&_context, NULL, NULL);
743 IBRCOMMON_LOGGER_TAG(
"DHTNameService", warning)
744 <<
"bootstrapping from default domain failed with error: "
745 << rc << IBRCOMMON_LOGGER_ENDL;
747 IBRCOMMON_LOGGER_DEBUG_TAG(
"DHTNameService", 25)
748 <<
"DHT Bootstrapping done for default domain"
749 << IBRCOMMON_LOGGER_ENDL;
755 void dtn::dht::DHTNameService::bootstrappingIPs() {
757 std::vector < string > ips = _config.getIPBootstrappingIPs();
758 std::vector<string>::const_iterator ip_iter = ips.begin();
759 while (ip_iter != ips.end()) {
760 std::vector < string > ip
762 int size, ipversion = AF_INET;
763 struct sockaddr *wellknown_node;
764 struct sockaddr_in sin;
765 struct sockaddr_in6 sin6;
766 memset(&sin, 0,
sizeof(sin));
771 port = atoi(ip[1].c_str());
776 rc = inet_pton(ipversion, ip[0].c_str(), &(sin.sin_addr));
778 ipversion = AF_INET6;
779 rc = inet_pton(ipversion, ip[0].c_str(), &(sin6.sin6_addr));
783 sin6.sin6_family = ipversion;
784 sin6.sin6_port = htons(port);
786 wellknown_node = (
struct sockaddr *) &sin6;
789 sin.sin_family = ipversion;
790 sin.sin_port = htons(port);
792 wellknown_node = (
struct sockaddr *) &sin;
795 ibrcommon::MutexLock l(this->_libmutex);
796 dtn_dht_ping_node(wellknown_node, size);
808 if (this->_initialized) {
809 stringstream service;
810 service <<
"port=" << this->_context.port <<
";";
811 if (!this->_config.isNeighbourAllowedToAnnounceMe()) {
812 service <<
"proxy=false;";
816 if(!this->_config.isNeighbourAllowedToAnnounceMe()) {
825 if (result == NULL || result->eid == NULL || result->clayer == NULL) {
831 std::string clname__;
832 struct dtn_eid * eid = result->eid;
834 for (i = 0; i < eid->eidlen; ++i) {
835 eid__ += eid->eid[i];
840 struct dtn_convergence_layer * cl = result->clayer;
844 ss <<
"Adding Node " << eid__ <<
": ";
849 stringstream service;
851 for (i = 0; i < cl->clnamelen; ++i) {
852 clname__ += cl->clname[i];
854 if (clname__ ==
"tcp") {
855 proto__ = Node::CONN_TCPIP;
856 }
else if (clname__ ==
"udp") {
857 proto__ = Node::CONN_UDPIP;
858 }
else if (clname__ ==
"email") {
859 proto__ = Node::CONN_EMAIL;
861 proto__ = Node::CONN_UNDEFINED;
865 struct dtn_convergence_layer_arg * arg = cl->args;
866 std::string argstring__;
867 while (arg != NULL) {
868 if (arg->keylen <= 0 || arg->valuelen <= 0) {
873 for (i = 0; i < arg->keylen; ++i) {
874 argstring__ += arg->key[i];
876 service << argstring__ <<
"=";
878 for (i = 0; i < arg->valuelen && arg->value[i] !=
'\0'; ++i) {
879 argstring__ += arg->value[i];
881 service << argstring__ <<
";";
884 ss << clname__ <<
"(" << service.str() <<
") ";
887 Node::URI(Node::NODE_DHT_DISCOVERED, proto__, service.str(),
897 IBRCOMMON_LOGGER_TAG(
"DHTNameService", info) << ss.str() << IBRCOMMON_LOGGER_ENDL;
903 struct dtn_eid * neighbour = result->neighbours;
904 std::string neighbour__;
907 for (i = 0; i < neighbour->eidlen; ++i) {
908 neighbour__ += neighbour->eid[i];
917 neighbour = neighbour->next;
921 struct dtn_eid *
group = result->groups;
static Configuration & getInstance(bool reset=false)
void decode(std::string &address, unsigned int &port) const
const std::set< dtn::core::Node > getNeighbors()
void raiseEvent(const dtn::routing::QueueBundleEvent &evt)
const std::list< NetConfig > & getInterfaces() const
static dtn::data::EID local
static void add(EventReceiver< E > *receiver)
bool sameHost(const std::string &other) const
std::string getOwnAddress() const
bool isNeighbor(const dtn::core::Node &)
virtual ~DHTNameService()
#define DHT_PATH_EXPIRE_TIMEOUT
#define DHT_DISCOVERED_NODE_PRIORITY
static void remove(const EventReceiver< E > *receiver)
void addRoute(const dtn::data::EID &destination, const dtn::data::EID &nexthop, const dtn::data::Timeout timeout=0)
dtn::net::ConnectionManager & getConnectionManager()
const std::string getName() const
dtn::net::DiscoveryAgent & getDiscoveryAgent()
bool doForwarding() const
void unregisterService(const ibrcommon::vinterface &iface, const dtn::net::DiscoveryBeaconHandler *handler)
const Configuration::Network & getNetwork() const
void add(const dtn::core::Node &n)
void dtn_dht_handle_lookup_result(const struct dtn_dht_lookup_result *result)
virtual const eid_set getDistinctDestinations()=0
#define DHT_RESULTS_EXPIRE_TIMEOUT
std::list< URI > get(Node::Protocol proto) const
static std::string toString(const Node::Type type)
std::string getString() const
void dtn_dht_operation_done(const unsigned char *info_hash)
const Configuration::EMail & getEMail() const
const dtn::data::EID & getEID() const
dtn::storage::BundleStorage & getStorage()
void registerService(const ibrcommon::vinterface &iface, dtn::net::DiscoveryBeaconHandler *handler)
const dtn::core::Node getNeighbor(const dtn::data::EID &eid)
static std::vector< std::string > tokenize(const std::string &token, const std::string &data, const std::string::size_type max=std::string::npos)
void onUpdateBeacon(const ibrcommon::vinterface &iface, DiscoveryBeacon &beacon)
std::set< Node::Type > getTypes() const
static BundleCore & getInstance()