doc: gnunet-c-tutorial: Add nodes.
[oweals/gnunet.git] / src / core / gnunet-service-core_kx.c
index b2949a68883cd69bb0f163edaab7d535050f01d0..8a7cada5c5a1a1b76191e7859bb54ee703c6d760 100644 (file)
@@ -26,7 +26,6 @@
 #include "platform.h"
 #include "gnunet-service-core_kx.h"
 #include "gnunet-service-core.h"
-#include "gnunet-service-core_clients.h"
 #include "gnunet-service-core_sessions.h"
 #include "gnunet_statistics_service.h"
 #include "gnunet_transport_core_service.h"
@@ -262,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.
    */
@@ -320,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)
@@ -370,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.
  */
@@ -392,34 +391,9 @@ static struct GSC_KeyExchangeInfo *kx_tail;
 static struct GNUNET_SCHEDULER_Task *rekey_task;
 
 /**
- * Notification context for all monitors.
+ * Notification context for broadcasting to monitors.
  */
-static struct GNUNET_SERVER_NotificationContext *nc;
-
-
-/**
- * Inform the given monitor about the KX state of
- * the given peer.
- *
- * @param client client to inform
- * @param kx key exchange state to inform about
- */
-static void
-monitor_notify (struct GNUNET_SERVER_Client *client,
-                struct GSC_KeyExchangeInfo *kx)
-{
-  struct MonitorNotifyMessage msg;
-
-  msg.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_MONITOR_NOTIFY);
-  msg.header.size = htons (sizeof (msg));
-  msg.state = htonl ((uint32_t) kx->status);
-  msg.peer = *kx->peer;
-  msg.timeout = GNUNET_TIME_absolute_hton (kx->timeout);
-  GNUNET_SERVER_notification_context_unicast (nc,
-                                              client,
-                                              &msg.header,
-                                              GNUNET_NO);
-}
+static struct GNUNET_NotificationContext *nc;
 
 
 /**
@@ -453,9 +427,9 @@ monitor_notify_all (struct GSC_KeyExchangeInfo *kx)
   msg.state = htonl ((uint32_t) kx->status);
   msg.peer = *kx->peer;
   msg.timeout = GNUNET_TIME_absolute_hton (kx->timeout);
-  GNUNET_SERVER_notification_context_broadcast (nc,
-                                                &msg.header,
-                                                GNUNET_NO);
+  GNUNET_notification_context_broadcast (nc,
+                                        &msg.header,
+                                        GNUNET_NO);
   kx->last_notify_timeout = kx->timeout;
 }
 
@@ -727,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).
@@ -753,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;
@@ -803,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));
@@ -827,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);
 }
 
@@ -840,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,
@@ -1358,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)
   {
@@ -1442,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).
@@ -1501,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;
 
@@ -1546,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;
@@ -1562,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),
@@ -1596,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)
     {
@@ -1643,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);
 }
 
@@ -1668,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",
@@ -1678,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.
@@ -1807,35 +1767,31 @@ do_rekey (void *cls)
  * Initialize KX subsystem.
  *
  * @param pk private key to use for the peer
- * @param server the server of the CORE service
  * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure
  */
 int
