aboutsummaryrefslogtreecommitdiff
path: root/src/core/gnunet-service-core_kx.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2016-07-26 21:12:56 +0000
committerChristian Grothoff <christian@grothoff.org>2016-07-26 21:12:56 +0000
commit8c2dc7d19810d58f23c43bf900e2fb3eebe06fed (patch)
tree9173a966e2f51a34d9259a0126484e05d44dcaac /src/core/gnunet-service-core_kx.c
parenta89ea716333ad5ad43757a946efc01cb5e95a0c0 (diff)
downloadgnunet-8c2dc7d19810d58f23c43bf900e2fb3eebe06fed.tar.gz
gnunet-8c2dc7d19810d58f23c43bf900e2fb3eebe06fed.zip
-converting CORE service to new transport MQ API
Diffstat (limited to 'src/core/gnunet-service-core_kx.c')
-rw-r--r--src/core/gnunet-service-core_kx.c465
1 files changed, 283 insertions, 182 deletions
diff --git a/src/core/gnunet-service-core_kx.c b/src/core/gnunet-service-core_kx.c
index 6a71099ae..d2b46ff41 100644
--- a/src/core/gnunet-service-core_kx.c
+++ b/src/core/gnunet-service-core_kx.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2009-2013 GNUnet e.V. 3 Copyright (C) 2009-2013, 2016 GNUnet e.V.
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published 6 it under the terms of the GNU General Public License as published
@@ -27,9 +27,9 @@
27#include "gnunet-service-core_kx.h" 27#include "gnunet-service-core_kx.h"
28#include "gnunet-service-core.h" 28#include "gnunet-service-core.h"
29#include "gnunet-service-core_clients.h" 29#include "gnunet-service-core_clients.h"
30#include "gnunet-service-core_neighbours.h"
31#include "gnunet-service-core_sessions.h" 30#include "gnunet-service-core_sessions.h"
32#include "gnunet_statistics_service.h" 31#include "gnunet_statistics_service.h"
32#include "gnunet_transport_core_service.h"
33#include "gnunet_constants.h" 33#include "gnunet_constants.h"
34#include "gnunet_signatures.h" 34#include "gnunet_signatures.h"
35#include "gnunet_protocols.h" 35#include "gnunet_protocols.h"
@@ -87,8 +87,8 @@ struct EphemeralKeyMessage
87 int32_t sender_status GNUNET_PACKED; 87 int32_t sender_status GNUNET_PACKED;
88 88
89 /** 89 /**
90 * An ECC signature of the @e origin_identity asserting the validity of 90 * An ECC signature of the @e origin_identity asserting the validity
91 * the given ephemeral key. 91 * of the given ephemeral key.
92 */ 92 */
93 struct GNUNET_CRYPTO_EddsaSignature signature; 93 struct GNUNET_CRYPTO_EddsaSignature signature;
94 94
@@ -113,7 +113,8 @@ struct EphemeralKeyMessage
113 struct GNUNET_CRYPTO_EcdhePublicKey ephemeral_key; 113 struct GNUNET_CRYPTO_EcdhePublicKey ephemeral_key;
114 114
115 /** 115 /**
116 * Public key of the signing peer (persistent version, not the ephemeral public key). 116 * Public key of the signing peer (persistent version, not the
117 * ephemeral public key).
117 */ 118 */
118 struct GNUNET_PeerIdentity origin_identity; 119 struct GNUNET_PeerIdentity origin_identity;
119 120
@@ -202,8 +203,9 @@ struct EncryptedMessage
202 /** 203 /**
203 * MAC of the encrypted message (starting at @e sequence_number), 204 * MAC of the encrypted message (starting at @e sequence_number),
204 * used to verify message integrity. Everything after this value 205 * used to verify message integrity. Everything after this value
205 * (excluding this value itself) will be encrypted and authenticated. 206 * (excluding this value itself) will be encrypted and
206 * #ENCRYPTED_HEADER_SIZE must be set to the offset of the *next* field. 207 * authenticated. #ENCRYPTED_HEADER_SIZE must be set to the offset
208 * of the *next* field.
207 */ 209 */
208 struct GNUNET_HashCode hmac; 210 struct GNUNET_HashCode hmac;
209 211
@@ -216,7 +218,7 @@ struct EncryptedMessage
216 /** 218 /**
217 * Reserved, always zero. 219 * Reserved, always zero.
218 */ 220 */
219 uint32_t reserved; 221 uint32_t reserved GNUNET_PACKED;
220 222
221 /** 223 /**
222 * Timestamp. Used to prevent replay of ancient messages 224 * Timestamp. Used to prevent replay of ancient messages
@@ -254,9 +256,14 @@ struct GSC_KeyExchangeInfo
254 /** 256 /**
255 * Identity of the peer. 257 * Identity of the peer.
256 */ 258 */
257 struct GNUNET_PeerIdentity peer; 259 const struct GNUNET_PeerIdentity *peer;
258 260
259 /** 261 /**
262 * Message queue for sending messages to @a peer.
263 */
264 struct GNUNET_MQ_Handle *mq;
265
266 /**
260 * PING message we transmit to the other peer. 267 * PING message we transmit to the other peer.
261 */ 268 */
262 struct PingMessage ping; 269 struct PingMessage ping;
@@ -309,8 +316,8 @@ struct GSC_KeyExchangeInfo
309 struct GNUNET_SCHEDULER_Task *keep_alive_task; 316 struct GNUNET_SCHEDULER_Task *keep_alive_task;
310 317
311 /** 318 /**
312 * Bit map indicating which of the 32 sequence numbers before the last 319 * Bit map indicating which of the 32 sequence numbers before the
313 * were received (good for accepting out-of-order packets and 320 * last were received (good for accepting out-of-order packets and
314 * estimating reliability of the connection) 321 * estimating reliability of the connection)
315 */ 322 */
316 unsigned int last_packets_bitmap; 323 unsigned int last_packets_bitmap;
@@ -331,6 +338,11 @@ struct GSC_KeyExchangeInfo
331 uint32_t ping_challenge; 338 uint32_t ping_challenge;
332 339
333 /** 340 /**
341 * #GNUNET_YES if this peer currently has excess bandwidth.
342 */
343 int has_excess_bandwidth;
344
345 /**
334 * What is our connection status? 346 * What is our connection status?
335 */ 347 */
336 enum GNUNET_CORE_KxState status; 348 enum GNUNET_CORE_KxState status;
@@ -339,6 +351,11 @@ struct GSC_KeyExchangeInfo
339 351
340 352
341/** 353/**
354 * Transport service.
355 */
356static struct GNUNET_TRANSPORT_CoreHandle *transport;
357
358/**
342 * Our private key. 359 * Our private key.
343 */ 360 */
344static struct GNUNET_CRYPTO_EddsaPrivateKey *my_private_key; 361static struct GNUNET_CRYPTO_EddsaPrivateKey *my_private_key;
@@ -396,7 +413,7 @@ monitor_notify (struct GNUNET_SERVER_Client *client,
396 msg.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_MONITOR_NOTIFY); 413 msg.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_MONITOR_NOTIFY);
397 msg.header.size = htons (sizeof (msg)); 414 msg.header.size = htons (sizeof (msg));
398 msg.state = htonl ((uint32_t) kx->status); 415 msg.state = htonl ((uint32_t) kx->status);
399 msg.peer = kx->peer; 416 msg.peer = *kx->peer;
400 msg.timeout = GNUNET_TIME_absolute_hton (kx->timeout); 417 msg.timeout = GNUNET_TIME_absolute_hton (kx->timeout);
401 GNUNET_SERVER_notification_context_unicast (nc, 418 GNUNET_SERVER_notification_context_unicast (nc,
402 client, 419 client,
@@ -434,7 +451,7 @@ monitor_notify_all (struct GSC_KeyExchangeInfo *kx)
434 msg.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_MONITOR_NOTIFY); 451 msg.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_MONITOR_NOTIFY);
435 msg.header.size = htons (sizeof (msg)); 452 msg.header.size = htons (sizeof (msg));
436 msg.state = htonl ((uint32_t) kx->status); 453 msg.state = htonl ((uint32_t) kx->status);
437 msg.peer = kx->peer; 454 msg.peer = *kx->peer;
438 msg.timeout = GNUNET_TIME_absolute_hton (kx->timeout); 455 msg.timeout = GNUNET_TIME_absolute_hton (kx->timeout);
439 GNUNET_SERVER_notification_context_broadcast (nc, 456 GNUNET_SERVER_notification_context_broadcast (nc,
440 &msg.header, 457 &msg.header,
@@ -566,9 +583,14 @@ do_encrypt (struct GSC_KeyExchangeInfo *kx,
566 return GNUNET_NO; 583 return GNUNET_NO;
567 } 584 }
568 GNUNET_assert (size == 585 GNUNET_assert (size ==
569 GNUNET_CRYPTO_symmetric_encrypt (in, (uint16_t) size, 586 GNUNET_CRYPTO_symmetric_encrypt (in,
570 &kx->encrypt_key, iv, out)); 587 (uint16_t) size,
571 GNUNET_STATISTICS_update (GSC_stats, gettext_noop ("# bytes encrypted"), size, 588 &kx->encrypt_key,
589 iv,
590 out));
591 GNUNET_STATISTICS_update (GSC_stats,
592 gettext_noop ("# bytes encrypted"),
593 size,
572 GNUNET_NO); 594 GNUNET_NO);
573 /* the following is too sensitive to write to log files by accident, 595 /* the following is too sensitive to write to log files by accident,
574 so we require manual intervention to get this one... */ 596 so we require manual intervention to get this one... */
@@ -576,19 +598,19 @@ do_encrypt (struct GSC_KeyExchangeInfo *kx,
576 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 598 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
577 "Encrypted %u bytes for `%s' using key %u, IV %u\n", 599 "Encrypted %u bytes for `%s' using key %u, IV %u\n",
578 (unsigned int) size, 600 (unsigned int) size,
579 GNUNET_i2s (&kx->peer), 601 GNUNET_i2s (kx->peer),
580 (unsigned int) kx->encrypt_key.crc32, GNUNET_CRYPTO_crc32_n (iv, 602 (unsigned int) kx->encrypt_key.crc32,
581 sizeof 603 GNUNET_CRYPTO_crc32_n (iv,
582 (iv))); 604 sizeof (iv)));
583#endif 605#endif
584 return GNUNET_OK; 606 return GNUNET_OK;
585} 607}
586 608
587 609
588/** 610/**
589 * Decrypt size bytes from @a in and write the result to @a out. Use the 611 * Decrypt size bytes from @a in and write the result to @a out. Use
590 * @a kx key for inbound traffic of the given neighbour. This function does 612 * the @a kx key for inbound traffic of the given neighbour. This
591 * NOT do any integrity-checks on the result. 613 * function does NOT do any integrity-checks on the result.
592 * 614 *
593 * @param kx key information context 615 * @param kx key information context
594 * @param iv initialization vector to use 616 * @param iv initialization vector to use
@@ -636,7 +658,7 @@ do_decrypt (struct GSC_KeyExchangeInfo *kx,
636 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 658 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
637 "Decrypted %u bytes from `%s' using key %u, IV %u\n", 659 "Decrypted %u bytes from `%s' using key %u, IV %u\n",
638 (unsigned int) size, 660 (unsigned int) size,
639 GNUNET_i2s (&kx->peer), 661 GNUNET_i2s (kx->peer),
640 (unsigned int) kx->decrypt_key.crc32, 662 (unsigned int) kx->decrypt_key.crc32,
641 GNUNET_CRYPTO_crc32_n (iv, 663 GNUNET_CRYPTO_crc32_n (iv,
642 sizeof 664 sizeof
@@ -690,23 +712,34 @@ setup_fresh_ping (struct GSC_KeyExchangeInfo *kx)
690 pm->header.size = htons (sizeof (struct PingMessage)); 712 pm->header.size = htons (sizeof (struct PingMessage));
691 pm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_PING); 713 pm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_PING);
692 pm->iv_seed = calculate_seed (kx); 714 pm->iv_seed = calculate_seed (kx);
693 derive_iv (&iv, &kx->encrypt_key, pm->iv_seed, &kx->peer); 715 derive_iv (&iv,
716 &kx->encrypt_key,
717 pm->iv_seed,
718 kx->peer);
694 pp.challenge = kx->ping_challenge; 719 pp.challenge = kx->ping_challenge;
695 pp.target = kx->peer; 720 pp.target = *kx->peer;
696 do_encrypt (kx, &iv, &pp.target, &pm->target, 721 do_encrypt (kx,
722 &iv,
723 &pp.target,
724 &pm->target,
697 sizeof (struct PingMessage) - ((void *) &pm->target - 725 sizeof (struct PingMessage) - ((void *) &pm->target -
698 (void *) pm)); 726 (void *) pm));
699} 727}
700 728
701 729
702/** 730/**
703 * Start the key exchange with the given peer. 731 * Function called by transport to notify us that
732 * a peer connected to us (on the network level).
733 * Starts the key exchange with the given peer.
704 * 734 *
735 * @param cls closure (NULL)
705 * @param pid identity of the peer to do a key exchange with 736 * @param pid identity of the peer to do a key exchange with
706 * @return key exchange information context 737 * @return key exchange information context
707 */ 738 */
708struct GSC_KeyExchangeInfo * 739static void *
709GSC_KX_start (const struct GNUNET_PeerIdentity *pid) 740handle_transport_notify_connect (void *cls,
741 const struct GNUNET_PeerIdentity *pid,
742 struct GNUNET_MQ_Handle *mq)
710{ 743{
711 struct GSC_KeyExchangeInfo *kx; 744 struct GSC_KeyExchangeInfo *kx;
712 struct GNUNET_HashCode h1; 745 struct GNUNET_HashCode h1;
@@ -720,7 +753,8 @@ GSC_KX_start (const struct GNUNET_PeerIdentity *pid)
720 1, 753 1,
721 GNUNET_NO); 754 GNUNET_NO);
722 kx = GNUNET_new (struct GSC_KeyExchangeInfo); 755 kx = GNUNET_new (struct GSC_KeyExchangeInfo);
723 kx->peer = *pid; 756 kx->mq = mq;
757 kx->peer = pid;
724 kx->set_key_retry_frequency = INITIAL_SET_KEY_RETRY_FREQUENCY; 758 kx->set_key_retry_frequency = INITIAL_SET_KEY_RETRY_FREQUENCY;
725 GNUNET_CONTAINER_DLL_insert (kx_head, 759 GNUNET_CONTAINER_DLL_insert (kx_head,
726 kx_tail, 760 kx_tail,
@@ -755,16 +789,29 @@ GSC_KX_start (const struct GNUNET_PeerIdentity *pid)
755 789
756 790
757/** 791/**
792 * Function called by transport telling us that a peer
793 * disconnected.
758 * Stop key exchange with the given peer. Clean up key material. 794 * Stop key exchange with the given peer. Clean up key material.
759 * 795 *
760 * @param kx key exchange to stop 796 * @param cls closure
797 * @param peer the peer that disconnected
798 * @param handler_cls the `struct GSC_KeyExchangeInfo` of the peer
761 */ 799 */
762void 800static void
763GSC_KX_stop (struct GSC_KeyExchangeInfo *kx) 801handle_transport_notify_disconnect (void *cls,
802 const struct GNUNET_PeerIdentity *peer,
803 void *handler_cls)
764{ 804{
765 GSC_SESSIONS_end (&kx->peer); 805 struct GSC_KeyExchangeInfo *kx = handler_cls;
766 GNUNET_STATISTICS_update (GSC_stats, gettext_noop ("# key exchanges stopped"), 806
767 1, GNUNET_NO); 807 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
808 "Peer `%s' disconnected from us.\n",
809 GNUNET_i2s (peer));
810 GSC_SESSIONS_end (kx->peer);
811 GNUNET_STATISTICS_update (GSC_stats,
812 gettext_noop ("# key exchanges stopped"),
813 1,
814 GNUNET_NO);
768 if (NULL != kx->retry_set_key_task) 815 if (NULL != kx->retry_set_key_task)
769 { 816 {
770 GNUNET_SCHEDULER_cancel (kx->retry_set_key_task); 817 GNUNET_SCHEDULER_cancel (kx->retry_set_key_task);
@@ -792,13 +839,15 @@ GSC_KX_stop (struct GSC_KeyExchangeInfo *kx)
792static void 839static void
793send_ping (struct GSC_KeyExchangeInfo *kx) 840send_ping (struct GSC_KeyExchangeInfo *kx)
794{ 841{
842 struct GNUNET_MQ_Envelope *env;
843
795 GNUNET_STATISTICS_update (GSC_stats, 844 GNUNET_STATISTICS_update (GSC_stats,
796 gettext_noop ("# PING messages transmitted"), 845 gettext_noop ("# PING messages transmitted"),
797 1, 846 1,
798 GNUNET_NO); 847 GNUNET_NO);
799 GSC_NEIGHBOURS_transmit (&kx->peer, 848 env = GNUNET_MQ_msg_copy (&kx->ping.header);
800 &kx->ping.header, 849 GNUNET_MQ_send (kx->mq,
801 kx->set_key_retry_frequency); 850 env);
802} 851}
803 852
804 853
@@ -821,10 +870,10 @@ derive_session_keys (struct GSC_KeyExchangeInfo *kx)
821 return; 870 return;
822 } 871 }
823 derive_aes_key (&GSC_my_identity, 872 derive_aes_key (&GSC_my_identity,
824 &kx->peer, 873 kx->peer,
825 &key_material, 874 &key_material,
826 &kx->encrypt_key); 875 &kx->encrypt_key);
827 derive_aes_key (&kx->peer, 876 derive_aes_key (kx->peer,
828 &GSC_my_identity, 877 &GSC_my_identity,
829 &key_material, 878 &key_material,
830 &kx->decrypt_key); 879 &kx->decrypt_key);
@@ -840,27 +889,19 @@ derive_session_keys (struct GSC_KeyExchangeInfo *kx)
840 * We received a #GNUNET_MESSAGE_TYPE_CORE_EPHEMERAL_KEY message. 889 * We received a #GNUNET_MESSAGE_TYPE_CORE_EPHEMERAL_KEY message.
841 * Validate and update our key material and status. 890 * Validate and update our key material and status.
842 * 891 *
843 * @param kx key exchange status for the corresponding peer 892 * @param cls key exchange status for the corresponding peer
844 * @param msg the set key message we received 893 * @param m the set key message we received
845 */ 894 */
846void 895static void
847GSC_KX_handle_ephemeral_key (struct GSC_KeyExchangeInfo *kx, 896handle_ephemeral_key (void *cls,
848 const struct GNUNET_MessageHeader *msg) 897 const struct EphemeralKeyMessage *m)
849{ 898{
850 const struct EphemeralKeyMessage *m; 899 struct GSC_KeyExchangeInfo *kx = cls;
851 struct GNUNET_TIME_Absolute start_t; 900 struct GNUNET_TIME_Absolute start_t;
852 struct GNUNET_TIME_Absolute end_t; 901 struct GNUNET_TIME_Absolute end_t;
853 struct GNUNET_TIME_Absolute now; 902 struct GNUNET_TIME_Absolute now;
854 enum GNUNET_CORE_KxState sender_status; 903 enum GNUNET_CORE_KxState sender_status;
855 uint16_t size;
856 904
857 size = ntohs (msg->size);
858 if (sizeof (struct EphemeralKeyMessage) != size)
859 {
860 GNUNET_break_op (0);
861 return;
862 }
863 m = (const struct EphemeralKeyMessage *) msg;
864 end_t = GNUNET_TIME_absolute_ntoh (m->expiration_time); 905 end_t = GNUNET_TIME_absolute_ntoh (m->expiration_time);
865 if ( ( (GNUNET_CORE_KX_STATE_KEY_RECEIVED == kx->status) || 906 if ( ( (GNUNET_CORE_KX_STATE_KEY_RECEIVED == kx->status) ||
866 (GNUNET_CORE_KX_STATE_UP == kx->status) || 907 (GNUNET_CORE_KX_STATE_UP == kx->status) ||
@@ -880,19 +921,19 @@ GSC_KX_handle_ephemeral_key (struct GSC_KeyExchangeInfo *kx,
880 921
881 if (0 != 922 if (0 !=
882 memcmp (&m->origin_identity, 923 memcmp (&m->origin_identity,
883 &kx->peer, 924 kx->peer,
884 sizeof (struct GNUNET_PeerIdentity))) 925 sizeof (struct GNUNET_PeerIdentity)))
885 { 926 {
886 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 927 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
887 "Received EPHEMERAL_KEY from %s, but expected %s\n", 928 "Received EPHEMERAL_KEY from %s, but expected %s\n",
888 GNUNET_i2s (&m->origin_identity), 929 GNUNET_i2s (&m->origin_identity),
889 GNUNET_i2s_full (&kx->peer)); 930 GNUNET_i2s_full (kx->peer));
890 GNUNET_break_op (0); 931 GNUNET_break_op (0);
891 return; 932 return;
892 } 933 }
893 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 934 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
894 "Core service receives EPHEMERAL_KEY request from `%s'.\n", 935 "Core service receives EPHEMERAL_KEY request from `%s'.\n",
895 GNUNET_i2s (&kx->peer)); 936 GNUNET_i2s (kx->peer));
896 if ((ntohl (m->purpose.size) != 937 if ((ntohl (m->purpose.size) !=
897 sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) + 938 sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) +
898 sizeof (struct GNUNET_TIME_AbsoluteNBO) + 939 sizeof (struct GNUNET_TIME_AbsoluteNBO) +
@@ -915,7 +956,7 @@ GSC_KX_handle_ephemeral_key (struct GSC_KeyExchangeInfo *kx,
915 { 956 {
916 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 957 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
917 _("Ephemeral key message from peer `%s' rejected as its validity range does not match our system time (%llu not in [%llu,%llu]).\n"), 958 _("Ephemeral key message from peer `%s' rejected as its validity range does not match our system time (%llu not in [%llu,%llu]).\n"),
918 GNUNET_i2s (&kx->peer), 959 GNUNET_i2s (kx->peer),
919 (unsigned long long) now.abs_value_us, 960 (unsigned long long) now.abs_value_us,
920 (unsigned long long) start_t.abs_value_us, 961 (unsigned long long) start_t.abs_value_us,
921 (unsigned long long) end_t.abs_value_us); 962 (unsigned long long) end_t.abs_value_us);
@@ -937,11 +978,11 @@ GSC_KX_handle_ephemeral_key (struct GSC_KeyExchangeInfo *kx,
937 break; 978 break;
938 case GNUNET_CORE_KX_STATE_KEY_SENT: 979 case GNUNET_CORE_KX_STATE_KEY_SENT:
939 /* fine, need to send our key after updating our status, see below */ 980 /* fine, need to send our key after updating our status, see below */
940 GSC_SESSIONS_reinit (&kx->peer); 981 GSC_SESSIONS_reinit (kx->peer);
941 break; 982 break;
942 case GNUNET_CORE_KX_STATE_KEY_RECEIVED: 983 case GNUNET_CORE_KX_STATE_KEY_RECEIVED:
943 /* other peer already got our key, but typemap did go down */ 984 /* other peer already got our key, but typemap did go down */
944 GSC_SESSIONS_reinit (&kx->peer); 985 GSC_SESSIONS_reinit (kx->peer);
945 break; 986 break;
946 case GNUNET_CORE_KX_STATE_UP: 987 case GNUNET_CORE_KX_STATE_UP:
947 /* other peer already got our key, typemap NOT down */ 988 /* other peer already got our key, typemap NOT down */
@@ -1006,26 +1047,20 @@ GSC_KX_handle_ephemeral_key (struct GSC_KeyExchangeInfo *kx,
1006 * We received a PING message. Validate and transmit 1047 * We received a PING message. Validate and transmit
1007 * a PONG message. 1048 * a PONG message.
1008 * 1049 *
1009 * @param kx key exchange status for the corresponding peer 1050 * @param cls key exchange status for the corresponding peer
1010 * @param msg the encrypted PING message itself 1051 * @param m the encrypted PING message itself
1011 */ 1052 */
1012void 1053static void
1013GSC_KX_handle_ping (struct GSC_KeyExchangeInfo *kx, 1054handle_ping (void *cls,
1014 const struct GNUNET_MessageHeader *msg) 1055 const struct PingMessage *m)
1015{ 1056{
1016 const struct PingMessage *m; 1057 struct GSC_KeyExchangeInfo *kx = cls;
1017 struct PingMessage t; 1058 struct PingMessage t;
1018 struct PongMessage tx; 1059 struct PongMessage tx;
1019 struct PongMessage tp; 1060 struct PongMessage *tp;
1061 struct GNUNET_MQ_Envelope *env;
1020 struct GNUNET_CRYPTO_SymmetricInitializationVector iv; 1062 struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
1021 uint16_t msize;
1022 1063
1023 msize = ntohs (msg->size);
1024 if (msize != sizeof (struct PingMessage))
1025 {
1026 GNUNET_break_op (0);
1027 return;
1028 }
1029 GNUNET_STATISTICS_update (GSC_stats, 1064 GNUNET_STATISTICS_update (GSC_stats,
1030 gettext_noop ("# PING messages received"), 1065 gettext_noop ("# PING messages received"),
1031 1, 1066 1,
@@ -1041,13 +1076,18 @@ GSC_KX_handle_ping (struct GSC_KeyExchangeInfo *kx,
1041 GNUNET_NO); 1076 GNUNET_NO);
1042 return; 1077 return;
1043 } 1078 }
1044 m = (const struct PingMessage *) msg;
1045 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1079 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1046 "Core service receives PING request from `%s'.\n", 1080 "Core service receives PING request from `%s'.\n",
1047 GNUNET_i2s (&kx->peer)); 1081 GNUNET_i2s (kx->peer));
1048 derive_iv (&iv, &kx->decrypt_key, m->iv_seed, &GSC_my_identity); 1082 derive_iv (&iv,
1083 &kx->decrypt_key,
1084 m->iv_seed,
1085 &GSC_my_identity);
1049 if (GNUNET_OK != 1086 if (GNUNET_OK !=
1050 do_decrypt (kx, &iv, &m->target, &t.target, 1087 do_decrypt (kx,
1088 &iv,
1089 &m->target,
1090 &t.target,
1051 sizeof (struct PingMessage) - ((void *) &m->target - 1091 sizeof (struct PingMessage) - ((void *) &m->target -
1052 (void *) m))) 1092 (void *) m)))
1053 { 1093 {
@@ -1062,11 +1102,11 @@ GSC_KX_handle_ping (struct GSC_KeyExchangeInfo *kx,
1062 if (GNUNET_CORE_KX_STATE_REKEY_SENT != kx->status) 1102 if (GNUNET_CORE_KX_STATE_REKEY_SENT != kx->status)
1063 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 1103 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1064 "Decryption of PING from peer `%s' failed\n", 1104 "Decryption of PING from peer `%s' failed\n",
1065 GNUNET_i2s (&kx->peer)); 1105 GNUNET_i2s (kx->peer));
1066 else 1106 else
1067 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1107 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1068 "Decryption of PING from peer `%s' failed after rekey (harmless)\n", 1108 "Decryption of PING from peer `%s' failed after rekey (harmless)\n",
1069 GNUNET_i2s (&kx->peer)); 1109 GNUNET_i2s (kx->peer));
1070 GNUNET_break_op (0); 1110 GNUNET_break_op (0);
1071 return; 1111 return;
1072 } 1112 }
@@ -1074,27 +1114,26 @@ GSC_KX_handle_ping (struct GSC_KeyExchangeInfo *kx,
1074 tx.reserved = 0; 1114 tx.reserved = 0;
1075 tx.challenge = t.challenge; 1115 tx.challenge = t.challenge;
1076 tx.target = t.target; 1116 tx.target = t.target;
1077 tp.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_PONG); 1117 env = GNUNET_MQ_msg (tp,
1078 tp.header.size = htons (sizeof (struct PongMessage)); 1118 GNUNET_MESSAGE_TYPE_CORE_PONG);
1079 tp.iv_seed = calculate_seed (kx); 1119 tp->iv_seed = calculate_seed (kx);
1080 derive_pong_iv (&iv, 1120 derive_pong_iv (&iv,
1081 &kx->encrypt_key, 1121 &kx->encrypt_key,
1082 tp.iv_seed, 1122 tp->iv_seed,
1083 t.challenge, 1123 t.challenge,
1084 &kx->peer); 1124 kx->peer);
1085 do_encrypt (kx, 1125 do_encrypt (kx,
1086 &iv, 1126 &iv,
1087 &tx.challenge, 1127 &tx.challenge,
1088 &tp.challenge, 1128 &tp->challenge,
1089 sizeof (struct PongMessage) - ((void *) &tp.challenge - 1129 sizeof (struct PongMessage) - ((void *) &tp->challenge -
1090 (void *) &tp)); 1130 (void *) tp));
1091 GNUNET_STATISTICS_update (GSC_stats, 1131 GNUNET_STATISTICS_update (GSC_stats,
1092 gettext_noop ("# PONG messages created"), 1132 gettext_noop ("# PONG messages created"),
1093 1, 1133 1,
1094 GNUNET_NO); 1134 GNUNET_NO);
1095 GSC_NEIGHBOURS_transmit (&kx->peer, 1135 GNUNET_MQ_send (kx->mq,
1096 &tp.header, 1136 env);
1097 kx->set_key_retry_frequency);
1098} 1137}
1099 1138
1100 1139
@@ -1119,7 +1158,7 @@ send_keep_alive (void *cls)
1119 gettext_noop ("# sessions terminated by timeout"), 1158 gettext_noop ("# sessions terminated by timeout"),
1120 1, 1159 1,
1121 GNUNET_NO); 1160 GNUNET_NO);
1122 GSC_SESSIONS_end (&kx->peer); 1161 GSC_SESSIONS_end (kx->peer);
1123 kx->status = GNUNET_CORE_KX_STATE_KEY_SENT; 1162 kx->status = GNUNET_CORE_KX_STATE_KEY_SENT;
1124 monitor_notify_all (kx); 1163 monitor_notify_all (kx);
1125 send_key (kx); 1164 send_key (kx);
@@ -1127,7 +1166,7 @@ send_keep_alive (void *cls)
1127 } 1166 }
1128 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1167 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1129 "Sending KEEPALIVE to `%s'\n", 1168 "Sending KEEPALIVE to `%s'\n",
1130 GNUNET_i2s (&kx->peer)); 1169 GNUNET_i2s (kx->peer));
1131 GNUNET_STATISTICS_update (GSC_stats, 1170 GNUNET_STATISTICS_update (GSC_stats,
1132 gettext_noop ("# keepalive messages sent"), 1171 gettext_noop ("# keepalive messages sent"),
1133 1, 1172 1,
@@ -1182,23 +1221,16 @@ update_timeout (struct GSC_KeyExchangeInfo *kx)
1182 * We received a PONG message. Validate and update our status. 1221 * We received a PONG message. Validate and update our status.
1183 * 1222 *
1184 * @param kx key exchange context for the the PONG 1223 * @param kx key exchange context for the the PONG
1185 * @param msg the encrypted PONG message itself 1224 * @param m the encrypted PONG message itself
1186 */ 1225 */
1187void 1226static void
1188GSC_KX_handle_pong (struct GSC_KeyExchangeInfo *kx, 1227handle_pong (void *cls,
1189 const struct GNUNET_MessageHeader *msg) 1228 const struct PongMessage *m)
1190{ 1229{
1191 const struct PongMessage *m; 1230 struct GSC_KeyExchangeInfo *kx = cls;
1192 struct PongMessage t; 1231 struct PongMessage t;
1193 struct GNUNET_CRYPTO_SymmetricInitializationVector iv; 1232 struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
1194 uint16_t msize;
1195 1233
1196 msize = ntohs (msg->size);
1197 if (sizeof (struct PongMessage) != msize)
1198 {
1199 GNUNET_break_op (0);
1200 return;
1201 }
1202 GNUNET_STATISTICS_update (GSC_stats, 1234 GNUNET_STATISTICS_update (GSC_stats,
1203 gettext_noop ("# PONG messages received"), 1235 gettext_noop ("# PONG messages received"),
1204 1, 1236 1,
@@ -1225,10 +1257,9 @@ GSC_KX_handle_pong (struct GSC_KeyExchangeInfo *kx,
1225 GNUNET_break (0); 1257 GNUNET_break (0);
1226 return; 1258 return;
1227 } 1259 }
1228 m = (const struct PongMessage *) msg;
1229 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1260 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1230 "Core service receives PONG response from `%s'.\n", 1261 "Core service receives PONG response from `%s'.\n",
1231 GNUNET_i2s (&kx->peer)); 1262 GNUNET_i2s (kx->peer));
1232 /* mark as garbage, just to be sure */ 1263 /* mark as garbage, just to be sure */
1233 memset (&t, 255, sizeof (t)); 1264 memset (&t, 255, sizeof (t));
1234 derive_pong_iv (&iv, 1265 derive_pong_iv (&iv,
@@ -1252,14 +1283,14 @@ GSC_KX_handle_pong (struct GSC_KeyExchangeInfo *kx,
1252 1, 1283 1,
1253 GNUNET_NO); 1284 GNUNET_NO);
1254 if ((0 != memcmp (&t.target, 1285 if ((0 != memcmp (&t.target,
1255 &kx->peer, 1286 kx->peer,
1256 sizeof (struct GNUNET_PeerIdentity))) || 1287 sizeof (struct GNUNET_PeerIdentity))) ||
1257 (kx->ping_challenge != t.challenge)) 1288 (kx->ping_challenge != t.challenge))
1258 { 1289 {
1259 /* PONG malformed */ 1290 /* PONG malformed */
1260 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1291 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1261 "Received malformed PONG wanted sender `%s' with challenge %u\n", 1292 "Received malformed PONG wanted sender `%s' with challenge %u\n",
1262 GNUNET_i2s (&kx->peer), 1293 GNUNET_i2s (kx->peer),
1263 (unsigned int) kx->ping_challenge); 1294 (unsigned int) kx->ping_challenge);
1264 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1295 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1265 "Received malformed PONG received from `%s' with challenge %u\n", 1296 "Received malformed PONG received from `%s' with challenge %u\n",
@@ -1269,7 +1300,7 @@ GSC_KX_handle_pong (struct GSC_KeyExchangeInfo *kx,
1269 } 1300 }
1270 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1301 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1271 "Received PONG from `%s'\n", 1302 "Received PONG from `%s'\n",
1272 GNUNET_i2s (&kx->peer)); 1303 GNUNET_i2s (kx->peer));
1273 /* no need to resend key any longer */ 1304 /* no need to resend key any longer */
1274 if (NULL != kx->retry_set_key_task) 1305 if (NULL != kx->retry_set_key_task)
1275 { 1306 {
@@ -1291,7 +1322,7 @@ GSC_KX_handle_pong (struct GSC_KeyExchangeInfo *kx,
1291 GNUNET_NO); 1322 GNUNET_NO);
1292 kx->status = GNUNET_CORE_KX_STATE_UP; 1323 kx->status = GNUNET_CORE_KX_STATE_UP;
1293 monitor_notify_all (kx); 1324 monitor_notify_all (kx);
1294 GSC_SESSIONS_create (&kx->peer, kx); 1325 GSC_SESSIONS_create (kx->peer, kx);
1295 GNUNET_assert (NULL == kx->keep_alive_task); 1326 GNUNET_assert (NULL == kx->keep_alive_task);
1296 update_timeout (kx); 1327 update_timeout (kx);
1297 break; 1328 break;
@@ -1326,6 +1357,8 @@ GSC_KX_handle_pong (struct GSC_KeyExchangeInfo *kx,
1326static void 1357static void
1327send_key (struct GSC_KeyExchangeInfo *kx) 1358send_key (struct GSC_KeyExchangeInfo *kx)
1328{ 1359{
1360 struct GNUNET_MQ_Envelope *env;
1361
1329 GNUNET_assert (GNUNET_CORE_KX_STATE_DOWN != kx->status); 1362 GNUNET_assert (GNUNET_CORE_KX_STATE_DOWN != kx->status);
1330 if (NULL != kx->retry_set_key_task) 1363 if (NULL != kx->retry_set_key_task)
1331 { 1364 {
@@ -1335,12 +1368,12 @@ send_key (struct GSC_KeyExchangeInfo *kx)
1335 /* always update sender status in SET KEY message */ 1368 /* always update sender status in SET KEY message */
1336 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1369 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1337 "Sending key to `%s' (my status: %d)\n", 1370 "Sending key to `%s' (my status: %d)\n",
1338 GNUNET_i2s (&kx->peer), 1371 GNUNET_i2s (kx->peer),
1339 kx->status); 1372 kx->status);
1340 current_ekm.sender_status = htonl ((int32_t) (kx->status)); 1373 current_ekm.sender_status = htonl ((int32_t) (kx->status));
1341 GSC_NEIGHBOURS_transmit (&kx->peer, 1374 env = GNUNET_MQ_msg_copy (&current_ekm.header);
1342 &current_ekm.header, 1375 GNUNET_MQ_send (kx->mq,
1343 kx->set_key_retry_frequency); 1376 env);
1344 if (GNUNET_CORE_KX_STATE_KEY_SENT != kx->status) 1377 if (GNUNET_CORE_KX_STATE_KEY_SENT != kx->status)
1345 send_ping (kx); 1378 send_ping (kx);
1346 kx->retry_set_key_task = 1379 kx->retry_set_key_task =
@@ -1364,9 +1397,9 @@ GSC_KX_encrypt_and_transmit (struct GSC_KeyExchangeInfo *kx,
1364{ 1397{
1365 size_t used = payload_size + sizeof (struct EncryptedMessage); 1398 size_t used = payload_size + sizeof (struct EncryptedMessage);
1366 char pbuf[used]; /* plaintext */ 1399 char pbuf[used]; /* plaintext */
1367 char cbuf[used]; /* ciphertext */
1368 struct EncryptedMessage *em; /* encrypted message */ 1400 struct EncryptedMessage *em; /* encrypted message */
1369 struct EncryptedMessage *ph; /* plaintext header */ 1401 struct EncryptedMessage *ph; /* plaintext header */
1402 struct GNUNET_MQ_Envelope *env;
1370 struct GNUNET_CRYPTO_SymmetricInitializationVector iv; 1403 struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
1371 struct GNUNET_CRYPTO_AuthKey auth_key; 1404 struct GNUNET_CRYPTO_AuthKey auth_key;
1372 1405
@@ -1376,17 +1409,16 @@ GSC_KX_encrypt_and_transmit (struct GSC_KeyExchangeInfo *kx,
1376 ph->reserved = 0; 1409 ph->reserved = 0;
1377 ph->timestamp = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get ()); 1410 ph->timestamp = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get ());
1378 GNUNET_memcpy (&ph[1], 1411 GNUNET_memcpy (&ph[1],
1379 payload, 1412 payload,
1380 payload_size); 1413 payload_size);
1381 1414 env = GNUNET_MQ_msg_extra (em,
1382 em = (struct EncryptedMessage *) cbuf; 1415 payload_size,
1383 em->header.size = htons (used); 1416 GNUNET_MESSAGE_TYPE_CORE_ENCRYPTED_MESSAGE);
1384 em->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_ENCRYPTED_MESSAGE);
1385 em->iv_seed = ph->iv_seed; 1417 em->iv_seed = ph->iv_seed;
1386 derive_iv (&iv, 1418 derive_iv (&iv,
1387 &kx->encrypt_key, 1419 &kx->encrypt_key,
1388 ph->iv_seed, 1420 ph->iv_seed,
1389 &kx->peer); 1421 kx->peer);
1390 GNUNET_assert (GNUNET_OK == 1422 GNUNET_assert (GNUNET_OK ==
1391 do_encrypt (kx, 1423 do_encrypt (kx,
1392 &iv, 1424 &iv,
@@ -1396,7 +1428,7 @@ GSC_KX_encrypt_and_transmit (struct GSC_KeyExchangeInfo *kx,
1396 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1428 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1397 "Encrypted %u bytes for %s\n", 1429 "Encrypted %u bytes for %s\n",
1398 (unsigned int) (used - ENCRYPTED_HEADER_SIZE), 1430 (unsigned int) (used - ENCRYPTED_HEADER_SIZE),
1399 GNUNET_i2s (&kx->peer)); 1431 GNUNET_i2s (kx->peer));
1400 derive_auth_key (&auth_key, 1432 derive_auth_key (&auth_key,
1401 &kx->encrypt_key, 1433 &kx->encrypt_key,
1402 ph->iv_seed); 1434 ph->iv_seed);
@@ -1404,9 +1436,8 @@ GSC_KX_encrypt_and_transmit (struct GSC_KeyExchangeInfo *kx,
1404 &em->sequence_number, 1436 &em->sequence_number,
1405 used - ENCRYPTED_HEADER_SIZE, 1437 used - ENCRYPTED_HEADER_SIZE,
1406 &em->hmac); 1438 &em->hmac);
1407 GSC_NEIGHBOURS_transmit (&kx->peer, 1439 GNUNET_MQ_send (kx->mq,
1408 &em->header, 1440 env);
1409 GNUNET_TIME_UNIT_FOREVER_REL);
1410} 1441}
1411 1442
1412 1443
@@ -1429,17 +1460,40 @@ struct DeliverMessageContext
1429 1460
1430 1461
1431/** 1462/**
1463 * We received an encrypted message. Check that it is
1464 * well-formed (size-wise).
1465 *
1466 * @param cls key exchange context for encrypting the message
1467 * @param m encrypted message
1468 * @return #GNUNET_OK if @a msg is well-formed (size-wise)
1469 */
1470static int
1471check_encrypted (void *cls,
1472 const struct EncryptedMessage *m)
1473{
1474 uint16_t size = ntohs (m->header.size) - sizeof (*m);
1475
1476 if (size < sizeof (struct GNUNET_MessageHeader))
1477 {
1478 GNUNET_break_op (0);
1479 return GNUNET_SYSERR;
1480 }
1481 return GNUNET_OK;
1482}
1483
1484
1485/**
1432 * We received an encrypted message. Decrypt, validate and 1486 * We received an encrypted message. Decrypt, validate and
1433 * pass on to the appropriate clients. 1487 * pass on to the appropriate clients.
1434 * 1488 *
1435 * @param kx key exchange context for encrypting the message 1489 * @param cls key exchange context for encrypting the message
1436 * @param msg encrypted message 1490 * @param m encrypted message
1437 */ 1491 */
1438void 1492static void
1439GSC_KX_handle_encrypted_message (struct GSC_KeyExchangeInfo *kx, 1493handle_encrypted (void *cls,
1440 const struct GNUNET_MessageHeader *msg) 1494 const struct EncryptedMessage *m)
1441{ 1495{
1442 const struct EncryptedMessage *m; 1496 struct GSC_KeyExchangeInfo *kx = cls;
1443 struct EncryptedMessage *pt; /* plaintext */ 1497 struct EncryptedMessage *pt; /* plaintext */
1444 struct GNUNET_HashCode ph; 1498 struct GNUNET_HashCode ph;
1445 uint32_t snum; 1499 uint32_t snum;
@@ -1447,16 +1501,9 @@ GSC_KX_handle_encrypted_message (struct GSC_KeyExchangeInfo *kx,
1447 struct GNUNET_CRYPTO_SymmetricInitializationVector iv; 1501 struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
1448 struct GNUNET_CRYPTO_AuthKey auth_key; 1502 struct GNUNET_CRYPTO_AuthKey auth_key;
1449 struct DeliverMessageContext dmc; 1503 struct DeliverMessageContext dmc;
1450 uint16_t size = ntohs (msg->size); 1504 uint16_t size = ntohs (m->header.size);
1451 char buf[size] GNUNET_ALIGN; 1505 char buf[size] GNUNET_ALIGN;
1452 1506
1453 if (size <
1454 sizeof (struct EncryptedMessage) + sizeof (struct GNUNET_MessageHeader))
1455 {
1456 GNUNET_break_op (0);
1457 return;
1458 }
1459 m = (const struct EncryptedMessage *) msg;
1460 if (GNUNET_CORE_KX_STATE_UP != kx->status) 1507 if (GNUNET_CORE_KX_STATE_UP != kx->status)
1461 { 1508 {
1462 GNUNET_STATISTICS_update (GSC_stats, 1509 GNUNET_STATISTICS_update (GSC_stats,
@@ -1469,11 +1516,11 @@ GSC_KX_handle_encrypted_message (struct GSC_KeyExchangeInfo *kx,
1469 { 1516 {
1470 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 1517 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1471 _("Session to peer `%s' went down due to key expiration (should not happen)\n"), 1518 _("Session to peer `%s' went down due to key expiration (should not happen)\n"),
1472 GNUNET_i2s (&kx->peer)); 1519 GNUNET_i2s (kx->peer));
1473 GNUNET_STATISTICS_update (GSC_stats, 1520 GNUNET_STATISTICS_update (GSC_stats,
1474 gettext_noop ("# sessions terminated by key expiration"), 1521 gettext_noop ("# sessions terminated by key expiration"),
1475 1, GNUNET_NO); 1522 1, GNUNET_NO);
1476 GSC_SESSIONS_end (&kx->peer); 1523 GSC_SESSIONS_end (kx->peer);
1477 if (NULL != kx->keep_alive_task) 1524 if (NULL != kx->keep_alive_task)
1478 { 1525 {
1479 GNUNET_SCHEDULER_cancel (kx->keep_alive_task); 1526 GNUNET_SCHEDULER_cancel (kx->keep_alive_task);
@@ -1500,7 +1547,7 @@ GSC_KX_handle_encrypted_message (struct GSC_KeyExchangeInfo *kx,
1500 /* checksum failed */ 1547 /* checksum failed */
1501 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1548 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1502 "Failed checksum validation for a message from `%s'\n", 1549 "Failed checksum validation for a message from `%s'\n",
1503 GNUNET_i2s (&kx->peer)); 1550 GNUNET_i2s (kx->peer));
1504 return; 1551 return;
1505 } 1552 }
1506 derive_iv (&iv, 1553 derive_iv (&iv,
@@ -1518,7 +1565,7 @@ GSC_KX_handle_encrypted_message (struct GSC_KeyExchangeInfo *kx,
1518 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1565 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1519 "Decrypted %u bytes from %s\n", 1566 "Decrypted %u bytes from %s\n",
1520 (unsigned int) (size - ENCRYPTED_HEADER_SIZE), 1567 (unsigned int) (size - ENCRYPTED_HEADER_SIZE),
1521 GNUNET_i2s (&kx->peer)); 1568 GNUNET_i2s (kx->peer));
1522 pt = (struct EncryptedMessage *) buf; 1569 pt = (struct EncryptedMessage *) buf;
1523 1570
1524 /* validate sequence number */ 1571 /* validate sequence number */
@@ -1596,9 +1643,10 @@ GSC_KX_handle_encrypted_message (struct GSC_KeyExchangeInfo *kx,
1596 size - sizeof (struct EncryptedMessage), 1643 size - sizeof (struct EncryptedMessage),
1597 GNUNET_NO); 1644 GNUNET_NO);
1598 dmc.kx = kx; 1645 dmc.kx = kx;
1599 dmc.peer = &kx->peer; 1646 dmc.peer = kx->peer;
1600 if (GNUNET_OK != 1647 if (GNUNET_OK !=
1601 GNUNET_SERVER_mst_receive (mst, &dmc, 1648 GNUNET_SERVER_mst_receive (mst,
1649 &dmc,
1602 &buf[sizeof (struct EncryptedMessage)], 1650 &buf[sizeof (struct EncryptedMessage)],
1603 size - sizeof (struct EncryptedMessage), 1651 size - sizeof (struct EncryptedMessage),
1604 GNUNET_YES, 1652 GNUNET_YES,
@@ -1608,44 +1656,31 @@ GSC_KX_handle_encrypted_message (struct GSC_KeyExchangeInfo *kx,
1608 1656
1609 1657
1610/** 1658/**
1611 * Obtain the array of message handlers provided by KX. 1659 * One of our neighbours has excess bandwidth, remember this.
1612 * 1660 *
1613 * @return NULL-entry terminated array of handlers 1661 * @param cls NULL
1662 * @param pid identity of the peer with excess bandwidth
1663 * @param connect_cls the `struct Neighbour`
1614 */ 1664 */
1615const struct GNUNET_MQ_MessageHandler * 1665static void
1616GSC_KX_get_handlers (void) 1666handle_transport_notify_excess_bw (void *cls,
1667 const struct GNUNET_PeerIdentity *pid,
1668 void *connect_cls)
1617{ 1669{
1618#if 0 1670 struct GSC_KeyExchangeInfo *kx = connect_cls;
1619 GNUNET_MQ_hd_fixed_size (ephemeral_key, 1671
1620 GNUNET_MESSAGE_TYPE_CORE_EPHEMERAL_KEY, 1672 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1621 struct EphemeralKeyMessage); 1673 "Peer %s has excess bandwidth available\n",
1622 GNUNET_MQ_hd_fixed_size (ping, 1674 GNUNET_i2s (pid));
1623 PING, 1675 kx->has_excess_bandwidth = GNUNET_YES;
1624 struct PingMessage); 1676 GSC_SESSIONS_solicit (pid);
1625 GNUNET_MQ_hd_fixed_size (pong,
1626 PING,
1627 struct PongMessage);
1628 GNUNET_MQ_hd_var_size (encrypted,
1629 PING,
1630 struct ping);
1631#endif
1632 static struct GNUNET_MQ_MessageHandler handlers[] = {
1633#if 0
1634 make_ephemeral_key_handler (),
1635 make_ping_handler (),
1636 make_pong_handler (),
1637 make_encrypted_handler (),
1638#endif
1639 GNUNET_MQ_handler_end()
1640 };
1641 return handlers;
1642} 1677}
1643 1678
1644 1679
1645/** 1680/**
1646 * Deliver P2P message to interested clients. 1681 * Deliver P2P message to interested clients. Invokes send twice,
1647 * Invokes send twice, once for clients that want the full message, and once 1682 * once for clients that want the full message, and once for clients
1648 * for clients that only want the header 1683 * that only want the header
1649 * 1684 *
1650 * @param cls always NULL 1685 * @param cls always NULL
1651 * @param client who sent us the message (struct GSC_KeyExchangeInfo) 1686 * @param client who sent us the message (struct GSC_KeyExchangeInfo)
@@ -1778,11 +1813,31 @@ int
1778GSC_KX_init (struct GNUNET_CRYPTO_EddsaPrivateKey *pk, 1813GSC_KX_init (struct GNUNET_CRYPTO_EddsaPrivateKey *pk,
1779 struct GNUNET_SERVER_Handle *server) 1814 struct GNUNET_SERVER_Handle *server)
1780{ 1815{
1816 GNUNET_MQ_hd_fixed_size (ephemeral_key,
1817 GNUNET_MESSAGE_TYPE_CORE_EPHEMERAL_KEY,
1818 struct EphemeralKeyMessage);
1819 GNUNET_MQ_hd_fixed_size (ping,
1820 GNUNET_MESSAGE_TYPE_CORE_PING,
1821 struct PingMessage);
1822 GNUNET_MQ_hd_fixed_size (pong,
1823 GNUNET_MESSAGE_TYPE_CORE_PONG,
1824 struct PongMessage);
1825 GNUNET_MQ_hd_var_size (encrypted,
1826 GNUNET_MESSAGE_TYPE_CORE_ENCRYPTED_MESSAGE,
1827 struct EncryptedMessage);
1828 struct GNUNET_MQ_MessageHandler handlers[] = {
1829 make_ephemeral_key_handler (NULL),
1830 make_ping_handler (NULL),
1831 make_pong_handler (NULL),
1832 make_encrypted_handler (NULL),
1833 GNUNET_MQ_handler_end()
1834 };
1835
1781 nc = GNUNET_SERVER_notification_context_create (server, 1836 nc = GNUNET_SERVER_notification_context_create (server,
1782 1); 1837 1);
1783 my_private_key = pk; 1838 my_private_key = pk;
1784 GNUNET_CRYPTO_eddsa_key_get_public (my_private_key, 1839 GNUNET_CRYPTO_eddsa_key_get_public (my_private_key,
1785 &GSC_my_identity.public_key); 1840 &GSC_my_identity.public_key);
1786 my_ephemeral_key = GNUNET_CRYPTO_ecdhe_key_create (); 1841 my_ephemeral_key = GNUNET_CRYPTO_ecdhe_key_create ();
1787 if (NULL == my_ephemeral_key) 1842 if (NULL == my_ephemeral_key)
1788 { 1843 {
@@ -1796,6 +1851,19 @@ GSC_KX_init (struct GNUNET_CRYPTO_EddsaPrivateKey *pk,
1796 &do_rekey, 1851 &do_rekey,
1797 NULL); 1852 NULL);
1798 mst = GNUNET_SERVER_mst_create (&deliver_message, NULL); 1853 mst = GNUNET_SERVER_mst_create (&deliver_message, NULL);
1854 transport
1855 = GNUNET_TRANSPORT_core_connect (GSC_cfg,
1856 &GSC_my_identity,
1857 handlers,
1858 NULL,
1859 &handle_transport_notify_connect,
1860 &handle_transport_notify_disconnect,
1861 &handle_transport_notify_excess_bw);
1862 if (NULL == transport)
1863 {
1864 GSC_KX_done ();
1865 return GNUNET_SYSERR;
1866 }
1799 return GNUNET_OK; 1867 return GNUNET_OK;
1800} 1868}
1801 1869
@@ -1806,6 +1874,11 @@ GSC_KX_init (struct GNUNET_CRYPTO_EddsaPrivateKey *pk,
1806void 1874void
1807GSC_KX_done () 1875GSC_KX_done ()
1808{ 1876{
1877 if (NULL != transport)
1878 {
1879 GNUNET_TRANSPORT_core_disconnect (transport);
1880 transport = NULL;
1881 }
1809 if (NULL != rekey_task) 1882 if (NULL != rekey_task)
1810 { 1883 {
1811 GNUNET_SCHEDULER_cancel (rekey_task); 1884 GNUNET_SCHEDULER_cancel (rekey_task);
@@ -1834,6 +1907,32 @@ GSC_KX_done ()
1834} 1907}
1835 1908
1836 1909
1910 /**
1911 * Check how many messages are queued for the given neighbour.
1912 *
1913 * @param kxinfo data about neighbour to check
1914 * @return number of items in the message queue
1915 */
1916unsigned int
1917GSC_NEIGHBOURS_get_queue_length (const struct GSC_KeyExchangeInfo *kxinfo)
1918{
1919 return GNUNET_MQ_get_length (kxinfo->mq);
1920}
1921
1922
1923/**
1924 * Check if the given neighbour has excess bandwidth available.
1925 *
1926 * @param target neighbour to check
1927 * @return #GNUNET_YES if excess bandwidth is available, #GNUNET_NO if not
1928 */
1929int
1930GSC_NEIGHBOURS_check_excess_bandwidth (const struct GSC_KeyExchangeInfo *kxinfo)
1931{
1932 return kxinfo->has_excess_bandwidth;
1933}
1934
1935
1837/** 1936/**
1838 * Handle #GNUNET_MESSAGE_TYPE_CORE_MONITOR_PEERS request. For this 1937 * Handle #GNUNET_MESSAGE_TYPE_CORE_MONITOR_PEERS request. For this
1839 * request type, the client does not have to have transmitted an INIT 1938 * request type, the client does not have to have transmitted an INIT
@@ -1860,7 +1959,9 @@ GSC_KX_handle_client_monitor_peers (void *cls,
1860 done_msg.header.size = htons (sizeof (struct MonitorNotifyMessage)); 1959 done_msg.header.size = htons (sizeof (struct MonitorNotifyMessage));
1861 done_msg.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_MONITOR_NOTIFY); 1960 done_msg.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_MONITOR_NOTIFY);
1862 done_msg.state = htonl ((uint32_t) GNUNET_CORE_KX_ITERATION_FINISHED); 1961 done_msg.state = htonl ((uint32_t) GNUNET_CORE_KX_ITERATION_FINISHED);
1863 memset (&done_msg.peer, 0, sizeof (struct GNUNET_PeerIdentity)); 1962 memset (&done_msg.peer,
1963 0,
1964 sizeof (struct GNUNET_PeerIdentity));
1864 done_msg.timeout = GNUNET_TIME_absolute_hton (GNUNET_TIME_UNIT_FOREVER_ABS); 1965 done_msg.timeout = GNUNET_TIME_absolute_hton (GNUNET_TIME_UNIT_FOREVER_ABS);
1865 GNUNET_SERVER_notification_context_unicast (nc, 1966 GNUNET_SERVER_notification_context_unicast (nc,
1866 client, 1967 client,