doc: gnunet-c-tutorial: Add nodes.
[oweals/gnunet.git] / src / core / gnunet-service-core_kx.c
index 6743ce21537eb063bfe058f36f8009738be35bed..8a7cada5c5a1a1b76191e7859bb54ee703c6d760 100644 (file)
@@ -261,7 +261,12 @@ struct GSC_KeyExchangeInfo
    * Message queue for sending messages to @a peer.
    */
   struct GNUNET_MQ_Handle *mq;
-  
+
+  /**
+   * Our message stream tokenizer (for encrypted payload).
+   */
+  struct GNUNET_MessageStreamTokenizer *mst;
+
   /**
    * PING message we transmit to the other peer.
    */
@@ -319,7 +324,7 @@ struct GSC_KeyExchangeInfo
    * last were received (good for accepting out-of-order packets and
    * estimating reliability of the connection)
    */
-  unsigned int last_packets_bitmap;
+  uint32_t last_packets_bitmap;
 
   /**
    * last sequence number received on this connection (highest)
@@ -369,11 +374,6 @@ static struct GNUNET_CRYPTO_EcdhePrivateKey *my_ephemeral_key;
  */
 static struct EphemeralKeyMessage current_ekm;
 
-/**
- * Our message stream tokenizer (for encrypted payload).
- */
-static struct GNUNET_SERVER_MessageStreamTokenizer *mst;
-
 /**
  * DLL head.
  */
@@ -701,6 +701,55 @@ setup_fresh_ping (struct GSC_KeyExchangeInfo *kx)
 }
 
 
+/**
+ * Deliver P2P message to interested clients.  Invokes send twice,
+ * once for clients that want the full message, and once for clients
+ * that only want the header
+ *
+ * @param cls the `struct GSC_KeyExchangeInfo`
+ * @param m the message
+ */
+static int
+deliver_message (void *cls,
+                 const struct GNUNET_MessageHeader *m)
+{
+  struct GSC_KeyExchangeInfo *kx = cls;
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Decrypted message of type %d from %s\n",
+              ntohs (m->type),
+              GNUNET_i2s (kx->peer));
+  if (GNUNET_CORE_KX_STATE_UP != kx->status)
+  {
+    GNUNET_STATISTICS_update (GSC_stats,
+                              gettext_noop ("# PAYLOAD dropped (out of order)"),
+                              1,
+                              GNUNET_NO);
+    return GNUNET_OK;
+  }
+  switch (ntohs (m->type))
+  {
+  case GNUNET_MESSAGE_TYPE_CORE_BINARY_TYPE_MAP:
+  case GNUNET_MESSAGE_TYPE_CORE_COMPRESSED_TYPE_MAP:
+    GSC_SESSIONS_set_typemap (kx->peer, m);
+    return GNUNET_OK;
+  case GNUNET_MESSAGE_TYPE_CORE_CONFIRM_TYPE_MAP:
+    GSC_SESSIONS_confirm_typemap (kx->peer, m);
+    return GNUNET_OK;
+  default:
+    GSC_CLIENTS_deliver_message (kx->peer,
+                                 m,
+                                 ntohs (m->size),
+                                 GNUNET_CORE_OPTION_SEND_FULL_INBOUND);
+    GSC_CLIENTS_deliver_message (kx->peer,
+                                 m,
+                                 sizeof (struct GNUNET_MessageHeader),
+                                 GNUNET_CORE_OPTION_SEND_HDR_INBOUND);
+  }
+  return GNUNET_OK;
+}
+
+
 /**
  * Function called by transport to notify us that
  * a peer connected to us (on the network level).
@@ -727,6 +776,8 @@ handle_transport_notify_connect (void *cls,
                             1,
                             GNUNET_NO);
   kx = GNUNET_new (struct GSC_KeyExchangeInfo);
+  kx->mst = GNUNET_MST_create (&deliver_message,
+                               kx);
   kx->mq = mq;
   kx->peer = pid;
   kx->set_key_retry_frequency = INITIAL_SET_KEY_RETRY_FREQUENCY;
@@ -777,7 +828,7 @@ handle_transport_notify_disconnect (void *cls,
                                    void *handler_cls)
 {
   struct GSC_KeyExchangeInfo *kx = handler_cls;
-  
+
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Peer `%s' disconnected from us.\n",
               GNUNET_i2s (peer));
@@ -801,6 +852,7 @@ handle_transport_notify_disconnect (void *cls,
   GNUNET_CONTAINER_DLL_remove (kx_head,
                               kx_tail,
                               kx);
+  GNUNET_MST_destroy (kx->mst);
   GNUNET_free (kx);
 }
 
@@ -814,7 +866,7 @@ static void
 send_ping (struct GSC_KeyExchangeInfo *kx)
 {
   struct GNUNET_MQ_Envelope *env;
-  
+
   GNUNET_STATISTICS_update (GSC_stats,
                             gettext_noop ("# PING messages transmitted"),
                             1,
@@ -1332,7 +1384,7 @@ static void
 send_key (struct GSC_KeyExchangeInfo *kx)
 {
   struct GNUNET_MQ_Envelope *env;
-  
+
   GNUNET_assert (GNUNET_CORE_KX_STATE_DOWN != kx->status);
   if (NULL != kx->retry_set_key_task)
   {
@@ -1416,24 +1468,6 @@ GSC_KX_encrypt_and_transmit (struct GSC_KeyExchangeInfo *kx,
 }
 
 
-/**
- * Closure for #deliver_message()
- */
-struct DeliverMessageContext
-{
-
-  /**
-   * Key exchange context.
-   */
-  struct GSC_KeyExchangeInfo *kx;
-
-  /**
-   * Sender of the message.
-   */
-  const struct GNUNET_PeerIdentity *peer;
-};
-
-
 /**
  * We received an encrypted message.  Check that it is
  * well-formed (size-wise).
@@ -1475,7 +1509,6 @@ handle_encrypted (void *cls,
   struct GNUNET_TIME_Absolute t;
   struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
   struct GNUNET_CRYPTO_AuthKey auth_key;
-  struct DeliverMessageContext dmc;
   uint16_t size = ntohs (m->header.size);
   char buf[size] GNUNET_ALIGN;
 
@@ -1520,7 +1553,7 @@ handle_encrypted (void *cls,
                    sizeof (struct GNUNET_HashCode)))
   {
     /* checksum failed */