-GSC_KX_init (struct GNUNET_CRYPTO_EddsaPrivateKey *pk,
-             struct GNUNET_SERVER_Handle *server)
+GSC_KX_init (struct GNUNET_CRYPTO_EddsaPrivateKey *pk)
 {
-  GNUNET_MQ_hd_fixed_size (ephemeral_key,
-                          GNUNET_MESSAGE_TYPE_CORE_EPHEMERAL_KEY,
-                          struct EphemeralKeyMessage);
-  GNUNET_MQ_hd_fixed_size (ping,
-                          GNUNET_MESSAGE_TYPE_CORE_PING,
-                          struct PingMessage);
-  GNUNET_MQ_hd_fixed_size (pong,
-                          GNUNET_MESSAGE_TYPE_CORE_PONG,
-                          struct PongMessage);
-  GNUNET_MQ_hd_var_size (encrypted,
-                        GNUNET_MESSAGE_TYPE_CORE_ENCRYPTED_MESSAGE,
-                        struct EncryptedMessage);
   struct GNUNET_MQ_MessageHandler handlers[] = {
-    make_ephemeral_key_handler (NULL),
-    make_ping_handler (NULL),
-    make_pong_handler (NULL),
-    make_encrypted_handler (NULL),
+    GNUNET_MQ_hd_fixed_size (ephemeral_key,
+                             GNUNET_MESSAGE_TYPE_CORE_EPHEMERAL_KEY,
+                             struct EphemeralKeyMessage,
+                             NULL),
+    GNUNET_MQ_hd_fixed_size (ping,
+                             GNUNET_MESSAGE_TYPE_CORE_PING,
+                             struct PingMessage,
+                             NULL),
+    GNUNET_MQ_hd_fixed_size (pong,
+                             GNUNET_MESSAGE_TYPE_CORE_PONG,
+                             struct PongMessage,
+                             NULL),
+    GNUNET_MQ_hd_var_size (encrypted,
+                           GNUNET_MESSAGE_TYPE_CORE_ENCRYPTED_MESSAGE,
+                           struct EncryptedMessage,
+                           NULL),
     GNUNET_MQ_handler_end()
   };
 
-  nc = GNUNET_SERVER_notification_context_create (server,
-                                                  1);
   my_private_key = pk;
   GNUNET_CRYPTO_eddsa_key_get_public (my_private_key,
                                       &GSC_my_identity.public_key);
@@ -1848,11 +1804,11 @@ GSC_KX_init (struct GNUNET_CRYPTO_EddsaPrivateKey *pk,
     return GNUNET_SYSERR;
   }
   sign_ephemeral_key ();
+  nc = GNUNET_notification_context_create (1);
   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,
@@ -1895,14 +1851,9 @@ 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_SERVER_notification_context_destroy (nc);
+    GNUNET_notification_context_destroy (nc);
     nc = NULL;
   }
 }
@@ -1940,34 +1891,36 @@ GSC_NEIGHBOURS_check_excess_bandwidth (const struct GSC_KeyExchangeInfo *kxinfo)
  * request.  All current peers are returned, regardless of which
  * message types they accept.
  *
- * @param cls unused
- * @param client client sending the iteration request
- * @param message iteration request message
+ * @param mq message queue to add for monitoring
  */
 void
-GSC_KX_handle_client_monitor_peers (void *cls,
-                                    struct GNUNET_SERVER_Client *client,
-                                    const struct GNUNET_MessageHeader *message)
+GSC_KX_handle_client_monitor_peers (struct GNUNET_MQ_Handle *mq)
 {
-  struct MonitorNotifyMessage done_msg;
+  struct GNUNET_MQ_Envelope *env;
+  struct MonitorNotifyMessage *done_msg;
   struct GSC_KeyExchangeInfo *kx;
 
-  GNUNET_SERVER_receive_done (client, GNUNET_OK);
-  GNUNET_SERVER_notification_context_add (nc,
-                                          client);
+  GNUNET_notification_context_add (nc,
+                                  mq);
   for (kx = kx_head; NULL != kx; kx = kx->next)
-    monitor_notify (client, kx);
-  done_msg.header.size = htons (sizeof (struct MonitorNotifyMessage));
-  done_msg.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_MONITOR_NOTIFY);
-  done_msg.state = htonl ((uint32_t) GNUNET_CORE_KX_ITERATION_FINISHED);
-  memset (&done_msg.peer,
-         0,
-         sizeof (struct GNUNET_PeerIdentity));
-  done_msg.timeout = GNUNET_TIME_absolute_hton (GNUNET_TIME_UNIT_FOREVER_ABS);
-  GNUNET_SERVER_notification_context_unicast (nc,
-                                              client,
-                                              &done_msg.header,
-                                              GNUNET_NO);
+  {
+    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);
+    msg->peer = *kx->peer;
+    msg->timeout = GNUNET_TIME_absolute_hton (kx->timeout);
+    GNUNET_MQ_send (mq,
+                   env);
+  }
+  env = GNUNET_MQ_msg (done_msg,
+                      GNUNET_MESSAGE_TYPE_CORE_MONITOR_NOTIFY);
+  done_msg->state = htonl ((uint32_t) GNUNET_CORE_KX_ITERATION_FINISHED);
+  done_msg->timeout = GNUNET_TIME_absolute_hton (GNUNET_TIME_UNIT_FOREVER_ABS);
+  GNUNET_MQ_send (mq,
+                 env);
 }