diff options
author | Christian Grothoff <christian@grothoff.org> | 2016-07-26 21:12:56 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2016-07-26 21:12:56 +0000 |
commit | 8c2dc7d19810d58f23c43bf900e2fb3eebe06fed (patch) | |
tree | 9173a966e2f51a34d9259a0126484e05d44dcaac /src/core/gnunet-service-core_kx.c | |
parent | a89ea716333ad5ad43757a946efc01cb5e95a0c0 (diff) | |
download | gnunet-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.c | 465 |
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 | */ | ||
356 | static struct GNUNET_TRANSPORT_CoreHandle *transport; | ||
357 | |||
358 | /** | ||
342 | * Our private key. | 359 | * Our private key. |
343 | */ | 360 | */ |
344 | static struct GNUNET_CRYPTO_EddsaPrivateKey *my_private_key; | 361 | static 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 | */ |
708 | struct GSC_KeyExchangeInfo * | 739 | static void * |
709 | GSC_KX_start (const struct GNUNET_PeerIdentity *pid) | 740 | handle_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 | */ |
762 | void | 800 | static void |
763 | GSC_KX_stop (struct GSC_KeyExchangeInfo *kx) | 801 | handle_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) | |||
792 | static void | 839 | static void |
793 | send_ping (struct GSC_KeyExchangeInfo *kx) | 840 | send_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 | */ |
846 | void | 895 | static void |
847 | GSC_KX_handle_ephemeral_key (struct GSC_KeyExchangeInfo *kx, | 896 | handle_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 | */ |
1012 | void | 1053 | static void |
1013 | GSC_KX_handle_ping (struct GSC_KeyExchangeInfo *kx, | 1054 | handle_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 | */ |
1187 | void | 1226 | static void |
1188 | GSC_KX_handle_pong (struct GSC_KeyExchangeInfo *kx, | 1227 | handle_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, | |||
1326 | static void | 1357 | static void |
1327 | send_key (struct GSC_KeyExchangeInfo *kx) | 1358 | send_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 (¤t_ekm.header); |
1342 | ¤t_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 | */ | ||
1470 | static int | ||
1471 | check_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 | */ |
1438 | void | 1492 | static void |
1439 | GSC_KX_handle_encrypted_message (struct GSC_KeyExchangeInfo *kx, | 1493 | handle_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 | */ |
1615 | const struct GNUNET_MQ_MessageHandler * | 1665 | static void |
1616 | GSC_KX_get_handlers (void) | 1666 | handle_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 | |||
1778 | GSC_KX_init (struct GNUNET_CRYPTO_EddsaPrivateKey *pk, | 1813 | GSC_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, | |||
1806 | void | 1874 | void |
1807 | GSC_KX_done () | 1875 | GSC_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 | */ | ||
1916 | unsigned int | ||
1917 | GSC_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 | */ | ||
1929 | int | ||
1930 | GSC_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, |