gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] r27603 - gnunet/src/set


From: gnunet
Subject: [GNUnet-SVN] r27603 - gnunet/src/set
Date: Wed, 26 Jun 2013 02:41:08 +0200

Author: dold
Date: 2013-06-26 02:41:08 +0200 (Wed, 26 Jun 2013)
New Revision: 27603

Modified:
   gnunet/src/set/gnunet-service-set.c
   gnunet/src/set/gnunet-service-set.h
   gnunet/src/set/gnunet-service-set_union.c
Log:
- fixed tunnel destruction/cleanup
- peers can connect before the listener


Modified: gnunet/src/set/gnunet-service-set.c
===================================================================
--- gnunet/src/set/gnunet-service-set.c 2013-06-26 00:18:51 UTC (rev 27602)
+++ gnunet/src/set/gnunet-service-set.c 2013-06-26 00:41:08 UTC (rev 27603)
@@ -91,6 +91,7 @@
 set_get (struct GNUNET_SERVER_Client *client)
 {
   struct Set *set;
+
   for (set = sets_head; NULL != set; set = set->next)
     if (set->client == client)
       return set;
@@ -99,16 +100,17 @@
 
 
 /**
- * Get the listener associated to a client, if any.
+ * Get the listener associated with the given client, if any.
  *
  * @param client the client
  * @return listener associated with the client, NULL
  *         if there isn't any
  */
 static struct Listener *
-get_listener (struct GNUNET_SERVER_Client *client)
+listener_get (struct GNUNET_SERVER_Client *client)
 {
   struct Listener *listener;
+
   for (listener = listeners_head; NULL != listener; listener = listener->next)
     if (listener->client == client)
       return listener;
@@ -127,6 +129,7 @@
 get_incoming (uint32_t id)
 {
   struct Incoming *incoming;
+
   for (incoming = incoming_head; NULL != incoming; incoming = incoming->next)
     if (incoming->accept_id == id)
       return incoming;
@@ -193,7 +196,7 @@
   set = set_get (client);
   if (NULL != set)
     set_destroy (set);
-  listener = get_listener (client);
+  listener = listener_get (client);
   if (NULL != listener)
     listener_destroy (listener);
 }
@@ -207,20 +210,13 @@
 static void
 incoming_destroy (struct Incoming *incoming)
 {
-  if (NULL != incoming->tc)
-  {
-    GNUNET_free (incoming->tc);
-    GNUNET_assert (NULL != incoming->tc->tunnel);
-    GNUNET_MESH_tunnel_destroy (incoming->tc->tunnel);
-    incoming->tc = NULL;
-  }
   GNUNET_CONTAINER_DLL_remove (incoming_head, incoming_tail, incoming);
   GNUNET_free (incoming);
 }
 
 
 static struct Listener *
-get_listener_by_target (enum GNUNET_SET_OperationType op,
+listener_get_by_target (enum GNUNET_SET_OperationType op,
                         const struct GNUNET_HashCode *app_id)
 {
   struct Listener *l;
@@ -237,12 +233,31 @@
 }
 
 
-
+/**
+ * Suggest the given request to the listener,
+ * who can accept or reject the request.
+ *
+ * @param incoming the incoming peer with the request to suggest
+ * @param listener the listener to suggest the request to
+ */
 static void
-tunnel_context_destroy (struct TunnelContext *tc)
+incoming_suggest (struct Incoming *incoming, struct Listener *listener)
 {
-  GNUNET_free (tc);
-  /* FIXME destroy the rest */
+  struct GNUNET_MQ_Envelope *mqm;
+  struct GNUNET_SET_RequestMessage *cmsg;
+
+  GNUNET_assert (GNUNET_NO == incoming->suggested);
+  incoming->suggested = GNUNET_YES;
+
+  GNUNET_SCHEDULER_cancel (incoming->timeout_task);
+  mqm = GNUNET_MQ_msg_nested_mh (cmsg, GNUNET_MESSAGE_TYPE_SET_REQUEST,
+                                 incoming->context_msg);
+  GNUNET_assert (NULL != mqm);
+  GNUNET_log (GNUNET_ERROR_TYPE_INFO, "suggesting request with accept id 
%u\n", incoming->accept_id);
+  cmsg->accept_id = htonl (incoming->accept_id);
+  cmsg->peer_id = incoming->tc->peer;
+  GNUNET_MQ_send (listener->client_mq, mqm);
+
 }
 
 
@@ -264,49 +279,46 @@
   struct TunnelContext *tc = *tunnel_ctx;
   struct Incoming *incoming;
   const struct OperationRequestMessage *msg = (const struct 
OperationRequestMessage *) mh;
-  struct GNUNET_MQ_Envelope *mqm;
-  struct GNUNET_SET_RequestMessage *cmsg;
   struct Listener *listener;
-  const struct GNUNET_MessageHeader *context_msg;
 
   if (CONTEXT_INCOMING != tc->type)
   {
-    GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "unexpected operation request\n");
-    tunnel_context_destroy (tc);
-    /* don't kill the whole mesh connection */
-    return GNUNET_OK;
+    /* unexpected request */
+    GNUNET_break_op (0);
+    /* kill the tunnel, cleaner will be called */
+    return GNUNET_SYSERR;
   }
 
   incoming = tc->data;
 
-  context_msg = GNUNET_MQ_extract_nested_mh (msg);
+  if (GNUNET_YES == incoming->received_request)
+  {
+    /* double operation request */
+    GNUNET_break_op (0);
+    return GNUNET_SYSERR;
+  }
+
+  incoming->accept_id = accept_id++;
+  incoming->context_msg =
+      GNUNET_copy_message (GNUNET_MQ_extract_nested_mh (msg));
+
+  if ( (NULL != incoming->context_msg) &&
+       (ntohs (incoming->context_msg->size) > 
GNUNET_SET_CONTEXT_MESSAGE_MAX_SIZE) )
+  {
+    GNUNET_break_op (0);
+    return GNUNET_SYSERR;
+  }
+
   GNUNET_log (GNUNET_ERROR_TYPE_INFO, "received P2P operation request (op %u, 
app %s)\n",
               ntohs (msg->operation), GNUNET_h2s (&msg->app_id));
-  listener = get_listener_by_target (ntohs (msg->operation), &msg->app_id);
+  listener = listener_get_by_target (ntohs (msg->operation), &msg->app_id);
   if (NULL == listener)
   {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "set operation request from peer failed: "
-                "no set with matching application ID and operation type\n");
-    tunnel_context_destroy (tc);
-    /* don't kill the whole mesh connection */
+    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                "no listener matches incoming request, waiting with 
timeout\n");
     return GNUNET_OK;
   }
-  mqm = GNUNET_MQ_msg_nested_mh (cmsg, GNUNET_MESSAGE_TYPE_SET_REQUEST, 
context_msg);
-  if (NULL == mqm)
-  {
-    /* FIXME: disconnect the peer */
-    GNUNET_break_op (0);
-    tunnel_context_destroy (tc);
-    /* don't kill the whole mesh connection */
-    return GNUNET_OK;
-  }
-  incoming->accept_id = accept_id++;
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO, "sending request with accept id %u\n", 
incoming->accept_id);
-  cmsg->accept_id = htonl (incoming->accept_id);
-  cmsg->peer_id = incoming->tc->peer;
-  GNUNET_MQ_send (listener->client_mq, mqm);
-
+  incoming_suggest (incoming, listener);
   return GNUNET_OK;
 }
 
