diff --git a/c/opendht.cpp b/c/opendht.cpp
index 0524a72e5adcb64aabef444b6cbf810ceabd6ea7..b73acbb4a0ca86bd07d2ef39aad0278196c1415c 100644
--- a/c/opendht.cpp
+++ b/c/opendht.cpp
@@ -294,6 +294,25 @@ dht_infohash dht_runner_get_id(const dht_runner* r) {
     return ret;
 }
 
+const 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));
+    for (size_t i=0; i<addrs.size(); i++) {
+        if (auto len = addrs[i].getLength()) {
+            ret[i] = (const struct sockaddr*)malloc(len);
+            memcpy((struct sockaddr*)ret[i], addrs[i].get(), len);
+        } else {
+            ret[i] = nullptr;
+        }
+    }
+    ret[addrs.size()] = nullptr;
+    return ret;
+}
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/c/opendht_c.h b/c/opendht_c.h
index d142aab9c344653b05315bdefea42460c93b8925..47c734122880906d995581ffe7e39159fcf6d1d7 100644
--- a/c/opendht_c.h
+++ b/c/opendht_c.h
@@ -11,6 +11,8 @@ 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;
@@ -137,6 +139,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);
 
 #ifdef __cplusplus
 }