diff --git a/CMakeLists.txt b/CMakeLists.txt index 82a3ab65d7f6e68d77ce385b436e5958f97d5732..9f15373a47b16e060ea87ddc1cf8c89a99997170 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -64,6 +64,7 @@ list (APPEND opendht_SOURCES list (APPEND opendht_HEADERS include/opendht/utils.h + include/opendht/sockaddr.h include/opendht/rng.h include/opendht/crypto.h include/opendht/infohash.h diff --git a/include/opendht/dht.h b/include/opendht/dht.h index 6fe39bae04714e2121443d3762e4b3157d9a6882..446e91140fe1f50daf48b430a23cf4d12d7ebd54 100644 --- a/include/opendht/dht.h +++ b/include/opendht/dht.h @@ -113,14 +113,20 @@ public: * The node is not pinged, so this should be * used to bootstrap efficiently from previously known nodes. */ - void insertNode(const InfoHash& id, const sockaddr*, socklen_t); + void insertNode(const InfoHash& id, const SockAddr&); + void insertNode(const InfoHash& id, const sockaddr* sa, socklen_t salen) { + insertNode(id, SockAddr(sa, salen)); + } void insertNode(const NodeExport& n) { - insertNode(n.id, reinterpret_cast<const sockaddr*>(&n.ss), n.sslen); + insertNode(n.id, SockAddr(n.ss, n.sslen)); } void pingNode(const sockaddr*, socklen_t); - time_point periodic(const uint8_t *buf, size_t buflen, const sockaddr *from, socklen_t fromlen); + time_point periodic(const uint8_t *buf, size_t buflen, const SockAddr&); + time_point periodic(const uint8_t *buf, size_t buflen, const sockaddr* from, socklen_t fromlen) { + return periodic(buf, buflen, SockAddr(from, fromlen)); + } /** * Get a value by searching on all available protocols (IPv4, IPv6), @@ -276,7 +282,7 @@ public: return {total_store_size, total_values}; } - std::vector<Address> getPublicAddress(sa_family_t family = 0); + std::vector<SockAddr> getPublicAddress(sa_family_t family = 0); protected: Logger DHT_LOG; @@ -371,7 +377,7 @@ private: unsigned pending_pings4 {0}; unsigned pending_pings6 {0}; - using ReportedAddr = std::pair<unsigned, Address>; + using ReportedAddr = std::pair<unsigned, SockAddr>; std::vector<ReportedAddr> reported_addr; void rotateSecrets(); @@ -379,7 +385,7 @@ private: Blob makeToken(const sockaddr *sa, bool old) const; bool tokenMatch(const Blob& token, const sockaddr *sa) const; - void reportedAddr(const sockaddr *sa, socklen_t sa_len); + void reportedAddr(const SockAddr&); // Storage decltype(Dht::store)::iterator findStorage(const InfoHash& id); @@ -511,11 +517,11 @@ private: bool neighbourhoodMaintenance(RoutingTable&); - void processMessage(const uint8_t *buf, size_t buflen, const sockaddr *from, socklen_t fromlen); + void processMessage(const uint8_t *buf, size_t buflen, const SockAddr&); void onError(std::shared_ptr<Request> node, DhtProtocolException e); /* when our address is reported by a distant peer. */ - void onReportedAddr(const InfoHash& id, sockaddr* sa , socklen_t salen); + void onReportedAddr(const InfoHash& id, const SockAddr&); /* when we receive a ping request */ NetworkEngine::RequestAnswer onPing(std::shared_ptr<Node> node); /* when we receive a "find node" request */ diff --git a/include/opendht/dhtrunner.h b/include/opendht/dhtrunner.h index 0dd3ad26c5fcb35b4ab8abedb802b2494bc98034..42fd7f7153562ea80258e27694ed2bb917e967ed 100644 --- a/include/opendht/dhtrunner.h +++ b/include/opendht/dhtrunner.h @@ -24,6 +24,7 @@ #include "infohash.h" #include "value.h" #include "callbacks.h" +#include "sockaddr.h" #include <thread> #include <mutex> @@ -217,7 +218,7 @@ public: * Returns the currently bound address. * @param f: address family of the bound address to retreive. */ - const Address& getBound(sa_family_t f = AF_INET) const { + const SockAddr& getBound(sa_family_t f = AF_INET) const { return (f == AF_INET) ? bound4 : bound6; } @@ -253,7 +254,7 @@ public: std::string getStorageLog() const; std::string getRoutingTablesLog(sa_family_t af) const; std::string getSearchesLog(sa_family_t af = 0) const; - std::vector<Address> getPublicAddress(sa_family_t af = 0); + std::vector<SockAddr> getPublicAddress(sa_family_t af = 0); std::vector<std::string> getPublicAddressStr(sa_family_t af = 0); // securedht methods @@ -347,7 +348,7 @@ private: std::thread rcv_thread {}; std::mutex sock_mtx {}; - std::vector<std::pair<Blob, std::pair<sockaddr_storage, socklen_t>>> rcv {}; + std::vector<std::pair<Blob, SockAddr>> rcv {}; std::queue<std::function<void(SecureDht&)>> pending_ops_prio {}; std::queue<std::function<void(SecureDht&)>> pending_ops {}; @@ -359,8 +360,8 @@ private: status6 {NodeStatus::Disconnected}; StatusCallback statusCb {nullptr}; - Address bound4 {}; - Address bound6 {}; + SockAddr bound4 {}; + SockAddr bound6 {}; }; } diff --git a/include/opendht/network_engine.h b/include/opendht/network_engine.h index 184c450818c1f8b52c2ff5de5988e71b4745798c..388401827cdf16ffe904ed69020704ea777e0c4d 100644 --- a/include/opendht/network_engine.h +++ b/include/opendht/network_engine.h @@ -196,7 +196,7 @@ private: * @param saddr (type: sockaddr*) sockaddr* pointer containing address ip information. * @param saddr_len (type: socklen_t) lenght of the sockaddr struct. */ - std::function<void(const InfoHash&, sockaddr*, socklen_t)> onReportedAddr; + std::function<void(const InfoHash&, const SockAddr&)> onReportedAddr; /** * @brief on ping request callback. * @@ -347,10 +347,10 @@ public: * @param fromlen The length of the corresponding sockaddr structure. * @param now The time to adjust the clock in the network engine. */ - void processMessage(const uint8_t *buf, size_t buflen, const sockaddr* from, socklen_t fromlen); + void processMessage(const uint8_t *buf, size_t buflen, const SockAddr& addr); - std::shared_ptr<Node> insertNode(const InfoHash& myid, const sockaddr* from, socklen_t fromlen) { - auto n = cache.getNode(myid, from, fromlen, scheduler.time(), 0); + std::shared_ptr<Node> insertNode(const InfoHash& myid, const SockAddr& addr) { + auto n = cache.getNode(myid, addr, scheduler.time(), 0); onNewNode(n, 0); return n; } @@ -386,21 +386,10 @@ private: static const std::string my_v; - /* DHT info */ - const InfoHash& myid; - const NetId network {0}; - const int dht_socket {-1}; - const int dht_socket6 {-1}; - const Logger& DHT_LOG; - - NodeCache cache {}; - sockaddr_storage blacklist[BLACKLISTED_MAX] {}; - unsigned next_blacklisted = 0; - bool rateLimit(); - static bool isMartian(const sockaddr* sa, socklen_t len); - bool isNodeBlacklisted(const sockaddr*, socklen_t) const; + static bool isMartian(const SockAddr& addr); + bool isNodeBlacklisted(const SockAddr& addr) const; void requestStep(std::shared_ptr<Request> req); @@ -430,16 +419,15 @@ private: // basic wrapper for socket sendto function - int send(const char *buf, size_t len, int flags, const sockaddr *sa, socklen_t salen); + int send(const char *buf, size_t len, int flags, const SockAddr& addr); /************* * Answers * *************/ /* answer to a ping request */ - void sendPong(const sockaddr* sa, socklen_t salen, TransId tid); + void sendPong(const SockAddr& addr, TransId tid); /* answer to findnodes/getvalues request */ - void sendNodesValues(const sockaddr* sa, - socklen_t salen, + void sendNodesValues(const SockAddr& addr, TransId tid, const Blob& nodes, const Blob& nodes6, @@ -454,12 +442,11 @@ private: std::vector<std::shared_ptr<Node>>& nodes, std::vector<std::shared_ptr<Node>>& nodes6); /* answer to a listen request */ - void sendListenConfirmation(const sockaddr* sa, socklen_t salen, TransId tid); + void sendListenConfirmation(const SockAddr& addr, TransId tid); /* answer to put request */ - void sendValueAnnounced(const sockaddr* sa, socklen_t salen, TransId, Value::Id); + void sendValueAnnounced(const SockAddr& addr, TransId, Value::Id); /* answer in case of error */ - void sendError(const sockaddr* sa, - socklen_t salen, + void sendError(const SockAddr& addr, TransId tid, uint16_t code, const std::string& message, @@ -467,6 +454,14 @@ private: void deserializeNodes(ParsedMessage& msg); + /* DHT info */ + const InfoHash& myid; + const NetId network {0}; + const int dht_socket {-1}; + const int dht_socket6 {-1}; + const Logger& DHT_LOG; + + NodeCache cache {}; std::queue<time_point> rate_limit_time {}; static std::mt19937 rd_device; @@ -474,6 +469,7 @@ private: uint16_t transaction_id {1}; std::map<uint16_t, std::shared_ptr<Request>> requests {}; MessageStats in_stats {}, out_stats {}; + std::set<SockAddr> blacklist {}; Scheduler& scheduler; }; diff --git a/include/opendht/node.h b/include/opendht/node.h index 8760e7336104e99a0cdc451abb95e2e9a7e24a63..5ecb9a61e1e4853e2e01605840a26a409f79db99 100644 --- a/include/opendht/node.h +++ b/include/opendht/node.h @@ -22,6 +22,7 @@ #include "infohash.h" // includes socket structures #include "utils.h" +#include "sockaddr.h" #include <list> @@ -30,40 +31,34 @@ namespace dht { struct Request; struct Node { - friend class NetworkEngine; - InfoHash id; - - socklen_t sslen {0}; - sockaddr_storage ss; + SockAddr addr; time_point time {time_point::min()}; /* last time eared about */ time_point reply_time {time_point::min()}; /* time of last correct reply received */ Node(const InfoHash& id, const sockaddr* sa, socklen_t salen) - : id(id), sslen(salen), ss() { - std::copy_n((const uint8_t*)sa, salen, (uint8_t*)&ss); - if ((unsigned)salen < sizeof(ss)) - std::fill_n((uint8_t*)&ss+salen, sizeof(ss)-salen, 0); - } + : id(id), addr(sa, salen) {} + Node(const InfoHash& id, const SockAddr& addr) : id(id), addr(addr) {} + InfoHash getId() const { return id; } std::pair<const sockaddr*, socklen_t> getAddr() const { - return {(const sockaddr*)&ss, sslen}; + return {(const sockaddr*)&addr.first, addr.second}; } std::string getAddrStr() const { - return print_addr(ss, sslen); + return addr.toString(); } bool isExpired() const { return expired_; } bool isGood(time_point now) const; bool isPendingMessage() const; size_t getPendingMessageCount() const; - NodeExport exportNode() const { return NodeExport {id, ss, sslen}; } - sa_family_t getFamily() const { return ss.ss_family; } + NodeExport exportNode() const { return NodeExport {id, addr.first, addr.second}; } + sa_family_t getFamily() const { return addr.getFamily(); } - void update(const sockaddr* sa, socklen_t salen); + void update(const SockAddr&); void requested(std::shared_ptr<Request>& req); void received(time_point now, std::shared_ptr<Request> req); @@ -88,7 +83,6 @@ struct Node { static constexpr const std::chrono::seconds MAX_RESPONSE_TIME {1}; private: - std::list<std::weak_ptr<Request>> requests_ {}; bool expired_ {false}; @@ -97,7 +91,6 @@ private: return w.expired(); }); } - }; } diff --git a/include/opendht/node_cache.h b/include/opendht/node_cache.h index 119f7d6091c212b25e67ee327da038b618979d3f..5fa582409aca46630a2531c2a9798e43f83df05b 100644 --- a/include/opendht/node_cache.h +++ b/include/opendht/node_cache.h @@ -28,7 +28,7 @@ namespace dht { struct NodeCache { std::shared_ptr<Node> getNode(const InfoHash& id, sa_family_t family); - std::shared_ptr<Node> getNode(const InfoHash& id, const sockaddr* sa, socklen_t sa_len, time_point now, bool confirmed); + std::shared_ptr<Node> getNode(const InfoHash& id, const SockAddr&, time_point now, bool confirmed); std::vector<std::shared_ptr<Node>> getCachedNodes(const InfoHash& id, sa_family_t sa_f, size_t count); /** @@ -42,7 +42,7 @@ private: class NodeMap : public std::map<InfoHash, std::weak_ptr<Node>> { public: std::shared_ptr<Node> getNode(const InfoHash& id); - std::shared_ptr<Node> getNode(const InfoHash& id, const sockaddr* sa, socklen_t sa_len, time_point now, bool confirmed); + std::shared_ptr<Node> getNode(const InfoHash& id, const SockAddr&, time_point now, bool confirmed); void clearBadNodes(); }; diff --git a/include/opendht/sockaddr.h b/include/opendht/sockaddr.h new file mode 100644 index 0000000000000000000000000000000000000000..110b224ae214c995a0d7ae5d5e440556cd5c14d5 --- /dev/null +++ b/include/opendht/sockaddr.h @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2016 Savoir-faire Linux Inc. + * Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#pragma once + +#ifndef _WIN32 +#include <sys/socket.h> +#else +#include <ws2def.h> +#include <ws2tcpip.h> +#endif + +namespace dht { + +std::string print_addr(const sockaddr* sa, socklen_t slen); +std::string print_addr(const sockaddr_storage& ss, socklen_t sslen); + +struct SockAddr : public std::pair<sockaddr_storage, socklen_t> { +public: + using std::pair<sockaddr_storage, socklen_t>::pair; + + SockAddr() : pair<sockaddr_storage, socklen_t>::pair({},0) {} + SockAddr(const SockAddr& o) : pair<sockaddr_storage, socklen_t>::pair({},o.second) { + std::copy_n((uint8_t*)&o.first, o.second, (uint8_t*)&first); + } + SockAddr(const sockaddr* sa, socklen_t len) : pair<sockaddr_storage, socklen_t>::pair({},len) { + if (len > sizeof(sockaddr_storage)) + throw std::runtime_error("Socket address length is too large"); + std::copy_n((uint8_t*)sa, len, (uint8_t*)&first); + } + + bool operator<(const SockAddr& o) const { + if (second != o.second) + return second < o.second; + return std::memcmp((uint8_t*)&first, (uint8_t*)&o.first, second) < 0; + } + + bool operator==(const SockAddr& o) const { + return second == o.second + && std::memcmp((uint8_t*)&first, (uint8_t*)&o.first, second) == 0; + } + SockAddr& operator=(const SockAddr& o) { + std::copy_n((const uint8_t*)&o.first, o.second, (uint8_t*)&first); + second = o.second; + return *this; + } + + std::string toString() const { + return print_addr(first, second); + } + sa_family_t getFamily() const { return second > sizeof(sa_family_t) ? first.ss_family : AF_UNSPEC; } +}; + +std::string printAddr(const SockAddr& addr); + +} diff --git a/include/opendht/utils.h b/include/opendht/utils.h index 9dcb1660be57ba763beedfa52b879935ec8267d6..8d5e1c7cb92a71f35cef87e8d5d548fc9f0e9c4e 100644 --- a/include/opendht/utils.h +++ b/include/opendht/utils.h @@ -13,8 +13,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #pragma once @@ -24,13 +23,6 @@ #include <msgpack.hpp> -#ifndef _WIN32 -#include <sys/socket.h> -#else -#include <ws2def.h> -#include <ws2tcpip.h> -#endif - #include <chrono> #include <random> #include <functional> @@ -40,14 +32,9 @@ namespace dht { -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); -std::string print_addr(const sockaddr_storage& ss, socklen_t sslen); -std::string printAddr(const Address& addr); - template <typename Key, typename Item, typename Condition> void erase_if(std::map<Key, Item>& map, const Condition& condition) { diff --git a/src/Makefile.am b/src/Makefile.am index ba0af9bad947198147e3ddda4c2ad8265a312fe4..e1cc7556121971261de0dd43c53ec8561b0b0430 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -36,6 +36,7 @@ nobase_include_HEADERS = \ ../include/opendht/network_engine.h \ ../include/opendht/scheduler.h \ ../include/opendht/utils.h \ + ../include/opendht/sockaddr.h \ ../include/opendht/infohash.h \ ../include/opendht/node.h \ ../include/opendht/value.h \ diff --git a/src/dht.cpp b/src/dht.cpp index bc50a54d7da3603aef9c06bfb751363fb82ff127..196c5e6436d82c98d014e00420e7476de994f77a 100644 --- a/src/dht.cpp +++ b/src/dht.cpp @@ -700,13 +700,13 @@ Dht::sendCachedPing(Bucket& b) return 0; } -std::vector<Address> +std::vector<SockAddr> Dht::getPublicAddress(sa_family_t family) { std::sort(reported_addr.begin(), reported_addr.end(), [](const ReportedAddr& a, const ReportedAddr& b) { return a.first > b.first; }); - std::vector<Address> ret; + std::vector<SockAddr> ret; for (const auto& addr : reported_addr) if (!family || family == addr.second.first.ss_family) ret.emplace_back(addr.second); @@ -733,15 +733,14 @@ Dht::trySearchInsert(const std::shared_ptr<Node>& node) } void -Dht::reportedAddr(const sockaddr *sa, socklen_t sa_len) +Dht::reportedAddr(const SockAddr& addr) { - auto it = std::find_if(reported_addr.begin(), reported_addr.end(), [=](const ReportedAddr& addr){ - return (addr.second.second == sa_len) && - std::equal((uint8_t*)&addr.second.first, (uint8_t*)&addr.second.first + addr.second.second, (uint8_t*)sa); + auto it = std::find_if(reported_addr.begin(), reported_addr.end(), [&](const ReportedAddr& a){ + return a.second == addr; }); if (it == reported_addr.end()) { if (reported_addr.size() < 32) - reported_addr.emplace_back(1, std::make_pair(*((sockaddr_storage*)sa), sa_len)); + reported_addr.emplace_back(1, addr); } else it->first++; } @@ -2166,7 +2165,7 @@ Dht::storageChanged(Storage& st, ValueStorage& v) DHT_LOG.DEBUG("[Storage %s] Sending update to %s.", st.id.toString().c_str(), l.first->toString().c_str()); std::vector<std::shared_ptr<Value>> vals {}; vals.push_back(v.data); - Blob ntoken = makeToken((const sockaddr*)&l.first->ss, false); + Blob ntoken = makeToken((const sockaddr*)&l.first->addr.first, false); network_engine.tellListener(l.first, l.second.rid, st.id, 0, ntoken, {}, {}, std::move(vals), l.second.query); } @@ -2255,7 +2254,7 @@ Dht::storageAddListener(const InfoHash& id, const std::shared_ptr<Node>& node, s if (l == (*st)->listeners.end()) { auto vals = (*st)->get(query.where.getFilter()); if (not vals.empty()) { - network_engine.tellListener(node, rid, id, WANT4 | WANT6, makeToken((sockaddr*)&node->ss, false), + network_engine.tellListener(node, rid, id, WANT4 | WANT6, makeToken((sockaddr*)&node->addr.first, false), buckets.findClosestNodes(id, now, TARGET_NODES), buckets6.findClosestNodes(id, now, TARGET_NODES), std::move(vals), query); } @@ -2538,8 +2537,7 @@ Dht::dumpSearch(const Search& sr, std::ostream& out) const out << "] "; } } - out << print_addr(n.node->ss, n.node->sslen); - out << std::endl; + out << n.node->addr.toString() << std::endl; } } @@ -2629,7 +2627,7 @@ Dht::Dht(int s, int s6, Config config) network_engine(myid, config.network, 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), + std::bind(&Dht::onReportedAddr, this, _1, _2), std::bind(&Dht::onPing, this, _1), std::bind(&Dht::onFindNode, this, _1, _2, _3), std::bind(&Dht::onGetValues, this, _1, _2, _3, _4), @@ -2827,15 +2825,15 @@ Dht::maintainStorage(InfoHash id, bool force, DoneCallback donecb) { } void -Dht::processMessage(const uint8_t *buf, size_t buflen, const sockaddr *from, socklen_t fromlen) +Dht::processMessage(const uint8_t *buf, size_t buflen, const SockAddr& from) { if (buflen == 0) return; try { - network_engine.processMessage(buf, buflen, from, fromlen); + network_engine.processMessage(buf, buflen, from); } catch (const std::exception& e) { - DHT_LOG.ERR("Can't parse message from %s: %s", print_addr(from, fromlen).c_str(), e.what()); + DHT_LOG.ERR("Can't parse message from %s: %s", from.toString().c_str(), e.what()); //auto code = e.getCode(); //if (code == DhtProtocolException::INVALID_TID_SIZE or code == DhtProtocolException::WRONG_NODE_INFO_BUF_LEN) { /* This is really annoying, as it means that we will @@ -2848,10 +2846,10 @@ Dht::processMessage(const uint8_t *buf, size_t buflen, const sockaddr *from, soc } time_point -Dht::periodic(const uint8_t *buf, size_t buflen, const sockaddr *from, socklen_t fromlen) +Dht::periodic(const uint8_t *buf, size_t buflen, const SockAddr& from) { scheduler.syncTime(); - processMessage(buf, buflen, from, fromlen); + processMessage(buf, buflen, from); return scheduler.run(); } @@ -3002,12 +3000,12 @@ Dht::exportNodes() } void -Dht::insertNode(const InfoHash& id, const sockaddr* sa, socklen_t salen) +Dht::insertNode(const InfoHash& id, const SockAddr& addr) { - if (sa->sa_family != AF_INET && sa->sa_family != AF_INET6) + if (addr.getFamily() != AF_INET && addr.getFamily() != AF_INET6) return; scheduler.syncTime(); - network_engine.insertNode(id, sa, salen); + network_engine.insertNode(id, addr); } void @@ -3046,12 +3044,12 @@ Dht::onError(std::shared_ptr<Request> req, DhtProtocolException e) { } void -Dht::onReportedAddr(const InfoHash& id, sockaddr* addr , socklen_t addr_length) +Dht::onReportedAddr(const InfoHash& id, const SockAddr& addr) { - const auto& b = (addr->sa_family == AF_INET ? buckets : buckets6).findBucket(id); + const auto& b = (addr.getFamily() == AF_INET ? buckets : buckets6).findBucket(id); b->time = scheduler.time(); - if (addr and addr_length) - reportedAddr(addr, addr_length); + if (addr.second) + reportedAddr(addr); } NetworkEngine::RequestAnswer @@ -3065,7 +3063,7 @@ Dht::onFindNode(std::shared_ptr<Node> node, InfoHash& target, want_t want) { const auto& now = scheduler.time(); NetworkEngine::RequestAnswer answer; - answer.ntoken = makeToken((sockaddr*)&node->ss, false); + answer.ntoken = makeToken((sockaddr*)&node->addr.first, false); if (want & WANT4) answer.nodes4 = buckets.findClosestNodes(target, now, TARGET_NODES); if (want & WANT6) @@ -3086,7 +3084,7 @@ Dht::onGetValues(std::shared_ptr<Node> node, InfoHash& hash, want_t, const Query const auto& now = scheduler.time(); NetworkEngine::RequestAnswer answer {}; auto st = findStorage(hash); - answer.ntoken = makeToken((sockaddr*)&node->ss, false); + answer.ntoken = makeToken((sockaddr*)&node->addr.first, false); answer.nodes4 = buckets.findClosestNodes(hash, now, TARGET_NODES); answer.nodes6 = buckets6.findClosestNodes(hash, now, TARGET_NODES); if (st != store.end() && not (*st)->empty()) { @@ -3180,7 +3178,7 @@ Dht::onListen(std::shared_ptr<Node> node, InfoHash& hash, Blob& token, size_t ri DhtProtocolException::LISTEN_NO_INFOHASH }; } - if (!tokenMatch(token, (sockaddr*)&node->ss)) { + if (!tokenMatch(token, (sockaddr*)&node->addr.first)) { DHT_LOG.WARN("[node %s] incorrect token %s for 'listen'.", node->toString().c_str(), hash.toString().c_str()); throw DhtProtocolException {DhtProtocolException::UNAUTHORIZED, DhtProtocolException::LISTEN_WRONG_TOKEN}; } @@ -3224,7 +3222,7 @@ Dht::onAnnounce(std::shared_ptr<Node> node, DhtProtocolException::PUT_NO_INFOHASH }; } - if (!tokenMatch(token, (sockaddr*)&node->ss)) { + if (!tokenMatch(token, (sockaddr*)&node->addr.first)) { DHT_LOG.WARN("[node %s] incorrect token %s for 'put'.", node->toString().c_str(), hash.toString().c_str()); throw DhtProtocolException {DhtProtocolException::UNAUTHORIZED, DhtProtocolException::PUT_WRONG_TOKEN}; } @@ -3254,7 +3252,7 @@ Dht::onAnnounce(std::shared_ptr<Node> node, DHT_LOG.WARN("[value %s %lu] nothing to do.", hash.toString().c_str(), lv->id); } else { const auto& type = getType(lv->type); - if (type.editPolicy(hash, lv, vc, node->id, (sockaddr*)&node->ss, node->sslen)) { + if (type.editPolicy(hash, lv, vc, node->id, (sockaddr*)&node->addr.first, node->addr.second)) { DHT_LOG.DEBUG("[value %s %lu] editing %s.", hash.toString().c_str(), lv->id, vc->toString().c_str()); storageStore(hash, vc, created); @@ -3266,7 +3264,7 @@ Dht::onAnnounce(std::shared_ptr<Node> node, } else { // Allow the value to be edited by the storage policy const auto& type = getType(vc->type); - if (type.storePolicy(hash, vc, node->id, (sockaddr*)&node->ss, node->sslen)) { + if (type.storePolicy(hash, vc, node->id, (sockaddr*)&node->addr.first, node->addr.second)) { DHT_LOG.DEBUG("[value %s %lu] storing %s.", hash.toString().c_str(), vc->id, vc->toString().c_str()); storageStore(hash, vc, created); } else { diff --git a/src/dhtrunner.cpp b/src/dhtrunner.cpp index 068883f513ff78852d1fe14fdf1b7545ed4a1b58..fd96c16ab7a9c3c6ece214d5bae52eeaa6e75bfe 100644 --- a/src/dhtrunner.cpp +++ b/src/dhtrunner.cpp @@ -252,7 +252,7 @@ DhtRunner::getSearchesLog(sa_family_t af) const std::lock_guard<std::mutex> lck(dht_mtx); return dht_->getSearchesLog(af); } -std::vector<Address> +std::vector<SockAddr> DhtRunner::getPublicAddress(sa_family_t af) { std::lock_guard<std::mutex> lck(dht_mtx); @@ -315,7 +315,7 @@ DhtRunner::loop_() for (const auto& pck : received) { auto& buf = pck.first; auto& from = pck.second; - wakeup = dht_->periodic(buf.data(), buf.size()-1, (sockaddr*)&from.first, from.second); + wakeup = dht_->periodic(buf.data(), buf.size()-1, from); } received.clear(); } else { @@ -400,19 +400,19 @@ DhtRunner::doRun(const sockaddr_in* sin4, const sockaddr_in6* sin6, SecureDht::C if(rc > 0) { std::array<uint8_t, 1024 * 64> buf; - sockaddr_storage from; - socklen_t fromlen {sizeof(from)}; + SockAddr from; + from.second = sizeof(from.first); if(s4 >= 0 && FD_ISSET(s4, &readfds)) - rc = recvfrom(s4, (char*)buf.data(), buf.size(), 0, (struct sockaddr*)&from, &fromlen); + rc = recvfrom(s4, (char*)buf.data(), buf.size(), 0, (struct sockaddr*)&from.first, &from.second); else if(s6 >= 0 && FD_ISSET(s6, &readfds)) - rc = recvfrom(s6, (char*)buf.data(), buf.size(), 0, (struct sockaddr*)&from, &fromlen); + rc = recvfrom(s6, (char*)buf.data(), buf.size(), 0, (struct sockaddr*)&from.first, &from.second); else break; if (rc > 0) { { std::lock_guard<std::mutex> lck(sock_mtx); - rcv.emplace_back(Blob {buf.begin(), buf.begin()+rc+1}, std::make_pair(from, fromlen)); + rcv.emplace_back(Blob {buf.begin(), buf.begin()+rc+1}, from); } cv.notify_all(); } diff --git a/src/network_engine.cpp b/src/network_engine.cpp index f973b985a80ad3d0dfecf85741a252371f4695c8..14aef4eced9953bdc840f0d72917420c5e24f04a 100644 --- a/src/network_engine.cpp +++ b/src/network_engine.cpp @@ -80,7 +80,7 @@ struct ParsedMessage { want_t want; /* states if ipv4 or ipv6 request */ uint16_t error_code; /* error code in case of error */ std::string ua; - Address addr; /* reported address by the distant node */ + SockAddr addr; /* reported address by the distant node */ void msgpack_unpack(msgpack::object o); }; @@ -96,7 +96,7 @@ NetworkEngine::tellListener(std::shared_ptr<Node> node, uint16_t rid, const Info { auto nnodes = bufferNodes(node->getFamily(), hash, want, nodes, nodes6); try { - sendNodesValues((const sockaddr*)&node->ss, node->sslen, TransId {TransPrefix::GET_VALUES, (uint16_t)rid}, nnodes.first, nnodes.second, + sendNodesValues(node->addr, TransId {TransPrefix::GET_VALUES, (uint16_t)rid}, nnodes.first, nnodes.second, values, query, ntoken); } catch (const std::overflow_error& e) { DHT_LOG.ERR("Can't send value: buffer not large enough !"); @@ -162,7 +162,7 @@ NetworkEngine::requestStep(std::shared_ptr<Request> req) send((char*)req->msg.data(), req->msg.size(), (req->node->reply_time >= now - UDP_REPLY_TIME) ? 0 : MSG_CONFIRM, - (sockaddr*)&req->node->ss, req->node->sslen); + req->node->addr); ++req->attempt_count; req->last_try = now; std::weak_ptr<Request> wreq = req; @@ -206,15 +206,15 @@ NetworkEngine::rateLimit() } bool -NetworkEngine::isMartian(const sockaddr* sa, socklen_t len) +NetworkEngine::isMartian(const SockAddr& addr) { // Check that sa_family can be accessed safely - if (!sa || len < sizeof(sockaddr_in)) + if (addr.second < sizeof(sockaddr_in)) return true; - switch(sa->sa_family) { + switch(addr.first.ss_family) { case AF_INET: { - sockaddr_in *sin = (sockaddr_in*)sa; + sockaddr_in *sin = (sockaddr_in*)&addr.first; const uint8_t *address = (const uint8_t*)&sin->sin_addr; return sin->sin_port == 0 || (address[0] == 0) || @@ -222,9 +222,9 @@ NetworkEngine::isMartian(const sockaddr* sa, socklen_t len) ((address[0] & 0xE0) == 0xE0); } case AF_INET6: { - if (len < sizeof(sockaddr_in6)) + if (addr.second < sizeof(sockaddr_in6)) return true; - sockaddr_in6 *sin6 = (sockaddr_in6*)sa; + sockaddr_in6 *sin6 = (sockaddr_in6*)&addr.first; const uint8_t *address = (const uint8_t*)&sin6->sin6_addr; return sin6->sin6_port == 0 || (address[0] == 0xFF) || @@ -253,37 +253,25 @@ NetworkEngine::blacklistNode(const std::shared_ptr<Node>& n) ++rit; } } - memcpy(&blacklist[next_blacklisted], &n->ss, n->sslen); - next_blacklisted = (next_blacklisted + 1) % BLACKLISTED_MAX; + blacklist.emplace(n->addr); } bool -NetworkEngine::isNodeBlacklisted(const sockaddr *sa, socklen_t salen) const +NetworkEngine::isNodeBlacklisted(const SockAddr& addr) const { - if (salen > sizeof(sockaddr_storage)) - return true; - - /*if (isBlacklisted(sa, salen)) - return true;*/ - - for (unsigned i = 0; i < BLACKLISTED_MAX; i++) { - if (memcmp(&blacklist[i], sa, salen) == 0) - return true; - } - - return false; + return blacklist.find(addr) != blacklist.end(); } void -NetworkEngine::processMessage(const uint8_t *buf, size_t buflen, const sockaddr* from, socklen_t fromlen) +NetworkEngine::processMessage(const uint8_t *buf, size_t buflen, const SockAddr& from) { - if (isMartian(from, fromlen)) { - DHT_LOG.WARN("Received packet from martian node %s", print_addr(from, fromlen).c_str()); + if (isMartian(from)) { + DHT_LOG.WARN("Received packet from martian node %s", from.toString().c_str()); return; } - if (isNodeBlacklisted(from, fromlen)) { - DHT_LOG.WARN("Received packet from blacklisted node %s", print_addr(from, fromlen).c_str()); + if (isNodeBlacklisted(from)) { + DHT_LOG.WARN("Received packet from blacklisted node %s", from.toString().c_str()); return; } @@ -322,7 +310,7 @@ NetworkEngine::processMessage(const uint8_t *buf, size_t buflen, const sockaddr* if (msg.tid.length != 4) { DHT_LOG.ERR("Broken node truncates transaction ids (len: %d): ", msg.tid.length); DHT_LOG.ERR.logPrintable(buf, buflen); - blacklistNode(cache.getNode(msg.id, from, fromlen, now, true)); + blacklistNode(cache.getNode(msg.id, from, now, true)); return; } @@ -337,7 +325,7 @@ NetworkEngine::processMessage(const uint8_t *buf, size_t buflen, const sockaddr* auto node = req->node; if (node->id != msg.id) { bool unknown_node = node->id == zeroes; - node = cache.getNode(msg.id, from, fromlen, now, true); + node = cache.getNode(msg.id, from, now, true); if (unknown_node) { // received reply to a message sent when we didn't know the node ID. req->node = node; @@ -349,11 +337,11 @@ NetworkEngine::processMessage(const uint8_t *buf, size_t buflen, const sockaddr* return; } } else - node->update(from, fromlen); + node->update(from); node->received(now, req); onNewNode(node, 2); - onReportedAddr(msg.id, (sockaddr*)&msg.addr.first, msg.addr.second); + onReportedAddr(msg.id, msg.addr); if (req->cancelled() or req->expired() or (req->completed() and not req->persistent)) { DHT_LOG.WARN("[node %s] response to expired, cancelled or completed request", node->toString().c_str()); @@ -373,7 +361,7 @@ NetworkEngine::processMessage(const uint8_t *buf, size_t buflen, const sockaddr* onError(req, DhtProtocolException {DhtProtocolException::UNAUTHORIZED}); } else { DHT_LOG.WARN("[node %s %s] received unknown error message %u", - msg.id.toString().c_str(), print_addr(from, fromlen).c_str(), msg.error_code); + msg.id.toString().c_str(), from.toString().c_str(), msg.error_code); DHT_LOG.WARN.logPrintable(buf, buflen); } break; @@ -391,7 +379,7 @@ NetworkEngine::processMessage(const uint8_t *buf, size_t buflen, const sockaddr* break; } } else { - auto node = cache.getNode(msg.id, from, fromlen, now, true); + auto node = cache.getNode(msg.id, from, now, true); node->received(now, {}); onNewNode(node, 1); try { @@ -400,29 +388,29 @@ NetworkEngine::processMessage(const uint8_t *buf, size_t buflen, const sockaddr* ++in_stats.ping; DHT_LOG.DEBUG("Sending pong."); onPing(node); - sendPong(from, fromlen, msg.tid); + sendPong(from, msg.tid); break; case MessageType::FindNode: { DHT_LOG.DEBUG("[node %s %s] got 'find' request (%d).", - msg.id.toString().c_str(), print_addr(from, fromlen).c_str(), msg.want); + msg.id.toString().c_str(), from.toString().c_str(), msg.want); ++in_stats.find; RequestAnswer answer = onFindNode(node, msg.target, msg.want); - auto nnodes = bufferNodes(from->sa_family, msg.target, msg.want, answer.nodes4, answer.nodes6); - sendNodesValues(from, fromlen, msg.tid, nnodes.first, nnodes.second, {}, {}, answer.ntoken); + auto nnodes = bufferNodes(from.getFamily(), msg.target, msg.want, answer.nodes4, answer.nodes6); + sendNodesValues(from, msg.tid, nnodes.first, nnodes.second, {}, {}, answer.ntoken); break; } case MessageType::GetValues: { DHT_LOG.DEBUG("[node %s %s] got 'get' request for %s.", - msg.id.toString().c_str(), print_addr(from, fromlen).c_str(), msg.info_hash.toString().c_str()); + msg.id.toString().c_str(), from.toString().c_str(), msg.info_hash.toString().c_str()); ++in_stats.get; RequestAnswer answer = onGetValues(node, msg.info_hash, msg.want, msg.query); - auto nnodes = bufferNodes(from->sa_family, msg.info_hash, msg.want, answer.nodes4, answer.nodes6); - sendNodesValues(from, fromlen, msg.tid, nnodes.first, nnodes.second, answer.values, msg.query, answer.ntoken); + auto nnodes = bufferNodes(from.getFamily(), msg.info_hash, msg.want, answer.nodes4, answer.nodes6); + sendNodesValues(from, msg.tid, nnodes.first, nnodes.second, answer.values, msg.query, answer.ntoken); break; } case MessageType::AnnounceValue: { DHT_LOG.DEBUG("[node %s %s] got 'put' request for %s.", - msg.id.toString().c_str(), print_addr(from, fromlen).c_str(), + msg.id.toString().c_str(), from.toString().c_str(), msg.info_hash.toString().c_str()); ++in_stats.put; onAnnounce(node, msg.info_hash, msg.token, msg.values, msg.created); @@ -431,16 +419,16 @@ NetworkEngine::processMessage(const uint8_t *buf, size_t buflen, const sockaddr* This is to prevent them from backtracking, and hence polluting the DHT. */ for (auto& v : msg.values) { - sendValueAnnounced(from, fromlen, msg.tid, v->id); + sendValueAnnounced(from, msg.tid, v->id); } break; } case MessageType::Listen: { DHT_LOG.DEBUG("[node %s %s] got 'listen' request for %s.", - msg.id.toString().c_str(), print_addr(from, fromlen).c_str(), msg.info_hash.toString().c_str()); + msg.id.toString().c_str(), from.toString().c_str(), msg.info_hash.toString().c_str()); ++in_stats.listen; RequestAnswer answer = onListen(node, msg.info_hash, msg.token, msg.tid.getTid(), std::move(msg.query)); - sendListenConfirmation(from, fromlen, msg.tid); + sendListenConfirmation(from, msg.tid); break; } default: @@ -449,7 +437,7 @@ NetworkEngine::processMessage(const uint8_t *buf, size_t buflen, const sockaddr* } catch (const std::overflow_error& e) { DHT_LOG.ERR("Can't send value: buffer not large enough !"); } catch (DhtProtocolException& e) { - sendError(from, fromlen, msg.tid, e.getCode(), e.getMsg().c_str(), true); + sendError(from, msg.tid, e.getCode(), e.getMsg().c_str(), true); } } } @@ -462,34 +450,34 @@ 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& addr) { - size_t addr_len = std::min<size_t>(sa_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; + size_t addr_len = std::min<size_t>(addr.second, + (addr.getFamily() == AF_INET) ? sizeof(in_addr) : sizeof(in6_addr)); + void* addr_ptr = (addr.getFamily() == AF_INET) ? (void*)&((sockaddr_in*)&addr.first)->sin_addr + : (void*)&((sockaddr_in6*)&addr.first)->sin6_addr; pk.pack("sa"); pk.pack_bin(addr_len); pk.pack_bin_body((char*)addr_ptr, addr_len); } int -NetworkEngine::send(const char *buf, size_t len, int flags, const sockaddr *sa, socklen_t salen) +NetworkEngine::send(const char *buf, size_t len, int flags, const SockAddr& addr) { - if (salen == 0) + if (addr.second == 0) return -1; int s; - if (sa->sa_family == AF_INET) + if (addr.getFamily() == AF_INET) s = dht_socket; - else if (sa->sa_family == AF_INET6) + else if (addr.getFamily() == AF_INET6) s = dht_socket6; else s = -1; if (s < 0) return -1; - return sendto(s, buf, len, flags, sa, salen); + return sendto(s, buf, len, flags, (const sockaddr*)&addr.first, addr.second); } std::shared_ptr<Request> @@ -531,14 +519,14 @@ NetworkEngine::sendPing(std::shared_ptr<Node> node, RequestCb on_done, RequestEx } void -NetworkEngine::sendPong(const sockaddr* sa, socklen_t salen, TransId tid) { +NetworkEngine::sendPong(const SockAddr& addr, TransId tid) { msgpack::sbuffer buffer; msgpack::packer<msgpack::sbuffer> pk(&buffer); pk.pack_map(4+(network?1:0)); pk.pack(std::string("r")); pk.pack_map(2); pk.pack(std::string("id")); pk.pack(myid); - insertAddr(pk, sa, salen); + insertAddr(pk, addr); pk.pack(std::string("t")); pk.pack_bin(tid.size()); pk.pack_bin_body((const char*)tid.data(), tid.size()); @@ -548,7 +536,7 @@ NetworkEngine::sendPong(const sockaddr* sa, socklen_t salen, TransId tid) { pk.pack(std::string("n")); pk.pack(network); } - send(buffer.data(), buffer.size(), 0, sa, salen); + send(buffer.data(), buffer.size(), 0, addr); } std::shared_ptr<Request> @@ -652,19 +640,21 @@ NetworkEngine::deserializeNodes(ParsedMessage& msg) { } else { // deserialize nodes const auto& now = scheduler.time(); + SockAddr addr; for (unsigned i = 0; i < msg.nodes4_raw.size() / NODE4_INFO_BUF_LEN; i++) { uint8_t *ni = msg.nodes4_raw.data() + i * NODE4_INFO_BUF_LEN; const InfoHash& ni_id = *reinterpret_cast<InfoHash*>(ni); if (ni_id == myid) continue; - sockaddr_in sin; - std::fill_n((uint8_t*)&sin, sizeof(sockaddr_in), 0); - sin.sin_family = AF_INET; - memcpy(&sin.sin_addr, ni + ni_id.size(), 4); - memcpy(&sin.sin_port, ni + ni_id.size() + 4, 2); - if (isMartian((sockaddr*)&sin, sizeof(sin)) || isNodeBlacklisted((sockaddr*)&sin, sizeof(sin))) + auto sin = (sockaddr_in*)&addr.first; + std::fill_n((uint8_t*)sin, sizeof(sockaddr_in), 0); + sin->sin_family = AF_INET; + memcpy(&sin->sin_addr, ni + ni_id.size(), 4); + memcpy(&sin->sin_port, ni + ni_id.size() + 4, 2); + addr.second = sizeof(sockaddr_in); + if (isMartian(addr) || isNodeBlacklisted(addr)) continue; - msg.nodes4.emplace_back(cache.getNode(ni_id, (sockaddr*)&sin, sizeof(sin), now, false)); + msg.nodes4.emplace_back(cache.getNode(ni_id, addr, now, false)); onNewNode(msg.nodes4.back(), 0); } for (unsigned i = 0; i < msg.nodes6_raw.size() / NODE6_INFO_BUF_LEN; i++) { @@ -672,21 +662,22 @@ NetworkEngine::deserializeNodes(ParsedMessage& msg) { const InfoHash& ni_id = *reinterpret_cast<InfoHash*>(ni); if (ni_id == myid) continue; - sockaddr_in6 sin6; - std::fill_n((uint8_t*)&sin6, sizeof(sockaddr_in6), 0); - sin6.sin6_family = AF_INET6; - memcpy(&sin6.sin6_addr, ni + HASH_LEN, 16); - memcpy(&sin6.sin6_port, ni + HASH_LEN + 16, 2); - if (isMartian((sockaddr*)&sin6, sizeof(sin6)) || isNodeBlacklisted((sockaddr*)&sin6, sizeof(sin6))) + auto sin6 = (sockaddr_in6*)&addr.first; + std::fill_n((uint8_t*)sin6, sizeof(sockaddr_in6), 0); + sin6->sin6_family = AF_INET6; + memcpy(&sin6->sin6_addr, ni + HASH_LEN, 16); + memcpy(&sin6->sin6_port, ni + HASH_LEN + 16, 2); + addr.second = sizeof(sockaddr_in6); + if (isMartian(addr) || isNodeBlacklisted(addr)) continue; - msg.nodes6.emplace_back(cache.getNode(ni_id, (sockaddr*)&sin6, sizeof(sin6), now, false)); + msg.nodes6.emplace_back(cache.getNode(ni_id, addr, now, false)); onNewNode(msg.nodes6.back(), 0); } } } void -NetworkEngine::sendNodesValues(const sockaddr* sa, socklen_t salen, TransId tid, const Blob& nodes, const Blob& nodes6, +NetworkEngine::sendNodesValues(const SockAddr& addr, TransId tid, const Blob& nodes, const Blob& nodes6, const std::vector<std::shared_ptr<Value>>& st, const Query& query, const Blob& token) { msgpack::sbuffer buffer; msgpack::packer<msgpack::sbuffer> pk(&buffer); @@ -695,7 +686,7 @@ NetworkEngine::sendNodesValues(const sockaddr* sa, socklen_t salen, TransId tid, 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)); pk.pack(std::string("id")); pk.pack(myid); - insertAddr(pk, sa, salen); + insertAddr(pk, addr); if (nodes.size() > 0) { pk.pack(std::string("n4")); pk.pack_bin(nodes.size()); @@ -760,7 +751,7 @@ NetworkEngine::sendNodesValues(const sockaddr* sa, socklen_t salen, TransId tid, pk.pack(std::string("n")); pk.pack(network); } - send(buffer.data(), buffer.size(), 0, sa, salen); + send(buffer.data(), buffer.size(), 0, addr); } Blob @@ -776,7 +767,7 @@ NetworkEngine::bufferNodes(sa_family_t af, const InfoHash& id, std::vector<std:: const constexpr size_t size = HASH_LEN + sizeof(in_addr) + sizeof(in_port_t); // 26 for (size_t i=0; i<nnode; i++) { const Node& n = *nodes[i]; - sockaddr_in *sin = (sockaddr_in*)&n.ss; + sockaddr_in *sin = (sockaddr_in*)&n.addr.first; auto dest = bnodes.data() + size * i; memcpy(dest, n.id.data(), HASH_LEN); memcpy(dest + HASH_LEN, &sin->sin_addr, sizeof(in_addr)); @@ -787,7 +778,7 @@ NetworkEngine::bufferNodes(sa_family_t af, const InfoHash& id, std::vector<std:: const constexpr size_t size = HASH_LEN + sizeof(in6_addr) + sizeof(in_port_t); // 38 for (size_t i=0; i<nnode; i++) { const Node& n = *nodes[i]; - sockaddr_in6 *sin6 = (sockaddr_in6*)&n.ss; + sockaddr_in6 *sin6 = (sockaddr_in6*)&n.addr.first; auto dest = bnodes.data() + size * i; memcpy(dest, n.id.data(), HASH_LEN); memcpy(dest + HASH_LEN, &sin6->sin6_addr, sizeof(in6_addr)); @@ -857,14 +848,14 @@ NetworkEngine::sendListen(std::shared_ptr<Node> n, const InfoHash& infohash, con } void -NetworkEngine::sendListenConfirmation(const sockaddr* sa, socklen_t salen, TransId tid) { +NetworkEngine::sendListenConfirmation(const SockAddr& addr, TransId tid) { msgpack::sbuffer buffer; msgpack::packer<msgpack::sbuffer> pk(&buffer); pk.pack_map(4+(network?1:0)); pk.pack(std::string("r")); pk.pack_map(2); pk.pack(std::string("id")); pk.pack(myid); - insertAddr(pk, sa, salen); + insertAddr(pk, addr); pk.pack(std::string("t")); pk.pack_bin(tid.size()); pk.pack_bin_body((const char*)tid.data(), tid.size()); @@ -874,7 +865,7 @@ NetworkEngine::sendListenConfirmation(const sockaddr* sa, socklen_t salen, Trans pk.pack(std::string("n")); pk.pack(network); } - send(buffer.data(), buffer.size(), 0, sa, salen); + send(buffer.data(), buffer.size(), 0, addr); } std::shared_ptr<Request> @@ -929,7 +920,7 @@ NetworkEngine::sendAnnounceValue(std::shared_ptr<Node> n, const InfoHash& infoha } void -NetworkEngine::sendValueAnnounced(const sockaddr* sa, socklen_t salen, TransId tid, Value::Id vid) { +NetworkEngine::sendValueAnnounced(const SockAddr& addr, TransId tid, Value::Id vid) { msgpack::sbuffer buffer; msgpack::packer<msgpack::sbuffer> pk(&buffer); pk.pack_map(4+(network?1:0)); @@ -937,7 +928,7 @@ NetworkEngine::sendValueAnnounced(const sockaddr* sa, socklen_t salen, TransId t pk.pack(std::string("r")); pk.pack_map(3); pk.pack(std::string("id")); pk.pack(myid); pk.pack(std::string("vid")); pk.pack(vid); - insertAddr(pk, sa, salen); + insertAddr(pk, addr); pk.pack(std::string("t")); pk.pack_bin(tid.size()); pk.pack_bin_body((const char*)tid.data(), tid.size()); @@ -947,12 +938,11 @@ NetworkEngine::sendValueAnnounced(const sockaddr* sa, socklen_t salen, TransId t pk.pack(std::string("n")); pk.pack(network); } - send(buffer.data(), buffer.size(), 0, sa, salen); + send(buffer.data(), buffer.size(), 0, addr); } void -NetworkEngine::sendError(const sockaddr* sa, - socklen_t salen, +NetworkEngine::sendError(const SockAddr& addr, TransId tid, uint16_t code, const std::string& message, @@ -978,7 +968,7 @@ NetworkEngine::sendError(const sockaddr* sa, pk.pack(std::string("n")); pk.pack(network); } - send(buffer.data(), buffer.size(), 0, sa, salen); + send(buffer.data(), buffer.size(), 0, addr); } void diff --git a/src/node.cpp b/src/node.cpp index 74149decd63aed8d71b1cc63e0417e1c86c1183c..3476b8c66d1371c7423ee4f8c6e588cf3c0e5da2 100644 --- a/src/node.cpp +++ b/src/node.cpp @@ -65,10 +65,9 @@ Node::getPendingMessageCount() const } void -Node::update(const sockaddr* sa, socklen_t salen) +Node::update(const SockAddr& new_addr) { - std::copy_n((const uint8_t*)sa, salen, (uint8_t*)&ss); - sslen = salen; + addr = new_addr; } /** To be called when a message was sent to the node */ @@ -119,7 +118,7 @@ Node::toString() const std::ostream& operator<< (std::ostream& s, const Node& h) { - s << h.id << " " << print_addr(h.ss, h.sslen); + s << h.id << " " << h.addr.toString(); return s; } diff --git a/src/node_cache.cpp b/src/node_cache.cpp index 72655ab438d795826519513aacfe20d61af9d602..1491812e5a1239127ef02520c3b20f2450700247 100644 --- a/src/node_cache.cpp +++ b/src/node_cache.cpp @@ -27,10 +27,10 @@ NodeCache::getNode(const InfoHash& id, sa_family_t family) { } std::shared_ptr<Node> -NodeCache::getNode(const InfoHash& id, const sockaddr* sa, socklen_t sa_len, time_point now, bool confirm) { +NodeCache::getNode(const InfoHash& id, const SockAddr& addr, time_point now, bool confirm) { if (id == zeroes) - return std::make_shared<Node>(id, sa, sa_len); - return (sa->sa_family == AF_INET ? cache_4 : cache_6).getNode(id, sa, sa_len, now, confirm); + return std::make_shared<Node>(id, addr); + return (addr.getFamily() == AF_INET ? cache_4 : cache_6).getNode(id, addr, now, confirm); } std::vector<std::shared_ptr<Node>> @@ -89,15 +89,15 @@ NodeCache::NodeMap::getNode(const InfoHash& id) } std::shared_ptr<Node> -NodeCache::NodeMap::getNode(const InfoHash& id, const sockaddr* sa, socklen_t sa_len, time_point now, bool confirm) +NodeCache::NodeMap::getNode(const InfoHash& id, const SockAddr& addr, time_point now, bool confirm) { auto it = emplace(id, std::weak_ptr<Node>{}); auto node = it.first->second.lock(); if (not node) { - node = std::make_shared<Node>(id, sa, sa_len); + node = std::make_shared<Node>(id, addr); it.first->second = node; } else if (confirm || node->time < now - Node::NODE_EXPIRE_TIME) { - node->update(sa, sa_len); + node->update(addr); } return node; } diff --git a/src/utils.cpp b/src/utils.cpp index 1abf0fe0471048c55662c68ecbe714379d2ff503..a75ff99890923f1699a19df137eb1a8fbf2274e3 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -18,6 +18,7 @@ */ #include "utils.h" +#include "sockaddr.h" #include "default_types.h" namespace dht { @@ -47,7 +48,7 @@ print_addr(const sockaddr_storage& ss, socklen_t sslen) } std::string -printAddr(const Address& addr) { +printAddr(const SockAddr& addr) { return print_addr((const sockaddr*)&addr.first, addr.second); }