-allow caller ID to differ from zone used for resolution
[oweals/gnunet.git] / src / transport / plugin_transport_udp.c
index 12e551fef2a3fbc2032467dd2a8160aa4bd56070..9bf2d81813828b7c6bddedf059290dccf2240e0f 100644 (file)
@@ -749,7 +749,7 @@ append_port (void *cls, const char *hostname)
 
   if (hostname == NULL )
   {
-    ppc->asc (ppc->asc_cls, NULL );
+    ppc->asc (ppc->asc_cls, NULL, GNUNET_OK); /* Final call, done */
     GNUNET_CONTAINER_DLL_remove(ppc_dll_head, ppc_dll_tail, ppc);
     GNUNET_SCHEDULER_cancel (ppc->timeout_task);
     ppc->timeout_task = GNUNET_SCHEDULER_NO_TASK;
@@ -758,13 +758,12 @@ append_port (void *cls, const char *hostname)
     return;
   }
   for (cur = ppc_dll_head; (NULL != cur); cur = cur->next)
-  {
     if (cur == ppc)
       break;
-  }
   if (NULL == cur)
   {
-    GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Invalid callback for PPC %p \n", ppc);
+    ppc->asc (ppc->asc_cls, NULL, GNUNET_SYSERR);
+    GNUNET_break(0);
     return;
   }
 
@@ -774,7 +773,7 @@ append_port (void *cls, const char *hostname)
   else
     GNUNET_asprintf (&ret, "%s.%u.%s:%d", PLUGIN_NAME, ppc->options, hostname,
         ppc->port);
-  ppc->asc (ppc->asc_cls, ret);
+  ppc->asc (ppc->asc_cls, ret, GNUNET_OK);
   GNUNET_free(ret);
 }
 
@@ -847,7 +846,8 @@ udp_plugin_address_pretty_printer (void *cls,
   {
     /* invalid address */
     GNUNET_break_op(0);
-    asc (asc_cls, NULL );
+    asc (asc_cls, NULL , GNUNET_SYSERR);
+    asc (asc_cls, NULL, GNUNET_OK);
     return;
   }
   ppc = GNUNET_new (struct PrettyPrinterContext);
@@ -1201,6 +1201,32 @@ fragmented_message_done (struct UDP_FragmentationContext *fc,
   GNUNET_free(fc);
 }
 
+/**
+ * Scan the heap for a receive context with the given address.
+ *
+ * @param cls the `struct FindReceiveContext`
+ * @param node internal node of the heap
+ * @param element value stored at the node (a 'struct ReceiveContext')
+ * @param cost cost associated with the node
+ * @return #GNUNET_YES if we should continue to iterate,
+ *         #GNUNET_NO if not.
+ */
+static int
+find_receive_context (void *cls, struct GNUNET_CONTAINER_HeapNode *node,
+    void *element, GNUNET_CONTAINER_HeapCostType cost)
+{
+  struct FindReceiveContext *frc = cls;
+  struct DefragContext *e = element;
+
+  if ((frc->addr_len == e->addr_len)
+      && (0 == memcmp (frc->addr, e->src_addr, frc->addr_len)))
+  {
+    frc->rc = e;
+    return GNUNET_NO;
+  }
+  return GNUNET_YES;
+}
+
 
 /**
  * Functions with this signature are called whenever we need
@@ -1217,6 +1243,7 @@ udp_disconnect_session (void *cls, struct Session *s)
   struct Plugin *plugin = cls;
   struct UDP_MessageWrapper *udpw;
   struct UDP_MessageWrapper *next;
+  struct FindReceiveContext frc;
 
   GNUNET_assert(GNUNET_YES != s->in_destroy);
   LOG(GNUNET_ERROR_TYPE_DEBUG, "Session %p to peer `%s' address ended\n", s,
@@ -1234,6 +1261,23 @@ udp_disconnect_session (void *cls, struct Session *s)
     fragmented_message_done (s->frag_ctx, GNUNET_SYSERR);
   }
 
+  frc.rc = NULL;
+  frc.addr = s->address->address;
+  frc.addr_len = s->address->address_length;
+  /* Lookup existing receive context for this address */
+  if (NULL != plugin->defrag_ctxs)
+  {
+    GNUNET_CONTAINER_heap_iterate (plugin->defrag_ctxs,
+        &find_receive_context, &frc);
+    if (NULL != frc.rc)
+    {
+        struct DefragContext *d_ctx = frc.rc;
+        GNUNET_CONTAINER_heap_remove_node (d_ctx->hnode);
+        GNUNET_DEFRAGMENT_context_destroy (d_ctx->defrag);
+        GNUNET_free (d_ctx);
+  }
+  }
+
   next = plugin->ipv4_queue_head;
   while (NULL != (udpw = next))
   {
@@ -1256,7 +1300,7 @@ udp_disconnect_session (void *cls, struct Session *s)
       GNUNET_free(udpw);
     }
   }
