how did this test ever work without assigning core handles?
[oweals/gnunet.git] / src / core / gnunet-service-core_kx.c
index ca40d56a0f50469eee9bd8fc8a39d359d6775e56..9f904742dac12052952f8bf714f3548af7817ddd 100644 (file)
@@ -1,6 +1,6 @@
 /*
      This file is part of GNUnet.
-     (C) 2009, 2010, 2011, 2012 Christian Grothoff (and other contributing authors)
+     (C) 2009-2013 Christian Grothoff (and other contributing authors)
 
      GNUnet is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published
@@ -111,12 +111,12 @@ struct EphemeralKeyMessage
    * Ephemeral public ECC key (always for NIST P-521) encoded in a format suitable
    * for network transmission as created using 'gcry_sexp_sprint'.
    */
-  struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded ephemeral_key;  
+  struct GNUNET_CRYPTO_EccPublicKey ephemeral_key;  
 
   /**
    * Public key of the signing peer (persistent version, not the ephemeral public key).
    */
-  struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded origin_public_key;
+  struct GNUNET_CRYPTO_EccPublicKey origin_public_key;
 
 };
 
@@ -392,7 +392,7 @@ static struct EphemeralKeyMessage current_ekm;
 /**
  * Our public key.
  */
-static struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded my_public_key;
+static struct GNUNET_CRYPTO_EccPublicKey my_public_key;
 
 /**
  * Our message stream tokenizer (for encrypted payload).
@@ -498,7 +498,7 @@ derive_aes_key (const struct GNUNET_PeerIdentity *sender,
 
   GNUNET_CRYPTO_kdf (skey, sizeof (struct GNUNET_CRYPTO_AesSessionKey),
                     ctx, sizeof (ctx),
-                    skey, sizeof (struct GNUNET_CRYPTO_AesSessionKey),
+                    key_material, sizeof (struct GNUNET_HashCode),
                     sender, sizeof (struct GNUNET_PeerIdentity),
                     receiver, sizeof (struct GNUNET_PeerIdentity),
                     NULL);
@@ -756,7 +756,7 @@ GSC_KX_handle_ephemeral_key (struct GSC_KeyExchangeInfo *kx,
   if ( ( (KX_STATE_KEY_RECEIVED == kx->status) ||
         (KX_STATE_UP == kx->status) ||
         (KX_STATE_REKEY_SENT == kx->status) ) &&       
-       (end_t.abs_value <= kx->foreign_key_expires.abs_value) )
+       (end_t.abs_value_us <= kx->foreign_key_expires.abs_value_us) )
   {
     GNUNET_STATISTICS_update (GSC_stats, gettext_noop ("# old ephemeral keys ignored"),
                              1, GNUNET_NO);
@@ -771,7 +771,7 @@ GSC_KX_handle_ephemeral_key (struct GSC_KeyExchangeInfo *kx,
               "Core service receives `%s' request from `%4s'.\n", "EPHEMERAL_KEY",
               GNUNET_i2s (&kx->peer));
   GNUNET_CRYPTO_hash (&m->origin_public_key,
-                     sizeof (struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded),
+                     sizeof (struct GNUNET_CRYPTO_EccPublicKey),
                      &signer_id.hashPubKey);
   if (0 !=
       memcmp (&signer_id, &kx->peer,
@@ -784,8 +784,8 @@ GSC_KX_handle_ephemeral_key (struct GSC_KeyExchangeInfo *kx,
        sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) +
        sizeof (struct GNUNET_TIME_AbsoluteNBO) +
        sizeof (struct GNUNET_TIME_AbsoluteNBO) +
-       sizeof (struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded) +
-       sizeof (struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded)) ||
+       sizeof (struct GNUNET_CRYPTO_EccPublicKey) +
+       sizeof (struct GNUNET_CRYPTO_EccPublicKey)) ||
       (GNUNET_OK !=
        GNUNET_CRYPTO_ecc_verify (GNUNET_SIGNATURE_PURPOSE_SET_ECC_KEY,
                                 &m->purpose,
@@ -796,14 +796,15 @@ GSC_KX_handle_ephemeral_key (struct GSC_KeyExchangeInfo *kx,
     return;
   }
   now = GNUNET_TIME_absolute_get ();
-  if ( (end_t.abs_value < GNUNET_TIME_absolute_subtract (now, REKEY_TOLERANCE).abs_value) ||
-       (start_t.abs_value > GNUNET_TIME_absolute_add (now, REKEY_TOLERANCE).abs_value) )
+  if ( (end_t.abs_value_us < GNUNET_TIME_absolute_subtract (now, REKEY_TOLERANCE).abs_value_us) ||
+       (start_t.abs_value_us > GNUNET_TIME_absolute_add (now, REKEY_TOLERANCE).abs_value_us) )
   {
     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-               _("Ephemeral key message rejected as its validity range does not match our system time (%llu not in [%llu,%llu]).\n"),
-               now.abs_value,
-               start_t.abs_value,
-               end_t.abs_value);
+               _("Ephemeral key message from peer `%s' rejected as its validity range does not match our system time (%llu not in [%llu,%llu]).\n"),
+               GNUNET_i2s (&kx->peer),
+               now.abs_value_us,
+               start_t.abs_value_us,
+               end_t.abs_value_us);
     return;
   }
   if (GNUNET_OK !=
@@ -854,18 +855,21 @@ GSC_KX_handle_ephemeral_key (struct GSC_KeyExchangeInfo *kx,
   switch (kx->status)
   {
   case KX_STATE_DOWN:
+    GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == kx->keep_alive_task);
     kx->status = KX_STATE_KEY_RECEIVED;
     if (KX_STATE_KEY_SENT == sender_status)
       send_key (kx);
     send_ping (kx);
     break;
   case KX_STATE_KEY_SENT:
+    GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == kx->keep_alive_task);
     kx->status = KX_STATE_KEY_RECEIVED;
     if (KX_STATE_KEY_SENT == sender_status)
       send_key (kx);
     send_ping (kx);
     break;
   case KX_STATE_KEY_RECEIVED:
+    GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == kx->keep_alive_task);
     if (KX_STATE_KEY_SENT == sender_status)
       send_key (kx);
     send_ping (kx);
@@ -990,7 +994,7 @@ send_keep_alive (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
 
   kx->keep_alive_task = GNUNET_SCHEDULER_NO_TASK;
   left = GNUNET_TIME_absolute_get_remaining (kx->timeout);
-  if (0 == left.rel_value)
+  if (0 == left.rel_value_us)
   {
     GNUNET_STATISTICS_update (GSC_stats,
                               gettext_noop ("# sessions terminated by timeout"),
@@ -1247,11 +1251,6 @@ GSC_KX_encrypt_and_transmit (struct GSC_KeyExchangeInfo *kx,
 struct DeliverMessageContext
 {
 
-  /**
-   * Performance information for the connection.
-   */
-  const struct GNUNET_ATS_Information *atsi;
-
   /**
    * Key exchange context.
    */
