Allowed to destroy NULL paths
[oweals/gnunet.git] / src / mesh / mesh_api_new.c
index d3ce0b2aebb22be1e925905b5367a0dc4c05640a..64f880e062ef3335d588a84886ce9ef80af02366 100644 (file)
@@ -45,7 +45,7 @@ extern "C"
 #include "mesh.h"
 #include "mesh_protocol.h"
 
-#define DEBUG GNUNET_YES
+#define MESH_API_DEBUG GNUNET_YES
 
 #define LOG(kind,...) GNUNET_log_from (kind, "mesh-api",__VA_ARGS__)
 
@@ -618,7 +618,7 @@ send_connect (struct GNUNET_MESH_Handle *h)
       types[ntypes] = htons (h->message_handlers[ntypes].type);
     msg->applications = htons (napps);
     msg->types = htons (ntypes);
-#if DEBUG
+#if MESH_API_DEBUG
     LOG (GNUNET_ERROR_TYPE_DEBUG,
          "mesh: Sending %lu bytes long message %d types and %d apps\n",
          ntohs (msg->header.size), ntypes, napps);
@@ -642,7 +642,7 @@ reconnect (struct GNUNET_MESH_Handle *h)
   struct GNUNET_MESH_Tunnel *t;
   unsigned int i;
 
-#if DEBUG
+#if MESH_API_DEBUG
   LOG (GNUNET_ERROR_TYPE_DEBUG, "mesh: *****************************\n");
   LOG (GNUNET_ERROR_TYPE_DEBUG, "mesh: *******   RECONNECT   *******\n");
   LOG (GNUNET_ERROR_TYPE_DEBUG, "mesh: *****************************\n");
