gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gnunet] branch master updated: -work on receive logic


From: gnunet
Subject: [gnunet] branch master updated: -work on receive logic
Date: Tue, 06 Jul 2021 21:07:13 +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 7d384a118 -work on receive logic
7d384a118 is described below

commit 7d384a118326f5ce8237281c5b5ffa36c32662fe
Author: Christian Grothoff <grothoff@gnunet.org>
AuthorDate: Tue Jul 6 21:04:08 2021 +0200

    -work on receive logic
---
 src/dhtu/plugin_dhtu_ip.c | 390 +++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 347 insertions(+), 43 deletions(-)

diff --git a/src/dhtu/plugin_dhtu_ip.c b/src/dhtu/plugin_dhtu_ip.c
index c76744d9a..19fe19192 100644
--- a/src/dhtu/plugin_dhtu_ip.c
+++ b/src/dhtu/plugin_dhtu_ip.c
@@ -167,9 +167,14 @@ struct Plugin
   struct GNUNET_SCHEDULER_Task *scan_task;
 
   /**
-   * Port we bind to. FIXME: initialize...
+   * Task that reads incoming UDP packets.
    */
-  char *my_port;
+  struct GNUNET_SCHEDULER_Task *read_task;
+
+  /**
+   * Port we bind to. 
+   */
+  char *port;
 
   /**
    * How often have we scanned for IPs?
@@ -179,7 +184,7 @@ struct Plugin
   /**
    * My UDP socket.
    */
-  int sock;
+  struct GNUNET_NETWORK_Handle *sock;
 };
 
 
@@ -266,7 +271,7 @@ ip_try_connect (void *cls,
   colon = strchr (addr, ':');
   if (NULL == colon)
   {
-    port = plugin->my_port;
+    port = plugin->port;
   }
   else
   {
@@ -359,16 +364,92 @@ ip_send (void *cls,
 {
   struct Plugin *plugin = cls;
 
-  sendto (plugin->sock,
-          msg,
-          msg_size,
-          0,
-          (const struct sockaddr *) &target->addr,
-          target->addrlen);
+  GNUNET_NETWORK_socket_sendto (plugin->sock,
+                                msg,
+                                msg_size,
+                                (const struct sockaddr *) &target->addr,
+                                target->addrlen);
   finished_cb (finished_cb_cls);
 }
 
 
+/**
+ * Create a new source on which we may be receiving traffic.
+ *
+ * @param plugin our plugin
+ * @param addr our address
+ * @param addrlen number of bytes in @a addr
+ * @return new source object
+ */
+static struct GNUNET_DHTU_Source *
+create_source (struct Plugin *plugin,
+               const struct sockaddr *addr,
+               socklen_t addrlen)
+{
+  struct GNUNET_DHTU_Source *src;
+  
+  src = GNUNET_new (struct GNUNET_DHTU_Source);
+  src->addrlen = addrlen;
+  memcpy (&src->addr,
+          addr,
+          addrlen);
+  src->scan_generation = plugin->scan_generation;
+  switch (addr->sa_family)
+  {
+  case AF_INET:
+    {
+      const struct sockaddr_in *s4 = (const struct sockaddr_in *) addr;
+      char buf[INET_ADDRSTRLEN];
+
+      GNUNET_assert (sizeof (struct sockaddr_in) == addrlen);
+      GNUNET_CRYPTO_hash (&s4->sin_addr,
+                          sizeof (struct in_addr),
+                          &src->id.hc);
+      GNUNET_asprintf (&src->address,
+                       "ip+udp://%s:%u",
+                       inet_ntop (AF_INET,
+                                  &s4->sin_addr,
+                                  buf,
+                                  sizeof (buf)),
+                       ntohs (s4->sin_port));
+    }
+    break;
+  case AF_INET6:
+    {
+      const struct sockaddr_in6 *s6 = (const struct sockaddr_in6 *) addr;
+      char buf[INET6_ADDRSTRLEN];
+
+      GNUNET_assert (sizeof (struct sockaddr_in6) == addrlen);
+      GNUNET_CRYPTO_hash (&s6->sin6_addr,
+                          sizeof (struct in6_addr),
+                          &src->id.hc);
+      GNUNET_asprintf (&src->address,
+                       "ip+udp://[%s]:%u",
+                       inet_ntop (AF_INET6,
+                                  &s6->sin6_addr,
+                                  buf,
+                                  sizeof (buf)),
+                       ntohs (s6->sin6_port));
+    }
+    break;
+  default:
+    GNUNET_break (0);
+    GNUNET_free (src);
+    return NULL;
+  }
+  GNUNET_CONTAINER_DLL_insert (plugin->src_head,
+                               plugin->src_tail,
+                               src);
+  plugin->env->address_add_cb (plugin->env->cls,
+                               &src->id,
+                               NULL, /* no key */
+                               src->address,
+                               src,
+                               &src->app_ctx);
+  return src;
+}
+
+
 /**
  * Callback function invoked for each interface found.
  *
@@ -406,36 +487,9 @@ process_ifcs (void *cls,
       return GNUNET_OK;
     }
   }
-  src = GNUNET_new (struct GNUNET_DHTU_Source);
-  src->addrlen = addrlen;
-  memcpy (&src->addr,
-          addr,
-          addrlen);
-  src->scan_generation = plugin->scan_generation;
-  switch (addr->sa_family)
-  {
-    case AF_INET:
-      // hash v4 address
-      // convert address to src->address
-      break;
-    case AF_INET6:
-      // hash v6 address
-      // convert address to src->address
-      break;
-    default:
-      GNUNET_break (0);
-      GNUNET_free (src);
-      return GNUNET_OK;
-  }
-  GNUNET_CONTAINER_DLL_insert (plugin->src_head,
-                               plugin->src_tail,
-                               src);
-  plugin->env->address_add_cb (plugin->env->cls,
-                               &src->id,
-                               NULL, /* no key */
-                               src->address,
-                               src,
-                               &src->app_ctx);
+  (void) create_source (plugin,
+                        addr,
+                        addrlen);
   return GNUNET_OK;
 }
 
@@ -474,6 +528,186 @@ scan (void *cls)
 }
 
 
