aboutsummaryrefslogtreecommitdiff
path: root/src/core
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
parenta89ea716333ad5ad43757a946efc01cb5e95a0c0 (diff)
downloadgnunet-8c2dc7d19810d58f23c43bf900e2fb3eebe06fed.tar.gz
gnunet-8c2dc7d19810d58f23c43bf900e2fb3eebe06fed.zip
-converting CORE service to new transport MQ API
Diffstat (limited to 'src/core')
-rw-r--r--src/core/Makefile.am5
-rw-r--r--src/core/core_api.c29
-rw-r--r--src/core/gnunet-service-core.c22
-rw-r--r--src/core/gnunet-service-core_clients.c26
-rw-r--r--src/core/gnunet-service-core_kx.c465
-rw-r--r--src/core/gnunet-service-core_kx.h96
-rw-r--r--src/core/gnunet-service-core_neighbours.c679
-rw-r--r--src/core/gnunet-service-core_neighbours.h83
-rw-r--r--src/core/gnunet-service-core_sessions.c74
-rw-r--r--src/core/test_core_api_data.conf1
-rw-r--r--src/core/test_core_api_reliability.c82
-rw-r--r--src/core/test_core_api_start_only.c117
-rw-r--r--src/core/test_core_defaults.conf1
-rw-r--r--src/core/test_core_quota_compliance.c302
14 files changed, 718 insertions, 1264 deletions
diff --git a/src/core/Makefile.am b/src/core/Makefile.am
index be855b453..3437aa43a 100644
--- a/src/core/Makefile.am
+++ b/src/core/Makefile.am
@@ -42,7 +42,6 @@ bin_PROGRAMS = \
42gnunet_service_core_SOURCES = \ 42gnunet_service_core_SOURCES = \
43 gnunet-service-core.c gnunet-service-core.h \ 43 gnunet-service-core.c gnunet-service-core.h \
44 gnunet-service-core_clients.c gnunet-service-core_clients.h \ 44 gnunet-service-core_clients.c gnunet-service-core_clients.h \
45 gnunet-service-core_neighbours.c gnunet-service-core_neighbours.h \
46 gnunet-service-core_kx.c gnunet-service-core_kx.h \ 45 gnunet-service-core_kx.c gnunet-service-core_kx.h \
47 gnunet-service-core_sessions.c gnunet-service-core_sessions.h \ 46 gnunet-service-core_sessions.c gnunet-service-core_sessions.h \
48 gnunet-service-core_typemap.c gnunet-service-core_typemap.h 47 gnunet-service-core_typemap.c gnunet-service-core_typemap.h
@@ -60,7 +59,9 @@ gnunet_core_LDADD = \
60 $(top_builddir)/src/util/libgnunetutil.la 59 $(top_builddir)/src/util/libgnunetutil.la
61 60
62if HAVE_TESTING 61if HAVE_TESTING
63 TESTING_TESTS = test_core_api_send_to_self test_core_api_mq 62 TESTING_TESTS = \
63 test_core_api_send_to_self \
64 test_core_api_mq
64endif 65endif
65 66
66check_PROGRAMS = \ 67check_PROGRAMS = \
diff --git a/src/core/core_api.c b/src/core/core_api.c
index dd912ac22..caf614afc 100644
--- a/src/core/core_api.c
+++ b/src/core/core_api.c
@@ -674,6 +674,8 @@ handle_send_ready (void *cls,
674 struct GNUNET_TIME_Relative delay; 674 struct GNUNET_TIME_Relative delay;
675 struct GNUNET_TIME_Relative overdue; 675 struct GNUNET_TIME_Relative overdue;
676 unsigned int ret; 676 unsigned int ret;
677 unsigned int priority;
678 int cork;
677 679
678 GNUNET_break (GNUNET_NO == h->currently_down); 680 GNUNET_break (GNUNET_NO == h->currently_down);
679 pr = GNUNET_CONTAINER_multipeermap_get (h->peers, 681 pr = GNUNET_CONTAINER_multipeermap_get (h->peers,
@@ -708,11 +710,12 @@ handle_send_ready (void *cls,
708 sm->priority = htonl ((uint32_t) th->priority); 710 sm->priority = htonl ((uint32_t) th->priority);
709 sm->deadline = GNUNET_TIME_absolute_hton (th->deadline); 711 sm->deadline = GNUNET_TIME_absolute_hton (th->deadline);
710 sm->peer = pr->peer; 712 sm->peer = pr->peer;
711 sm->cork = htonl ((uint32_t) th->cork); 713 sm->cork = htonl ((uint32_t) (cork = th->cork));
712 sm->reserved = htonl (0); 714 sm->reserved = htonl (0);
713 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 715 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
714 "Calling get_message with buffer of %u bytes\n", 716 "Calling get_message with buffer of %u bytes (%s)\n",
715 (unsigned int) th->msize); 717 (unsigned int) th->msize,
718 cork ? "corked" : "uncorked");
716 /* FIXME: this is ugly and a bit brutal, but "get_message" 719 /* FIXME: this is ugly and a bit brutal, but "get_message"
717 may call GNUNET_CORE_notify_transmit_ready() which 720 may call GNUNET_CORE_notify_transmit_ready() which
718 may call GNUNET_MQ_send() as well, and we MUST get this 721 may call GNUNET_MQ_send() as well, and we MUST get this
@@ -725,30 +728,33 @@ handle_send_ready (void *cls,
725 be required */ 728 be required */
726 GNUNET_MQ_send (h->mq, 729 GNUNET_MQ_send (h->mq,
727 env); 730 env);
731 delay = GNUNET_TIME_absolute_get_duration (th->request_time);
732 overdue = GNUNET_TIME_absolute_get_duration (th->deadline);
733 priority = th->priority;
728 ret = th->get_message (th->get_message_cls, 734 ret = th->get_message (th->get_message_cls,
729 th->msize, 735 th->msize,
730 &sm[1]); 736 &sm[1]);
737 /* after this point, 'th' should not be used anymore, it
738 may now be about another message! */
731 sm->header.size = htons (ret + sizeof (struct SendMessage)); 739 sm->header.size = htons (ret + sizeof (struct SendMessage));
732 delay = GNUNET_TIME_absolute_get_duration (th->request_time);
733 overdue = GNUNET_TIME_absolute_get_duration (th->deadline);
734 if (overdue.rel_value_us > GNUNET_CONSTANTS_LATENCY_WARN.rel_value_us) 740 if (overdue.rel_value_us > GNUNET_CONSTANTS_LATENCY_WARN.rel_value_us)
735 LOG (GNUNET_ERROR_TYPE_WARNING, 741 LOG (GNUNET_ERROR_TYPE_WARNING,
736 "Transmitting overdue %u bytes to `%s' at priority %u with %s delay %s\n", 742 "Transmitting overdue %u bytes to `%s' at priority %u with %s delay %s\n",
737 ret, 743 ret,
738 GNUNET_i2s (&pr->peer), 744 GNUNET_i2s (&pr->peer),
739 (unsigned int) th->priority, 745 priority,
740 GNUNET_STRINGS_relative_time_to_string (delay, 746 GNUNET_STRINGS_relative_time_to_string (delay,
741 GNUNET_YES), 747 GNUNET_YES),
742 (th->cork) ? " (corked)" : ""); 748 (cork) ? " (corked)" : " (uncorked)");
743 else 749 else
744 LOG (GNUNET_ERROR_TYPE_DEBUG, 750 LOG (GNUNET_ERROR_TYPE_DEBUG,
745 "Transmitting %u bytes to `%s' at priority %u with %s delay %s\n", 751 "Transmitting %u bytes to `%s' at priority %u with %s delay %s\n",
746 ret, 752 ret,
747 GNUNET_i2s (&pr->peer), 753 GNUNET_i2s (&pr->peer),
748 (unsigned int) th->priority, 754 priority,
749 GNUNET_STRINGS_relative_time_to_string (delay, 755 GNUNET_STRINGS_relative_time_to_string (delay,
750 GNUNET_YES), 756 GNUNET_YES),
751 (th->cork) ? " (corked)" : ""); 757 (cork) ? " (corked)" : " (uncorked)");
752} 758}
753 759
754 760
@@ -995,9 +1001,10 @@ GNUNET_CORE_notify_transmit_ready (struct GNUNET_CORE_Handle *handle,
995 return NULL; 1001 return NULL;
996 } 1002 }
997 LOG (GNUNET_ERROR_TYPE_DEBUG, 1003 LOG (GNUNET_ERROR_TYPE_DEBUG,
998 "Asking core for transmission of %u bytes to `%s'\n", 1004 "Asking core for transmission of %u bytes to `%s'%s\n",
999 (unsigned int) notify_size, 1005 (unsigned int) notify_size,
1000 GNUNET_i2s (target)); 1006 GNUNET_i2s (target),
1007 cork ? " (corked)" : "");
1001 pr = GNUNET_CONTAINER_multipeermap_get (handle->peers, 1008 pr = GNUNET_CONTAINER_multipeermap_get (handle->peers,
1002 target); 1009 target);
1003 if (NULL == pr) 1010 if (NULL == pr)
diff --git a/src/core/gnunet-service-core.c b/src/core/gnunet-service-core.c
index 70b83b24c..f9391e616 100644
--- a/src/core/gnunet-service-core.c
+++ b/src/core/gnunet-service-core.c
@@ -29,7 +29,6 @@
29#include "gnunet-service-core.h" 29#include "gnunet-service-core.h"
30#include "gnunet-service-core_clients.h" 30#include "gnunet-service-core_clients.h"
31#include "gnunet-service-core_kx.h" 31#include "gnunet-service-core_kx.h"
32#include "gnunet-service-core_neighbours.h"
33#include "gnunet-service-core_sessions.h" 32#include "gnunet-service-core_sessions.h"
34#include "gnunet-service-core_typemap.h" 33#include "gnunet-service-core_typemap.h"
35 34
@@ -67,13 +66,13 @@ shutdown_task (void *cls)
67 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 66 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
68 "Core service shutting down.\n"); 67 "Core service shutting down.\n");
69 GSC_CLIENTS_done (); 68 GSC_CLIENTS_done ();
70 GSC_NEIGHBOURS_done ();
71 GSC_SESSIONS_done (); 69 GSC_SESSIONS_done ();
72 GSC_KX_done (); 70 GSC_KX_done ();
73 GSC_TYPEMAP_done (); 71 GSC_TYPEMAP_done ();
74 if (NULL != GSC_stats) 72 if (NULL != GSC_stats)
75 { 73 {
76 GNUNET_STATISTICS_destroy (GSC_stats, GNUNET_NO); 74 GNUNET_STATISTICS_destroy (GSC_stats,
75 GNUNET_NO);
77 GSC_stats = NULL; 76 GSC_stats = NULL;
78 } 77 }
79 GSC_cfg = NULL; 78 GSC_cfg = NULL;
@@ -88,7 +87,8 @@ shutdown_task (void *cls)
88 * @param c configuration to use 87 * @param c configuration to use
89 */ 88 */
90static void 89static void
91run (void *cls, struct GNUNET_SERVER_Handle *server, 90run (void *cls,
91 struct GNUNET_SERVER_Handle *server,
92 const struct GNUNET_CONFIGURATION_Handle *c) 92 const struct GNUNET_CONFIGURATION_Handle *c)
93{ 93{
94 struct GNUNET_CRYPTO_EddsaPrivateKey *pk; 94 struct GNUNET_CRYPTO_EddsaPrivateKey *pk;
@@ -97,7 +97,9 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
97 GSC_cfg = c; 97 GSC_cfg = c;
98 GSC_server = server; 98 GSC_server = server;
99 if (GNUNET_OK != 99 if (GNUNET_OK !=
100 GNUNET_CONFIGURATION_get_value_filename (GSC_cfg, "PEER", "PRIVATE_KEY", 100 GNUNET_CONFIGURATION_get_value_filename (GSC_cfg,
101 "PEER",
102 "PRIVATE_KEY",
101 &keyfile)) 103 &keyfile))
102 { 104 {
103 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 105 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
@@ -105,7 +107,8 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
105 GNUNET_SCHEDULER_shutdown (); 107 GNUNET_SCHEDULER_shutdown ();
106 return; 108 return;
107 } 109 }
108 GSC_stats = GNUNET_STATISTICS_create ("core", GSC_cfg); 110 GSC_stats = GNUNET_STATISTICS_create ("core",
111 GSC_cfg);
109 GNUNET_SCHEDULER_add_shutdown (&shutdown_task, 112 GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
110 NULL); 113 NULL);
111 GNUNET_SERVER_suspend (server); 114 GNUNET_SERVER_suspend (server);
@@ -113,9 +116,8 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
113 pk = GNUNET_CRYPTO_eddsa_key_create_from_file (keyfile); 116 pk = GNUNET_CRYPTO_eddsa_key_create_from_file (keyfile);
114 GNUNET_free (keyfile); 117 GNUNET_free (keyfile);
115 GNUNET_assert (NULL != pk); 118 GNUNET_assert (NULL != pk);
116 if ((GNUNET_OK != GSC_KX_init (pk, 119 if (GNUNET_OK != GSC_KX_init (pk,
117 server)) || 120 server))
118 (GNUNET_OK != GSC_NEIGHBOURS_init ()))
119 { 121 {
120 GNUNET_SCHEDULER_shutdown (); 122 GNUNET_SCHEDULER_shutdown ();
121 return; 123 return;
@@ -124,7 +126,7 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
124 GSC_CLIENTS_init (GSC_server); 126 GSC_CLIENTS_init (GSC_server);
125 GNUNET_SERVER_resume (GSC_server); 127 GNUNET_SERVER_resume (GSC_server);
126 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 128 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
127 _("Core service of `%4s' ready.\n"), 129 _("Core service of `%s' ready.\n"),
128 GNUNET_i2s (&GSC_my_identity)); 130 GNUNET_i2s (&GSC_my_identity));
129} 131}
130 132
diff --git a/src/core/gnunet-service-core_clients.c b/src/core/gnunet-service-core_clients.c
index 3030eb701..2f042dfbf 100644
--- a/src/core/gnunet-service-core_clients.c
+++ b/src/core/gnunet-service-core_clients.c
@@ -29,7 +29,6 @@
29#include "gnunet_transport_service.h" 29#include "gnunet_transport_service.h"
30#include "gnunet-service-core.h" 30#include "gnunet-service-core.h"
31#include "gnunet-service-core_clients.h" 31#include "gnunet-service-core_clients.h"
32#include "gnunet-service-core_neighbours.h"
33#include "gnunet-service-core_sessions.h" 32#include "gnunet-service-core_sessions.h"
34#include "gnunet-service-core_typemap.h" 33#include "gnunet-service-core_typemap.h"
35#include "core.h" 34#include "core.h"
@@ -402,8 +401,8 @@ handle_client_send_request (void *cls,
402 /* dequeue and recycle memory from pending request, there can only 401 /* dequeue and recycle memory from pending request, there can only
403 be at most one per client and peer */ 402 be at most one per client and peer */
404 GNUNET_STATISTICS_update (GSC_stats, 403 GNUNET_STATISTICS_update (GSC_stats,
405 gettext_noop 404 gettext_noop ("# dequeuing CAR (duplicate request)"),
406 ("# dequeuing CAR (duplicate request)"), 1, 405 1,
407 GNUNET_NO); 406 GNUNET_NO);
408 GSC_SESSIONS_dequeue_request (car); 407 GSC_SESSIONS_dequeue_request (car);
409 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 408 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -476,7 +475,8 @@ handle_client_send (void *cls,
476 if (msize < sizeof (struct SendMessage)) 475 if (msize < sizeof (struct SendMessage))
477 { 476 {
478 GNUNET_break (0); 477 GNUNET_break (0);
479 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 478 GNUNET_SERVER_receive_done (client,
479 GNUNET_SYSERR);
480 return; 480 return;
481 } 481 }
482 sm = (const struct SendMessage *) message; 482 sm = (const struct SendMessage *) message;
@@ -487,12 +487,12 @@ handle_client_send (void *cls,
487 { 487 {
488 /* client did not send INIT first! */ 488 /* client did not send INIT first! */
489 GNUNET_break (0); 489 GNUNET_break (0);
490 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 490 GNUNET_SERVER_receive_done (client,
491 GNUNET_SYSERR);
491 return; 492 return;
492 } 493 }
493 tc.car 494 tc.car = GNUNET_CONTAINER_multipeermap_get (c->requests,
494 = GNUNET_CONTAINER_multipeermap_get (c->requests, 495 &sm->peer);
495 &sm->peer);
496 if (NULL == tc.car) 496 if (NULL == tc.car)
497 { 497 {
498 /* Must have been that we first approved the request, then got disconnected 498 /* Must have been that we first approved the request, then got disconnected
@@ -501,9 +501,9 @@ handle_client_send (void *cls,
501 * might also now be *again* connected. So this can happen (but should be 501 * might also now be *again* connected. So this can happen (but should be
502 * rare). If it does happen, the message is discarded. */ 502 * rare). If it does happen, the message is discarded. */
503 GNUNET_STATISTICS_update (GSC_stats, 503 GNUNET_STATISTICS_update (GSC_stats,
504 gettext_noop 504 gettext_noop ("# messages discarded (session disconnected)"),
505 ("# messages discarded (session disconnected)"), 505 1,
506 1, GNUNET_NO); 506 GNUNET_NO);
507 GNUNET_SERVER_receive_done (client, 507 GNUNET_SERVER_receive_done (client,
508 GNUNET_OK); 508 GNUNET_OK);
509 return; 509 return;
@@ -519,7 +519,7 @@ handle_client_send (void *cls,
519 GNUNET_YES), 519 GNUNET_YES),
520 msize, 520 msize,
521 GNUNET_i2s (&sm->peer), 521 GNUNET_i2s (&sm->peer),
522 tc.cork ? "" : " (corked)"); 522 tc.cork ? " (cork)" : " (uncorked)");
523 else 523 else
524 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 524 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
525 "Client waited %s for transmission of %u bytes to `%s'%s\n", 525 "Client waited %s for transmission of %u bytes to `%s'%s\n",
@@ -527,7 +527,7 @@ handle_client_send (void *cls,
527 GNUNET_YES), 527 GNUNET_YES),
528 msize, 528 msize,
529 GNUNET_i2s (&sm->peer), 529 GNUNET_i2s (&sm->peer),
530 tc.cork ? "" : " (corked)"); 530 tc.cork ? " (cork)" : " (uncorked)");
531 531
532 GNUNET_assert (GNUNET_YES == 532 GNUNET_assert (GNUNET_YES ==
533 GNUNET_CONTAINER_multipeermap_remove (c->requests, 533 GNUNET_CONTAINER_multipeermap_remove (c->requests,
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,
diff --git a/src/core/gnunet-service-core_kx.h b/src/core/gnunet-service-core_kx.h
index 7649315ce..8614f090f 100644
--- a/src/core/gnunet-service-core_kx.h
+++ b/src/core/gnunet-service-core_kx.h
@@ -37,50 +37,6 @@ struct GSC_KeyExchangeInfo;
37 37
38 38
39/** 39/**
40 * Obtain the array of message handlers provided by KX.
41 *
42 * @return NULL-entry terminated array of handlers
43 */
44const struct GNUNET_MQ_MessageHandler *
45GSC_KX_get_handlers (void);
46
47
48/**
49 * We received a EPHEMERAL_KEY message. Validate and update
50 * our key material and status.
51 *
52 * @param kx key exchange status for the corresponding peer
53 * @param msg the set key message we received
54 */
55void
56GSC_KX_handle_ephemeral_key (struct GSC_KeyExchangeInfo *kx,
57 const struct GNUNET_MessageHeader *msg);
58
59
60/**
61 * We received a PING message. Validate and transmit
62 * a PONG message.
63 *
64 * @param kx key exchange status for the corresponding peer
65 * @param msg the encrypted PING message itself
66 */
67void
68GSC_KX_handle_ping (struct GSC_KeyExchangeInfo *kx,
69 const struct GNUNET_MessageHeader *msg);
70
71
72/**
73 * We received a PONG message. Validate and update our status.
74 *
75 * @param kx key exchange status for the corresponding peer
76 * @param msg the encrypted PONG message itself
77 */
78void
79GSC_KX_handle_pong (struct GSC_KeyExchangeInfo *kx,
80 const struct GNUNET_MessageHeader *msg);
81
82
83/**
84 * Encrypt and transmit a message with the given payload. 40 * Encrypt and transmit a message with the given payload.
85 * 41 *
86 * @param kx key exchange context 42 * @param kx key exchange context
@@ -89,57 +45,47 @@ GSC_KX_handle_pong (struct GSC_KeyExchangeInfo *kx,
89 */ 45 */
90void 46void
91GSC_KX_encrypt_and_transmit (struct GSC_KeyExchangeInfo *kx, 47GSC_KX_encrypt_and_transmit (struct GSC_KeyExchangeInfo *kx,
92 const void *payload, size_t payload_size); 48 const void *payload,
49 size_t payload_size);
93 50
94 51
95/** 52/**
96 * We received an encrypted message. Decrypt, validate and 53 * Initialize KX subsystem.
97 * pass on to the appropriate clients.
98 *
99 * @param kx key exchange information context
100 * @param msg encrypted message
101 */
102void
103GSC_KX_handle_encrypted_message (struct GSC_KeyExchangeInfo *kx,
104 const struct GNUNET_MessageHeader *msg);
105
106
107/**
108 * Start the key exchange with the given peer.
109 * 54 *
110 * @param pid identity of the peer to do a key exchange with 55 * @param pk private key to use for the peer
111 * @return key exchange information context 56 * @param server the server of the CORE service
57 * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure
112 */ 58 */
113struct GSC_KeyExchangeInfo * 59int
114GSC_KX_start (const struct GNUNET_PeerIdentity *pid); 60GSC_KX_init (struct GNUNET_CRYPTO_EddsaPrivateKey *pk,
61 struct GNUNET_SERVER_Handle *server);
115 62
116 63
117/** 64/**
118 * Stop key exchange with the given peer. Clean up key material. 65 * Shutdown KX subsystem.
119 *
120 * @param kx key exchange to stop
121 */ 66 */
122void 67void
123GSC_KX_stop (struct GSC_KeyExchangeInfo *kx); 68GSC_KX_done (void);
124 69
125 70
126/** 71/**
127 * Initialize KX subsystem. 72 * Check if the given neighbour has excess bandwidth available.
128 * 73 *
129 * @param pk private key to use for the peer 74 * @param target neighbour to check
130 * @param server the server of the CORE service 75 * @return #GNUNET_YES if excess bandwidth is available, #GNUNET_NO if not
131 * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure
132 */ 76 */
133int 77int
134GSC_KX_init (struct GNUNET_CRYPTO_EddsaPrivateKey *pk, 78GSC_NEIGHBOURS_check_excess_bandwidth (const struct GSC_KeyExchangeInfo *target);
135 struct GNUNET_SERVER_Handle *server);
136 79
137 80
138/** 81/**
139 * Shutdown KX subsystem. 82 * Check how many messages are queued for the given neighbour.
83 *
84 * @param target neighbour to check
85 * @return number of items in the message queue
140 */ 86 */
141void 87unsigned int
142GSC_KX_done (void); 88GSC_NEIGHBOURS_get_queue_length (const struct GSC_KeyExchangeInfo *target);
143 89
144 90
145/** 91/**
diff --git a/src/core/gnunet-service-core_neighbours.c b/src/core/gnunet-service-core_neighbours.c
deleted file mode 100644
index 7af49a3b3..000000000
--- a/src/core/gnunet-service-core_neighbours.c
+++ /dev/null
@@ -1,679 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2009, 2010, 2011, 2016 GNUnet e.V.
4
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
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20
21/**
22 * @file core/gnunet-service-core_neighbours.c
23 * @brief code for managing low-level 'plaintext' connections with transport (key exchange may or may not be done yet)
24 * @author Christian Grothoff
25 */
26#include "platform.h"
27#include "gnunet_util_lib.h"
28#include "gnunet_statistics_service.h"
29#include "gnunet_transport_service.h"
30#include "gnunet_transport_core_service.h"
31#include "gnunet-service-core.h"
32#include "gnunet-service-core_neighbours.h"
33#include "gnunet-service-core_kx.h"
34#include "gnunet-service-core_sessions.h"
35#include "gnunet_constants.h"
36
37
38/**
39 * Message ready for transmission via transport service. This struct
40 * is followed by the actual content of the message.
41 */
42struct NeighbourMessageEntry
43{
44
45 /**
46 * We keep messages in a doubly linked list.
47 */
48 struct NeighbourMessageEntry *next;
49
50 /**
51 * We keep messages in a doubly linked list.
52 */
53 struct NeighbourMessageEntry *prev;
54
55 /**
56 * By when are we supposed to transmit this message?
57 */
58 struct GNUNET_TIME_Absolute deadline;
59
60 /**
61 * What time did we submit the request?
62 */
63 struct GNUNET_TIME_Absolute submission_time;
64
65 /**
66 * How long is the message? (number of bytes following the `struct
67 * MessageEntry`, but not including the size of `struct
68 * MessageEntry` itself!)
69 */
70 size_t size;
71
72};
73
74
75/**
76 * Data kept per transport-connected peer.
77 */
78struct Neighbour
79{
80
81 /**
82 * Head of the batched message queue (already ordered, transmit
83 * starting with the head).
84 */
85 struct NeighbourMessageEntry *message_head;
86
87 /**
88 * Tail of the batched message queue (already ordered, append new
89 * messages to tail).
90 */
91 struct NeighbourMessageEntry *message_tail;
92
93 /**
94 * Handle for pending requests for transmission to this peer
95 * with the transport service. NULL if no request is pending.
96 */
97 struct GNUNET_TRANSPORT_TransmitHandle *th;
98
99 /**
100 * Information about the key exchange with the other peer.
101 */
102 struct GSC_KeyExchangeInfo *kxinfo;
103
104 /**
105 * Identity of the other peer.
106 */
107 struct GNUNET_PeerIdentity peer;
108
109 /**
110 * ID of task used for re-trying plaintext scheduling.
111 */
112 struct GNUNET_SCHEDULER_Task *retry_plaintext_task;
113
114 /**
115 * How many messages are in the queue for this neighbour?
116 */
117 unsigned int queue_size;
118
119 /**
120 * #GNUNET_YES if this peer currently has excess bandwidth.
121 */
122 int has_excess_bandwidth;
123
124};
125
126
127/**
128 * Map of peer identities to `struct Neighbour`.
129 */
130static struct GNUNET_CONTAINER_MultiPeerMap *neighbours;
131
132/**
133 * Transport service.
134 */
135static struct GNUNET_TRANSPORT_Handle *transport;
136
137
138/**
139 * Find the entry for the given neighbour.
140 *
141 * @param peer identity of the neighbour
142 * @return NULL if we are not connected, otherwise the
143 * neighbour's entry.
144 */
145static struct Neighbour *
146find_neighbour (const struct GNUNET_PeerIdentity *peer)
147{
148 if (NULL == neighbours)
149 return NULL;
150 return GNUNET_CONTAINER_multipeermap_get (neighbours,
151 peer);
152}
153
154
155/**
156 * Free the given entry for the neighbour.
157 *
158 * @param n neighbour to free
159 */
160static void
161free_neighbour (struct Neighbour *n)
162{
163 struct NeighbourMessageEntry *m;
164
165 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
166 "Destroying neighbour entry for peer `%s'\n",
167 GNUNET_i2s (&n->peer));
168 while (NULL != (m = n->message_head))
169 {
170 GNUNET_CONTAINER_DLL_remove (n->message_head,
171 n->message_tail,
172 m);
173 n->queue_size--;
174 GNUNET_free (m);
175 }
176 GNUNET_assert (0 == n->queue_size);
177 if (NULL != n->th)
178 {
179 GNUNET_TRANSPORT_notify_transmit_ready_cancel (n->th);
180 n->th = NULL;
181 }
182 GNUNET_STATISTICS_update (GSC_stats,
183 gettext_noop
184 ("# sessions terminated by transport disconnect"),
185 1, GNUNET_NO);
186 if (NULL != n->kxinfo)
187 {
188 GSC_KX_stop (n->kxinfo);
189 n->kxinfo = NULL;
190 }
191 if (NULL != n->retry_plaintext_task)
192 {
193 GNUNET_SCHEDULER_cancel (n->retry_plaintext_task);
194 n->retry_plaintext_task = NULL;
195 }
196 GNUNET_assert (GNUNET_OK ==
197 GNUNET_CONTAINER_multipeermap_remove (neighbours,
198 &n->peer, n));
199 GNUNET_STATISTICS_set (GSC_stats,
200 gettext_noop ("# neighbour entries allocated"),
201 GNUNET_CONTAINER_multipeermap_size (neighbours),
202 GNUNET_NO);
203 GNUNET_free (n);
204}
205
206
207/**
208 * Check if we have encrypted messages for the specified neighbour
209 * pending, and if so, check with the transport about sending them
210 * out.
211 *
212 * @param n neighbour to check.
213 */
214static void
215process_queue (struct Neighbour *n);
216
217
218/**
219 * Function called when the transport service is ready to receive a
220 * message for the respective peer
221 *
222 * @param cls neighbour to use message from
223 * @param size number of bytes we can transmit
224 * @param buf where to copy the message
225 * @return number of bytes transmitted
226 */
227static size_t
228transmit_ready (void *cls,
229 size_t size,
230 void *buf)
231{
232 struct Neighbour *n = cls;
233 struct NeighbourMessageEntry *m;
234 size_t ret;
235 char *cbuf;
236 struct GNUNET_TIME_Relative delay;
237 struct GNUNET_TIME_Relative overdue;
238
239 n->th = NULL;
240 m = n->message_head;
241 if (NULL == m)
242 {
243 GNUNET_break (0);
244 return 0;
245 }
246 GNUNET_CONTAINER_DLL_remove (n->message_head,
247 n->message_tail,
248 m);
249 n->queue_size--;
250 if (NULL == buf)
251 {
252 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
253 "Transmission of message of type %u and size %u failed\n",
254 (unsigned int)
255 ntohs (((struct GNUNET_MessageHeader *) &m[1])->type),
256 (unsigned int) m->size);
257 GNUNET_free (m);
258 process_queue (n);
259 return 0;
260 }
261 delay = GNUNET_TIME_absolute_get_duration (m->submission_time);
262 overdue = GNUNET_TIME_absolute_get_duration (m->deadline);
263 cbuf = buf;
264 GNUNET_assert (size >= m->size);
265 GNUNET_memcpy (cbuf,
266 &m[1],
267 m->size);
268 ret = m->size;
269 if (overdue.rel_value_us > GNUNET_CONSTANTS_LATENCY_WARN.rel_value_us)
270 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
271 "Copied overdue message of type %u and size %u into transport buffer for `%s' with delay of %s\n",
272 (unsigned int)
273 ntohs (((struct GNUNET_MessageHeader *) &m[1])->type),
274 (unsigned int) ret,
275 GNUNET_i2s (&n->peer),
276 GNUNET_STRINGS_relative_time_to_string (delay,
277 GNUNET_YES));
278 else
279 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
280 "Copied message of type %u and size %u into transport buffer for `%s' with delay of %s\n",
281 (unsigned int)
282 ntohs (((struct GNUNET_MessageHeader *) &m[1])->type),
283 (unsigned int) ret,
284 GNUNET_i2s (&n->peer),
285 GNUNET_STRINGS_relative_time_to_string (delay,
286 GNUNET_YES));
287 GNUNET_free (m);
288 n->has_excess_bandwidth = GNUNET_NO;
289 process_queue (n);
290 GNUNET_STATISTICS_update (GSC_stats,
291 gettext_noop
292 ("# encrypted bytes given to transport"), ret,
293 GNUNET_NO);
294 return ret;
295}
296
297
298/**
299 * Check if we have messages for the specified neighbour pending, and
300 * if so, check with the transport about sending them out.
301 *
302 * @param n neighbour to check.
303 */
304static void
305process_queue (struct Neighbour *n)
306{
307 struct NeighbourMessageEntry *m;
308
309 if (NULL != n->th)
310 return; /* request already pending */
311 m = n->message_head;
312 if (NULL == m)
313 {
314 /* notify sessions that the queue is empty and more messages
315 * could thus be queued now */
316 GSC_SESSIONS_solicit (&n->peer);
317 return;
318 }
319 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
320 "Asking transport for transmission of %u bytes to `%s' in next %s\n",
321 (unsigned int) m->size,
322 GNUNET_i2s (&n->peer),
323 GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_remaining (m->deadline),
324 GNUNET_NO));
325 m->submission_time = GNUNET_TIME_absolute_get ();
326 n->th
327 = GNUNET_TRANSPORT_notify_transmit_ready (transport,
328 &n->peer,
329 m->size,
330 GNUNET_TIME_absolute_get_remaining (m->deadline),
331 &transmit_ready,
332 n);
333 if (NULL != n->th)
334 return;
335 /* message request too large or duplicate request */
336 GNUNET_break (0);
337 /* discard encrypted message */
338 GNUNET_CONTAINER_DLL_remove (n->message_head,
339 n->message_tail,
340 m);
341 n->queue_size--;
342 GNUNET_free (m);
343 process_queue (n);
344}
345
346
347/**
348 * Function called by transport to notify us that
349 * a peer connected to us (on the network level).
350 *
351 * @param cls closure
352 * @param peer the peer that connected
353 */
354static void
355handle_transport_notify_connect (void *cls,
356 const struct GNUNET_PeerIdentity *peer)
357{
358 struct Neighbour *n;
359
360 if (0 == memcmp (peer,
361 &GSC_my_identity,
362 sizeof (struct GNUNET_PeerIdentity)))
363 {
364 GNUNET_break (0);
365 return;
366 }
367 n = find_neighbour (peer);
368 if (NULL != n)
369 {
370 /* duplicate connect notification!? */
371 GNUNET_break (0);
372 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
373 "Peer %s exists already\n",
374 GNUNET_i2s (peer));
375 return;
376 }
377 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
378 "Received connection from `%s'.\n",
379 GNUNET_i2s (peer));
380 n = GNUNET_new (struct Neighbour);
381 n->peer = *peer;
382 GNUNET_assert (GNUNET_OK ==
383 GNUNET_CONTAINER_multipeermap_put (neighbours,
384 &n->peer,
385 n,
386 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
387 GNUNET_STATISTICS_set (GSC_stats,
388 gettext_noop ("# neighbour entries allocated"),
389 GNUNET_CONTAINER_multipeermap_size (neighbours),
390 GNUNET_NO);
391 n->kxinfo = GSC_KX_start (peer);
392}
393
394
395/**
396 * Function called by transport telling us that a peer
397 * disconnected.
398 *
399 * @param cls closure
400 * @param peer the peer that disconnected
401 */
402static void
403handle_transport_notify_disconnect (void *cls,
404 const struct GNUNET_PeerIdentity *peer)
405{
406 struct Neighbour *n;
407
408 if (0 == memcmp (peer,
409 &GSC_my_identity,
410 sizeof (struct GNUNET_PeerIdentity)))
411 {
412 GNUNET_break (0);
413 return;
414 }
415 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
416 "Peer `%s' disconnected from us; received notification from transport.\n",
417 GNUNET_i2s (peer));
418 n = find_neighbour (peer);
419 if (NULL == n)
420 {
421 GNUNET_break (0);
422 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
423 "Peer %s not found\n",
424 GNUNET_i2s (peer));
425 return;
426 }
427 free_neighbour (n);
428}
429
430
431/**
432 * Function called by the transport for each received message.
433 *
434 * @param cls closure
435 * @param peer (claimed) identity of the other peer
436 * @param message the message
437 */
438static void
439handle_transport_receive (void *cls,
440 const struct GNUNET_PeerIdentity *peer,
441 const struct GNUNET_MessageHeader *message)
442{
443 struct Neighbour *n;
444 uint16_t type;
445
446 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
447 "Received message of type %u from `%s', demultiplexing.\n",
448 (unsigned int) ntohs (message->type),
449 GNUNET_i2s (peer));
450 if (0 == memcmp (peer,
451 &GSC_my_identity,
452 sizeof (struct GNUNET_PeerIdentity)))
453 {
454 GNUNET_break (0);
455 return;
456 }
457 n = find_neighbour (peer);
458 if (NULL == n)
459 {
460 /* received message from peer that is not connected!? */
461 GNUNET_break (0);
462 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
463 "Peer %s not found\n",
464 GNUNET_i2s (peer));
465 return;
466 }
467 type = ntohs (message->type);
468 switch (type)
469 {
470 case GNUNET_MESSAGE_TYPE_CORE_EPHEMERAL_KEY:
471 GSC_KX_handle_ephemeral_key (n->kxinfo, message);
472 break;
473 case GNUNET_MESSAGE_TYPE_CORE_PING:
474 GSC_KX_handle_ping (n->kxinfo, message);
475 break;
476 case GNUNET_MESSAGE_TYPE_CORE_PONG:
477 GSC_KX_handle_pong (n->kxinfo, message);
478 break;
479 case GNUNET_MESSAGE_TYPE_CORE_ENCRYPTED_MESSAGE:
480 GSC_KX_handle_encrypted_message (n->kxinfo, message);
481 break;
482 default:
483 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
484 _("Unsupported message of type %u (%u bytes) received from peer `%s'\n"),
485 (unsigned int) type,
486 (unsigned int) ntohs (message->size),
487 GNUNET_i2s (peer));
488 return;
489 }
490}
491
492
493/**
494 * Transmit the given message to the given target.
495 *
496 * @param target peer that should receive the message (must be connected)
497 * @param msg message to transmit
498 * @param timeout by when should the transmission be done?
499 */
500void
501GSC_NEIGHBOURS_transmit (const struct GNUNET_PeerIdentity *target,
502 const struct GNUNET_MessageHeader *msg,
503 struct GNUNET_TIME_Relative timeout)
504{
505 struct NeighbourMessageEntry *me;
506 struct Neighbour *n;
507 size_t msize;
508
509 n = find_neighbour (target);
510 if (NULL == n)
511 {
512 GNUNET_break (0);
513 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
514 "Peer %s not found\n",
515 GNUNET_i2s (target));
516 return;
517 }
518 msize = ntohs (msg->size);
519 me = GNUNET_malloc (sizeof (struct NeighbourMessageEntry) + msize);
520 me->deadline = GNUNET_TIME_relative_to_absolute (timeout);
521 me->size = msize;
522 GNUNET_memcpy (&me[1],
523 msg,
524 msize);
525 GNUNET_CONTAINER_DLL_insert_tail (n->message_head,
526 n->message_tail,
527 me);
528 n->queue_size++;
529 process_queue (n);
530}
531
532
533/**
534 * One of our neighbours has excess bandwidth, remember this.
535 *
536 * @param cls NULL
537 * @param pid identity of the peer with excess bandwidth
538 */
539static void
540handle_transport_notify_excess_bw (void *cls,
541 const struct GNUNET_PeerIdentity *pid)
542{
543 struct Neighbour *n;
544
545 n = find_neighbour (pid);
546 if (NULL == n)
547 {
548 GNUNET_break (0);
549 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
550 "Peer %s not found\n",
551 GNUNET_i2s (pid));
552 return;
553 }
554 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
555 "Peer %s has excess bandwidth available\n",
556 GNUNET_i2s (pid));
557 n->has_excess_bandwidth = GNUNET_YES;
558 GSC_SESSIONS_solicit (pid);
559}
560
561
562/**
563 * Check how many messages are queued for the given neighbour.
564 *
565 * @param target neighbour to check
566 * @return number of items in the message queue
567 */
568unsigned int
569GSC_NEIGHBOURS_get_queue_size (const struct GNUNET_PeerIdentity *target)
570{
571 struct Neighbour *n;
572
573 n = find_neighbour (target);
574 if (NULL == n)
575 {
576 GNUNET_break (0);
577 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
578 "Peer %s not found\n",
579 GNUNET_i2s (target));
580 return UINT_MAX;
581 }
582 return n->queue_size;
583}
584
585
586/**
587 * Check if the given neighbour has excess bandwidth available.
588 *
589 * @param target neighbour to check
590 * @return #GNUNET_YES if excess bandwidth is available, #GNUNET_NO if not
591 */
592int
593GSC_NEIGHBOURS_check_excess_bandwidth (const struct GNUNET_PeerIdentity *target)
594{
595 struct Neighbour *n;
596
597 n = find_neighbour (target);
598 if (NULL == n)
599 {
600 GNUNET_break (0);
601 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
602 "Peer %s not found\n",
603 GNUNET_i2s (target));
604 return GNUNET_SYSERR;
605 }
606 return n->has_excess_bandwidth;
607}
608
609
610/**
611 * Initialize neighbours subsystem.
612 */
613int
614GSC_NEIGHBOURS_init ()
615{
616 neighbours = GNUNET_CONTAINER_multipeermap_create (128,
617 GNUNET_YES);
618 transport =
619 GNUNET_TRANSPORT_connect2 (GSC_cfg,
620 &GSC_my_identity,
621 NULL,
622 &handle_transport_receive,
623 &handle_transport_notify_connect,
624 &handle_transport_notify_disconnect,
625 &handle_transport_notify_excess_bw);
626 if (NULL == transport)
627 {
628 GNUNET_CONTAINER_multipeermap_destroy (neighbours);
629 neighbours = NULL;
630 return GNUNET_SYSERR;
631 }
632 return GNUNET_OK;
633}
634
635
636/**
637 * Wrapper around #free_neighbour().
638 *
639 * @param cls unused
640 * @param key peer identity
641 * @param value the `struct Neighbour` to free
642 * @return #GNUNET_OK (continue to iterate)
643 */
644static int
645free_neighbour_helper (void *cls,
646 const struct GNUNET_PeerIdentity * key,
647 void *value)
648{
649 struct Neighbour *n = value;
650
651 /* transport should have 'disconnected' all neighbours... */
652 GNUNET_break (0);
653 free_neighbour (n);
654 return GNUNET_OK;
655}
656
657
658/**
659 * Shutdown neighbours subsystem.
660 */
661void
662GSC_NEIGHBOURS_done ()
663{
664 if (NULL != transport)
665 {
666 GNUNET_TRANSPORT_disconnect (transport);
667 transport = NULL;
668 }
669 if (NULL != neighbours)
670 {
671 GNUNET_CONTAINER_multipeermap_iterate (neighbours,
672 &free_neighbour_helper,
673 NULL);
674 GNUNET_CONTAINER_multipeermap_destroy (neighbours);
675 neighbours = NULL;
676 }
677}
678
679/* end of gnunet-service-core_neighbours.c */
diff --git a/src/core/gnunet-service-core_neighbours.h b/src/core/gnunet-service-core_neighbours.h
deleted file mode 100644
index b366d6b1c..000000000
--- a/src/core/gnunet-service-core_neighbours.h
+++ /dev/null
@@ -1,83 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2009-2014 GNUnet e.V.
4
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
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20
21/**
22 * @file core/gnunet-service-core_neighbours.h
23 * @brief code for managing low-level 'plaintext' connections with transport (key exchange may or may not be done yet)
24 * @author Christian Grothoff
25 */
26#ifndef GNUNET_SERVICE_CORE_NEIGHBOURS_H
27#define GNUNET_SERVICE_CORE_NEIGHBOURS_H
28
29#include "gnunet_util_lib.h"
30
31/**
32 * Transmit the given message to the given target. Note that a
33 * non-control messages should only be transmitted after a
34 * #GSC_SESSION_solicit() call was made (that call is always invoked
35 * when the message queue is empty). Outbound quotas and memory
36 * bounds will then be enfoced (as #GSC_SESSION_solicit() is only called
37 * if sufficient bandwidth is available).
38 *
39 * @param target peer that should receive the message (must be connected)
40 * @param msg message to transmit
41 * @param timeout by when should the transmission be done?
42 */
43void
44GSC_NEIGHBOURS_transmit (const struct GNUNET_PeerIdentity *target,
45 const struct GNUNET_MessageHeader *msg,
46 struct GNUNET_TIME_Relative timeout);
47
48
49/**
50 * Check if the given neighbour has excess bandwidth available.
51 *
52 * @param target neighbour to check
53 * @return #GNUNET_YES if excess bandwidth is available, #GNUNET_NO if not
54 */
55int
56GSC_NEIGHBOURS_check_excess_bandwidth (const struct GNUNET_PeerIdentity *target);
57
58
59/**
60 * Check how many messages are queued for the given neighbour.
61 *
62 * @param target neighbour to check
63 * @return number of items in the message queue
64 */
65unsigned int
66GSC_NEIGHBOURS_get_queue_size (const struct GNUNET_PeerIdentity *target);
67
68
69/**
70 * Initialize neighbours subsystem.
71 */
72int
73GSC_NEIGHBOURS_init (void);
74
75
76/**
77 * Shutdown neighbours subsystem.
78 */
79void
80GSC_NEIGHBOURS_done (void);
81
82
83#endif
diff --git a/src/core/gnunet-service-core_sessions.c b/src/core/gnunet-service-core_sessions.c
index 41d3cc24b..ef5285b45 100644
--- a/src/core/gnunet-service-core_sessions.c
+++ b/src/core/gnunet-service-core_sessions.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-2014 GNUnet e.V. 3 Copyright (C) 2009-2014, 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
@@ -25,7 +25,6 @@
25 */ 25 */
26#include "platform.h" 26#include "platform.h"
27#include "gnunet-service-core.h" 27#include "gnunet-service-core.h"
28#include "gnunet-service-core_neighbours.h"
29#include "gnunet-service-core_kx.h" 28#include "gnunet-service-core_kx.h"
30#include "gnunet-service-core_typemap.h" 29#include "gnunet-service-core_typemap.h"
31#include "gnunet-service-core_sessions.h" 30#include "gnunet-service-core_sessions.h"
@@ -88,9 +87,14 @@ struct Session
88 /** 87 /**
89 * Identity of the other peer. 88 * Identity of the other peer.
90 */ 89 */
91 struct GNUNET_PeerIdentity peer; 90 const struct GNUNET_PeerIdentity *peer;
92 91
93 /** 92 /**
93 * Key exchange state for this peer.
94 */
95 struct GSC_KeyExchangeInfo *kx;
96
97 /**
94 * Head of list of requests from clients for transmission to 98 * Head of list of requests from clients for transmission to
95 * this peer. 99 * this peer.
96 */ 100 */
@@ -113,11 +117,6 @@ struct Session
113 struct SessionMessageEntry *sme_tail; 117 struct SessionMessageEntry *sme_tail;
114 118
115 /** 119 /**
116 * Information about the key exchange with the other peer.
117 */
118 struct GSC_KeyExchangeInfo *kxinfo;
119
120 /**
121 * Current type map for this peer. 120 * Current type map for this peer.
122 */ 121 */
123 struct GSC_TypeMap *tmap; 122 struct GSC_TypeMap *tmap;
@@ -197,7 +196,10 @@ static struct GNUNET_CONTAINER_MultiPeerMap *sessions;
197static struct Session * 196static struct Session *
198find_session (const struct GNUNET_PeerIdentity *peer) 197find_session (const struct GNUNET_PeerIdentity *peer)
199{ 198{
200 return GNUNET_CONTAINER_multipeermap_get (sessions, peer); 199 if (NULL == sessions)
200 return NULL;
201 return GNUNET_CONTAINER_multipeermap_get (sessions,
202 peer);
201} 203}
202 204
203 205
@@ -218,8 +220,8 @@ GSC_SESSIONS_end (const struct GNUNET_PeerIdentity *pid)
218 if (NULL == session) 220 if (NULL == session)
219 return; 221 return;
220 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 222 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
221 "Destroying session for peer `%4s'\n", 223 "Destroying session for peer `%s'\n",
222 GNUNET_i2s (&session->peer)); 224 GNUNET_i2s (session->peer));
223 if (NULL != session->cork_task) 225 if (NULL != session->cork_task)
224 { 226 {
225 GNUNET_SCHEDULER_cancel (session->cork_task); 227 GNUNET_SCHEDULER_cancel (session->cork_task);
@@ -244,13 +246,15 @@ GSC_SESSIONS_end (const struct GNUNET_PeerIdentity *pid)
244 GNUNET_SCHEDULER_cancel (session->typemap_task); 246 GNUNET_SCHEDULER_cancel (session->typemap_task);
245 session->typemap_task = NULL; 247 session->typemap_task = NULL;
246 } 248 }
247 GSC_CLIENTS_notify_clients_about_neighbour (&session->peer, 249 GSC_CLIENTS_notify_clients_about_neighbour (session->peer,
248 session->tmap, NULL); 250 session->tmap,
251 NULL);
249 GNUNET_assert (GNUNET_YES == 252 GNUNET_assert (GNUNET_YES ==
250 GNUNET_CONTAINER_multipeermap_remove (sessions, 253 GNUNET_CONTAINER_multipeermap_remove (sessions,
251 &session->peer, 254 session->peer,
252 session)); 255 session));
253 GNUNET_STATISTICS_set (GSC_stats, gettext_noop ("# peers connected"), 256 GNUNET_STATISTICS_set (GSC_stats,
257 gettext_noop ("# peers connected"),
254 GNUNET_CONTAINER_multipeermap_size (sessions), 258 GNUNET_CONTAINER_multipeermap_size (sessions),
255 GNUNET_NO); 259 GNUNET_NO);
256 GSC_TYPEMAP_destroy (session->tmap); 260 GSC_TYPEMAP_destroy (session->tmap);
@@ -285,7 +289,7 @@ transmit_typemap_task (void *cls)
285 1, 289 1,
286 GNUNET_NO); 290 GNUNET_NO);
287 hdr = GSC_TYPEMAP_compute_type_map_message (); 291 hdr = GSC_TYPEMAP_compute_type_map_message ();
288 GSC_KX_encrypt_and_transmit (session->kxinfo, 292 GSC_KX_encrypt_and_transmit (session->kx,
289 hdr, 293 hdr,
290 ntohs (hdr->size)); 294 ntohs (hdr->size));
291 GNUNET_free (hdr); 295 GNUNET_free (hdr);
@@ -327,14 +331,15 @@ GSC_SESSIONS_create (const struct GNUNET_PeerIdentity *peer,
327 GNUNET_i2s (peer)); 331 GNUNET_i2s (peer));
328 session = GNUNET_new (struct Session); 332 session = GNUNET_new (struct Session);
329 session->tmap = GSC_TYPEMAP_create (); 333 session->tmap = GSC_TYPEMAP_create ();
330 session->peer = *peer; 334 session->peer = peer;
331 session->kxinfo = kx; 335 session->kx = kx;
332 GNUNET_assert (GNUNET_OK == 336 GNUNET_assert (GNUNET_OK ==
333 GNUNET_CONTAINER_multipeermap_put (sessions, 337 GNUNET_CONTAINER_multipeermap_put (sessions,
334 &session->peer, 338 session->peer,
335 session, 339 session,
336 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); 340 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
337 GNUNET_STATISTICS_set (GSC_stats, gettext_noop ("# peers connected"), 341 GNUNET_STATISTICS_set (GSC_stats,
342 gettext_noop ("# peers connected"),
338 GNUNET_CONTAINER_multipeermap_size (sessions), 343 GNUNET_CONTAINER_multipeermap_size (sessions),
339 GNUNET_NO); 344 GNUNET_NO);
340 GSC_CLIENTS_notify_clients_about_neighbour (peer, 345 GSC_CLIENTS_notify_clients_about_neighbour (peer,
@@ -433,7 +438,7 @@ notify_client_about_session (void *cls,
433 struct Session *session = value; 438 struct Session *session = value;
434 439
435 GSC_CLIENTS_notify_client_about_neighbour (client, 440 GSC_CLIENTS_notify_client_about_neighbour (client,
436 &session->peer, 441 session->peer,
437 NULL, /* old TMAP: none */ 442 NULL, /* old TMAP: none */
438 session->tmap); 443 session->tmap);
439 return GNUNET_OK; 444 return GNUNET_OK;
@@ -620,7 +625,7 @@ try_transmission (struct Session *session)
620 if (GNUNET_YES != session->ready_to_transmit) 625 if (GNUNET_YES != session->ready_to_transmit)
621 { 626 {
622 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 627 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
623 "Already ready to transmit, not evaluating queue\n"); 628 "Not yet ready to transmit, not evaluating queue\n");
624 return; 629 return;
625 } 630 }
626 msize = 0; 631 msize = 0;
@@ -628,13 +633,13 @@ try_transmission (struct Session *session)
628 /* if the peer has excess bandwidth, background traffic is allowed, 633 /* if the peer has excess bandwidth, background traffic is allowed,
629 otherwise not */ 634 otherwise not */
630 if (MAX_ENCRYPTED_MESSAGE_QUEUE_SIZE <= 635 if (MAX_ENCRYPTED_MESSAGE_QUEUE_SIZE <=
631 GSC_NEIGHBOURS_get_queue_size (&session->peer)) 636 GSC_NEIGHBOURS_get_queue_length (session->kx))
632 { 637 {
633 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 638 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
634 "Transmission queue already very long, waiting...\n"); 639 "Transmission queue already very long, waiting...\n");
635 return; /* queue already too long */ 640 return; /* queue already too long */
636 } 641 }
637 excess = GSC_NEIGHBOURS_check_excess_bandwidth (&session->peer); 642 excess = GSC_NEIGHBOURS_check_excess_bandwidth (session->kx);
638 if (GNUNET_YES == excess) 643 if (GNUNET_YES == excess)
639 maxp = GNUNET_CORE_PRIO_BACKGROUND; 644 maxp = GNUNET_CORE_PRIO_BACKGROUND;
640 else 645 else
@@ -769,7 +774,7 @@ try_transmission (struct Session *session)
769 GNUNET_NO); 774 GNUNET_NO);
770 /* now actually transmit... */ 775 /* now actually transmit... */
771 session->ready_to_transmit = GNUNET_NO; 776 session->ready_to_transmit = GNUNET_NO;
772 GSC_KX_encrypt_and_transmit (session->kxinfo, 777 GSC_KX_encrypt_and_transmit (session->kx,
773 pbuf, 778 pbuf,
774 used); 779 used);
775 } 780 }
@@ -797,7 +802,9 @@ do_restart_typemap_message (void *cls,
797 802
798 size = ntohs (hdr->size); 803 size = ntohs (hdr->size);
799 sme = GNUNET_malloc (sizeof (struct SessionMessageEntry) + size); 804 sme = GNUNET_malloc (sizeof (struct SessionMessageEntry) + size);
800 GNUNET_memcpy (&sme[1], hdr, size); 805 GNUNET_memcpy (&sme[1],
806 hdr,
807 size);
801 sme->size = size; 808 sme->size = size;
802 sme->priority = GNUNET_CORE_PRIO_CRITICAL_CONTROL; 809 sme->priority = GNUNET_CORE_PRIO_CRITICAL_CONTROL;
803 GNUNET_CONTAINER_DLL_insert (session->sme_head, 810 GNUNET_CONTAINER_DLL_insert (session->sme_head,
@@ -871,12 +878,18 @@ GSC_SESSIONS_transmit (struct GSC_ClientActiveRequest *car,
871 return; 878 return;
872 msize = ntohs (msg->size); 879 msize = ntohs (msg->size);
873 sme = GNUNET_malloc (sizeof (struct SessionMessageEntry) + msize); 880 sme = GNUNET_malloc (sizeof (struct SessionMessageEntry) + msize);
874 GNUNET_memcpy (&sme[1], msg, msize); 881 GNUNET_memcpy (&sme[1],
882 msg,
883 msize);
875 sme->size = msize; 884 sme->size = msize;
876 sme->priority = priority; 885 sme->priority = priority;
877 if (GNUNET_YES == cork) 886 if (GNUNET_YES == cork)
887 {
878 sme->deadline = 888 sme->deadline =
879 GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_MAX_CORK_DELAY); 889 GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_MAX_CORK_DELAY);
890 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
891 "Mesage corked, delaying transmission\n");
892 }
880 pos = session->sme_head; 893 pos = session->sme_head;
881 while ( (NULL != pos) && 894 while ( (NULL != pos) &&
882 (pos->priority >= sme->priority) ) 895 (pos->priority >= sme->priority) )
@@ -998,9 +1011,9 @@ free_session_helper (void *cls,
998 const struct GNUNET_PeerIdentity *key, 1011 const struct GNUNET_PeerIdentity *key,
999 void *value) 1012 void *value)
1000{ 1013{
1001 struct Session *session = value; 1014 /* struct Session *session = value; */
1002 1015
1003 GSC_SESSIONS_end (&session->peer); 1016 GSC_SESSIONS_end (key);
1004 return GNUNET_OK; 1017 return GNUNET_OK;
1005} 1018}
1006 1019
@@ -1014,7 +1027,8 @@ GSC_SESSIONS_done ()
1014 if (NULL != sessions) 1027 if (NULL != sessions)
1015 { 1028 {
1016 GNUNET_CONTAINER_multipeermap_iterate (sessions, 1029 GNUNET_CONTAINER_multipeermap_iterate (sessions,
1017 &free_session_helper, NULL); 1030 &free_session_helper,
1031 NULL);
1018 GNUNET_CONTAINER_multipeermap_destroy (sessions); 1032 GNUNET_CONTAINER_multipeermap_destroy (sessions);
1019 sessions = NULL; 1033 sessions = NULL;
1020 } 1034 }
diff --git a/src/core/test_core_api_data.conf b/src/core/test_core_api_data.conf
index 53f864bdd..a13cc8706 100644
--- a/src/core/test_core_api_data.conf
+++ b/src/core/test_core_api_data.conf
@@ -8,3 +8,4 @@ WAN_QUOTA_OUT = 64 kiB
8[core] 8[core]
9PORT = 2092 9PORT = 2092
10UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-core.sock 10UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-core.sock
11
diff --git a/src/core/test_core_api_reliability.c b/src/core/test_core_api_reliability.c
index 9924bef97..a4a6d182c 100644
--- a/src/core/test_core_api_reliability.c
+++ b/src/core/test_core_api_reliability.c
@@ -74,6 +74,8 @@ static struct PeerContext p1;
74 74
75static struct PeerContext p2; 75static struct PeerContext p2;
76 76
77static struct GNUNET_CORE_TransmitHandle *nth;
78
77static int ok; 79static int ok;
78 80
79static int32_t tr_n; 81static int32_t tr_n;
@@ -132,24 +134,6 @@ terminate_peer (struct PeerContext *p)
132 134
133 135
134static void 136static void
135terminate_task (void *cls)
136{
137 unsigned long long delta;
138
139 delta = GNUNET_TIME_absolute_get_duration (start_time).rel_value_us;
140 FPRINTF (stderr,
141 "\nThroughput was %llu kb/s\n",
142 total_bytes * 1000000LL / 1024 / delta);
143 GAUGER ("CORE",
144 "Core throughput/s",
145 total_bytes * 1000000LL / 1024 / delta,
146 "kb/s");
147 GNUNET_SCHEDULER_shutdown ();
148 ok = 0;
149}
150
151
152static void
153terminate_task_error (void *cls) 137terminate_task_error (void *cls)
154{ 138{
155 err_task = NULL; 139 err_task = NULL;
@@ -162,13 +146,29 @@ terminate_task_error (void *cls)
162static void 146static void
163do_shutdown (void *cls) 147do_shutdown (void *cls)
164{ 148{
149 unsigned long long delta;
150
151 delta = GNUNET_TIME_absolute_get_duration (start_time).rel_value_us;
152 FPRINTF (stderr,
153 "\nThroughput was %llu kb/s\n",
154 total_bytes * 1000000LL / 1024 / delta);
155 GAUGER ("CORE",
156 "Core throughput/s",
157 total_bytes * 1000000LL / 1024 / delta,
158 "kb/s");
165 if (NULL != err_task) 159 if (NULL != err_task)
166 { 160 {
167 GNUNET_SCHEDULER_cancel (err_task); 161 GNUNET_SCHEDULER_cancel (err_task);
168 err_task = NULL; 162 err_task = NULL;
169 } 163 }
164 if (NULL != nth)
165 {
166 GNUNET_CORE_notify_transmit_ready_cancel (nth);
167 nth = NULL;
168 }
170 terminate_peer (&p1); 169 terminate_peer (&p1);
171 terminate_peer (&p2); 170 terminate_peer (&p2);
171
172} 172}
173 173
174 174
@@ -182,16 +182,19 @@ transmit_ready (void *cls,
182 unsigned int s; 182 unsigned int s;
183 unsigned int ret; 183 unsigned int ret;
184 184
185 nth = NULL;
185 GNUNET_assert (size <= GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE); 186 GNUNET_assert (size <= GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE);
186 if (NULL == buf) 187 if (NULL == buf)
187 { 188 {
188 if (NULL != p1.ch) 189 if (NULL != p1.ch)
189 GNUNET_break (NULL != 190 GNUNET_break (NULL !=
190 GNUNET_CORE_notify_transmit_ready (p1.ch, GNUNET_NO, 191 (nth = GNUNET_CORE_notify_transmit_ready (p1.ch, GNUNET_NO,
191 GNUNET_CORE_PRIO_BEST_EFFORT, 192 GNUNET_CORE_PRIO_BEST_EFFORT,
192 FAST_TIMEOUT, &p2.id, 193 FAST_TIMEOUT,
193 get_size (tr_n), 194 &p2.id,
194 &transmit_ready, &p1)); 195 get_size (tr_n),
196 &transmit_ready,
197 &p1)));
195 return 0; 198 return 0;
196 } 199 }
197 GNUNET_assert (tr_n < TOTAL_MSGS); 200 GNUNET_assert (tr_n < TOTAL_MSGS);
@@ -223,7 +226,8 @@ transmit_ready (void *cls,
223 GNUNET_SCHEDULER_cancel (err_task); 226 GNUNET_SCHEDULER_cancel (err_task);
224 err_task = 227 err_task =
225 GNUNET_SCHEDULER_add_delayed (TIMEOUT, 228 GNUNET_SCHEDULER_add_delayed (TIMEOUT,
226 &terminate_task_error, NULL); 229 &terminate_task_error,
230 NULL);
227 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 231 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
228 "Returning total message block of size %u\n", 232 "Returning total message block of size %u\n",
229 ret); 233 ret);
@@ -238,9 +242,11 @@ connect_notify (void *cls,
238{ 242{
239 struct PeerContext *pc = cls; 243 struct PeerContext *pc = cls;
240 244
241 if (0 == memcmp (&pc->id, peer, sizeof (struct GNUNET_PeerIdentity))) 245 if (0 == memcmp (&pc->id,
246 peer,
247 sizeof (struct GNUNET_PeerIdentity)))
242 return; 248 return;
243 GNUNET_assert (pc->connect_status == 0); 249 GNUNET_assert (0 == pc->connect_status);
244 pc->connect_status = 1; 250 pc->connect_status = 1;
245 if (pc == &p1) 251 if (pc == &p1)
246 { 252 {
@@ -252,14 +258,19 @@ connect_notify (void *cls,
252 GNUNET_i2s (&p2.id)); 258 GNUNET_i2s (&p2.id));
253 GNUNET_SCHEDULER_cancel (err_task); 259 GNUNET_SCHEDULER_cancel (err_task);
254 err_task = 260 err_task =
255 GNUNET_SCHEDULER_add_delayed (TIMEOUT, &terminate_task_error, NULL); 261 GNUNET_SCHEDULER_add_delayed (TIMEOUT,
262 &terminate_task_error,
263 NULL);
256 start_time = GNUNET_TIME_absolute_get (); 264 start_time = GNUNET_TIME_absolute_get ();
257 GNUNET_break (NULL != 265 GNUNET_break (NULL !=
258 GNUNET_CORE_notify_transmit_ready (p1.ch, GNUNET_NO, 266 (nth = GNUNET_CORE_notify_transmit_ready (p1.ch,
259 GNUNET_CORE_PRIO_BEST_EFFORT, 267 GNUNET_NO,
260 TIMEOUT, &p2.id, 268 GNUNET_CORE_PRIO_BEST_EFFORT,
261 get_size (0), 269 TIMEOUT,
262 &transmit_ready, &p1)); 270 &p2.id,
271 get_size (0),
272 &transmit_ready,
273 &p1)));
263 } 274 }
264} 275}
265 276
@@ -342,7 +353,8 @@ process_mtype (void *cls,
342 ntohs (message->size), 353 ntohs (message->size),
343 ntohl (hdr->num)); 354 ntohl (hdr->num));
344 GNUNET_SCHEDULER_cancel (err_task); 355 GNUNET_SCHEDULER_cancel (err_task);
345 err_task = GNUNET_SCHEDULER_add_now (&terminate_task_error, NULL); 356 err_task = GNUNET_SCHEDULER_add_now (&terminate_task_error,
357 NULL);
346 return GNUNET_SYSERR; 358 return GNUNET_SYSERR;
347 } 359 }
348 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 360 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -354,8 +366,8 @@ process_mtype (void *cls,
354 FPRINTF (stderr, "%s", "."); 366 FPRINTF (stderr, "%s", ".");
355 if (n == TOTAL_MSGS) 367 if (n == TOTAL_MSGS)
356 { 368 {
357 GNUNET_SCHEDULER_cancel (err_task); 369 ok = 0;
358 GNUNET_SCHEDULER_add_now (&terminate_task, NULL); 370 GNUNET_SCHEDULER_shutdown ();
359 } 371 }
360 else 372 else
361 { 373 {
diff --git a/src/core/test_core_api_start_only.c b/src/core/test_core_api_start_only.c
index 42bf4e452..07a402189 100644
--- a/src/core/test_core_api_start_only.c
+++ b/src/core/test_core_api_start_only.c
@@ -25,10 +25,7 @@
25#include "platform.h" 25#include "platform.h"
26#include "gnunet_arm_service.h" 26#include "gnunet_arm_service.h"
27#include "gnunet_core_service.h" 27#include "gnunet_core_service.h"
28#include "gnunet_getopt_lib.h" 28#include "gnunet_util_lib.h"
29#include "gnunet_os_lib.h"
30#include "gnunet_program_lib.h"
31#include "gnunet_scheduler_lib.h"
32 29
33#define TIMEOUT 5 30#define TIMEOUT 5
34 31
@@ -46,32 +43,28 @@ static struct PeerContext p1;
46 43
47static struct PeerContext p2; 44static struct PeerContext p2;
48 45
49static struct GNUNET_SCHEDULER_Task * timeout_task_id; 46static struct GNUNET_SCHEDULER_Task *timeout_task_id;
50 47
51static int ok; 48static int ok;
52 49
53#if VERBOSE
54#define OKPP do { ok++; FPRINTF (stderr, "Now at stage %u at %s:%u\n", ok, __FILE__, __LINE__); } while (0)
55#else
56#define OKPP do { ok++; } while (0)
57#endif
58
59
60 50
61static void 51static void
62connect_notify (void *cls, const struct GNUNET_PeerIdentity *peer) 52connect_notify (void *cls,
53 const struct GNUNET_PeerIdentity *peer)
63{ 54{
64} 55}
65 56
66 57
67static void 58static void
68disconnect_notify (void *cls, const struct GNUNET_PeerIdentity *peer) 59disconnect_notify (void *cls,
60 const struct GNUNET_PeerIdentity *peer)
69{ 61{
70} 62}
71 63
72 64
73static int 65static int
74inbound_notify (void *cls, const struct GNUNET_PeerIdentity *other, 66inbound_notify (void *cls,
67 const struct GNUNET_PeerIdentity *other,
75 const struct GNUNET_MessageHeader *message) 68 const struct GNUNET_MessageHeader *message)
76{ 69{
77 return GNUNET_OK; 70 return GNUNET_OK;
@@ -79,7 +72,8 @@ inbound_notify (void *cls, const struct GNUNET_PeerIdentity *other,
79 72
80 73
81static int 74static int
82outbound_notify (void *cls, const struct GNUNET_PeerIdentity *other, 75outbound_notify (void *cls,
76 const struct GNUNET_PeerIdentity *other,
83 const struct GNUNET_MessageHeader *message) 77 const struct GNUNET_MessageHeader *message)
84{ 78{
85 return GNUNET_OK; 79 return GNUNET_OK;
@@ -112,33 +106,45 @@ init_notify (void *cls,
112 { 106 {
113 /* connect p2 */ 107 /* connect p2 */
114 p2.ch = 108 p2.ch =
115 GNUNET_CORE_connect (p2.cfg, &p2, &init_notify, &connect_notify, 109 GNUNET_CORE_connect (p2.cfg,
116 &disconnect_notify, &inbound_notify, GNUNET_YES, 110 &p2,
117 &outbound_notify, GNUNET_YES, handlers); 111 &init_notify,
112 &connect_notify,
113 &disconnect_notify,
114 &inbound_notify, GNUNET_YES,
115 &outbound_notify, GNUNET_YES,
116 handlers);
118 } 117 }
119 else 118 else
120 { 119 {
121 GNUNET_assert (p == &p2); 120 GNUNET_assert (p == &p2);
122 GNUNET_SCHEDULER_cancel (timeout_task_id); 121 GNUNET_SCHEDULER_cancel (timeout_task_id);
123 GNUNET_SCHEDULER_add_now (&shutdown_task, NULL); 122 timeout_task_id = NULL;
123 GNUNET_SCHEDULER_add_now (&shutdown_task,
124 NULL);
124 } 125 }
125} 126}
126 127
127 128
128static void 129static void
129setup_peer (struct PeerContext *p, const char *cfgname) 130setup_peer (struct PeerContext *p,
131 const char *cfgname)
130{ 132{
131 char *binary; 133 char *binary;
132 134
133 binary = GNUNET_OS_get_libexec_binary_path ("gnunet-service-arm"); 135 binary = GNUNET_OS_get_libexec_binary_path ("gnunet-service-arm");
134 p->cfg = GNUNET_CONFIGURATION_create (); 136 p->cfg = GNUNET_CONFIGURATION_create ();
135 p->arm_proc = 137 p->arm_proc =
136 GNUNET_OS_start_process (GNUNET_YES, GNUNET_OS_INHERIT_STD_OUT_AND_ERR, 138 GNUNET_OS_start_process (GNUNET_YES,
139 GNUNET_OS_INHERIT_STD_OUT_AND_ERR,
137 NULL, NULL, NULL, 140 NULL, NULL, NULL,
138 binary, 141 binary,
139 "gnunet-service-arm", 142 "gnunet-service-arm",
140 "-c", cfgname, NULL); 143 "-c", cfgname,
141 GNUNET_assert (GNUNET_OK == GNUNET_CONFIGURATION_load (p->cfg, cfgname)); 144 NULL);
145 GNUNET_assert (GNUNET_OK ==
146 GNUNET_CONFIGURATION_load (p->cfg,
147 cfgname));
142 GNUNET_free (binary); 148 GNUNET_free (binary);
143} 149}
144 150
@@ -147,12 +153,12 @@ static void
147timeout_task (void *cls) 153timeout_task (void *cls)
148{ 154{
149 FPRINTF (stderr, "%s", "Timeout.\n"); 155 FPRINTF (stderr, "%s", "Timeout.\n");
150 if (p1.ch != NULL) 156 if (NULL != p1.ch)
151 { 157 {
152 GNUNET_CORE_disconnect (p1.ch); 158 GNUNET_CORE_disconnect (p1.ch);
153 p1.ch = NULL; 159 p1.ch = NULL;
154 } 160 }
155 if (p2.ch != NULL) 161 if (NULL != p2.ch)
156 { 162 {
157 GNUNET_CORE_disconnect (p2.ch); 163 GNUNET_CORE_disconnect (p2.ch);
158 p2.ch = NULL; 164 p2.ch = NULL;
@@ -162,34 +168,47 @@ timeout_task (void *cls)
162 168
163 169
164static void 170static void
165run (void *cls, char *const *args, const char *cfgfile, 171run (void *cls,
172 char *const *args,
173 const char *cfgfile,
166 const struct GNUNET_CONFIGURATION_Handle *cfg) 174 const struct GNUNET_CONFIGURATION_Handle *cfg)
167{ 175{
168 GNUNET_assert (ok == 1); 176 GNUNET_assert (ok == 1);
169 OKPP; 177 ok++;
170 setup_peer (&p1, "test_core_api_peer1.conf"); 178 setup_peer (&p1, "test_core_api_peer1.conf");
171 setup_peer (&p2, "test_core_api_peer2.conf"); 179 setup_peer (&p2, "test_core_api_peer2.conf");
172 timeout_task_id = 180 timeout_task_id =
173 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply 181 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
174 (GNUNET_TIME_UNIT_MINUTES, TIMEOUT), 182 (GNUNET_TIME_UNIT_MINUTES,
183 TIMEOUT),
175 &timeout_task, NULL); 184 &timeout_task, NULL);
176 p1.ch = 185 p1.ch = GNUNET_CORE_connect (p1.cfg,
177 GNUNET_CORE_connect (p1.cfg, &p1, &init_notify, &connect_notify, 186 &p1,
178 &disconnect_notify, &inbound_notify, GNUNET_YES, 187 &init_notify,
179 &outbound_notify, GNUNET_YES, handlers); 188 &connect_notify,
189 &disconnect_notify,
190 &inbound_notify, GNUNET_YES,
191 &outbound_notify, GNUNET_YES,
192 handlers);
180} 193}
181 194
182 195
183static void 196static void
184stop_arm (struct PeerContext *p) 197stop_arm (struct PeerContext *p)
185{ 198{
186 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stopping peer\n"); 199 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
187 if (0 != GNUNET_OS_process_kill (p->arm_proc, GNUNET_TERM_SIG)) 200 "Stopping peer\n");
188 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); 201 if (0 != GNUNET_OS_process_kill (p->arm_proc,
189 if (GNUNET_OS_process_wait (p->arm_proc) != GNUNET_OK) 202 GNUNET_TERM_SIG))
190 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid"); 203 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
191 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ARM process %u stopped\n", 204 "kill");
192 GNUNET_OS_process_get_pid (p->arm_proc)); 205 if (GNUNET_OK !=
206 GNUNET_OS_process_wait (p->arm_proc))
207 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
208 "waitpid");
209 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
210 "ARM process %u stopped\n",
211 (unsigned int) GNUNET_OS_process_get_pid (p->arm_proc));
193 GNUNET_OS_process_destroy (p->arm_proc); 212 GNUNET_OS_process_destroy (p->arm_proc);
194 p->arm_proc = NULL; 213 p->arm_proc = NULL;
195 GNUNET_CONFIGURATION_destroy (p->cfg); 214 GNUNET_CONFIGURATION_destroy (p->cfg);
@@ -199,7 +218,8 @@ stop_arm (struct PeerContext *p)
199static int 218static int
200check () 219check ()
201{ 220{
202 char *const argv[] = { "test-core-api-start-only", 221 char *const argv[] = {
222 "test-core-api-start-only",
203 "-c", 223 "-c",
204 "test_core_api_data.conf", 224 "test_core_api_data.conf",
205 NULL 225 NULL
@@ -211,9 +231,15 @@ check ()
211 GNUNET_DISK_directory_remove ("/tmp/test-gnunet-core-peer-2"); 231 GNUNET_DISK_directory_remove ("/tmp/test-gnunet-core-peer-2");
212 232
213 ok = 1; 233 ok = 1;
214 GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, argv, 234 GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1,
215 "test-core-api-start-only", "nohelp", options, &run, &ok); 235 argv,
216 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Test finished\n"); 236 "test-core-api-start-only",
237 "nohelp",
238 options,
239 &run,
240 &ok);
241 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
242 "Test finished\n");
217 stop_arm (&p1); 243 stop_arm (&p1);
218 stop_arm (&p2); 244 stop_arm (&p2);
219 return ok; 245 return ok;
@@ -221,7 +247,8 @@ check ()
221 247
222 248
223int 249int
224main (int argc, char *argv[]) 250main (int argc,
251 char *argv[])
225{ 252{
226 int ret; 253 int ret;
227 254
diff --git a/src/core/test_core_defaults.conf b/src/core/test_core_defaults.conf
index 3f6b3dce3..eb9a1c379 100644
--- a/src/core/test_core_defaults.conf
+++ b/src/core/test_core_defaults.conf
@@ -25,3 +25,4 @@ BROADCAST = NO
25 25
26[peerinfo] 26[peerinfo]
27NO_IO = YES 27NO_IO = YES
28
diff --git a/src/core/test_core_quota_compliance.c b/src/core/test_core_quota_compliance.c
index a0c456cef..04f79b959 100644
--- a/src/core/test_core_quota_compliance.c
+++ b/src/core/test_core_quota_compliance.c
@@ -112,7 +112,7 @@ struct TestMessage
112static void 112static void
113terminate_peer (struct PeerContext *p) 113terminate_peer (struct PeerContext *p)
114{ 114{
115 if (p->nth != NULL) 115 if (NULL != p->nth)
116 { 116 {
117 GNUNET_CORE_notify_transmit_ready_cancel (p->nth); 117 GNUNET_CORE_notify_transmit_ready_cancel (p->nth);
118 p->nth = NULL; 118 p->nth = NULL;
@@ -156,9 +156,18 @@ terminate_peer (struct PeerContext *p)
156 156
157 157
158static void 158static void
159terminate_task (void *cls) 159shutdown_task (void *cls)
160{ 160{
161 err_task = NULL; 161 if (NULL != err_task)
162 {
163 GNUNET_SCHEDULER_cancel (err_task);
164 err_task = NULL;
165 }
166 if (NULL != measure_task)
167 {
168 GNUNET_SCHEDULER_cancel (measure_task);
169 measure_task = NULL;
170 }
162 terminate_peer (&p1); 171 terminate_peer (&p1);
163 terminate_peer (&p2); 172 terminate_peer (&p2);
164} 173}
@@ -169,15 +178,8 @@ terminate_task_error (void *cls)
169{ 178{
170 err_task = NULL; 179 err_task = NULL;
171 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 180 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
172 "Testcase failed!\n"); 181 "Testcase failed (timeout)!\n");
173 terminate_peer (&p1); 182 GNUNET_SCHEDULER_shutdown ();
174 terminate_peer (&p2);
175 //GNUNET_break (0);
176 if (NULL != measure_task)
177 {
178 GNUNET_SCHEDULER_cancel (measure_task);
179 measure_task = NULL;
180 }
181 ok = 42; 183 ok = 42;
182} 184}
183 185
@@ -245,37 +247,63 @@ measurement_stop (void *cls)
245 ok = 1; /* fail */ 247 ok = 1; /* fail */
246 else 248 else
247 ok = 0; /* pass */ 249 ok = 0; /* pass */
248 GNUNET_STATISTICS_get (p1.stats, "core", "# discarded CORE_SEND requests", 250 GNUNET_STATISTICS_get (p1.stats,
249 NULL, &print_stat, &p1); 251 "core",
250 252 "# discarded CORE_SEND requests",
251 GNUNET_STATISTICS_get (p1.stats, "core", 253 NULL,
254 &print_stat,
255 &p1);
256 GNUNET_STATISTICS_get (p1.stats,
257 "core",
252 "# discarded CORE_SEND request bytes", 258 "# discarded CORE_SEND request bytes",
253 NULL, &print_stat, &p1); 259 NULL,
254 GNUNET_STATISTICS_get (p1.stats, "core", 260 &print_stat,
261 &p1);
262 GNUNET_STATISTICS_get (p1.stats,
263 "core",
255 "# discarded lower priority CORE_SEND requests", 264 "# discarded lower priority CORE_SEND requests",
256 NULL, &print_stat, NULL); 265 NULL,
257 GNUNET_STATISTICS_get (p1.stats, "core", 266 &print_stat,
267 NULL);
268 GNUNET_STATISTICS_get (p1.stats,
269 "core",
258 "# discarded lower priority CORE_SEND request bytes", 270 "# discarded lower priority CORE_SEND request bytes",
259 NULL, &print_stat, &p1); 271 NULL,
260 GNUNET_STATISTICS_get (p2.stats, "core", "# discarded CORE_SEND requests", 272 &print_stat,
261 NULL, &print_stat, &p2); 273 &p1);
262 274 GNUNET_STATISTICS_get (p2.stats,
263 GNUNET_STATISTICS_get (p2.stats, "core", 275 "core",
276 "# discarded CORE_SEND requests",
277 NULL,
278 &print_stat,
279 &p2);
280
281 GNUNET_STATISTICS_get (p2.stats,
282 "core",
264 "# discarded CORE_SEND request bytes", 283 "# discarded CORE_SEND request bytes",
265 NULL, &print_stat, &p2); 284 NULL,
266 GNUNET_STATISTICS_get (p2.stats, "core", 285 &print_stat,
286 &p2);
287 GNUNET_STATISTICS_get (p2.stats,
288 "core",
267 "# discarded lower priority CORE_SEND requests", 289 "# discarded lower priority CORE_SEND requests",
268 NULL, &print_stat, &p2); 290 NULL,
269 GNUNET_STATISTICS_get (p2.stats, "core", 291 &print_stat,
292 &p2);
293 GNUNET_STATISTICS_get (p2.stats,
294 "core",
270 "# discarded lower priority CORE_SEND request bytes", 295 "# discarded lower priority CORE_SEND request bytes",
271 NULL, &print_stat, &p2); 296 NULL,
297 &print_stat,
298 &p2);
272 299
273 if (ok != 0) 300 if (ok != 0)
274 kind = GNUNET_ERROR_TYPE_ERROR; 301 kind = GNUNET_ERROR_TYPE_ERROR;
275 switch (test) 302 switch (test)
276 { 303 {
277 case SYMMETRIC: 304 case SYMMETRIC:
278 GNUNET_log (kind, "Core quota compliance test with symmetric quotas: %s\n", 305 GNUNET_log (kind,
306 "Core quota compliance test with symmetric quotas: %s\n",
279 (0 == ok) ? "PASSED" : "FAILED"); 307 (0 == ok) ? "PASSED" : "FAILED");
280 break; 308 break;
281 case ASYMMETRIC_SEND_LIMITED: 309 case ASYMMETRIC_SEND_LIMITED:
@@ -289,23 +317,34 @@ measurement_stop (void *cls)
289 (0 == ok) ? "PASSED" : "FAILED"); 317 (0 == ok) ? "PASSED" : "FAILED");
290 break; 318 break;
291 }; 319 };
292 GNUNET_log (kind, "Peer 1 send rate: %llu b/s (%llu bytes in %llu ms)\n", 320 GNUNET_log (kind,
293 throughput_out, total_bytes_sent, delta); 321 "Peer 1 send rate: %llu b/s (%llu bytes in %llu ms)\n",
294 GNUNET_log (kind, "Peer 1 send quota: %llu b/s\n", current_quota_p1_out); 322 throughput_out,
295 GNUNET_log (kind, "Peer 2 receive rate: %llu b/s (%llu bytes in %llu ms)\n", 323 total_bytes_sent,
296 throughput_in, total_bytes_recv, delta); 324 delta);
297 GNUNET_log (kind, "Peer 2 receive quota: %llu b/s\n", current_quota_p2_in); 325 GNUNET_log (kind,
326 "Peer 1 send quota: %llu b/s\n",
327 current_quota_p1_out);
328 GNUNET_log (kind,
329 "Peer 2 receive rate: %llu b/s (%llu bytes in %llu ms)\n",
330 throughput_in,
331 total_bytes_recv,
332 delta);
333 GNUNET_log (kind,
334 "Peer 2 receive quota: %llu b/s\n",
335 current_quota_p2_in);
298/* 336/*
299 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Max. inbound quota allowed: %llu b/s\n",max_quota_in ); 337 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Max. inbound quota allowed: %llu b/s\n",max_quota_in );
300 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Max. outbound quota allowed: %llu b/s\n",max_quota_out); 338 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Max. outbound quota allowed: %llu b/s\n",max_quota_out);
301*/ 339*/
302 GNUNET_SCHEDULER_cancel (err_task); 340 GNUNET_SCHEDULER_shutdown ();
303 err_task = GNUNET_SCHEDULER_add_now (&terminate_task, NULL);
304} 341}
305 342
306 343
307static size_t 344static size_t
308transmit_ready (void *cls, size_t size, void *buf) 345transmit_ready (void *cls,
346 size_t size,
347 void *buf)
309{ 348{
310 char *cbuf = buf; 349 char *cbuf = buf;
311 struct TestMessage hdr; 350 struct TestMessage hdr;
@@ -313,43 +352,56 @@ transmit_ready (void *cls, size_t size, void *buf)
313 352
314 p1.nth = NULL; 353 p1.nth = NULL;
315 GNUNET_assert (size <= GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE); 354 GNUNET_assert (size <= GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE);
316 if (buf == NULL) 355 if (NULL == buf)
317 { 356 {
318 if ((p1.ch != NULL) && (p1.connect_status == 1)) 357 if ( (NULL != p1.ch) &&
358 (1 == p1.connect_status) )
319 GNUNET_break (NULL != 359 GNUNET_break (NULL !=
320 (p1.nth = 360 (p1.nth =
321 GNUNET_CORE_notify_transmit_ready (p1.ch, GNUNET_NO, 361 GNUNET_CORE_notify_transmit_ready (p1.ch,
362 GNUNET_NO,
322 GNUNET_CORE_PRIO_BEST_EFFORT, 363 GNUNET_CORE_PRIO_BEST_EFFORT,
323 FAST_TIMEOUT, &p2.id, 364 FAST_TIMEOUT,
365 &p2.id,
324 MESSAGESIZE, 366 MESSAGESIZE,
325 &transmit_ready, &p1))); 367 &transmit_ready,
368 &p1)));
326 return 0; 369 return 0;
327 } 370 }
328 GNUNET_assert (tr_n < TOTAL_MSGS); 371 GNUNET_assert (tr_n < TOTAL_MSGS);
329 ret = 0; 372 ret = 0;
330 GNUNET_assert (size >= MESSAGESIZE); 373 GNUNET_assert (size >= MESSAGESIZE);
331 GNUNET_assert (buf != NULL); 374 GNUNET_assert (NULL != buf);
332 cbuf = buf; 375 cbuf = buf;
333 do 376 do
334 { 377 {
335 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 378 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
336 "Sending message %u of size %u at offset %u\n", tr_n, 379 "Sending message %u of size %u at offset %u\n",
337 MESSAGESIZE, ret); 380 tr_n,
381 MESSAGESIZE,
382 ret);
338 hdr.header.size = htons (MESSAGESIZE); 383 hdr.header.size = htons (MESSAGESIZE);
339 hdr.header.type = htons (MTYPE); 384 hdr.header.type = htons (MTYPE);
340 hdr.num = htonl (tr_n); 385 hdr.num = htonl (tr_n);
341 GNUNET_memcpy (&cbuf[ret], &hdr, sizeof (struct TestMessage)); 386 GNUNET_memcpy (&cbuf[ret],
387 &hdr,
388 sizeof (struct TestMessage));
342 ret += sizeof (struct TestMessage); 389 ret += sizeof (struct TestMessage);
343 memset (&cbuf[ret], tr_n, MESSAGESIZE - sizeof (struct TestMessage)); 390 memset (&cbuf[ret],
391 tr_n,
392 MESSAGESIZE - sizeof (struct TestMessage));
344 ret += MESSAGESIZE - sizeof (struct TestMessage); 393 ret += MESSAGESIZE - sizeof (struct TestMessage);
345 tr_n++; 394 tr_n++;
346 if (0 == GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 16)) 395 if (0 == GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
396 16))
347 break; /* sometimes pack buffer full, sometimes not */ 397 break; /* sometimes pack buffer full, sometimes not */
348 } 398 }
349 while (size - ret >= MESSAGESIZE); 399 while (size - ret >= MESSAGESIZE);
350 GNUNET_SCHEDULER_cancel (err_task); 400 GNUNET_SCHEDULER_cancel (err_task);
351 err_task = 401 err_task =
352 GNUNET_SCHEDULER_add_delayed (TIMEOUT, &terminate_task_error, NULL); 402 GNUNET_SCHEDULER_add_delayed (TIMEOUT,
403 &terminate_task_error,
404 NULL);
353 405
354 total_bytes_sent += ret; 406 total_bytes_sent += ret;
355 return ret; 407 return ret;
@@ -357,48 +409,60 @@ transmit_ready (void *cls, size_t size, void *buf)
357 409
358 410
359static void 411static void
360connect_notify (void *cls, const struct GNUNET_PeerIdentity *peer) 412connect_notify (void *cls,
413 const struct GNUNET_PeerIdentity *peer)
361{ 414{
362 struct PeerContext *pc = cls; 415 struct PeerContext *pc = cls;
363 416
364 if (0 == memcmp (&pc->id, peer, sizeof (struct GNUNET_PeerIdentity))) 417 if (0 == memcmp (&pc->id,
418 peer,
419 sizeof (struct GNUNET_PeerIdentity)))
365 return; /* loopback */ 420 return; /* loopback */
366 GNUNET_assert (pc->connect_status == 0); 421 GNUNET_assert (0 == pc->connect_status);
367 pc->connect_status = 1; 422 pc->connect_status = 1;
368 if (pc == &p1) 423 if (pc == &p1)
369 { 424 {
370 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 425 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
371 "Encrypted connection established to peer `%4s'\n", 426 "Encrypted connection established to peer `%s'\n",
372 GNUNET_i2s (peer)); 427 GNUNET_i2s (peer));
373 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 428 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
374 "Asking core (1) for transmission to peer `%4s'\n", 429 "Asking core (1) for transmission to peer `%s'\n",
375 GNUNET_i2s (&p2.id)); 430 GNUNET_i2s (&p2.id));
376 GNUNET_SCHEDULER_cancel (err_task); 431 GNUNET_SCHEDULER_cancel (err_task);
377 err_task = 432 err_task =
378 GNUNET_SCHEDULER_add_delayed (TIMEOUT, &terminate_task_error, NULL); 433 GNUNET_SCHEDULER_add_delayed (TIMEOUT,
434 &terminate_task_error,
435 NULL);
379 start_time = GNUNET_TIME_absolute_get (); 436 start_time = GNUNET_TIME_absolute_get ();
380 running = GNUNET_YES; 437 running = GNUNET_YES;
381 measure_task = 438 measure_task =
382 GNUNET_SCHEDULER_add_delayed (MEASUREMENT_LENGTH, &measurement_stop, 439 GNUNET_SCHEDULER_add_delayed (MEASUREMENT_LENGTH,
440 &measurement_stop,
383 NULL); 441 NULL);
384 442
385 GNUNET_break (NULL != 443 GNUNET_break (NULL !=
386 (p1.nth = 444 (p1.nth =
387 GNUNET_CORE_notify_transmit_ready (p1.ch, GNUNET_NO, 445 GNUNET_CORE_notify_transmit_ready (p1.ch,
446 GNUNET_NO,
388 GNUNET_CORE_PRIO_BEST_EFFORT, 447 GNUNET_CORE_PRIO_BEST_EFFORT,
389 TIMEOUT, &p2.id, 448 TIMEOUT,
449 &p2.id,
390 MESSAGESIZE, 450 MESSAGESIZE,
391 &transmit_ready, &p1))); 451 &transmit_ready,
452 &p1)));
392 } 453 }
393} 454}
394 455
395 456
396static void 457static void
397disconnect_notify (void *cls, const struct GNUNET_PeerIdentity *peer) 458disconnect_notify (void *cls,
459 const struct GNUNET_PeerIdentity *peer)
398{ 460{
399 struct PeerContext *pc = cls; 461 struct PeerContext *pc = cls;
400 462
401 if (0 == memcmp (&pc->id, peer, sizeof (struct GNUNET_PeerIdentity))) 463 if (0 == memcmp (&pc->id,
464 peer,
465 sizeof (struct GNUNET_PeerIdentity)))
402 return; /* loopback */ 466 return; /* loopback */
403 pc->connect_status = 0; 467 pc->connect_status = 0;
404 if (NULL != measure_task) 468 if (NULL != measure_task)
@@ -408,12 +472,13 @@ disconnect_notify (void *cls, const struct GNUNET_PeerIdentity *peer)
408 GNUNET_SCHEDULER_cancel (measure_task); 472 GNUNET_SCHEDULER_cancel (measure_task);
409 measure_task = NULL; 473 measure_task = NULL;
410 } 474 }
411 if (pc->nth != NULL) 475 if (NULL != pc->nth)
412 { 476 {
413 GNUNET_CORE_notify_transmit_ready_cancel (pc->nth); 477 GNUNET_CORE_notify_transmit_ready_cancel (pc->nth);
414 pc->nth = NULL; 478 pc->nth = NULL;
415 } 479 }
416 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Encrypted connection to `%4s' cut\n", 480 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
481 "Encrypted connection to `%s' cut\n",
417 GNUNET_i2s (peer)); 482 GNUNET_i2s (peer));
418} 483}
419 484
@@ -424,7 +489,7 @@ inbound_notify (void *cls,
424 const struct GNUNET_MessageHeader *message) 489 const struct GNUNET_MessageHeader *message)
425{ 490{
426 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 491 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
427 "Core provides inbound data from `%4s' %u.\n", 492 "Core provides inbound data from `%s' %u.\n",
428 GNUNET_i2s (other), 493 GNUNET_i2s (other),
429 (unsigned int) ntohs (message->size)); 494 (unsigned int) ntohs (message->size));
430 total_bytes_recv += ntohs (message->size); 495 total_bytes_recv += ntohs (message->size);
@@ -438,7 +503,7 @@ outbound_notify (void *cls,
438 const struct GNUNET_MessageHeader *message) 503 const struct GNUNET_MessageHeader *message)
439{ 504{
440 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 505 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
441 "Core notifies about outbound data for `%4s'.\n", 506 "Core notifies about outbound data for `%s'.\n",
442 GNUNET_i2s (other)); 507 GNUNET_i2s (other));
443 return GNUNET_OK; 508 return GNUNET_OK;
444} 509}
@@ -449,7 +514,8 @@ transmit_ready (void *cls, size_t size, void *buf);
449 514
450 515
451static int 516static int
452process_mtype (void *cls, const struct GNUNET_PeerIdentity *peer, 517process_mtype (void *cls,
518 const struct GNUNET_PeerIdentity *peer,
453 const struct GNUNET_MessageHeader *message) 519 const struct GNUNET_MessageHeader *message)
454{ 520{
455 static int n; 521 static int n;
@@ -462,34 +528,46 @@ process_mtype (void *cls, const struct GNUNET_PeerIdentity *peer,
462 { 528 {
463 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 529 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
464 "Expected message %u of size %u, got %u bytes of message %u\n", 530 "Expected message %u of size %u, got %u bytes of message %u\n",
465 n, MESSAGESIZE, ntohs (message->size), ntohl (hdr->num)); 531 n,
532 MESSAGESIZE,
533 ntohs (message->size),
534 ntohl (hdr->num));
466 GNUNET_SCHEDULER_cancel (err_task); 535 GNUNET_SCHEDULER_cancel (err_task);
467 err_task = GNUNET_SCHEDULER_add_now (&terminate_task_error, NULL); 536 err_task = GNUNET_SCHEDULER_add_now (&terminate_task_error,
537 NULL);
468 return GNUNET_SYSERR; 538 return GNUNET_SYSERR;
469 } 539 }
470 if (ntohl (hdr->num) != n) 540 if (ntohl (hdr->num) != n)
471 { 541 {
472 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 542 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
473 "Expected message %u of size %u, got %u bytes of message %u\n", 543 "Expected message %u of size %u, got %u bytes of message %u\n",
474 n, MESSAGESIZE, ntohs (message->size), ntohl (hdr->num)); 544 n,
545 MESSAGESIZE,
546 ntohs (message->size),
547 ntohl (hdr->num));
475 GNUNET_SCHEDULER_cancel (err_task); 548 GNUNET_SCHEDULER_cancel (err_task);
476 err_task = GNUNET_SCHEDULER_add_now (&terminate_task_error, NULL); 549 err_task = GNUNET_SCHEDULER_add_now (&terminate_task_error,
550 NULL);
477 return GNUNET_SYSERR; 551 return GNUNET_SYSERR;
478 } 552 }
479 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got message %u of size %u\n", 553 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
480 ntohl (hdr->num), ntohs (message->size)); 554 "Got message %u of size %u\n",
555 ntohl (hdr->num),
556 ntohs (message->size));
481 n++; 557 n++;
482 if (0 == (n % 10)) 558 if (0 == (n % 10))
483 FPRINTF (stderr, "%s", "."); 559 FPRINTF (stderr, "%s", ".");
484 560
485 561 if (GNUNET_YES == running)
486 if (running == GNUNET_YES)
487 GNUNET_break (NULL != 562 GNUNET_break (NULL !=
488 GNUNET_CORE_notify_transmit_ready (p1.ch, GNUNET_NO, 563 (p1.nth = GNUNET_CORE_notify_transmit_ready (p1.ch,
489 GNUNET_CORE_PRIO_BEST_EFFORT, 564 GNUNET_NO,
490 FAST_TIMEOUT, &p2.id, 565 GNUNET_CORE_PRIO_BEST_EFFORT,
491 MESSAGESIZE, 566 FAST_TIMEOUT,
492 &transmit_ready, &p1)); 567 &p2.id,
568 MESSAGESIZE,
569 &transmit_ready,
570 &p1)));
493 return GNUNET_OK; 571 return GNUNET_OK;
494} 572}
495 573
@@ -518,9 +596,16 @@ init_notify (void *cls,
518 OKPP; 596 OKPP;
519 /* connect p2 */ 597 /* connect p2 */
520 p2.ch = 598 p2.ch =
521 GNUNET_CORE_connect (p2.cfg, &p2, &init_notify, &connect_notify, 599 GNUNET_CORE_connect (p2.cfg,
522 &disconnect_notify, &inbound_notify, GNUNET_YES, 600 &p2,
523 &outbound_notify, GNUNET_YES, handlers); 601 &init_notify,
602 &connect_notify,
603 &disconnect_notify,
604 &inbound_notify,
605 GNUNET_YES,
606 &outbound_notify,
607 GNUNET_YES,
608 handlers);
524 } 609 }
525 else 610 else
526 { 611 {
@@ -550,12 +635,13 @@ offer_hello_done (void *cls)
550 635
551 636
552static void 637static void
553process_hello (void *cls, const struct GNUNET_MessageHeader *message) 638process_hello (void *cls,
639 const struct GNUNET_MessageHeader *message)
554{ 640{
555 struct PeerContext *p = cls; 641 struct PeerContext *p = cls;
556 642
557 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 643 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
558 "Received (my) `%s' from transport service\n", "HELLO"); 644 "Received (my) HELLO from transport service\n");
559 GNUNET_assert (message != NULL); 645 GNUNET_assert (message != NULL);
560 p->hello = GNUNET_malloc (ntohs (message->size)); 646 p->hello = GNUNET_malloc (ntohs (message->size));
561 GNUNET_memcpy (p->hello, message, ntohs (message->size)); 647 GNUNET_memcpy (p->hello, message, ntohs (message->size));
@@ -583,7 +669,8 @@ process_hello (void *cls, const struct GNUNET_MessageHeader *message)
583 669
584 670
585static void 671static void
586setup_peer (struct PeerContext *p, const char *cfgname) 672setup_peer (struct PeerContext *p,
673 const char *cfgname)
587{ 674{
588 char *binary; 675 char *binary;
589 676
@@ -606,13 +693,19 @@ setup_peer (struct PeerContext *p, const char *cfgname)
606 693
607 694
608static void 695static void
609run (void *cls, char *const *args, const char *cfgfile, 696run (void *cls,
697 char *const *args,
698 const char *cfgfile,
610 const struct GNUNET_CONFIGURATION_Handle *cfg) 699 const struct GNUNET_CONFIGURATION_Handle *cfg)
611{ 700{
612 GNUNET_assert (ok == 1); 701 GNUNET_assert (ok == 1);
613 OKPP; 702 OKPP;
614 err_task = 703 err_task =
615 GNUNET_SCHEDULER_add_delayed (TIMEOUT, &terminate_task_error, NULL); 704 GNUNET_SCHEDULER_add_delayed (TIMEOUT,
705 &terminate_task_error,
706 NULL);
707 GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
708 NULL);
616 if (test == SYMMETRIC) 709 if (test == SYMMETRIC)
617 { 710 {
618 setup_peer (&p1, "test_core_quota_peer1.conf"); 711 setup_peer (&p1, "test_core_quota_peer1.conf");
@@ -657,11 +750,16 @@ run (void *cls, char *const *args, const char *cfgfile,
657static void 750static void
658stop_arm (struct PeerContext *p) 751stop_arm (struct PeerContext *p)
659{ 752{
660 if (0 != GNUNET_OS_process_kill (p->arm_proc, GNUNET_TERM_SIG)) 753 if (0 != GNUNET_OS_process_kill (p->arm_proc,
661 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); 754 GNUNET_TERM_SIG))
662 if (GNUNET_OS_process_wait (p->arm_proc) != GNUNET_OK) 755 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
663 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid"); 756 "kill");
664 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ARM process %u stopped\n", 757 if (GNUNET_OK !=
758 GNUNET_OS_process_wait (p->arm_proc))
759 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
760 "waitpid");
761 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
762 "ARM process %u stopped\n",
665 GNUNET_OS_process_get_pid (p->arm_proc)); 763 GNUNET_OS_process_get_pid (p->arm_proc));
666 GNUNET_OS_process_destroy (p->arm_proc); 764 GNUNET_OS_process_destroy (p->arm_proc);
667 p->arm_proc = NULL; 765 p->arm_proc = NULL;
@@ -672,7 +770,8 @@ stop_arm (struct PeerContext *p)
672static int 770static int
673check () 771check ()
674{ 772{
675 char *const argv[] = { "test-core-quota-compliance", 773 char *const argv[] = {
774 "test-core-quota-compliance",
676 "-c", 775 "-c",
677 "test_core_api_data.conf", 776 "test_core_api_data.conf",
678 NULL 777 NULL
@@ -681,8 +780,12 @@ check ()
681 GNUNET_GETOPT_OPTION_END 780 GNUNET_GETOPT_OPTION_END
682 }; 781 };
683 ok = 1; 782 ok = 1;
684 GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, argv, 783 GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1,
685 "test-core-quota-compliance", "nohelp", options, &run, 784 argv,
785 "test-core-quota-compliance",
786 "nohelp",
787 options,
788 &run,
686 &ok); 789 &ok);
687 stop_arm (&p1); 790 stop_arm (&p1);
688 stop_arm (&p2); 791 stop_arm (&p2);
@@ -691,7 +794,8 @@ check ()
691 794
692 795
693int 796int
694main (int argc, char *argv[]) 797main (int argc,
798 char *argv[])
695{ 799{
696 int ret; 800 int ret;
697 801