glitch in the license text detected by hyazinthe, thank you!
[oweals/gnunet.git] / src / set / gnunet-service-set_union.c
index bb2acbf590c0791152ec968089bad5d266f3db3e..440d0d1b0d9974399df6fd9575e46958a1aa9c9f 100644 (file)
@@ -2,20 +2,15 @@
       This file is part of GNUnet
       Copyright (C) 2013-2017 GNUnet e.V.
 
-      GNUnet is free software; you can redistribute it and/or modify
-      it under the terms of the GNU General Public License as published
-      by the Free Software Foundation; either version 3, or (at your
-      option) any later version.
+      GNUnet is free software: you can redistribute it and/or modify it
+      under the terms of the GNU Affero General Public License as published
+      by the Free Software Foundation, either version 3 of the License,
+      or (at your option) any later version.
 
       GNUnet is distributed in the hope that it will be useful, but
       WITHOUT ANY WARRANTY; without even the implied warranty of
       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-      General Public License for more details.
-
-      You should have received a copy of the GNU General Public License
-      along with GNUnet; see the file COPYING.  If not, write to the
-      Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-      Boston, MA 02110-1301, USA.
+      Affero General Public License for more details.
 */
 /**
  * @file set/gnunet-service-set_union.c
@@ -364,7 +359,7 @@ fail_union_operation (struct Operation *op)
   struct GNUNET_MQ_Envelope *ev;
   struct GNUNET_SET_ResultMessage *msg;
 
-  LOG (GNUNET_ERROR_TYPE_ERROR,
+  LOG (GNUNET_ERROR_TYPE_WARNING,
        "union operation failed\n");
   ev = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_SET_RESULT);
   msg->result_status = htons (GNUNET_SET_STATUS_FAILURE);
@@ -389,10 +384,11 @@ get_ibf_key (const struct GNUNET_HashCode *src)
   struct IBF_Key key;
   uint16_t salt = 0;
 
-  GNUNET_CRYPTO_kdf (&key, sizeof (key),
-                     src, sizeof *src,
-                     &salt, sizeof (salt),
-                     NULL, 0);
+  GNUNET_assert (GNUNET_OK ==
+                GNUNET_CRYPTO_kdf (&key, sizeof (key),
+                                   src, sizeof *src,
+                                   &salt, sizeof (salt),
+                                   NULL, 0));
   return key;
 }
 
@@ -739,11 +735,10 @@ get_order_from_difference (unsigned int diff)
   unsigned int ibf_order;
 
   ibf_order = 2;
-  while ( (1<<ibf_order) < (IBF_ALPHA * diff) ||
-          ((1<<ibf_order) < SE_IBF_HASH_NUM) )
+  while ( ( (1<<ibf_order) < (IBF_ALPHA * diff) ||
+            ((1<<ibf_order) < SE_IBF_HASH_NUM) ) &&
+          (ibf_order < MAX_IBF_ORDER) )
     ibf_order++;
-  if (ibf_order > MAX_IBF_ORDER)
-    ibf_order = MAX_IBF_ORDER;
   // add one for correction
   return ibf_order + 1;
 }
@@ -769,7 +764,7 @@ send_full_element_iterator (void *cls,
   struct GNUNET_SET_Element *el = &ee->element;
   struct GNUNET_MQ_Envelope *ev;
 
-  LOG (GNUNET_ERROR_TYPE_INFO,
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
        "Sending element %s\n",
        GNUNET_h2s (key));
   ev = GNUNET_MQ_msg_extra (emsg,
@@ -796,7 +791,7 @@ send_full_set (struct Operation *op)
   struct GNUNET_MQ_Envelope *ev;
 
   op->state->phase = PHASE_FULL_SENDING;
-  LOG (GNUNET_ERROR_TYPE_INFO,
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
        "Dedicing to transmit the full set\n");
   /* FIXME: use a more memory-friendly way of doing this with an
      iterator, just as we do in the non-full case! */
