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