-    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                "Failed checksum validation for a message from `%s'\n",
                GNUNET_i2s (kx->peer));
     return;
@@ -1536,7 +1569,10 @@ handle_encrypted (void *cls,
                   &m->sequence_number,
                   &buf[ENCRYPTED_HEADER_SIZE],
                   size - ENCRYPTED_HEADER_SIZE))
+  {
+    GNUNET_break_op (0);
     return;
+  }
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Decrypted %u bytes from %s\n",
               (unsigned int) (size - ENCRYPTED_HEADER_SIZE),
@@ -1570,7 +1606,7 @@ handle_encrypted (void *cls,
   }
   if (kx->last_sequence_number_received > snum)
   {
-    unsigned int rotbit = 1 << (kx->last_sequence_number_received - snum - 1);
+    uint32_t rotbit = 1U << (kx->last_sequence_number_received - snum - 1);
 
     if ((kx->last_packets_bitmap & rotbit) != 0)
     {
@@ -1617,15 +1653,12 @@ handle_encrypted (void *cls,
                             gettext_noop ("# bytes of payload decrypted"),
                             size - sizeof (struct EncryptedMessage),
                             GNUNET_NO);
-  dmc.kx = kx;
-  dmc.peer = kx->peer;
   if (GNUNET_OK !=
-      GNUNET_SERVER_mst_receive (mst,
-                                &dmc,
-                                 &buf[sizeof (struct EncryptedMessage)],
-                                 size - sizeof (struct EncryptedMessage),
-                                 GNUNET_YES,
-                                 GNUNET_NO))
+      GNUNET_MST_from_buffer (kx->mst,
+                              &buf[sizeof (struct EncryptedMessage)],
+                              size - sizeof (struct EncryptedMessage),
+                              GNUNET_YES,
+                              GNUNET_NO))
     GNUNET_break_op (0);
 }
 
