-fix leak
[oweals/gnunet.git] / src / dht / dht_api.c
index 7b83c14c3b380b77a9ddd482bd3a618bef723264..be699e65eb56e916a8abb9b5aeae0f9bf0f3a5f7 100644 (file)
@@ -93,6 +93,28 @@ struct PendingMessage
 
 };
 
+#if ENABLE_MALICIOUS
+/**
+ * Handle to act malicious message
+ */
+struct GNUNET_DHT_ActMaliciousHandle
+{
+  /**
+   * Continuation to call when done.
+   */
+  GNUNET_DHT_ActMaliciousContinuation cont;
+
+  /**
+   * Main handle to this DHT api
+   */
+  struct GNUNET_DHT_Handle *dht_handle;
+
+  /**
+   * Closure for 'cont'.
+   */
+  void *cont_cls;
+};
+#endif
 
 /**
  * Handle to a PUT request.
@@ -142,8 +164,6 @@ struct GNUNET_DHT_PutHandle
 
 };
 
-
-
 /**
  * Handle to a GET request
  */
@@ -342,6 +362,13 @@ struct GNUNET_DHT_Handle
    * Did we start our receive loop yet?
    */
   int in_receive;
+  
+#if ENABLE_MALICIOUS
+  /**
+   * Handle of act malicious request.
+   */
+  struct GNUNET_DHT_ActMaliciousHandle *mh;
+#endif
 };
 
 
