From 2e47b9bab598544b777740aac74a7b51c971ac70 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Adrien=20B=C3=A9raud?= <adrien.beraud@savoirfairelinux.com>
Date: Mon, 21 Oct 2019 15:56:35 -0400
Subject: [PATCH] c wrapper: add dht_runner_get_public_address to dhtcnode

---
 c/opendht.cpp    | 12 +++++++-----
 c/opendht_c.h    |  4 +---
 tools/dhtcnode.c | 36 ++++++++++++++++++++++++++++++++++++
 3 files changed, 44 insertions(+), 8 deletions(-)

diff --git a/c/opendht.cpp b/c/opendht.cpp
index b73acbb4..f935db96 100644
--- a/c/opendht.cpp
+++ b/c/opendht.cpp
@@ -193,7 +193,10 @@ void dht_runner_ping(dht_runner* r, struct sockaddr* addr, socklen_t addr_len) {
 
 void dht_runner_bootstrap(dht_runner* r, const char* host, const char* service) {
     auto runner = reinterpret_cast<dht::DhtRunner*>(r);
-    runner->bootstrap(host, service);
+    if (service)
+        runner->bootstrap(host, service);
+    else
+        runner->bootstrap(host);
 }
 
 void dht_runner_get(dht_runner* r, const dht_infohash* h, dht_get_cb cb, dht_done_cb done_cb, void* cb_user_data) {
@@ -294,16 +297,15 @@ dht_infohash dht_runner_get_id(const dht_runner* r) {
     return ret;
 }
 
-const struct sockaddr** dht_runner_get_public_address(const dht_runner* r)
-{
+struct sockaddr** dht_runner_get_public_address(const dht_runner* r) {
     auto runner = reinterpret_cast<const dht::DhtRunner*>(r);
     auto addrs = const_cast<dht::DhtRunner*>(runner)->getPublicAddress();
     if (addrs.empty())
         return nullptr;
-    auto ret = (const struct sockaddr**)malloc(sizeof(struct sockaddr*) * (addrs.size() + 1));
+    auto ret = (struct sockaddr**)malloc(sizeof(struct sockaddr*) * (addrs.size() + 1));
     for (size_t i=0; i<addrs.size(); i++) {
         if (auto len = addrs[i].getLength()) {
-            ret[i] = (const struct sockaddr*)malloc(len);
+            ret[i] = (struct sockaddr*)malloc(len);
             memcpy((struct sockaddr*)ret[i], addrs[i].get(), len);
         } else {
             ret[i] = nullptr;
diff --git a/c/opendht_c.h b/c/opendht_c.h
index 47c73412..93687d49 100644
--- a/c/opendht_c.h
+++ b/c/opendht_c.h
@@ -11,8 +11,6 @@ extern "C" {
 #include <stdint.h>
 #include <stddef.h>
 
-struct sockaddr;
-
 // Non-owning data view
 struct OPENDHT_C_PUBLIC dht_data_view {
     const uint8_t* data;
@@ -139,7 +137,7 @@ OPENDHT_C_PUBLIC void dht_runner_cancel_put(dht_runner* runner, const dht_infoha
 OPENDHT_C_PUBLIC void dht_runner_shutdown(dht_runner* runner, dht_shutdown_cb done_cb, void* cb_user_data);
 OPENDHT_C_PUBLIC dht_infohash dht_runner_get_node_id(const dht_runner* runner);
 OPENDHT_C_PUBLIC dht_infohash dht_runner_get_id(const dht_runner* runner);
-OPENDHT_C_PUBLIC const struct sockaddr** dht_runner_get_public_address(const dht_runner* runner);
+OPENDHT_C_PUBLIC struct sockaddr** dht_runner_get_public_address(const dht_runner* runner);
 
 #ifdef __cplusplus
 }
diff --git a/tools/dhtcnode.c b/tools/dhtcnode.c
index 309bd19c..5446a2d8 100644
--- a/tools/dhtcnode.c
+++ b/tools/dhtcnode.c
@@ -4,6 +4,7 @@
 #include <string.h>
 #include <unistd.h>
 #include <stdlib.h>
+#include <arpa/inet.h>
 
 struct op_context {
     dht_runner* runner;
@@ -36,6 +37,27 @@ bool op_context_free(void* user_data)
     free(ctx);
 }
 
+char* print_addr(const struct sockaddr* addr) {
+    char* s = NULL;
+    switch(addr->sa_family) {
+    case AF_INET: {
+        struct sockaddr_in *addr_in = (struct sockaddr_in *)addr;
+        s = malloc(INET_ADDRSTRLEN);
+        inet_ntop(AF_INET, &(addr_in->sin_addr), s, INET_ADDRSTRLEN);
+        break;
+    }
+    case AF_INET6: {
+        struct sockaddr_in6 *addr_in6 = (struct sockaddr_in6 *)addr;
+        s = malloc(INET6_ADDRSTRLEN);
+        inet_ntop(AF_INET6, &(addr_in6->sin6_addr), s, INET6_ADDRSTRLEN);
+        break;
+    }
+    default:
+        break;
+    }
+    return s;
+}
+
 int main()
 {
     dht_runner* runner = dht_runner_new();
@@ -63,6 +85,20 @@ int main()
 
     sleep(1);
 
+    dht_runner_bootstrap(runner, "bootstrap.jami.net", NULL);
+
+    sleep(2);
+
+    struct sockaddr** addrs = dht_runner_get_public_address(runner);
+    for (struct sockaddr** addrIt = addrs; *addrIt; addrIt++) {
+        struct sockaddr* addr = *addrIt;
+        char* addr_str = print_addr(addr);
+        free(addr);
+        printf("Found public address: %s\n", addr_str);
+        free(addr_str);
+    }
+    free(addrs);
+
     dht_runner_cancel_listen(runner, &h, token);
     dht_op_token_delete(token);
 
-- 
GitLab