@@ -924,7 +919,7 @@ handle_union_p2p_strata_estimator (void *cls,
        (diff > op->state->initial_size / 4) ||
        (0 == other_size) )
   {
-    LOG (GNUNET_ERROR_TYPE_INFO,
+    LOG (GNUNET_ERROR_TYPE_DEBUG,
          "Deciding to go for full set transmission (diff=%d, own set=%u)\n",
          diff,
          op->state->initial_size);
@@ -941,7 +936,7 @@ handle_union_p2p_strata_estimator (void *cls,
     {
       struct GNUNET_MQ_Envelope *ev;
 
-      LOG (GNUNET_ERROR_TYPE_INFO,
+      LOG (GNUNET_ERROR_TYPE_DEBUG,
            "Telling other peer that we expect its full set\n");
       op->state->phase = PHASE_EXPECT_IBF;
       ev = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_SET_UNION_P2P_REQUEST_FULL);
@@ -1299,7 +1294,7 @@ handle_union_p2p_ibf (void *cls,
   else
   {
     GNUNET_assert (op->state->phase == PHASE_EXPECT_IBF_CONT);
-    LOG (GNUNET_ERROR_TYPE_INFO,
+    LOG (GNUNET_ERROR_TYPE_DEBUG,
          "Received more of IBF\n");
   }
   GNUNET_assert (NULL != op->state->remote_ibf);
@@ -1368,6 +1363,25 @@ send_client_element (struct Operation *op,
 }
 
 
+/**
+ * Destroy remote channel.
+ *
+ * @param op operation
+ */
+void destroy_channel (struct Operation *op)
+{
+  struct GNUNET_CADET_Channel *channel;
+
+  if (NULL != (channel = op->channel))
+  {
+    /* This will free op; called conditionally as this helper function
+       is also called from within the channel disconnect handler. */
+    op->channel = NULL;
+    GNUNET_CADET_channel_destroy (channel);
+  }
+}
+
+
 /**
  * Signal to the client that the operation has finished and
  * destroy the operation.
@@ -1381,6 +1395,24 @@ send_client_done (void *cls)
   struct GNUNET_MQ_Envelope *ev;
   struct GNUNET_SET_ResultMessage *rm;
 
+  if (GNUNET_YES == op->state->client_done_sent) {
+    return;
+  }
+
+  if (PHASE_DONE != op->state->phase) {
+    LOG (GNUNET_ERROR_TYPE_WARNING,
+         "union operation failed\n");
+    ev = GNUNET_MQ_msg (rm, GNUNET_MESSAGE_TYPE_SET_RESULT);
+    rm->result_status = htons (GNUNET_SET_STATUS_FAILURE);
+    rm->request_id = htonl (op->client_request_id);
+    rm->element_type = htons (0);
+    GNUNET_MQ_send (op->set->cs->mq,
+                    ev);
+    return;
+  }
+
+  op->state->client_done_sent = GNUNET_YES;
+
   LOG (GNUNET_ERROR_TYPE_INFO,
        "Signalling client that union operation is done\n");
   ev = GNUNET_MQ_msg (rm,
@@ -1393,22 +1425,6 @@ send_client_done (void *cls)
                   ev);
 }
 
-/**
- * Signal to the client that the operation has finished and
- * destroy the operation.
- *
- * @param cls operation to destroy
- */
-static void
-send_client_done_and_destroy (void *cls)
-{
-  struct Operation *op = cls;
-  send_client_done (cls);
-  /* Will also call the union-specific cancel function. */
-  _GSS_operation_destroy (op,
-                          GNUNET_YES);
-}
-
 
 /**
  * Tests if the operation is finished, and if so notify.
@@ -1446,15 +1462,9 @@ maybe_finish (struct Operation *op)
          num_demanded);
     if (0 == num_demanded)
     {
-      struct GNUNET_MQ_Envelope *ev;
-
       op->state->phase = PHASE_DONE;
-      ev = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_SET_UNION_P2P_OVER);
-      GNUNET_MQ_notify_sent (ev,
-                             &send_client_done,
-                             op);
-      GNUNET_MQ_send (op->mq,
-                      ev);
+      send_client_done (op);
+      destroy_channel (op);
     }
   }
 }
@@ -1752,7 +1762,7 @@ handle_union_p2p_inquiry (void *cls,
   const struct IBF_Key *ibf_key;
   unsigned int num_keys;
 
-  LOG (GNUNET_ERROR_TYPE_INFO,
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
        "Received union inquiry\n");
   num_keys = (ntohs (msg->header.size) - sizeof (struct InquiryMessage))
     / sizeof (struct IBF_Key);
@@ -1820,7 +1830,7 @@ handle_union_p2p_request_full (void *cls,
 {
   struct Operation *op = cls;
 
-  LOG (GNUNET_ERROR_TYPE_INFO,
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
        "Received request for full set transmission\n");
   if (GNUNET_SET_OPERATION_UNION != op->set->operation)
   {
@@ -1869,13 +1879,10 @@ handle_union_p2p_full_done (void *cls,
                                                op);
 
       ev = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_SET_UNION_P2P_FULL_DONE);
-      GNUNET_MQ_notify_sent (ev,
-                             &send_client_done,
-                             op);
       GNUNET_MQ_send (op->mq,
                       ev);
       op->state->phase = PHASE_DONE;
-      /* we now wait until the other peer shuts the tunnel down*/
+      /* we now wait until the other peer sends us the OVER message*/
     }
     break;
   case PHASE_FULL_SENDING:
@@ -1885,12 +1892,13 @@ handle_union_p2p_full_done (void *cls,
       /* We sent the full set, and got the response for that.  We're done. */
       op->state->phase = PHASE_DONE;
       GNUNET_CADET_receive_done (op->channel);
-      send_client_done_and_destroy (op);
+      send_client_done (op);
+      destroy_channel (op);
       return;
     }
     break;
   default:
-    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                 "Handle full done phase is %u\n",
                 (unsigned) op->state->phase);
     GNUNET_break_op (0);
@@ -2405,6 +2413,7 @@ union_copy_state (struct SetState *state)
 static void
 union_channel_death (struct Operation *op)
 {
+  send_client_done (op);
   _GSS_operation_destroy (op,
                           GNUNET_YES);
 }