[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[gnunet] branch master updated: -rudimentary untested IP DHTU plugin
From: |
gnunet |
Subject: |
[gnunet] branch master updated: -rudimentary untested IP DHTU plugin |
Date: |
Tue, 06 Jul 2021 23:19:59 +0200 |
This is an automated email from the git hooks/post-receive script.
grothoff pushed a commit to branch master
in repository gnunet.
The following commit(s) were added to refs/heads/master by this push:
new d0d24c62f -rudimentary untested IP DHTU plugin
d0d24c62f is described below
commit d0d24c62f4b4a1872c8b52ad902b11aa4962d2c2
Author: Christian Grothoff <grothoff@gnunet.org>
AuthorDate: Tue Jul 6 23:16:53 2021 +0200
-rudimentary untested IP DHTU plugin
---
src/dhtu/plugin_dhtu_ip.c | 366 ++++++++++++++++++++++++++++-----------
src/include/gnunet_dhtu_plugin.h | 4 +-
2 files changed, 269 insertions(+), 101 deletions(-)
diff --git a/src/dhtu/plugin_dhtu_ip.c b/src/dhtu/plugin_dhtu_ip.c
index 19fe19192..a0da9d680 100644
--- a/src/dhtu/plugin_dhtu_ip.c
+++ b/src/dhtu/plugin_dhtu_ip.c
@@ -23,6 +23,11 @@
*
* @file plugin_dhtu_ip.c
* @brief plain IP based DHT network underlay
+ *
+ * TODO:
+ * - call NSE callback
+ * - expire destination addresses
+ * - faster lookup of destinations
*/
#include "platform.h"
#include "gnunet_dhtu_plugin.h"
@@ -85,11 +90,26 @@ struct GNUNET_DHTU_Source
*/
struct GNUNET_DHTU_Target
{
+ // FIXME: add mechanism for targets to expire
+ /**
+ * Kept in a DLL.
+ */
+ struct GNUNET_DHTU_Target *next;
+
+ /**
+ * Kept in a DLL.
+ */
+ struct GNUNET_DHTU_Target *prev;
/**
* Application context for this target.
*/
void *app_ctx;
+
+ /**
+ * Hash of the IP address.
+ */
+ struct GNUNET_DHTU_Hash id;
/**
* Head of preferences expressed for this target.
@@ -161,6 +181,16 @@ struct Plugin
*/
struct GNUNET_DHTU_Source *src_tail;
+ /**
+ * Head of destinations that are active.
+ */
+ struct GNUNET_DHTU_Target *dst_head;
+
+ /**
+ * Tail of destinations that are active.
+ */
+ struct GNUNET_DHTU_Target *dst_tail;
+
/**
* Task that scans for IP address changes.
*/
@@ -230,6 +260,99 @@ ip_verify (void *cls,
}
+/**
+ * Create a target to which we may send traffic.
+ *
+ * @param plugin our plugin
+ * @param addr target address
+ * @param addrlen number of bytes in @a addr
+ * @return new target object
+ */
+static struct GNUNET_DHTU_Target *
+create_target (struct Plugin *plugin,
+ const struct sockaddr *addr,
+ socklen_t addrlen)
+{
+ static struct GNUNET_DHTU_PublicKey pk;
+ struct GNUNET_DHTU_Target *dst;
+
+ pk.size = htons (sizeof (pk));
+ dst = GNUNET_new (struct GNUNET_DHTU_Target);
+ dst->addrlen = addrlen;
+ memcpy (&dst->addr,
+ addr,
+ addrlen);
+ switch (addr->sa_family)
+ {
+ case AF_INET:
+ {
+ const struct sockaddr_in *s4 = (const struct sockaddr_in *) addr;
+
+ GNUNET_assert (sizeof (struct sockaddr_in) == addrlen);
+ GNUNET_CRYPTO_hash (&s4->sin_addr,
+ sizeof (struct in_addr),
+ &dst->id.hc);
+ }
+ break;
+ case AF_INET6:
+ {
+ const struct sockaddr_in6 *s6 = (const struct sockaddr_in6 *) addr;
+
+ GNUNET_assert (sizeof (struct sockaddr_in6) == addrlen);
+ GNUNET_CRYPTO_hash (&s6->sin6_addr,
+ sizeof (struct in6_addr),
+ &dst->id.hc);
+ }
+ break;
+ default:
+ GNUNET_break (0);
+ GNUNET_free (dst);
+ return NULL;
+ }
+ GNUNET_CONTAINER_DLL_insert (plugin->dst_head,
+ plugin->dst_tail,
+ dst);
+ plugin->env->connect_cb (plugin->env->cls,
+ &pk,
+ &dst->id,
+ dst,
+ &dst->app_ctx);
+ return dst;
+}
+
+
+/**
+ * Find target matching @a addr. If none exists,
+ * create one!
+ *
+ * @param plugin the plugin handle
+ * @param src source target is from, or NULL if unknown
+ * @param addr socket address to find
+ * @param addrlen number of bytes in @a addr
+ * @return matching target object
+ */
+static struct GNUNET_DHTU_Target *
+find_target (struct Plugin *plugin,
+ const void *addr,
+ size_t addrlen)
+{
+ // FIXME-OPTIMIZE: use hash map instead of linear search
+ for (struct GNUNET_DHTU_Target *dst = plugin->dst_head;
+ NULL != dst;
+ dst = dst->next)
+ {
+ if ( (addrlen == dst->addrlen) &&
+ (0 == memcmp (addr,
+ &dst->addr,
+ addrlen)) )
+ return dst;
+ }
+ return create_target (plugin,
+ (const struct sockaddr *) addr,
+ addrlen);
+}
+
+
/**
* Request creation of a session with a peer at the given @a address.
*
@@ -289,9 +412,9 @@ ip_try_connect (void *cls,
return;
}
GNUNET_free (addr);
- (void) result->ai_addr; // FIXME: use!
-
- // FIXME: create target, etc.
+ (void) find_target (plugin,
+ result->ai_addr,
+ result->ai_addrlen);
freeaddrinfo (result);
}
@@ -533,7 +656,7 @@ scan (void *cls)
* create one!
*
* @param plugin the plugin handle
- * @param addr IP address to find
+ * @param addr socket address to find
* @param addrlen number of bytes in @a addr
* @return matching source object
*/
@@ -546,61 +669,16 @@ find_source (struct Plugin *plugin,
NULL != src;
src = src->next)
{
- if ( (addrlen == sizeof (struct in_addr)) &&
- (src->addrlen == sizeof (struct sockaddr_in)) )
- {
- const struct sockaddr_in *sa =
- (const struct sockaddr_in *) &src->addr;
- if (0 == memcmp (addr,
- &sa->sin_addr,
- addrlen))
- return src;
- }
- if ( (addrlen == sizeof (struct in6_addr)) &&
- (src->addrlen == sizeof (struct sockaddr_in6)) )
- {
- const struct sockaddr_in6 *sa =
- (const struct sockaddr_in6 *) &src->addr;
- if (0 == memcmp (addr,
- &sa->sin6_addr,
- addrlen))
+ if ( (addrlen == src->addrlen) &&
+ (0 == memcmp (addr,
+ &src->addr,
+ addrlen)) )
return src;
- }
}
- {
- struct sockaddr_storage sa;
- socklen_t salen;
-
- memset (&sa,
- 0,
- sizeof (sa));
- if (addrlen == sizeof (struct in_addr))
- {
- struct sockaddr_in *s4 =
- (struct sockaddr_in *) &sa;
-
- s4->sin_family = AF_INET;
- memcpy (&s4->sin_addr,
- addr,
- addrlen);
- salen = sizeof (*s4);
- }
- if (addrlen == sizeof (struct in6_addr))
- {
- struct sockaddr_in6 *s6 =
- (struct sockaddr_in6 *) &sa;
-
- s6->sin6_family = AF_INET6;
- memcpy (&s6->sin6_addr,
- addr,
- addrlen);
- salen = sizeof (*s6);
- }
- return create_source (plugin,
- (const struct sockaddr *) &sa,
- salen);
- }
+ return create_source (plugin,
+ (const struct sockaddr *) addr,
+ addrlen);
}
@@ -620,7 +698,7 @@ read_cb (void *cls)
.iov_base = buf,
.iov_len = sizeof (buf)
};
- char ctl[1024];
+ char ctl[128];
struct msghdr mh = {
.msg_name = &sa,
.msg_namelen = sizeof (sa),
@@ -629,7 +707,7 @@ read_cb (void *cls)
.msg_control = ctl,
.msg_controllen = sizeof (ctl)
};
-
+
ret = recvmsg (GNUNET_NETWORK_get_fd (plugin->sock),
&mh,
MSG_DONTWAIT);
@@ -638,54 +716,70 @@ read_cb (void *cls)
struct GNUNET_DHTU_Target *dst = NULL;
struct GNUNET_DHTU_Source *src = NULL;
struct cmsghdr *cmsg;
- struct msghdr *msh = mh.msg_control;
/* find IP where we received message */
- for (cmsg = CMSG_FIRSTHDR (msh);
+ for (cmsg = CMSG_FIRSTHDR (&mh);
NULL != cmsg;
- cmsg = CMSG_NXTHDR (msh,
+ cmsg = CMSG_NXTHDR (&mh,
cmsg))
{
if ( (cmsg->cmsg_level == IPPROTO_IP) &&
- (cmsg->cmsg_type == IP_ORIGDSTADDR) )
+ (cmsg->cmsg_type == IP_PKTINFO) )
{
- if (CMSG_LEN (sizeof (struct in_addr)) ==
+ if (CMSG_LEN (sizeof (struct in_pktinfo)) ==
cmsg->cmsg_len)
{
- struct in6_addr ia;
+ struct in_pktinfo pi;
- memcpy (&ia,
+ memcpy (&pi,
CMSG_DATA (cmsg),
- sizeof (ia));
- src = find_source (plugin,
- &ia,
- sizeof (ia));
+ sizeof (pi));
+ {
+ struct sockaddr_in sa = {
+ .sin_family = AF_INET,
+ .sin_addr = pi.ipi_addr
+ };
+
+ src = find_source (plugin,
+ &sa,
+ sizeof (sa));
+ }
break;
}
else
GNUNET_break (0);
}
if ( (cmsg->cmsg_level == IPPROTO_IPV6) &&
- (cmsg->cmsg_type == IP_ORIGDSTADDR) )
+ (cmsg->cmsg_type == IPV6_RECVPKTINFO) )
{
- if (CMSG_LEN (sizeof (struct in6_addr)) ==
- cmsg->cmsg_len)
+ if (CMSG_LEN (sizeof (struct in6_pktinfo)) ==
+ cmsg->cmsg_len)
{
- struct in6_addr ia;
+ struct in6_pktinfo pi;
- memcpy (&ia,
+ memcpy (&pi,
CMSG_DATA (cmsg),
- sizeof (ia));
- src = find_source (plugin,
- &ia,
- sizeof (ia));
- break;
+ sizeof (pi));
+ {
+ struct sockaddr_in6 sa = {
+ .sin6_family = AF_INET6,
+ .sin6_addr = pi.ipi6_addr,
+ .sin6_scope_id = pi.ipi6_ifindex
+ };
+
+ src = find_source (plugin,
+ &sa,
+ sizeof (sa));
+ break;
+ }
}
else
GNUNET_break (0);
}
}
- // FIXME: find or create 'dst'!
+ dst = find_target (plugin,
+ &sa,
+ mh.msg_namelen);
if ( (NULL == src) ||
(NULL == dst) )
{
@@ -723,6 +817,7 @@ libgnunet_plugin_dhtu_ip_init (void *cls)
char *port;
unsigned int nport;
int sock;
+ int af;
if (GNUNET_OK !=
GNUNET_CONFIGURATION_get_value_string (env->cfg,
@@ -755,7 +850,8 @@ libgnunet_plugin_dhtu_ip_init (void *cls)
plugin = GNUNET_new (struct Plugin);
plugin->env = env;
plugin->port = port;
- sock = socket (AF_INET6,
+ af = AF_INET6;
+ sock = socket (af,
SOCK_DGRAM,
IPPROTO_UDP);
if (-1 == sock)
@@ -766,25 +862,79 @@ libgnunet_plugin_dhtu_ip_init (void *cls)
GNUNET_free (plugin);
return NULL;
}
- {
- struct sockaddr_in6 sa = {
- .sin6_family = AF_INET6,
- .sin6_port = htons ((uint16_t) nport)
- };
-
- if (0 !=
- bind (sock,
- &sa,
- sizeof (sa)))
+ switch (af) {
+ case AF_INET:
{
- GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
- "socket");
- GNUNET_break (0 ==
- close (sock));
- GNUNET_free (plugin->port);
- GNUNET_free (plugin);
- return NULL;
+ int on = 1;
+
+ if (0 !=
+ setsockopt (sock,
+ IPPROTO_IP,
+ IP_PKTINFO,
+ &on,
+ sizeof (on)))
+ {
+ GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
+ "setsockopt");
+ }
+ }
+ {
+ struct sockaddr_in sa = {
+ .sin_family = AF_INET,
+ .sin_port = htons ((uint16_t) nport)
+ };
+
+ if (0 !=
+ bind (sock,
+ &sa,
+ sizeof (sa)))
+ {
+ GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
+ "socket");
+ GNUNET_break (0 ==
+ close (sock));
+ GNUNET_free (plugin->port);
+ GNUNET_free (plugin);
+ return NULL;
+ }
}
+ break;
+ case AF_INET6:
+ {
+ int on = 1;
+
+ if (0 !=
+ setsockopt (sock,
+ IPPROTO_IPV6,
+ IPV6_RECVPKTINFO,
+ &on,
+ sizeof (on)))
+ {
+ GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
+ "setsockopt");
+ }
+ }
+ {
+ struct sockaddr_in6 sa = {
+ .sin6_family = AF_INET6,
+ .sin6_port = htons ((uint16_t) nport)
+ };
+
+ if (0 !=
+ bind (sock,
+ &sa,
+ sizeof (sa)))
+ {
+ GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
+ "socket");
+ GNUNET_break (0 ==
+ close (sock));
+ GNUNET_free (plugin->port);
+ GNUNET_free (plugin);
+ return NULL;
+ }
+ }
+ break;
}
plugin->sock = GNUNET_NETWORK_socket_box_native (sock);
plugin->read_task = GNUNET_SCHEDULER_add_read_net (
@@ -818,6 +968,26 @@ libgnunet_plugin_dhtu_ip_done (void *cls)
{
struct GNUNET_DHTU_PluginFunctions *api = cls;
struct Plugin *plugin = api->cls;
+ struct GNUNET_DHTU_Source *src;
+ struct GNUNET_DHTU_Target *dst;
+
+ while (NULL != (dst = plugin->dst_head))
+ {
+ plugin->env->disconnect_cb (dst->app_ctx);
+ GNUNET_CONTAINER_DLL_remove (plugin->dst_head,
+ plugin->dst_tail,
+ dst);
+ GNUNET_free (dst);
+ }
+ while (NULL != (src = plugin->src_head))
+ {
+ plugin->env->address_del_cb (src->app_ctx);
+ GNUNET_CONTAINER_DLL_remove (plugin->src_head,
+ plugin->src_tail,
+ src);
+ GNUNET_free (src->address);
+ GNUNET_free (src);
+ }
GNUNET_SCHEDULER_cancel (plugin->scan_task);
GNUNET_break (0 ==
diff --git a/src/include/gnunet_dhtu_plugin.h b/src/include/gnunet_dhtu_plugin.h
index bcf61eaa2..4e5abf476 100644
--- a/src/include/gnunet_dhtu_plugin.h
+++ b/src/include/gnunet_dhtu_plugin.h
@@ -168,7 +168,7 @@ struct GNUNET_DHTU_PluginEnvironment
* @param std_dev standard deviation for the estimate
*/
void
- (*network_size_cb)(void *ctx,
+ (*network_size_cb)(void *cls,
struct GNUNET_TIME_Absolute timestamp,
double logestimate,
double std_dev);
@@ -184,7 +184,6 @@ struct GNUNET_DHTU_PluginEnvironment
* pointer will remain valid until @e disconnect_cb is called
* @param target handle to the target,
* pointer will remain valid until @e disconnect_cb is called
- * @param sctx context of the source address on which the connection happened
* @param[out] ctx storage space for DHT to use in association with this
target
*/
void
@@ -192,7 +191,6 @@ struct GNUNET_DHTU_PluginEnvironment
const struct GNUNET_DHTU_PublicKey *pk,
const struct GNUNET_DHTU_Hash *peer_id,
struct GNUNET_DHTU_Target *target,
- void *sctx,
void **ctx);
/**
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [gnunet] branch master updated: -rudimentary untested IP DHTU plugin,
gnunet <=