@@ -375,8 +387,9 @@
 {
   struct GNUNET_SET_ListenMessage *msg = (struct GNUNET_SET_ListenMessage *) m;
   struct Listener *listener;
+  struct Incoming *incoming;
 
-  if (NULL != get_listener (client))
+  if (NULL != listener_get (client))
   {
     GNUNET_break (0);
     GNUNET_SERVER_client_disconnect (client);
@@ -390,6 +403,17 @@
   GNUNET_CONTAINER_DLL_insert_tail (listeners_head, listeners_tail, listener);
   GNUNET_log (GNUNET_ERROR_TYPE_INFO, "new listener created (op %u, app %s)\n",
               listener->operation, GNUNET_h2s (&listener->app_id));
+  for (incoming = incoming_head; NULL != incoming; incoming = incoming->next)
+  {
+    if ( (GNUNET_NO == incoming->received_request) ||
+         (GNUNET_YES == incoming->suggested) )
+      continue;
+    if (listener->operation != incoming->operation)
+      continue;
+    if (0 != GNUNET_CRYPTO_hash_cmp (&listener->app_id, &incoming->app_id))
+      continue;
+    incoming_suggest (incoming, listener);
+  }
   GNUNET_SERVER_receive_done (client, GNUNET_OK);
 }
 
@@ -459,7 +483,8 @@
     return;
   }
   GNUNET_log (GNUNET_ERROR_TYPE_INFO, "peer request rejected by client\n");