@@ -749,7 +749,7 @@ process_tunnel_created (struct GNUNET_MESH_Handle *h,
                         const struct GNUNET_MESH_TunnelNotification *msg)
 {
   struct GNUNET_MESH_Tunnel *t;
-  struct GNUNET_TRANSPORT_ATS_Information atsi;
+  struct GNUNET_ATS_Information atsi;
   MESH_TunnelNumber tid;
 
   tid = ntohl (msg->tunnel_id);
@@ -796,7 +796,6 @@ process_tunnel_destroy (struct GNUNET_MESH_Handle *h,
 
   if (NULL == t)
   {
-    GNUNET_break (0);
     return;
   }
   if (0 == t->owner)
@@ -821,7 +820,7 @@ process_peer_event (struct GNUNET_MESH_Handle *h,
 {
   struct GNUNET_MESH_Tunnel *t;
   struct GNUNET_MESH_Peer *p;
-  struct GNUNET_TRANSPORT_ATS_Information atsi;
+  struct GNUNET_ATS_Information atsi;
   GNUNET_PEER_Id id;
   uint16_t size;
 
@@ -886,15 +885,20 @@ process_incoming_data (struct GNUNET_MESH_Handle *h,
   unsigned int i;
   uint16_t type;
 
-
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "mesh: Got a data message!\n");
   type = ntohs (message->type);
   switch (type)
   {
   case GNUNET_MESSAGE_TYPE_MESH_UNICAST:
     ucast = (struct GNUNET_MESH_Unicast *) message;
+
     t = retrieve_tunnel (h, ntohl (ucast->tid));
     payload = (struct GNUNET_MessageHeader *) &ucast[1];
     peer = &ucast->oid;
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "mesh:   on tunnel %s [%x]\n",
+                GNUNET_i2s (peer),
+                ntohl (ucast->tid));
     break;
   case GNUNET_MESSAGE_TYPE_MESH_MULTICAST:
     mcast = (struct GNUNET_MESH_Multicast *) message;
@@ -923,7 +927,7 @@ process_incoming_data (struct GNUNET_MESH_Handle *h,
     handler = &h->message_handlers[i];
     if (handler->type == type)
     {
-      struct GNUNET_TRANSPORT_ATS_Information atsi;
+      struct GNUNET_ATS_Information atsi;
 
       atsi.type = 0;
       atsi.value = 0;
@@ -934,7 +938,7 @@ process_incoming_data (struct GNUNET_MESH_Handle *h,
         GNUNET_MESH_disconnect (h);
         return;
       }
-#if DEBUG
+#if MESH_API_DEBUG
       else
       {
         LOG (GNUNET_ERROR_TYPE_DEBUG,
@@ -1031,49 +1035,80 @@ send_callback (void *cls, size_t size, void *buf)
   tsize = 0;
   while ((NULL != (th = h->th_head)) && (size >= th->size))
   {
-#if DEBUG
-    LOG (GNUNET_ERROR_TYPE_DEBUG, "mesh:     type: %u\n",
-         ntohs (((struct GNUNET_MessageHeader *) &th[1])->type));
-    LOG (GNUNET_ERROR_TYPE_DEBUG, "mesh:     size: %u\n",
-         ntohs (((struct GNUNET_MessageHeader *) &th[1])->size));
-#endif
     if (NULL != th->notify)
     {
-      if (th->target == 0)
+      if (th->tunnel->tid >= GNUNET_MESH_LOCAL_TUNNEL_ID_SERV)
+      {
+        /* traffic to origin */
+        struct GNUNET_MESH_ToOrigin to;
+        struct GNUNET_MessageHeader *mh;
+
+        GNUNET_assert (size >= th->size);
+        mh = (struct GNUNET_MessageHeader *) &cbuf[sizeof (to)];
+        psize =
+            th->notify (th->notify_cls, size - sizeof (to), mh);
+        GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "mesh:   to origin, type %u\n",
+              ntohs (mh->type));
+        if (psize > 0)
+        {
+          psize += sizeof (to);
+          GNUNET_assert (size >= psize);
+          to.header.size = htons (psize);
+          to.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN);
+          to.tid = htonl (th->tunnel->tid);
+          memset (&to.oid, 0, sizeof (struct GNUNET_PeerIdentity));
+          memset (&to.sender, 0, sizeof (struct GNUNET_PeerIdentity));
+          memcpy (cbuf, &to, sizeof (to));
+        }
+      }
+      else if (th->target == 0)
       {
         /* multicast */
         struct GNUNET_MESH_Multicast mc;
+        struct GNUNET_MessageHeader *mh;
 
-        GNUNET_assert (size >= sizeof (mc) + th->size);
+        GNUNET_assert (size >= th->size);
+        mh = (struct GNUNET_MessageHeader *) &cbuf[sizeof (mc)];
         psize =
-            th->notify (th->notify_cls, size - sizeof (mc), &cbuf[sizeof (mc)]);
+            th->notify (th->notify_cls, size - sizeof (mc), mh);
+        GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                    "mesh:   multicast, type %u\n",
+                    ntohs (mh->type));
         if (psize > 0)
         {
-          mc.header.size = htons (sizeof (mc) + th->size);
+          psize += sizeof (mc);
+          GNUNET_assert (size >= psize);
+          mc.header.size = htons (psize);
           mc.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_MULTICAST);
           mc.tid = htonl (th->tunnel->tid);
           memset (&mc.oid, 0, sizeof (struct GNUNET_PeerIdentity));
           memcpy (cbuf, &mc, sizeof (mc));
-          psize = th->size + sizeof (mc);
         }
       }
       else
       {
         /* unicast */
         struct GNUNET_MESH_Unicast uc;
+        struct GNUNET_MessageHeader *mh;
 
-        GNUNET_assert (size >= sizeof (uc) + th->size);
+        GNUNET_assert (size >= th->size);
+        mh = (struct GNUNET_MessageHeader *) &cbuf[sizeof (uc)];
         psize =
-            th->notify (th->notify_cls, size - sizeof (uc), &cbuf[sizeof (uc)]);
+            th->notify (th->notify_cls, size - sizeof (uc), mh);
+        GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "mesh:   unicast, type %u\n",
+              ntohs (mh->type));
         if (psize > 0)
         {
-          uc.header.size = htons (sizeof (uc) + th->size);
+          psize += sizeof (uc);
+          GNUNET_assert (size >= psize);
+          uc.header.size = htons (psize);
           uc.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_UNICAST);
           uc.tid = htonl (th->tunnel->tid);
           memset (&uc.oid, 0, sizeof (struct GNUNET_PeerIdentity));
           GNUNET_PEER_resolve (th->target, &uc.destination);
           memcpy (cbuf, &uc, sizeof (uc));
-          psize = th->size + sizeof (uc);
         }
       }
     }
@@ -1312,6 +1347,7 @@ GNUNET_MESH_peer_request_connect_add (struct GNUNET_MESH_Tunnel *tunnel,
   {
     if (tunnel->peers[i]->id == peer_id)
     {
+      /* Peer already exists in tunnel */
       GNUNET_PEER_change_rc (peer_id, -1);
       GNUNET_break (0);
       return;
@@ -1434,6 +1470,17 @@ GNUNET_MESH_notify_transmit_ready (struct GNUNET_MESH_Tunnel *tunnel, int cork,
   uint32_t least_priority;
   size_t overhead;
 
+#if MESH_API_DEBUG
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "mesh: mesh notify transmit ready called\n");
+  if (NULL != target)
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "mesh:     target %s\n",
+                GNUNET_i2s (target));
+  else
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "mesh:     target multicast\n");
+#endif
   GNUNET_assert (NULL != notify);
   if (tunnel->mesh->npackets >= tunnel->mesh->max_queue_size &&
       tunnel->npackets > 0)
@@ -1473,7 +1520,9 @@ GNUNET_MESH_notify_transmit_ready (struct GNUNET_MESH_Tunnel *tunnel, int cork,
   th->priority = priority;
   th->timeout = GNUNET_TIME_relative_to_absolute (maxdelay);
   th->target = GNUNET_PEER_intern (target);
-  if (NULL == target)
+  if (tunnel->tid >= GNUNET_MESH_LOCAL_TUNNEL_ID_SERV)
+    overhead = sizeof (struct GNUNET_MESH_ToOrigin);
+  else if (NULL == target)
     overhead = sizeof (struct GNUNET_MESH_Multicast);
   else
     overhead = sizeof (struct GNUNET_MESH_Unicast);
@@ -1481,6 +1530,15 @@ GNUNET_MESH_notify_transmit_ready (struct GNUNET_MESH_Tunnel *tunnel, int cork,
   th->notify = notify;
   th->notify_cls = notify_cls;
   add_to_queue (tunnel->mesh, th);
+  if (NULL != tunnel->mesh->th)
+    return th;
+  tunnel->mesh->th =
+      GNUNET_CLIENT_notify_transmit_ready (tunnel->mesh->client,
+                                           th->size,
+                                           GNUNET_TIME_UNIT_FOREVER_REL,
+                                           GNUNET_YES,
+                                           &send_callback,
+                                           tunnel->mesh);
   return th;
 }