+/**
+ * Find our source matching @a addr. If none exists,
+ * create one!
+ *
+ * @param plugin the plugin handle
+ * @param addr IP address to find
+ * @param addrlen number of bytes in @a addr
+ * @return matching source object
+ */
+static struct GNUNET_DHTU_Source *
+find_source (struct Plugin *plugin,
+             const void *addr,
+             size_t addrlen)
+{
+  for (struct GNUNET_DHTU_Source *src = plugin->src_head;
+       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))
+        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);
+  }
+}
+
+
+/**
+ * UDP socket is ready to receive. Read.
+ *
+ * @param cls our `struct Plugin *`
+ */
+static void
+read_cb (void *cls)
+{
+  struct Plugin *plugin = cls;
+  ssize_t ret;
+  char buf[65536];
+  struct sockaddr_storage sa;
+  struct iovec iov = {
+    .iov_base = buf,
+    .iov_len = sizeof (buf)
+  };
+  char ctl[1024];
+  struct msghdr mh = {
+    .msg_name = &sa,
+    .msg_namelen = sizeof (sa),
+    .msg_iov = &iov,
+    .msg_iovlen = 1,
+    .msg_control = ctl,
+    .msg_controllen = sizeof (ctl)
+  };
+  
+  ret = recvmsg  (GNUNET_NETWORK_get_fd (plugin->sock),
+                  &mh,
+                  MSG_DONTWAIT);
+  if (ret >= 0)
+  {
+    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);
+         NULL != cmsg;
+         cmsg = CMSG_NXTHDR (msh,
+                             cmsg))
+    {
+      if ( (cmsg->cmsg_level == IPPROTO_IP) &&
+           (cmsg->cmsg_type == IP_ORIGDSTADDR) )
+      {
+        if (CMSG_LEN (sizeof (struct in_addr)) ==
+            cmsg->cmsg_len)
+        {
+          struct in6_addr ia;
+          
+          memcpy (&ia,
+                  CMSG_DATA (cmsg),
+                  sizeof (ia));
+          src = find_source (plugin,
+                             &ia,
+                             sizeof (ia));
+          break;
+        }
+        else
+          GNUNET_break (0);
+      }
+      if ( (cmsg->cmsg_level == IPPROTO_IPV6) &&
+           (cmsg->cmsg_type == IP_ORIGDSTADDR) )
+      {
+        if (CMSG_LEN (sizeof (struct in6_addr)) ==
+                 cmsg->cmsg_len)
+        {
+          struct in6_addr ia;
+          
+          memcpy (&ia,
+                  CMSG_DATA (cmsg),
+                  sizeof (ia));
+          src = find_source (plugin,
+                             &ia,
+                             sizeof (ia));
+          break;
+        }
+        else
+          GNUNET_break (0);
+      }   
+    }
+    // FIXME: find or create 'dst'!
+    if ( (NULL == src) ||
+         (NULL == dst) )
+    {
+      GNUNET_break (0);
+    }
+    else
+    {
+      plugin->env->receive_cb (plugin->env->cls,
+                               dst->app_ctx,
+                               src->app_ctx,
+                               buf,
+                               ret);
+    }
+  }
+  plugin->read_task = GNUNET_SCHEDULER_add_read_net (
+    GNUNET_TIME_UNIT_FOREVER_REL,
+    plugin->sock,
+    &read_cb,
+    plugin);
+}
+
+
 /**
  * Entry point for the plugin.
  *
@@ -486,14 +720,81 @@ libgnunet_plugin_dhtu_ip_init (void *cls)
   struct GNUNET_DHTU_PluginEnvironment *env = cls;
   struct GNUNET_DHTU_PluginFunctions *api;
   struct Plugin *plugin;
+  char *port;
+  unsigned int nport;
+  int sock;
 
+  if (GNUNET_OK !=
+      GNUNET_CONFIGURATION_get_value_string (env->cfg,
+                                             "DHTU-IP",
+                                             "UDP_PORT",
+                                             &port))
+  {
+    GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
+                               "DHTU-IP",
+                               "UDP_PORT");
+    return NULL;
+  }
+  {
+    char dummy;
+
+    if ( (1 != sscanf (port,
+                       "%u%c",
+                       &nport,
+                       &dummy)) ||
+         (nport > UINT16_MAX) )
+    {
+      GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
+                                 "DHTU-IP",
+                                 "UDP_PORT",
+                                 "must be number below 65536");
+      GNUNET_free (port);
+      return NULL;
+    }
+  }
   plugin = GNUNET_new (struct Plugin);
   plugin->env = env;
-  // FIXME: get port configuration!
+  plugin->port = port;
+  sock = socket (AF_INET6,
+                 SOCK_DGRAM,
+                 IPPROTO_UDP);
+  if (-1 == sock)
+  {
+    GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
+                         "socket");
+    GNUNET_free (plugin->port);
+    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)))
+    {
+      GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
+                           "socket");
+      GNUNET_break (0 ==
+                    close (sock));
+      GNUNET_free (plugin->port);
+      GNUNET_free (plugin);
+      return NULL;
+    }
+  }
+  plugin->sock = GNUNET_NETWORK_socket_box_native (sock);
+  plugin->read_task = GNUNET_SCHEDULER_add_read_net (
+    GNUNET_TIME_UNIT_FOREVER_REL,
+    plugin->sock,
+    &read_cb,
+    plugin);
+  // FIXME: deal with NSE callback...
   plugin->scan_task = GNUNET_SCHEDULER_add_now (&scan,
                                                 plugin);
-  // FIXME: bind, start receive loop
-  // FIXME: deal with NSE callback...
   api = GNUNET_new (struct GNUNET_DHTU_PluginFunctions);
   api->cls = plugin;
   api->sign = &ip_sign;
@@ -519,6 +820,9 @@ libgnunet_plugin_dhtu_ip_done (void *cls)
   struct Plugin *plugin = api->cls;
 
   GNUNET_SCHEDULER_cancel (plugin->scan_task);
+  GNUNET_break (0 ==
+                GNUNET_NETWORK_socket_close (plugin->sock));
+  GNUNET_free (plugin->port);
   GNUNET_free (plugin);
   GNUNET_free (api);
   return NULL;

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]