-  incoming_destroy (incoming);
+  /* the incoming peer will be destroyed in the tunnel end handler */
+  GNUNET_MESH_tunnel_destroy (incoming->tc->tunnel);
   GNUNET_SERVER_receive_done (client, GNUNET_OK);
 }
 
@@ -475,8 +500,8 @@
  */
 static void
 handle_client_add (void *cls,
-                      struct GNUNET_SERVER_Client *client,
-                      const struct GNUNET_MessageHeader *m)
+                   struct GNUNET_SERVER_Client *client,
+                   const struct GNUNET_MessageHeader *m)
 {
   struct Set *set;
 
@@ -611,7 +636,7 @@
       break;
   }
 
-  /* note: _GSS_*_accept has to make sure the socket and mq are set to NULL,
+  /* note: _GSS_*_accept has to make sure the tunnel and mq are set to NULL,
    * otherwise they will be destroyed and disconnected */
   incoming_destroy (incoming);
   GNUNET_SERVER_receive_done (client, GNUNET_OK);
@@ -635,19 +660,13 @@
   }
 
   while (NULL != incoming_head)
-  {
     incoming_destroy (incoming_head);
-  }
 
   while (NULL != listeners_head)
-  {
     listener_destroy (listeners_head);
-  }
 
   while (NULL != sets_head)
-  {
     set_destroy (sets_head);
-  }
 
   GNUNET_log (GNUNET_ERROR_TYPE_INFO, "handled shutdown request\n");
 }
@@ -706,7 +725,8 @@
   tc->mq = GNUNET_MESH_mq_create (tunnel);
   tc->data = incoming;
   tc->type = CONTEXT_INCOMING;
-  GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES, incoming_timeout_cb, 
incoming);
+  incoming->timeout_task = 
+      GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES, 
incoming_timeout_cb, incoming);
   GNUNET_CONTAINER_DLL_insert_tail (incoming_head, incoming_tail, incoming);
 
   return tc;
@@ -730,6 +750,15 @@
 {
   struct TunnelContext *ctx = tunnel_ctx;
 
+  /* tunnel is dead already */
+  ctx->tunnel = NULL;
+
+  if (NULL != ctx->mq)
+  {
+    GNUNET_MQ_destroy (ctx->mq);
+    ctx->mq = NULL;
+  }
+
   switch (ctx->type)
   {
     case CONTEXT_INCOMING:
@@ -746,6 +775,7 @@
       GNUNET_assert (0);
   }
 
+  GNUNET_free (tunnel_ctx);
 }
 
 

Modified: gnunet/src/set/gnunet-service-set.h
===================================================================
--- gnunet/src/set/gnunet-service-set.h 2013-06-26 00:18:51 UTC (rev 27602)
+++ gnunet/src/set/gnunet-service-set.h 2013-06-26 00:41:08 UTC (rev 27603)
@@ -186,11 +186,23 @@
   enum GNUNET_SET_OperationType operation;
 
   /**
+   * Has the incoming request been suggested to
+   * a client listener yet?
+   */
+  int suggested;
+
+  /**
    * Unique request id for the request from
    * a remote peer, sent to the client, which will
    * accept or reject the request.
    */
   uint32_t accept_id;
+
+  /**
+   * Timeout task, if the incoming peer has not been accepted
+   * after the timeout, it will be disconnected.
+   */
+  GNUNET_SCHEDULER_TaskIdentifier timeout_task;
 };
 
 

Modified: gnunet/src/set/gnunet-service-set_union.c
===================================================================
--- gnunet/src/set/gnunet-service-set_union.c   2013-06-26 00:18:51 UTC (rev 
27602)
+++ gnunet/src/set/gnunet-service-set_union.c   2013-06-26 00:41:08 UTC (rev 
27603)
@@ -1370,9 +1370,8 @@
 
   if (CONTEXT_OPERATION_UNION != tc->type)
   {
-    /* FIXME: kill the tunnel */
-    /* never kill mesh */
-    return GNUNET_OK;
+    GNUNET_break_op (0);
+    return GNUNET_SYSERR;
   }
 
   eo = tc->data;
@@ -1398,6 +1397,5 @@
       /* something wrong with mesh's message handlers? */
       GNUNET_assert (0);
   }
-  /* never kill mesh! */
   return GNUNET_OK;
 }




reply via email to

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