@@ -1261,11 +1260,6 @@ struct DeliverMessageContext
    * Sender of the message.
    */
   const struct GNUNET_PeerIdentity *peer;
-
-  /**
-   * Number of entries in 'atsi' array.
-   */
-  uint32_t atsi_count;
 };
 
 
@@ -1275,14 +1269,10 @@ struct DeliverMessageContext
  *
  * @param kx key exchange context for encrypting the message
  * @param msg encrypted message
- * @param atsi performance data
- * @param atsi_count number of entries in ats (excluding 0-termination)
  */
 void
 GSC_KX_handle_encrypted_message (struct GSC_KeyExchangeInfo *kx,
-                                 const struct GNUNET_MessageHeader *msg,
-                                 const struct GNUNET_ATS_Information *atsi,
-                                 uint32_t atsi_count)
+                                 const struct GNUNET_MessageHeader *msg)
 {
   const struct EncryptedMessage *m;
   struct EncryptedMessage *pt;  /* plaintext */
@@ -1310,12 +1300,20 @@ GSC_KX_handle_encrypted_message (struct GSC_KeyExchangeInfo *kx,
                               1, GNUNET_NO);
     return;
   }
-  if (0 == GNUNET_TIME_absolute_get_remaining (kx->foreign_key_expires).rel_value)
+  if (0 == GNUNET_TIME_absolute_get_remaining (kx->foreign_key_expires).rel_value_us)
   {
+    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+               _("Session to peer `%s' went down due to key expiration (should not happen)\n"),
+               GNUNET_i2s (&kx->peer));
     GNUNET_STATISTICS_update (GSC_stats,
                               gettext_noop ("# sessions terminated by key expiration"),
                               1, GNUNET_NO);
     GSC_SESSIONS_end (&kx->peer);
+    if (GNUNET_SCHEDULER_NO_TASK != kx->keep_alive_task)
+    {
+      GNUNET_SCHEDULER_cancel (kx->keep_alive_task);
+      kx->keep_alive_task = GNUNET_SCHEDULER_NO_TASK;
+    }
     kx->status = KX_STATE_KEY_SENT;
     send_key (kx);
     return;