-  plugin->env->session_end (plugin->env->cls, &s->target, s);
+  plugin->env->session_end (plugin->env->cls, s->address, s);
 
   if (NULL != s->frag_ctx)
   {
@@ -1272,7 +1316,7 @@ udp_disconnect_session (void *cls, struct Session *s)
 
   GNUNET_assert(
       GNUNET_YES == GNUNET_CONTAINER_multipeermap_remove (plugin->sessions, &s->target, s));
-  GNUNET_STATISTICS_set (plugin->env->stats, "# UDP, sessions active",
+  GNUNET_STATISTICS_set (plugin->env->stats, "# UDP sessions active",
       GNUNET_CONTAINER_multipeermap_size (plugin->sessions), GNUNET_NO);
   if (s->rc > 0)
     s->in_destroy = GNUNET_YES;
@@ -1559,7 +1603,7 @@ udp_plugin_create_session (void *cls,
       udp_address_to_string( NULL,address->address,address->address_length));
   GNUNET_assert(
       GNUNET_OK == GNUNET_CONTAINER_multipeermap_put (plugin->sessions, &s->target, s, GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE));
-  GNUNET_STATISTICS_set (plugin->env->stats, "# UDP, sessions active",
+  GNUNET_STATISTICS_set (plugin->env->stats, "# UDP sessions active",
       GNUNET_CONTAINER_multipeermap_size (plugin->sessions), GNUNET_NO);
   return s;
 }
@@ -2016,34 +2060,6 @@ process_udp_message (struct Plugin *plugin,
     free_session (s);
 }
 
-
-/**
- * Scan the heap for a receive context with the given address.
- *
- * @param cls the `struct FindReceiveContext`
- * @param node internal node of the heap
- * @param element value stored at the node (a 'struct ReceiveContext')
- * @param cost cost associated with the node
- * @return #GNUNET_YES if we should continue to iterate,
- *         #GNUNET_NO if not.
- */
-static int
-find_receive_context (void *cls, struct GNUNET_CONTAINER_HeapNode *node,
-    void *element, GNUNET_CONTAINER_HeapCostType cost)
-{
-  struct FindReceiveContext *frc = cls;
-  struct DefragContext *e = element;
-
-  if ((frc->addr_len == e->addr_len)
-      && (0 == memcmp (frc->addr, e->src_addr, frc->addr_len)))
-  {
-    frc->rc = e;
-    return GNUNET_NO;
-  }
-  return GNUNET_YES;
-}
-
-
 /**
  * Process a defragmented message.
  *
@@ -2177,7 +2193,14 @@ ack_proc (void *cls, uint32_t id, const struct GNUNET_MessageHeader *msg)
   s = l_ctx.res;
   if (NULL == s)
   {
-    GNUNET_break (0);
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+        "Trying to transmit ACK to peer `%s' but not session found!\n",
+        GNUNET_a2s(rc->src_addr, rc->addr_len));
+
+    GNUNET_CONTAINER_heap_remove_node (rc->hnode);
+    GNUNET_DEFRAGMENT_context_destroy (rc->defrag);
+    GNUNET_free (rc);
+
     return;
   }
   if (s->flow_delay_for_other_peer.rel_value_us <= UINT32_MAX)
@@ -2653,8 +2676,12 @@ udp_select_send (struct Plugin *plugin,
   }
   else
   {
-    GNUNET_break (0);
+    call_continuation (udpw, GNUNET_OK);
+    dequeue (plugin, udpw);
+    GNUNET_free (udpw);
+    return GNUNET_SYSERR;
   }
+
   sent = GNUNET_NETWORK_socket_sendto (sock, udpw->msg_buf, udpw->msg_size, a,
       slen);