@@ -599,6 +626,7 @@ transmit_pending (void *cls,
   struct PendingMessage *head;
   size_t tsize;
 
+
   handle->th = NULL;
   if (NULL == buf)
   {
@@ -635,6 +663,7 @@ transmit_pending (void *cls,
   {
     LOG (GNUNET_ERROR_TYPE_DEBUG, "Starting to process replies from DHT\n");
     handle->in_receive = GNUNET_YES;
+    
     GNUNET_CLIENT_receive (handle->client, &service_message_handler, handle,
                            GNUNET_TIME_UNIT_FOREVER_REL);
   }
@@ -855,6 +884,35 @@ process_monitor_put_message (struct GNUNET_DHT_Handle *handle,
 }
 
 
+#if ENABLE_MALICIOUS
+/**
+ * Process a act malicious confirmation from service.
+ * @param handle The DHT handle.
+ * @param msg confirmation message from the service.
+ * @return #GNUNET_OK if everything went fine,
+ *         #GNUNET_SYSERR if the message is malformed.
+ */
+static int
+process_act_malicious_confirmation_message (struct GNUNET_DHT_Handle *handle,
+           const struct GNUNET_DHT_ClientActMaliciousConfirmationMessage *msg)
+{
+   struct GNUNET_DHT_ActMaliciousHandle *mh;
+   GNUNET_DHT_PutContinuation cont;
+   void *cont_cls;
+   
+   mh = handle->mh;
+   if (NULL == mh)
+    return GNUNET_OK;
+  cont = mh->cont;
+  cont_cls = mh->cont_cls;
+  if (NULL != cont)
+    cont (cont_cls, GNUNET_OK);
+  
+  return GNUNET_OK;
+}
+#endif
+
+
 /**
  * Process a put confirmation message from the service.
  *
@@ -900,6 +958,7 @@ service_message_handler (void *cls, const struct GNUNET_MessageHeader *msg)
   uint16_t msize;
   int ret;
 
+
   if (NULL == msg)
   {
     LOG (GNUNET_ERROR_TYPE_DEBUG,
@@ -969,6 +1028,17 @@ service_message_handler (void *cls, const struct GNUNET_MessageHeader *msg)
     ret = process_put_confirmation_message (handle,
                                            (const struct GNUNET_DHT_ClientPutConfirmationMessage*) msg);
     break;
+#if ENABLE_MALICIOUS
+    case GNUNET_MESSAGE_TYPE_DHT_CLIENT_ACT_MALICIOUS_OK:
+       if(msize != sizeof (struct GNUNET_DHT_ClientActMaliciousConfirmationMessage))
+       {
+         GNUNET_break (0);
+         break;
+       }
+       ret = process_act_malicious_confirmation_message (handle,
+                                           (const struct GNUNET_DHT_ClientActMaliciousConfirmationMessage*) msg);
+      break;
+#endif
   default:
     GNUNET_break(0);
     LOG (GNUNET_ERROR_TYPE_WARNING,
@@ -1003,7 +1073,7 @@ GNUNET_DHT_connect (const struct GNUNET_CONFIGURATION_Handle *cfg,
   handle->cfg = cfg;
   handle->uid_gen =
       GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, UINT64_MAX);
-  handle->active_requests = GNUNET_CONTAINER_multihashmap_create (ht_len, GNUNET_NO);
+  handle->active_requests = GNUNET_CONTAINER_multihashmap_create (ht_len, GNUNET_YES);
   if (GNUNET_NO == try_connect (handle))
   {
     GNUNET_DHT_disconnect (handle);
@@ -1133,14 +1203,14 @@ mark_put_message_gone (void *cls,
  */
 struct GNUNET_DHT_PutHandle *
 GNUNET_DHT_put (struct GNUNET_DHT_Handle *handle,
-               const struct GNUNET_HashCode * key,
+                       const struct GNUNET_HashCode * key,
                 uint32_t desired_replication_level,
                 enum GNUNET_DHT_RouteOption options,
                 enum GNUNET_BLOCK_Type type, size_t size,
-               const void *data,
+                           const void *data,
                 struct GNUNET_TIME_Absolute exp,
                 struct GNUNET_TIME_Relative timeout,
-               GNUNET_DHT_PutContinuation cont,
+                           GNUNET_DHT_PutContinuation cont,
                 void *cont_cls)
 {
   struct GNUNET_DHT_ClientPutMessage *put_msg;
@@ -1280,12 +1350,15 @@ GNUNET_DHT_get_start (struct GNUNET_DHT_Handle *handle,
                                pending);
   pending->in_pending_queue = GNUNET_YES;
   get_handle = GNUNET_new (struct GNUNET_DHT_GetHandle);
+  get_handle->key = *key;
   get_handle->dht_handle = handle;
   get_handle->iter = iter;
   get_handle->iter_cls = iter_cls;
   get_handle->message = pending;
   get_handle->unique_id = get_msg->unique_id;
-  GNUNET_CONTAINER_multihashmap_put (handle->active_requests, key, get_handle,
+  GNUNET_CONTAINER_multihashmap_put (handle->active_requests,
+                                     &get_handle->key,
+                                     get_handle,
                                      GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
   process_pending_messages (handle);
   return get_handle;
@@ -1363,7 +1436,7 @@ GNUNET_DHT_get_stop (struct GNUNET_DHT_GetHandle *get_handle)
   /* remove 'GET' from active status */
   GNUNET_assert (GNUNET_YES ==
                  GNUNET_CONTAINER_multihashmap_remove (handle->active_requests,
-                                                       &get_msg->key,
+                                                       &get_handle->key,
                                                        get_handle));
   if (GNUNET_YES == get_handle->message->in_pending_queue)
   {
@@ -1416,7 +1489,7 @@ GNUNET_DHT_monitor_start (struct GNUNET_DHT_Handle *handle,
   h->dht_handle = handle;
   if (NULL != key)
   {
-    h->key = GNUNET_new(struct GNUNET_HashCode);
+    h->key = GNUNET_new (struct GNUNET_HashCode);
     *h->key = *key;
   }
 
@@ -1471,12 +1544,13 @@ GNUNET_DHT_monitor_stop (struct GNUNET_DHT_MonitorHandle *handle)
   m->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_MONITOR_STOP);
   m->header.size = htons (sizeof (struct GNUNET_DHT_MonitorStartStopMessage));
   m->type = htonl(handle->type);
-  m->get = htons(NULL != handle->get_cb);
+  m->get = htons (NULL != handle->get_cb);
   m->get_resp = htons(NULL != handle->get_resp_cb);
-  m->put = htons(NULL != handle->put_cb);
-  if (NULL != handle->key) {
-    m->filter_key = htons(1);
-    memcpy (&m->key, handle->key, sizeof(struct GNUNET_HashCode));
+  m->put = htons (NULL != handle->put_cb);
+  if (NULL != handle->key)
+  {
+    m->filter_key = htons (1);
+    m->key = *handle->key;
   }
   GNUNET_CONTAINER_DLL_insert (handle->dht_handle->pending_head,
                                handle->dht_handle->pending_tail,
@@ -1488,4 +1562,53 @@ GNUNET_DHT_monitor_stop (struct GNUNET_DHT_MonitorHandle *handle)
   GNUNET_free (handle);
 }
 
+
+#if ENABLE_MALICIOUS
+/**
+ * Turn the DHT service to act malicious.
+ *
+ * @param handle the DHT handle
+ * @param action 1 to make the service malicious; 0 to make it benign
+ * @param cont continuation to call when done (transmitting request to service)
+ * @param cont_cls closure for @a cont        
+ */
+struct GNUNET_DHT_ActMaliciousHandle *
+GNUNET_DHT_act_malicious (struct GNUNET_DHT_Handle *handle, 
+                          unsigned int action,
+                          GNUNET_DHT_PutContinuation cont,
+                          void *cont_cls)
+{
+  struct GNUNET_DHT_ActMaliciousMessage *amm;
+  struct GNUNET_DHT_ActMaliciousHandle *mh;
+  struct PendingMessage *pending;
+  size_t msize;
+  
+  msize = sizeof(struct GNUNET_DHT_ActMaliciousMessage);
+  if (msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
+  {
+    GNUNET_break(0);
+    return NULL;
+  }
+  mh = GNUNET_new (struct GNUNET_DHT_ActMaliciousHandle);
+  mh->dht_handle = handle;
+  mh->cont = cont;
+  mh->cont_cls = cont_cls;
+  pending = GNUNET_malloc (sizeof (struct PendingMessage) + msize);
+  amm = (struct GNUNET_DHT_ActMaliciousMessage *)&pending[1];
+  pending->msg = &amm->header;
+  pending->handle = handle;
+  pending->free_on_send = GNUNET_YES;
+  amm->header.size = htons (msize);
+  amm->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_ACT_MALICIOUS);
+  amm->action = action;
+  handle->mh = mh;
+  GNUNET_CONTAINER_DLL_insert (handle->pending_head, handle->pending_tail,
+                               pending);
+  pending->in_pending_queue = GNUNET_YES;
+  process_pending_messages (handle);
+  return mh;
+}
+#endif
+
+
 /* end of dht_api.c */