From 10f592d549432a4b791e2d8a68b9c77c8c0449be Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Adrien=20B=C3=A9raud?= <adrien.beraud@savoirfairelinux.com>
Date: Sun, 23 Oct 2016 18:29:54 -0400
Subject: [PATCH] nameservice: resolve outgoing names

Tuleap: #938
Change-Id: I4685a91dd7e345349855abdfbc041105bd6ae2a2
---
 src/ringdht/ringaccount.cpp | 67 ++++++++++++++++++++++++++++++-------
 src/ringdht/ringaccount.h   |  2 ++
 2 files changed, 57 insertions(+), 12 deletions(-)

diff --git a/src/ringdht/ringaccount.cpp b/src/ringdht/ringaccount.cpp
index 171fd80ac2..aa7fb53320 100644
--- a/src/ringdht/ringaccount.cpp
+++ b/src/ringdht/ringaccount.cpp
@@ -93,9 +93,9 @@ constexpr const char* const RingAccount::ACCOUNT_TYPE;
 static std::uniform_int_distribution<dht::Value::Id> udist;
 
 static const std::string
-parseRingUri(const std::string& toUrl)
+stripPrefix(const std::string& toUrl)
 {
-    auto dhtf = toUrl.find("ring:");
+    auto dhtf = toUrl.find(RING_URI_PREFIX);
     if (dhtf != std::string::npos) {
         dhtf = dhtf+5;
     } else {
@@ -104,16 +104,31 @@ parseRingUri(const std::string& toUrl)
     }
     while (dhtf < toUrl.length() && toUrl[dhtf] == '/')
         dhtf++;
+    return toUrl.substr(dhtf);
+}
 
-    if (toUrl.length() - dhtf < 40)
+static const std::string
+parseRingUri(const std::string& toUrl)
+{
+    auto sufix = stripPrefix(toUrl);
+    if (sufix.length() < 40)
         throw std::invalid_argument("id must be a ring infohash");
 
-    const std::string toUri = toUrl.substr(dhtf, 40);
+    const std::string toUri = sufix.substr(0, 40);
     if (std::find_if_not(toUri.cbegin(), toUri.cend(), ::isxdigit) != toUri.cend())
         throw std::invalid_argument("id must be a ring infohash");
     return toUri;
 }
 
+static bool
+isRingHash(const std::string& uri)
+{
+    if (uri.length() < 40)
+        return false;
+    if (std::find_if_not(uri.cbegin(), uri.cbegin()+40, ::isxdigit) != uri.cend())
+        return false;
+    return true;
+}
 
 static constexpr const char*
 dhtStatusStr(dht::NodeStatus status) {
@@ -206,17 +221,47 @@ template <>
 std::shared_ptr<SIPCall>
 RingAccount::newOutgoingCall(const std::string& toUrl)
 {
-    const std::string toUri = parseRingUri(toUrl);
-    RING_DBG("Calling DHT peer %s", toUri.c_str());
-
+    auto sufix = stripPrefix(toUrl);
+    RING_DBG("Calling DHT peer %s", sufix.c_str());
     auto& manager = Manager::instance();
     auto call = manager.callFactory.newCall<SIPCall, RingAccount>(*this, manager.getNewCallID(),
                                                                   Call::CallType::OUTGOING);
 
     call->setIPToIP(true);
     call->setSecure(isTlsEnabled());
-    call->initRecFilename(toUri);
+    call->initRecFilename(toUrl);
 
+    try {
+        const std::string toUri = parseRingUri(sufix);
+        startOutgoingCall(call, toUri);
+    } catch (...) {
+#if HAVE_RINGNS
+        std::weak_ptr<RingAccount> wthis_ = std::static_pointer_cast<RingAccount>(shared_from_this());
+        nameDir_.get().lookupName(sufix, [wthis_,call](const std::string& result, NameDirectory::Response response) mutable {
+            runOnMainThread([=]() mutable {
+                if (auto sthis = wthis_.lock()) {
+                    try {
+                        const std::string toUri = parseRingUri(result);
+                        sthis->startOutgoingCall(call, toUri);
+                    } catch (...) {
+                        call->onFailure(ENOENT);
+                    }
+                } else {
+                    call->onFailure();
+                }
+            });
+        });
+#else
+        call->onFailure(ENOENT);
+#endif
+    }
+
+    return call;
+}
+
+void
+RingAccount::startOutgoingCall(std::shared_ptr<SIPCall>& call, const std::string toUri)
+{
     auto sthis = std::static_pointer_cast<RingAccount>(shared_from_this());
 
     // TODO: for now, we automatically trust all explicitly called peers
@@ -332,8 +377,6 @@ RingAccount::newOutgoingCall(const std::string& toUrl)
             }
         }
     });
-
-    return call;
 }
 
 void
@@ -1187,7 +1230,7 @@ RingAccount::lookupName(const std::string& name)
 {
     auto acc = getAccountID();
     nameDir_.get().lookupName(name, [acc,name](const std::string& result, NameDirectory::Response response) {
-        emitSignal<DRing::ConfigurationSignal::RegisteredNameFound>(acc, 0, result, name);
+        emitSignal<DRing::ConfigurationSignal::RegisteredNameFound>(acc, (int)response, result, name);
     });
 }
 
@@ -1196,7 +1239,7 @@ RingAccount::lookupAddress(const std::string& addr)
 {
     auto acc = getAccountID();
     nameDir_.get().lookupAddress(addr, [acc,addr](const std::string& result, NameDirectory::Response response) {
-        emitSignal<DRing::ConfigurationSignal::RegisteredNameFound>(acc, 0, addr, result);
+        emitSignal<DRing::ConfigurationSignal::RegisteredNameFound>(acc, (int)response, addr, result);
     });
 }
 
diff --git a/src/ringdht/ringaccount.h b/src/ringdht/ringaccount.h
index cdf50d07a8..13e3ac5b3c 100644
--- a/src/ringdht/ringaccount.h
+++ b/src/ringdht/ringaccount.h
@@ -376,6 +376,8 @@ class RingAccount : public SIPAccountBase {
          */
         virtual void setAccountDetails(const std::map<std::string, std::string> &details) override;
 
+        void startOutgoingCall(std::shared_ptr<SIPCall>& call, const std::string toUri);
+
         /**
          * Start a SIP Call
          * @param call  The current call
-- 
GitLab