@@ -1642,7 +1675,7 @@ handle_transport_notify_excess_bw (void *cls,
                                    const struct GNUNET_PeerIdentity *pid,
                                   void *connect_cls)
 {
-  struct GSC_KeyExchangeInfo *kx = connect_cls;  
+  struct GSC_KeyExchangeInfo *kx = connect_cls;
 
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Peer %s has excess bandwidth available\n",
@@ -1652,53 +1685,6 @@ handle_transport_notify_excess_bw (void *cls,
 }
 
 
-/**
- * Deliver P2P message to interested clients.  Invokes send twice,
- * once for clients that want the full message, and once for clients
- * that only want the header
- *
- * @param cls always NULL
- * @param client who sent us the message (struct GSC_KeyExchangeInfo)
- * @param m the message
- */
-static int
-deliver_message (void *cls,
-                 void *client,
-                 const struct GNUNET_MessageHeader *m)
-{
-  struct DeliverMessageContext *dmc = client;
-
-  if (GNUNET_CORE_KX_STATE_UP != dmc->kx->status)
-  {
-    GNUNET_STATISTICS_update (GSC_stats,
-                              gettext_noop ("# PAYLOAD dropped (out of order)"),
-                              1,
-                              GNUNET_NO);
-    return GNUNET_OK;
-  }
-  switch (ntohs (m->type))
-  {
-  case GNUNET_MESSAGE_TYPE_CORE_BINARY_TYPE_MAP:
-  case GNUNET_MESSAGE_TYPE_CORE_COMPRESSED_TYPE_MAP:
-    GSC_SESSIONS_set_typemap (dmc->peer, m);
-    return GNUNET_OK;
-  case GNUNET_MESSAGE_TYPE_CORE_CONFIRM_TYPE_MAP:
-    GSC_SESSIONS_confirm_typemap (dmc->peer, m);
-    return GNUNET_OK;
-  default:
-    GSC_CLIENTS_deliver_message (dmc->peer,
-                                 m,
-                                 ntohs (m->size),
-                                 GNUNET_CORE_OPTION_SEND_FULL_INBOUND);
-    GSC_CLIENTS_deliver_message (dmc->peer,
-                                 m,
-                                 sizeof (struct GNUNET_MessageHeader),
-                                 GNUNET_CORE_OPTION_SEND_HDR_INBOUND);
-  }
-  return GNUNET_OK;
-}
-
-
 /**
  * Setup the message that links the ephemeral key to our persistent
  * public key and generate the appropriate signature.
@@ -1822,9 +1808,7 @@ GSC_KX_init (struct GNUNET_CRYPTO_EddsaPrivateKey *pk)
   rekey_task = GNUNET_SCHEDULER_add_delayed (REKEY_FREQUENCY,
                                              &do_rekey,
                                              NULL);
-  mst = GNUNET_SERVER_mst_create (&deliver_message,
-                                 NULL);
-  transport 
+  transport
     = GNUNET_TRANSPORT_core_connect (GSC_cfg,
                                     &GSC_my_identity,
                                     handlers,
@@ -1867,11 +1851,6 @@ GSC_KX_done ()
     GNUNET_free (my_private_key);
     my_private_key = NULL;
   }
-  if (NULL != mst)
-  {
-    GNUNET_SERVER_mst_destroy (mst);
-    mst = NULL;
-  }
   if (NULL != nc)
   {
     GNUNET_notification_context_destroy (nc);
@@ -1927,7 +1906,7 @@ GSC_KX_handle_client_monitor_peers (struct GNUNET_MQ_Handle *mq)
   {
     struct GNUNET_MQ_Envelope *env;
     struct MonitorNotifyMessage *msg;
-    
+
     env = GNUNET_MQ_msg (msg,
                         GNUNET_MESSAGE_TYPE_CORE_MONITOR_NOTIFY);
     msg->state = htonl ((uint32_t) kx->status);