@@ -1396,8 +1394,8 @@ GSC_KX_handle_encrypted_message (struct GSC_KeyExchangeInfo *kx,
 
   /* check timestamp */
   t = GNUNET_TIME_absolute_ntoh (pt->timestamp);
-  if (GNUNET_TIME_absolute_get_duration (t).rel_value >
-      MAX_MESSAGE_AGE.rel_value)
+  if (GNUNET_TIME_absolute_get_duration (t).rel_value_us >
+      MAX_MESSAGE_AGE.rel_value_us)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                 "Message received far too old (%s). Content ignored.\n",
@@ -1414,9 +1412,7 @@ GSC_KX_handle_encrypted_message (struct GSC_KeyExchangeInfo *kx,
   GNUNET_STATISTICS_update (GSC_stats,
                             gettext_noop ("# bytes of payload decrypted"),
                             size - sizeof (struct EncryptedMessage), GNUNET_NO);
-  dmc.atsi = atsi;
   dmc.kx = kx;
-  dmc.atsi_count = atsi_count;
   dmc.peer = &kx->peer;
   if (GNUNET_OK !=
       GNUNET_SERVER_mst_receive (mst, &dmc,
@@ -1456,10 +1452,10 @@ deliver_message (void *cls, void *client, const struct GNUNET_MessageHeader *m)
     GSC_SESSIONS_set_typemap (dmc->peer, m);
     return GNUNET_OK;
   default:
-    GSC_CLIENTS_deliver_message (dmc->peer, dmc->atsi, dmc->atsi_count, m,
+    GSC_CLIENTS_deliver_message (dmc->peer, m,
                                  ntohs (m->size),
                                  GNUNET_CORE_OPTION_SEND_FULL_INBOUND);
-    GSC_CLIENTS_deliver_message (dmc->peer, dmc->atsi, dmc->atsi_count, m,
+    GSC_CLIENTS_deliver_message (dmc->peer, m,
                                  sizeof (struct GNUNET_MessageHeader),
                                  GNUNET_CORE_OPTION_SEND_HDR_INBOUND);
   }
@@ -1481,11 +1477,21 @@ sign_ephemeral_key ()
   current_ekm.purpose.size = htonl (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) +
                                    sizeof (struct GNUNET_TIME_AbsoluteNBO) +
                                    sizeof (struct GNUNET_TIME_AbsoluteNBO) +
-                                   sizeof (struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded) +
-                                   sizeof (struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded));
+                                   sizeof (struct GNUNET_CRYPTO_EccPublicKey) +
+                                   sizeof (struct GNUNET_CRYPTO_EccPublicKey));
   current_ekm.creation_time = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get ());
-  current_ekm.expiration_time = GNUNET_TIME_absolute_hton (GNUNET_TIME_relative_to_absolute (GNUNET_TIME_relative_add (REKEY_FREQUENCY,
-                                                                                                                      REKEY_TOLERANCE)));
+  if (GNUNET_YES ==
+      GNUNET_CONFIGURATION_get_value_yesno (GSC_cfg,
+                                           "core",
+                                           "USE_EPHEMERAL_KEYS"))
+  {
+    current_ekm.expiration_time = GNUNET_TIME_absolute_hton (GNUNET_TIME_relative_to_absolute (GNUNET_TIME_relative_add (REKEY_FREQUENCY,
+                                                                                                                        REKEY_TOLERANCE)));
+  }
+  else
+  {
+    current_ekm.expiration_time = GNUNET_TIME_absolute_hton (GNUNET_TIME_UNIT_FOREVER_ABS);
+  }
   GNUNET_CRYPTO_ecc_key_get_public (my_ephemeral_key,
                                    &current_ekm.ephemeral_key);
   current_ekm.origin_public_key = my_public_key;
@@ -1512,7 +1518,7 @@ do_rekey (void *cls,
                                             &do_rekey,
                                             NULL);
   if (NULL != my_ephemeral_key)
-    GNUNET_CRYPTO_ecc_key_free (my_ephemeral_key);
+    GNUNET_free (my_ephemeral_key);
   my_ephemeral_key = GNUNET_CRYPTO_ecc_key_create ();
   GNUNET_assert (NULL != my_ephemeral_key);
   sign_ephemeral_key ();
@@ -1547,7 +1553,7 @@ GSC_KX_init (struct GNUNET_CRYPTO_EccPrivateKey *pk)
     if (NULL == my_ephemeral_key)
     {
       GNUNET_break (0);
-      GNUNET_CRYPTO_ecc_key_free (my_private_key);
+      GNUNET_free (my_private_key);
       my_private_key = NULL;
       return GNUNET_SYSERR;
     }
@@ -1580,12 +1586,12 @@ GSC_KX_done ()
   if ( (NULL != my_ephemeral_key) &&
        (my_ephemeral_key != my_private_key) )
   {
-    GNUNET_CRYPTO_ecc_key_free (my_ephemeral_key);
+    GNUNET_free (my_ephemeral_key);
     my_ephemeral_key = NULL;
   }
   if (NULL != my_private_key)
   {
-    GNUNET_CRYPTO_ecc_key_free (my_private_key);
+    GNUNET_free (my_private_key);
     my_private_key = NULL;
   }
   if (NULL != mst)