From cb2d14e9055bcf28b42bb919be32b376dd0f25e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrien=20B=C3=A9raud?= <adrien.beraud@savoirfairelinux.com> Date: Sun, 22 Feb 2015 21:04:32 -0500 Subject: [PATCH] add DhtMessage type for node-to-node communication --- include/opendht/value.h | 46 +++++++++++++++++++++++--- src/securedht.cpp | 6 ++-- src/value.cpp | 72 +++++++++++++++++++++++++++++------------ tools/dhtnode.cpp | 2 +- 4 files changed, 98 insertions(+), 28 deletions(-) diff --git a/include/opendht/value.h b/include/opendht/value.h index 96a83d9b..a7b6b16e 100644 --- a/include/opendht/value.h +++ b/include/opendht/value.h @@ -324,19 +324,19 @@ struct Value : public Serializable /* "Peer" announcement */ -struct ServiceAnnouncement : public Serializable +struct IpServiceAnnouncement : public Serializable { - ServiceAnnouncement(in_port_t p = 0) { + IpServiceAnnouncement(in_port_t p = 0) { ss.ss_family = 0; setPort(p); } - ServiceAnnouncement(const sockaddr* sa, socklen_t sa_len) { + IpServiceAnnouncement(const sockaddr* sa, socklen_t sa_len) { if (sa) std::copy_n((const uint8_t*)sa, sa_len, (uint8_t*)&ss); } - ServiceAnnouncement(const Blob& b) { + IpServiceAnnouncement(const Blob& b) { unpackBlob(b); } @@ -358,10 +358,46 @@ struct ServiceAnnouncement : public Serializable static bool storePolicy(InfoHash, std::shared_ptr<Value>&, InfoHash, const sockaddr*, socklen_t); /** print value for debugging */ - friend std::ostream& operator<< (std::ostream&, const ServiceAnnouncement&); + friend std::ostream& operator<< (std::ostream&, const IpServiceAnnouncement&); private: sockaddr_storage ss; }; + +struct DhtMessage : public Serializable +{ + DhtMessage(uint16_t s, Blob msg = {}) : service(s), message(msg) {} + + DhtMessage(const Blob& b) { + unpackBlob(b); + } + + virtual void pack(Blob& res) const; + virtual void unpack(Blob::const_iterator& begin, Blob::const_iterator& end); + + static const ValueType TYPE; + static bool storePolicy(InfoHash, std::shared_ptr<Value>&, InfoHash, const sockaddr*, socklen_t); + + /** print value for debugging */ + friend std::ostream& operator<< (std::ostream&, const DhtMessage&); + +private: + uint16_t service; + Blob message; +}; + +const std::array<std::reference_wrapper<const ValueType>, 2> +DEFAULT_TYPES +{ + ValueType::USER_DATA, + DhtMessage::TYPE, +}; + +const std::array<std::reference_wrapper<const ValueType>, 1> +DEFAULT_INSECURE_TYPES +{ + IpServiceAnnouncement::TYPE +}; + } diff --git a/src/securedht.cpp b/src/securedht.cpp index ddfd718c..cc94e98d 100644 --- a/src/securedht.cpp +++ b/src/securedht.cpp @@ -54,8 +54,10 @@ SecureDht::SecureDht(int s, int s6, crypto::Identity id) if (certId != key_->getPublicKey().getId()) throw DhtException("SecureDht: provided certificate doesn't match private key."); - registerType(ValueType::USER_DATA); - registerInsecureType(ServiceAnnouncement::TYPE); + for (const auto& type : DEFAULT_TYPES) + registerType(type); + for (const auto& type : DEFAULT_INSECURE_TYPES) + registerInsecureType(type); registerInsecureType(CERTIFICATE_TYPE); Dht::put(certId, Value { diff --git a/src/value.cpp b/src/value.cpp index 3dba6500..3f32de4c 100644 --- a/src/value.cpp +++ b/src/value.cpp @@ -41,8 +41,8 @@ std::ostream& operator<< (std::ostream& s, const Value& v) if (v.flags.isEncrypted()) s << "encrypted "; else { - if (v.type == ServiceAnnouncement::TYPE.id) { - s << ServiceAnnouncement(v.data); + if (v.type == IpServiceAnnouncement::TYPE.id) { + s << IpServiceAnnouncement(v.data); } else if (v.type == CERTIFICATE_TYPE.id) { s << "Certificate"; try { @@ -65,21 +65,6 @@ std::ostream& operator<< (std::ostream& s, const Value& v) const ValueType ValueType::USER_DATA = {0, "User Data"}; -bool -ServiceAnnouncement::storePolicy(InfoHash, std::shared_ptr<Value>& v, InfoHash, const sockaddr* from, socklen_t fromlen) -{ - ServiceAnnouncement request {}; - request.unpackBlob(v->data); - if (request.getPort() == 0) - return false; - ServiceAnnouncement sa_addr {from, fromlen}; - sa_addr.setPort(request.getPort()); - // argument v is modified (not the value). - v = std::make_shared<Value>(ServiceAnnouncement::TYPE, sa_addr, v->id); - return true; -} - -const ValueType ServiceAnnouncement::TYPE = {1, "Service Announcement", std::chrono::minutes(15), ServiceAnnouncement::storePolicy, ValueType::DEFAULT_EDIT_POLICY}; void Value::packToSign(Blob& res) const @@ -169,7 +154,7 @@ Value::unpack(Blob::const_iterator& begin, Blob::const_iterator& end) unpackBody(begin, end); } -std::ostream& operator<< (std::ostream& s, const ServiceAnnouncement& v) +std::ostream& operator<< (std::ostream& s, const IpServiceAnnouncement& v) { s << "Peer: "; s << "port " << v.getPort(); @@ -184,7 +169,7 @@ std::ostream& operator<< (std::ostream& s, const ServiceAnnouncement& v) } void -ServiceAnnouncement::pack(Blob& res) const +IpServiceAnnouncement::pack(Blob& res) const { serialize<in_port_t>(getPort(), res); if (ss.ss_family == AF_INET) { @@ -197,7 +182,7 @@ ServiceAnnouncement::pack(Blob& res) const } void -ServiceAnnouncement::unpack(Blob::const_iterator& begin, Blob::const_iterator& end) +IpServiceAnnouncement::unpack(Blob::const_iterator& begin, Blob::const_iterator& end) { setPort(deserialize<in_port_t>(begin, end)); size_t addr_size = end - begin; @@ -216,5 +201,52 @@ ServiceAnnouncement::unpack(Blob::const_iterator& begin, Blob::const_iterator& e } } +bool +IpServiceAnnouncement::storePolicy(InfoHash, std::shared_ptr<Value>& v, InfoHash, const sockaddr* from, socklen_t fromlen) +{ + IpServiceAnnouncement request {}; + request.unpackBlob(v->data); + if (request.getPort() == 0) + return false; + IpServiceAnnouncement sa_addr {from, fromlen}; + sa_addr.setPort(request.getPort()); + // argument v is modified (not the value). + v = std::make_shared<Value>(IpServiceAnnouncement::TYPE, sa_addr, v->id); + return true; +} + +const ValueType IpServiceAnnouncement::TYPE = {2, "Internet Service Announcement", std::chrono::minutes(15), IpServiceAnnouncement::storePolicy, ValueType::DEFAULT_EDIT_POLICY}; + +std::ostream& operator<< (std::ostream& s, const DhtMessage& v) +{ + s << "DhtMessage: service " << v.service << std::endl; + s.write((const char*)v.message.data(), v.message.size()); + return s; +} + +void +DhtMessage::pack(Blob& res) const +{ + serialize<int16_t>(service, res); + serialize<Blob>(message, res); +} + +void +DhtMessage::unpack(Blob::const_iterator& begin, Blob::const_iterator& end) +{ + service = deserialize<int16_t>(begin, end); + message = deserialize<Blob>(begin, end); +} + +bool +DhtMessage::storePolicy(InfoHash, std::shared_ptr<Value>& v, InfoHash, const sockaddr* from, socklen_t fromlen) +{ + DhtMessage request {v->data}; + if (request.service == 0) + return false; + return true; +} + +const ValueType DhtMessage::TYPE = {1, "DHT message", std::chrono::minutes(5), DhtMessage::storePolicy, ValueType::DEFAULT_EDIT_POLICY}; } diff --git a/tools/dhtnode.cpp b/tools/dhtnode.cpp index 7dd41ab8..decef155 100644 --- a/tools/dhtnode.cpp +++ b/tools/dhtnode.cpp @@ -276,7 +276,7 @@ main(int argc, char **argv) else if (op == "a") { in_port_t port; iss >> port; - dht.put(id, dht::Value {dht::ServiceAnnouncement::TYPE.id, dht::ServiceAnnouncement(port)}, [](bool ok) { + dht.put(id, dht::Value {dht::IpServiceAnnouncement::TYPE.id, dht::IpServiceAnnouncement(port)}, [](bool ok) { std::cout << "Announce done !" << ok << std::endl; }); } -- GitLab