aboutsummaryrefslogtreecommitdiff
path: root/src/cadet
diff options
context:
space:
mode:
Diffstat (limited to 'src/cadet')
-rw-r--r--src/cadet/Makefile.am12
-rw-r--r--src/cadet/cadet.conf.in6
-rw-r--r--src/cadet/cadet.h28
-rw-r--r--src/cadet/cadet_api.c258
-rw-r--r--src/cadet/cadet_protocol.h51
-rw-r--r--src/cadet/cadet_test_lib.c88
-rw-r--r--src/cadet/cadet_test_lib.h18
-rw-r--r--src/cadet/gnunet-cadet-profiler.c18
-rw-r--r--src/cadet/gnunet-cadet.c101
-rw-r--r--src/cadet/gnunet-service-cadet.c85
-rw-r--r--src/cadet/gnunet-service-cadet.h18
-rw-r--r--src/cadet/gnunet-service-cadet_channel.c32
-rw-r--r--src/cadet/gnunet-service-cadet_channel.h18
-rw-r--r--src/cadet/gnunet-service-cadet_connection.c114
-rw-r--r--src/cadet/gnunet-service-cadet_connection.h22
-rw-r--r--src/cadet/gnunet-service-cadet_core.c139
-rw-r--r--src/cadet/gnunet-service-cadet_core.h18
-rw-r--r--src/cadet/gnunet-service-cadet_dht.c18
-rw-r--r--src/cadet/gnunet-service-cadet_dht.h18
-rw-r--r--src/cadet/gnunet-service-cadet_hello.c25
-rw-r--r--src/cadet/gnunet-service-cadet_hello.h18
-rw-r--r--src/cadet/gnunet-service-cadet_paths.c22
-rw-r--r--src/cadet/gnunet-service-cadet_paths.h18
-rw-r--r--src/cadet/gnunet-service-cadet_peer.c103
-rw-r--r--src/cadet/gnunet-service-cadet_peer.h31
-rw-r--r--src/cadet/gnunet-service-cadet_tunnels.c563
-rw-r--r--src/cadet/gnunet-service-cadet_tunnels.h18
-rw-r--r--src/cadet/test_cadet.c331
-rw-r--r--src/cadet/test_cadet.conf34
-rw-r--r--src/cadet/test_cadet_flow.c886
-rw-r--r--src/cadet/test_cadet_local_mq.c30
31 files changed, 2360 insertions, 781 deletions
diff --git a/src/cadet/Makefile.am b/src/cadet/Makefile.am
index ce30ebe46..b2d436061 100644
--- a/src/cadet/Makefile.am
+++ b/src/cadet/Makefile.am
@@ -90,6 +90,7 @@ check_PROGRAMS = \
90 test_cadet_2_speed_backwards \ 90 test_cadet_2_speed_backwards \
91 test_cadet_2_speed_reliable \ 91 test_cadet_2_speed_reliable \
92 test_cadet_2_speed_reliable_backwards \ 92 test_cadet_2_speed_reliable_backwards \
93 test_cadet_2_reopen \
93 test_cadet_5_forward \ 94 test_cadet_5_forward \
94 test_cadet_5_signal \ 95 test_cadet_5_signal \
95 test_cadet_5_keepalive \ 96 test_cadet_5_keepalive \
@@ -97,7 +98,8 @@ check_PROGRAMS = \
97 test_cadet_5_speed_ack \ 98 test_cadet_5_speed_ack \
98 test_cadet_5_speed_reliable \ 99 test_cadet_5_speed_reliable \
99 test_cadet_5_speed_reliable_backwards \ 100 test_cadet_5_speed_reliable_backwards \
100 test_cadet_5_speed_backwards 101 test_cadet_5_speed_backwards \
102 test_cadet_5_reopen
101endif 103endif
102 104
103 105
@@ -197,6 +199,14 @@ test_cadet_5_speed_reliable_backwards_SOURCES = \
197 test_cadet.c 199 test_cadet.c
198test_cadet_5_speed_reliable_backwards_LDADD = $(ld_cadet_test_lib) 200test_cadet_5_speed_reliable_backwards_LDADD = $(ld_cadet_test_lib)
199 201
202test_cadet_2_reopen_SOURCES = \
203 test_cadet.c
204test_cadet_2_reopen_LDADD = $(ld_cadet_test_lib)
205
206test_cadet_5_reopen_SOURCES = \
207 test_cadet.c
208test_cadet_5_reopen_LDADD = $(ld_cadet_test_lib)
209
200 210
201if ENABLE_TEST_RUN 211if ENABLE_TEST_RUN
202AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH;unset XDG_DATA_HOME;unset XDG_CONFIG_HOME; 212AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH;unset XDG_DATA_HOME;unset XDG_CONFIG_HOME;
diff --git a/src/cadet/cadet.conf.in b/src/cadet/cadet.conf.in
index d50e168f0..d1ddcb96f 100644
--- a/src/cadet/cadet.conf.in
+++ b/src/cadet/cadet.conf.in
@@ -1,6 +1,6 @@
1[cadet] 1[cadet]
2FORCESTART = YES 2IMMEDIATE_START = YES
3AUTOSTART = @AUTOSTART@ 3START_ON_DEMAND = @START_ON_DEMAND@
4@JAVAPORT@PORT = 2096 4@JAVAPORT@PORT = 2096
5HOSTNAME = localhost 5HOSTNAME = localhost
6BINARY = gnunet-service-cadet 6BINARY = gnunet-service-cadet
@@ -8,7 +8,7 @@ BINARY = gnunet-service-cadet
8ACCEPT_FROM = 127.0.0.1; 8ACCEPT_FROM = 127.0.0.1;
9ACCEPT_FROM6 = ::1; 9ACCEPT_FROM6 = ::1;
10UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-cadet.sock 10UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-cadet.sock
11UNIX_MATCH_UID = YES 11UNIX_MATCH_UID = NO
12UNIX_MATCH_GID = YES 12UNIX_MATCH_GID = YES
13 13
14 14
diff --git a/src/cadet/cadet.h b/src/cadet/cadet.h
index 99f9f2653..bac4bc49d 100644
--- a/src/cadet/cadet.h
+++ b/src/cadet/cadet.h
@@ -2,20 +2,18 @@
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2001 - 2011 GNUnet e.V. 3 Copyright (C) 2001 - 2011 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 it
6 it under the terms of the GNU General Public License as published 6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation; either version 3, or (at your 7 by the Free Software Foundation, either version 3 of the License,
8 option) any later version. 8 or (at your option) any later version.
9 9
10 GNUnet is distributed in the hope that it will be useful, but 10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details. 13 Affero General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU Affero General Public License
16 along with GNUnet; see the file COPYING. If not, write to the 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/ 17*/
20 18
21/** 19/**
@@ -260,6 +258,11 @@ struct GNUNET_CADET_LocalInfoPeer
260 * #GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS 258 * #GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS
261 */ 259 */
262 struct GNUNET_MessageHeader header; 260 struct GNUNET_MessageHeader header;
261
262 /**
263 * Offset the peer has in the path this message is about.
264 */
265 uint16_t offset GNUNET_PACKED;
263 266
264 /** 267 /**
265 * Number of paths. 268 * Number of paths.
@@ -270,6 +273,11 @@ struct GNUNET_CADET_LocalInfoPeer
270 * Do we have a tunnel toward this peer? 273 * Do we have a tunnel toward this peer?
271 */ 274 */
272 int16_t tunnel GNUNET_PACKED; 275 int16_t tunnel GNUNET_PACKED;
276
277 /**
278 * We are finished with the paths.
279 */
280 uint16_t finished_with_paths;
273 281
274 /** 282 /**
275 * ID of the peer (can be local peer). 283 * ID of the peer (can be local peer).
diff --git a/src/cadet/cadet_api.c b/src/cadet/cadet_api.c
index 3c142a95c..23ea46e59 100644
--- a/src/cadet/cadet_api.c
+++ b/src/cadet/cadet_api.c
@@ -2,20 +2,18 @@
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2011, 2017 GNUnet e.V. 3 Copyright (C) 2011, 2017 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 it
6 it under the terms of the GNU General Public License as published 6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation; either version 3, or (at your 7 by the Free Software Foundation, either version 3 of the License,
8 option) any later version. 8 or (at your option) any later version.
9 9
10 GNUnet is distributed in the hope that it will be useful, but 10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details. 13 Affero General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU Affero General Public License
16 along with GNUnet; see the file COPYING. If not, write to the 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/ 17*/
20/** 18/**
21 * @file cadet/cadet_api.c 19 * @file cadet/cadet_api.c
@@ -359,67 +357,52 @@ reconnect (struct GNUNET_CADET_Handle *h);
359 357
360 358
361/** 359/**
362 * Reconnect callback: tries to reconnect again after a failer previous 360 * Function called during #reconnect_cbk() to (re)open
363 * reconnecttion 361 * all ports that are still open.
364 *
365 * @param cls closure (cadet handle)
366 */
367static void
368reconnect_cbk (void *cls)
369{
370 struct GNUNET_CADET_Handle *h = cls;
371
372 h->reconnect_task = NULL;
373 reconnect (h);
374}
375
376
377/**
378 * Function called during #reconnect() to destroy
379 * all channels that are still open.
380 * 362 *
381 * @param cls the `struct GNUNET_CADET_Handle` 363 * @param cls the `struct GNUNET_CADET_Handle`
382 * @param cid chanenl ID 364 * @param id port ID
383 * @param value a `struct GNUNET_CADET_Channel` to destroy 365 * @param value a `struct GNUNET_CADET_Channel` to open
384 * @return #GNUNET_OK (continue to iterate) 366 * @return #GNUNET_OK (continue to iterate)
385 */ 367 */
386static int 368static int
387destroy_channel_on_reconnect_cb (void *cls, 369open_port_cb (void *cls,
388 uint32_t cid, 370 const struct GNUNET_HashCode *id,
389 void *value) 371 void *value)
390{ 372{
391 /* struct GNUNET_CADET_Handle *handle = cls; */ 373 struct GNUNET_CADET_Handle *h = cls;
392 struct GNUNET_CADET_Channel *ch = value; 374 struct GNUNET_CADET_Port *port = value;
375 struct GNUNET_CADET_PortMessage *msg;
376 struct GNUNET_MQ_Envelope *env;
393 377
394 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 378 (void) id;
395 "Destroying channel due to reconnect\n"); 379 env = GNUNET_MQ_msg (msg,
396 destroy_channel (ch); 380 GNUNET_MESSAGE_TYPE_CADET_LOCAL_PORT_OPEN);
381 msg->port = port->id;
382 GNUNET_MQ_send (h->mq,
383 env);
397 return GNUNET_OK; 384 return GNUNET_OK;
398} 385}
399 386
400 387
401/** 388/**
402 * Reconnect to the service, retransmit all infomation to try to restore the 389 * Reconnect callback: tries to reconnect again after a failer previous
403 * original state. 390 * reconnecttion
404 *
405 * @param h handle to the cadet
406 * 391 *
407 * @return #GNUNET_YES in case of sucess, #GNUNET_NO otherwise (service down...) 392 * @param cls closure (cadet handle)
408 */ 393 */
409static void 394static void
410schedule_reconnect (struct GNUNET_CADET_Handle *h) 395reconnect_cbk (void *cls)
411{ 396{
412 if (NULL != h->reconnect_task) 397 struct GNUNET_CADET_Handle *h = cls;
413 return; 398
414 GNUNET_CONTAINER_multihashmap32_iterate (h->channels, 399 h->reconnect_task = NULL;
415 &destroy_channel_on_reconnect_cb,
416 h);
417 h->reconnect_task
418 = GNUNET_SCHEDULER_add_delayed (h->reconnect_time,
419 &reconnect_cbk,
420 h);
421 h->reconnect_time 400 h->reconnect_time
422 = GNUNET_TIME_STD_BACKOFF (h->reconnect_time); 401 = GNUNET_TIME_STD_BACKOFF (h->reconnect_time);
402 reconnect (h);
403 GNUNET_CONTAINER_multihashmap_iterate (h->ports,
404 &open_port_cb,
405 h);
423} 406}
424 407
425 408
@@ -464,6 +447,10 @@ cadet_mq_send_now (void *cls)
464 } 447 }
465 ch->allow_send--; 448 ch->allow_send--;
466 ch->pending_env = NULL; 449 ch->pending_env = NULL;
450 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
451 "Sending message on channel %s to CADET, new window size is %u\n",
452 GNUNET_i2s (&ch->peer),
453 ch->allow_send);
467 GNUNET_MQ_send (ch->cadet->mq, 454 GNUNET_MQ_send (ch->cadet->mq,
468 env); 455 env);
469 GNUNET_MQ_impl_send_continue (ch->mq); 456 GNUNET_MQ_impl_send_continue (ch->mq);
@@ -553,15 +540,19 @@ cadet_mq_error_handler (void *cls,
553{ 540{
554 struct GNUNET_CADET_Channel *ch = cls; 541 struct GNUNET_CADET_Channel *ch = cls;
555 542
556 GNUNET_break (0);
557 if (GNUNET_MQ_ERROR_NO_MATCH == error) 543 if (GNUNET_MQ_ERROR_NO_MATCH == error)
558 { 544 {
559 /* Got a message we did not understand, still try to continue! */ 545 /* Got a message we did not understand, still try to continue! */
546 GNUNET_break_op (0);
560 GNUNET_CADET_receive_done (ch); 547 GNUNET_CADET_receive_done (ch);
561 } 548 }
562 else 549 else
563 { 550 {
564 schedule_reconnect (ch->cadet); 551 GNUNET_break (0);
552 if (NULL != ch->disconnects)
553 ch->disconnects (ch->ctx,
554 ch);
555 GNUNET_CADET_channel_destroy (ch);
565 } 556 }
566} 557}
567 558
@@ -579,6 +570,7 @@ cadet_mq_cancel_impl (struct GNUNET_MQ_Handle *mq,
579{ 570{
580 struct GNUNET_CADET_Channel *ch = impl_state; 571 struct GNUNET_CADET_Channel *ch = impl_state;
581 572
573 (void) mq;
582 GNUNET_assert (NULL != ch->pending_env); 574 GNUNET_assert (NULL != ch->pending_env);
583 GNUNET_MQ_discard (ch->pending_env); 575 GNUNET_MQ_discard (ch->pending_env);
584 ch->pending_env = NULL; 576 ch->pending_env = NULL;
@@ -707,6 +699,7 @@ check_local_data (void *cls,
707{ 699{
708 uint16_t size; 700 uint16_t size;
709 701
702 (void) cls;
710 size = ntohs (message->header.size); 703 size = ntohs (message->header.size);
711 if (sizeof (*message) + sizeof (struct GNUNET_MessageHeader) > size) 704 if (sizeof (*message) + sizeof (struct GNUNET_MessageHeader) > size)
712 { 705 {
@@ -781,6 +774,11 @@ handle_local_ack (void *cls,
781 return; 774 return;
782 } 775 }
783 ch->allow_send++; 776 ch->allow_send++;
777 LOG (GNUNET_ERROR_TYPE_DEBUG,
778 "Got an ACK on mq channel %X (peer %s); new window size is %u!\n",
779 ntohl (ch->ccn.channel_of_client),
780 GNUNET_i2s (&ch->peer),
781 ch->allow_send);
784 if (NULL == ch->pending_env) 782 if (NULL == ch->pending_env)
785 { 783 {
786 LOG (GNUNET_ERROR_TYPE_DEBUG, 784 LOG (GNUNET_ERROR_TYPE_DEBUG,
@@ -792,9 +790,6 @@ handle_local_ack (void *cls,
792 } 790 }
793 if (NULL != ch->mq_cont) 791 if (NULL != ch->mq_cont)
794 return; /* already working on it! */ 792 return; /* already working on it! */
795 LOG (GNUNET_ERROR_TYPE_DEBUG,
796 "Got an ACK on mq channel %X, sending pending message!\n",
797 ntohl (ch->ccn.channel_of_client));
798 ch->mq_cont 793 ch->mq_cont
799 = GNUNET_SCHEDULER_add_now (&cadet_mq_send_now, 794 = GNUNET_SCHEDULER_add_now (&cadet_mq_send_now,
800 ch); 795 ch);
@@ -802,6 +797,32 @@ handle_local_ack (void *cls,
802 797
803 798
804/** 799/**
800 * Function called during #GNUNET_CADET_disconnect() to destroy
801 * all channels that are still open.
802 *
803 * @param cls the `struct GNUNET_CADET_Handle`
804 * @param cid chanenl ID
805 * @param value a `struct GNUNET_CADET_Channel` to destroy
806 * @return #GNUNET_OK (continue to iterate)
807 */
808static int
809destroy_channel_cb (void *cls,
810 uint32_t cid,
811 void *value)
812{
813 /* struct GNUNET_CADET_Handle *handle = cls; */
814 struct GNUNET_CADET_Channel *ch = value;
815
816 (void) cls;
817 (void) cid;
818 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
819 "Destroying channel due to GNUNET_CADET_disconnect()\n");
820 destroy_channel (ch);
821 return GNUNET_OK;
822}
823
824
825/**
805 * Generic error handler, called with the appropriate error code and 826 * Generic error handler, called with the appropriate error code and
806 * the same closure specified at the creation of the message queue. 827 * the same closure specified at the creation of the message queue.
807 * Not every message queue implementation supports an error handler. 828 * Not every message queue implementation supports an error handler.
@@ -818,9 +839,15 @@ handle_mq_error (void *cls,
818 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 839 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
819 "MQ ERROR: %u\n", 840 "MQ ERROR: %u\n",
820 error); 841 error);
842 GNUNET_CONTAINER_multihashmap32_iterate (h->channels,
843 &destroy_channel_cb,
844 h);
821 GNUNET_MQ_destroy (h->mq); 845 GNUNET_MQ_destroy (h->mq);
822 h->mq = NULL; 846 h->mq = NULL;
823 reconnect (h); 847 GNUNET_assert (NULL == h->reconnect_task);
848 h->reconnect_task = GNUNET_SCHEDULER_add_delayed (h->reconnect_time,
849 &reconnect_cbk,
850 h);
824} 851}
825 852
826 853
@@ -838,6 +865,7 @@ check_get_peers (void *cls,
838{ 865{
839 size_t esize; 866 size_t esize;
840 867
868 (void) cls;
841 esize = ntohs (message->size); 869 esize = ntohs (message->size);
842 if (sizeof (struct GNUNET_CADET_LocalInfoPeer) == esize) 870 if (sizeof (struct GNUNET_CADET_LocalInfoPeer) == esize)
843 return GNUNET_OK; 871 return GNUNET_OK;
@@ -891,12 +919,9 @@ check_get_peer (void *cls,
891 const struct GNUNET_CADET_LocalInfoPeer *message) 919 const struct GNUNET_CADET_LocalInfoPeer *message)
892{ 920{
893 size_t msize = sizeof (struct GNUNET_CADET_LocalInfoPeer); 921 size_t msize = sizeof (struct GNUNET_CADET_LocalInfoPeer);
894 const struct GNUNET_PeerIdentity *paths_array;
895 size_t esize; 922 size_t esize;
896 unsigned int epaths;
897 unsigned int paths;
898 unsigned int peers;
899 923
924 (void) cls;
900 esize = ntohs (message->header.size); 925 esize = ntohs (message->header.size);
901 if (esize < msize) 926 if (esize < msize)
902 { 927 {
@@ -908,20 +933,6 @@ check_get_peer (void *cls,
908 GNUNET_break (0); 933 GNUNET_break (0);
909 return GNUNET_SYSERR; 934 return GNUNET_SYSERR;
910 } 935 }
911 peers = (esize - msize) / sizeof (struct GNUNET_PeerIdentity);
912 epaths = ntohs (message->paths);
913 paths_array = (const struct GNUNET_PeerIdentity *) &message[1];
914 paths = 0;
915 for (unsigned int i = 0; i < peers; i++)
916 if (0 == memcmp (&paths_array[i],
917 &message->destination,
918 sizeof (struct GNUNET_PeerIdentity)))
919 paths++;
920 if (paths != epaths)
921 {
922 GNUNET_break (0);
923 return GNUNET_SYSERR;
924 }
925 return GNUNET_OK; 936 return GNUNET_OK;
926} 937}
927 938
@@ -945,6 +956,11 @@ handle_get_peer (void *cls,
945 956
946 if (NULL == h->info_cb.peer_cb) 957 if (NULL == h->info_cb.peer_cb)
947 return; 958 return;
959
960 LOG (GNUNET_ERROR_TYPE_DEBUG,
961 "number of paths %u\n",
962 ntohs (message->paths));
963
948 paths = ntohs (message->paths); 964 paths = ntohs (message->paths);
949 paths_array = (const struct GNUNET_PeerIdentity *) &message[1]; 965 paths_array = (const struct GNUNET_PeerIdentity *) &message[1];
950 peers = (ntohs (message->header.size) - sizeof (*message)) 966 peers = (ntohs (message->header.size) - sizeof (*message))
@@ -974,7 +990,9 @@ handle_get_peer (void *cls,
974 (int) ntohs (message->tunnel), 990 (int) ntohs (message->tunnel),
975 neighbor, 991 neighbor,
976 paths, 992 paths,
977 paths_array); 993 paths_array,
994 (int) ntohs (message->offset),
995 (int) ntohs (message->finished_with_paths));
978} 996}
979 997
980 998
@@ -992,6 +1010,7 @@ check_get_tunnels (void *cls,
992{ 1010{
993 size_t esize; 1011 size_t esize;
994 1012
1013 (void) cls;
995 esize = ntohs (message->size); 1014 esize = ntohs (message->size);
996 if (sizeof (struct GNUNET_CADET_LocalInfoTunnel) == esize) 1015 if (sizeof (struct GNUNET_CADET_LocalInfoTunnel) == esize)
997 return GNUNET_OK; 1016 return GNUNET_OK;
@@ -1051,6 +1070,7 @@ check_get_tunnel (void *cls,
1051 size_t esize; 1070 size_t esize;
1052 size_t msize; 1071 size_t msize;
1053 1072
1073 (void) cls;
1054 /* Verify message sanity */ 1074 /* Verify message sanity */
1055 msize = ntohs (msg->header.size); 1075 msize = ntohs (msg->header.size);
1056 esize = sizeof (struct GNUNET_CADET_LocalInfoTunnel); 1076 esize = sizeof (struct GNUNET_CADET_LocalInfoTunnel);
@@ -1096,7 +1116,6 @@ handle_get_tunnel (void *cls,
1096 1116
1097 if (NULL == h->info_cb.tunnel_cb) 1117 if (NULL == h->info_cb.tunnel_cb)
1098 return; 1118 return;
1099
1100 ch_n = ntohl (msg->channels); 1119 ch_n = ntohl (msg->channels);
1101 c_n = ntohl (msg->connections); 1120 c_n = ntohl (msg->connections);
1102 1121
@@ -1165,43 +1184,6 @@ reconnect (struct GNUNET_CADET_Handle *h)
1165 handlers, 1184 handlers,
1166 &handle_mq_error, 1185 &handle_mq_error,
1167 h); 1186 h);
1168 if (NULL == h->mq)
1169 {
1170 schedule_reconnect (h);
1171 return;
1172 }
1173 h->reconnect_time = GNUNET_TIME_UNIT_MILLISECONDS;
1174}
1175
1176
1177/**
1178 * Function called during #GNUNET_CADET_disconnect() to destroy
1179 * all channels that are still open.
1180 *
1181 * @param cls the `struct GNUNET_CADET_Handle`
1182 * @param cid chanenl ID
1183 * @param value a `struct GNUNET_CADET_Channel` to destroy
1184 * @return #GNUNET_OK (continue to iterate)
1185 */
1186static int
1187destroy_channel_cb (void *cls,
1188 uint32_t cid,
1189 void *value)
1190{
1191 /* struct GNUNET_CADET_Handle *handle = cls; */
1192 struct GNUNET_CADET_Channel *ch = value;
1193
1194 if (ntohl (ch->ccn.channel_of_client) >= GNUNET_CADET_LOCAL_CHANNEL_ID_CLI)
1195 {
1196 GNUNET_break (0);
1197 LOG (GNUNET_ERROR_TYPE_DEBUG,
1198 "channel %X not destroyed\n",
1199 ntohl (ch->ccn.channel_of_client));
1200 }
1201 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1202 "Destroying channel due to GNUNET_CADET_disconnect()\n");
1203 destroy_channel (ch);
1204 return GNUNET_OK;
1205} 1187}
1206 1188
1207 1189
@@ -1222,6 +1204,8 @@ destroy_port_cb (void *cls,
1222 /* struct GNUNET_CADET_Handle *handle = cls; */ 1204 /* struct GNUNET_CADET_Handle *handle = cls; */
1223 struct GNUNET_CADET_Port *port = value; 1205 struct GNUNET_CADET_Port *port = value;
1224 1206
1207 (void) cls;
1208 (void) id;
1225 /* This is a warning, the app should have cleanly closed all open ports */ 1209 /* This is a warning, the app should have cleanly closed all open ports */
1226 GNUNET_break (0); 1210 GNUNET_break (0);
1227 GNUNET_CADET_close_port (port); 1211 GNUNET_CADET_close_port (port);
@@ -1273,18 +1257,21 @@ GNUNET_CADET_disconnect (struct GNUNET_CADET_Handle *handle)
1273void 1257void
1274GNUNET_CADET_close_port (struct GNUNET_CADET_Port *p) 1258GNUNET_CADET_close_port (struct GNUNET_CADET_Port *p)
1275{ 1259{
1276 struct GNUNET_CADET_PortMessage *msg;
1277 struct GNUNET_MQ_Envelope *env;
1278
1279 GNUNET_assert (GNUNET_YES == 1260 GNUNET_assert (GNUNET_YES ==
1280 GNUNET_CONTAINER_multihashmap_remove (p->cadet->ports, 1261 GNUNET_CONTAINER_multihashmap_remove (p->cadet->ports,
1281 &p->id, 1262 &p->id,
1282 p)); 1263 p));
1283 env = GNUNET_MQ_msg (msg, 1264 if (NULL != p->cadet->mq)
1284 GNUNET_MESSAGE_TYPE_CADET_LOCAL_PORT_CLOSE); 1265 {
1285 msg->port = p->id; 1266 struct GNUNET_CADET_PortMessage *msg;
1286 GNUNET_MQ_send (p->cadet->mq, 1267 struct GNUNET_MQ_Envelope *env;
1287 env); 1268
1269 env = GNUNET_MQ_msg (msg,
1270 GNUNET_MESSAGE_TYPE_CADET_LOCAL_PORT_CLOSE);
1271 msg->port = p->id;
1272 GNUNET_MQ_send (p->cadet->mq,
1273 env);
1274 }
1288 GNUNET_free_non_null (p->handlers); 1275 GNUNET_free_non_null (p->handlers);
1289 GNUNET_free (p); 1276 GNUNET_free (p);
1290} 1277}
@@ -1293,7 +1280,7 @@ GNUNET_CADET_close_port (struct GNUNET_CADET_Port *p)
1293/** 1280/**
1294 * Destroy an existing channel. 1281 * Destroy an existing channel.
1295 * 1282 *
1296 * The existing end callback for the channel will be called immediately. 1283 * The existing end callback for the channel will NOT be called.
1297 * Any pending outgoing messages will be sent but no incoming messages will be 1284 * Any pending outgoing messages will be sent but no incoming messages will be
1298 * accepted and no data callbacks will be called. 1285 * accepted and no data callbacks will be called.
1299 * 1286 *
@@ -1316,6 +1303,7 @@ GNUNET_CADET_channel_destroy (struct GNUNET_CADET_Channel *channel)
1316 } 1303 }
1317 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 1304 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1318 "Destroying channel due to GNUNET_CADET_channel_destroy()\n"); 1305 "Destroying channel due to GNUNET_CADET_channel_destroy()\n");
1306 channel->disconnects = NULL;
1319 destroy_channel (channel); 1307 destroy_channel (channel);
1320} 1308}
1321 1309
@@ -1636,9 +1624,6 @@ GNUNET_CADET_connect (const struct GNUNET_CONFIGURATION_Handle *cfg)
1636 return NULL; 1624 return NULL;
1637 } 1625 }
1638 h->next_ccn.channel_of_client = htonl (GNUNET_CADET_LOCAL_CHANNEL_ID_CLI); 1626 h->next_ccn.channel_of_client = htonl (GNUNET_CADET_LOCAL_CHANNEL_ID_CLI);
1639 h->reconnect_time = GNUNET_TIME_UNIT_MILLISECONDS;
1640 h->reconnect_task = NULL;
1641
1642 return h; 1627 return h;
1643} 1628}
1644 1629
@@ -1664,8 +1649,6 @@ GNUNET_CADET_open_port (struct GNUNET_CADET_Handle *h,
1664 GNUNET_CADET_DisconnectEventHandler disconnects, 1649 GNUNET_CADET_DisconnectEventHandler disconnects,
1665 const struct GNUNET_MQ_MessageHandler *handlers) 1650 const struct GNUNET_MQ_MessageHandler *handlers)
1666{ 1651{
1667 struct GNUNET_CADET_PortMessage *msg;
1668 struct GNUNET_MQ_Envelope *env;
1669 struct GNUNET_CADET_Port *p; 1652 struct GNUNET_CADET_Port *p;
1670 1653
1671 GNUNET_assert (NULL != connects); 1654 GNUNET_assert (NULL != connects);
@@ -1691,13 +1674,11 @@ GNUNET_CADET_open_port (struct GNUNET_CADET_Handle *h,
1691 p->window_changes = window_changes; 1674 p->window_changes = window_changes;
1692 p->disconnects = disconnects; 1675 p->disconnects = disconnects;
1693 p->handlers = GNUNET_MQ_copy_handlers (handlers); 1676 p->handlers = GNUNET_MQ_copy_handlers (handlers);
1694 1677
1695 1678 GNUNET_assert (GNUNET_OK ==
1696 env = GNUNET_MQ_msg (msg, 1679 open_port_cb (h,
1697 GNUNET_MESSAGE_TYPE_CADET_LOCAL_PORT_OPEN); 1680 &p->id,
1698 msg->port = p->id; 1681 p));
1699 GNUNET_MQ_send (h->mq,
1700 env);
1701 return p; 1682 return p;
1702} 1683}
1703 1684
@@ -1756,7 +1737,8 @@ GNUNET_CADET_channel_create (struct GNUNET_CADET_Handle *h,
1756 handlers, 1737 handlers,
1757 &cadet_mq_error_handler, 1738 &cadet_mq_error_handler,
1758 ch); 1739 ch);
1759 GNUNET_MQ_set_handlers_closure (ch->mq, channel_cls); 1740 GNUNET_MQ_set_handlers_closure (ch->mq,
1741 channel_cls);
1760 1742
1761 /* Request channel creation to service */ 1743 /* Request channel creation to service */
1762 env = GNUNET_MQ_msg (msg, 1744 env = GNUNET_MQ_msg (msg,
diff --git a/src/cadet/cadet_protocol.h b/src/cadet/cadet_protocol.h
index de0cec5d0..4b4cfbf52 100644
--- a/src/cadet/cadet_protocol.h
+++ b/src/cadet/cadet_protocol.h
@@ -2,20 +2,18 @@
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2007 - 2017 GNUnet e.V. 3 Copyright (C) 2007 - 2017 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 it
6 it under the terms of the GNU General Public License as published 6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation; either version 3, or (at your 7 by the Free Software Foundation, either version 3 of the License,
8 option) any later version. 8 or (at your option) any later version.
9 9
10 GNUnet is distributed in the hope that it will be useful, but 10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details. 13 Affero General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU Affero General Public License
16 along with GNUnet; see the file COPYING. If not, write to the 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/ 17*/
20 18
21/** 19/**
@@ -28,6 +26,14 @@
28#ifndef CADET_PROTOCOL_H_ 26#ifndef CADET_PROTOCOL_H_
29#define CADET_PROTOCOL_H_ 27#define CADET_PROTOCOL_H_
30 28
29/**
30 * At best, enable when debugging #5328!
31 */
32#define DEBUG_KX 0
33#if DEBUG_KX
34#warning NEVER run this in production! KX debugging is on!
35#endif
36
31#include "platform.h" 37#include "platform.h"
32#include "gnunet_util_lib.h" 38#include "gnunet_util_lib.h"
33#include "cadet.h" 39#include "cadet.h"
@@ -234,6 +240,22 @@ struct GNUNET_CADET_TunnelKeyExchangeMessage
234 */ 240 */
235 struct GNUNET_CRYPTO_EcdhePublicKey ephemeral_key; 241 struct GNUNET_CRYPTO_EcdhePublicKey ephemeral_key;
236 242
243#if DEBUG_KX
244 /**
245 * Sender's ephemeral public ECC key encoded in a
246 * format suitable for network transmission, as created
247 * using 'gcry_sexp_sprint'.
248 */
249 struct GNUNET_CRYPTO_EcdhePrivateKey ephemeral_key_XXX; // for debugging KX-crypto!
250
251 /**
252 * Sender's ephemeral public ECC key encoded in a
253 * format suitable for network transmission, as created
254 * using 'gcry_sexp_sprint'.
255 */
256 struct GNUNET_CRYPTO_EddsaPrivateKey private_key_XXX; // for debugging KX-crypto!
257#endif
258
237 /** 259 /**
238 * Sender's next ephemeral public ECC key encoded in a 260 * Sender's next ephemeral public ECC key encoded in a
239 * format suitable for network transmission, as created 261 * format suitable for network transmission, as created
@@ -256,6 +278,15 @@ struct GNUNET_CADET_TunnelKeyExchangeAuthMessage
256 */ 278 */
257 struct GNUNET_CADET_TunnelKeyExchangeMessage kx; 279 struct GNUNET_CADET_TunnelKeyExchangeMessage kx;
258 280
281#if DEBUG_KX
282 /**
283 * Received ephemeral public ECC key encoded in a
284 * format suitable for network transmission, as created
285 * using 'gcry_sexp_sprint'.
286 */
287 struct GNUNET_CRYPTO_EcdhePublicKey r_ephemeral_key_XXX; // for debugging KX-crypto!
288#endif
289
259 /** 290 /**
260 * KDF-proof that sender could compute the 3-DH, used in lieu of a 291 * KDF-proof that sender could compute the 3-DH, used in lieu of a
261 * signature or payload data. 292 * signature or payload data.
diff --git a/src/cadet/cadet_test_lib.c b/src/cadet/cadet_test_lib.c
index 20ef028b2..1a1c15f48 100644
--- a/src/cadet/cadet_test_lib.c
+++ b/src/cadet/cadet_test_lib.c
@@ -2,20 +2,18 @@
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2012, 2017 GNUnet e.V. 3 Copyright (C) 2012, 2017 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 it
6 it under the terms of the GNU General Public License as published 6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation; either version 3, or (at your 7 by the Free Software Foundation, either version 3 of the License,
8 option) any later version. 8 or (at your option) any later version.
9 9
10 GNUnet is distributed in the hope that it will be useful, but 10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details. 13 Affero General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU Affero General Public License
16 along with GNUnet; see the file COPYING. If not, write to the 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/ 17*/
20/** 18/**
21 * @file cadet/cadet_test_lib.c 19 * @file cadet/cadet_test_lib.c
@@ -110,7 +108,7 @@ struct GNUNET_CADET_TEST_AdapterContext
110 * Port handlers for open ports. 108 * Port handlers for open ports.
111 */ 109 */
112 struct GNUNET_CADET_Port **ports; 110 struct GNUNET_CADET_Port **ports;
113 111
114 /** 112 /**
115 * General context. 113 * General context.
116 */ 114 */
@@ -135,14 +133,18 @@ cadet_connect_adapter (void *cls,
135 struct GNUNET_CADET_TEST_AdapterContext *actx = cls; 133 struct GNUNET_CADET_TEST_AdapterContext *actx = cls;
136 struct GNUNET_CADET_TEST_Context *ctx = actx->ctx; 134 struct GNUNET_CADET_TEST_Context *ctx = actx->ctx;
137 struct GNUNET_CADET_Handle *h; 135 struct GNUNET_CADET_Handle *h;
138 unsigned int i;
139 136
140 h = GNUNET_CADET_connect (cfg); 137 h = GNUNET_CADET_connect (cfg);
138 if (NULL == h)
139 {
140 GNUNET_break(0);
141 return NULL;
142 }
141 if (NULL == ctx->ports) 143 if (NULL == ctx->ports)
142 return h; 144 return h;
143 145 actx->ports = GNUNET_new_array (ctx->port_count,
144 actx->ports = GNUNET_new_array (ctx->port_count, struct GNUNET_CADET_Port *); 146 struct GNUNET_CADET_Port *);
145 for (i = 0; i < ctx->port_count; i++) 147 for (unsigned int i = 0; i < ctx->port_count; i++)
146 { 148 {
147 actx->ports[i] = GNUNET_CADET_open_port (h, 149 actx->ports[i] = GNUNET_CADET_open_port (h,
148 ctx->ports[i], 150 ctx->ports[i],
@@ -165,14 +167,14 @@ cadet_connect_adapter (void *cls,
165 */ 167 */
166static void 168static void
167cadet_disconnect_adapter (void *cls, 169cadet_disconnect_adapter (void *cls,
168 void *op_result) 170 void *op_result)
169{ 171{
170 struct GNUNET_CADET_Handle *cadet = op_result; 172 struct GNUNET_CADET_Handle *cadet = op_result;
171 struct GNUNET_CADET_TEST_AdapterContext *actx = cls; 173 struct GNUNET_CADET_TEST_AdapterContext *actx = cls;
172 174
173 if (NULL != actx->ports) 175 if (NULL != actx->ports)
174 { 176 {
175 for (int i = 0; i < actx->ctx->port_count; i++) 177 for (unsigned int i = 0; i < actx->ctx->port_count; i++)
176 { 178 {
177 GNUNET_CADET_close_port (actx->ports[i]); 179 GNUNET_CADET_close_port (actx->ports[i]);
178 actx->ports[i] = NULL; 180 actx->ports[i] = NULL;
@@ -201,22 +203,24 @@ cadet_connect_cb (void *cls,
201 const char *emsg) 203 const char *emsg)
202{ 204{
203 struct GNUNET_CADET_TEST_Context *ctx = cls; 205 struct GNUNET_CADET_TEST_Context *ctx = cls;
204 unsigned int i;
205 206
206 if (NULL != emsg) 207 if (NULL != emsg)
207 { 208 {
208 fprintf (stderr, "Failed to connect to CADET service: %s\n", 209 fprintf (stderr,
210 "Failed to connect to CADET service: %s\n",
209 emsg); 211 emsg);
210 GNUNET_SCHEDULER_shutdown (); 212 GNUNET_SCHEDULER_shutdown ();
211 return; 213 return;
212 } 214 }
213 for (i = 0; i < ctx->num_peers; i++) 215 for (unsigned int i = 0; i < ctx->num_peers; i++)
214 if (op == ctx->ops[i]) 216 if (op == ctx->ops[i])
215 { 217 {
216 ctx->cadets[i] = ca_result; 218 ctx->cadets[i] = ca_result;
217 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "...cadet %u connected\n", i); 219 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
220 "...cadet %u connected\n",
221 i);
218 } 222 }
219 for (i = 0; i < ctx->num_peers; i++) 223 for (unsigned int i = 0; i < ctx->num_peers; i++)
220 if (NULL == ctx->cadets[i]) 224 if (NULL == ctx->cadets[i])
221 return; /* still some CADET connections missing */ 225 return; /* still some CADET connections missing */
222 /* all CADET connections ready! */ 226 /* all CADET connections ready! */
@@ -231,9 +235,7 @@ cadet_connect_cb (void *cls,
231void 235void
232GNUNET_CADET_TEST_cleanup (struct GNUNET_CADET_TEST_Context *ctx) 236GNUNET_CADET_TEST_cleanup (struct GNUNET_CADET_TEST_Context *ctx)
233{ 237{
234 unsigned int i; 238 for (unsigned int i = 0; i < ctx->num_peers; i++)
235
236 for (i = 0; i < ctx->num_peers; i++)
237 { 239 {
238 GNUNET_assert (NULL != ctx->ops[i]); 240 GNUNET_assert (NULL != ctx->ops[i]);
239 GNUNET_TESTBED_operation_done (ctx->ops[i]); 241 GNUNET_TESTBED_operation_done (ctx->ops[i]);
@@ -269,33 +271,37 @@ cadet_test_run (void *cls,
269 unsigned int links_failed) 271 unsigned int links_failed)
270{ 272{
271 struct GNUNET_CADET_TEST_Context *ctx = cls; 273 struct GNUNET_CADET_TEST_Context *ctx = cls;
272 unsigned int i;
273 274
274 if (0 != links_failed) 275 if (0 != links_failed)
275 { 276 {
276 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Some links failed (%u), ending\n", 277 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
278 "Some links failed (%u), ending\n",
277 links_failed); 279 links_failed);
278 exit (2); 280 exit (2);
279 } 281 }
280
281 if (num_peers != ctx->num_peers) 282 if (num_peers != ctx->num_peers)
282 { 283 {
283 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Peers started %u/%u, ending\n", 284 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
284 num_peers, ctx->num_peers); 285 "Peers started %u/%u, ending\n",
286 num_peers,
287 ctx->num_peers);
285 exit (1); 288 exit (1);
286 } 289 }
287
288 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 290 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
289 "Testbed up, %u peers and %u links\n", 291 "Testbed up, %u peers and %u links\n",
290 num_peers, links_succeeded); 292 num_peers,
293 links_succeeded);
291 ctx->peers = peers; 294 ctx->peers = peers;
292 for (i = 0; i < num_peers; i++) 295 for (unsigned int i = 0; i < num_peers; i++)
293 { 296 {
294 struct GNUNET_CADET_TEST_AdapterContext *newctx; 297 struct GNUNET_CADET_TEST_AdapterContext *newctx;
298
295 newctx = GNUNET_new (struct GNUNET_CADET_TEST_AdapterContext); 299 newctx = GNUNET_new (struct GNUNET_CADET_TEST_AdapterContext);
296 newctx->peer = i; 300 newctx->peer = i;
297 newctx->ctx = ctx; 301 newctx->ctx = ctx;
298 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Connecting to cadet %u\n", i); 302 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
303 "Connecting to cadet %u\n",
304 i);
299 ctx->ops[i] = GNUNET_TESTBED_service_connect (ctx, 305 ctx->ops[i] = GNUNET_TESTBED_service_connect (ctx,
300 peers[i], 306 peers[i],
301 "cadet", 307 "cadet",
@@ -304,7 +310,9 @@ cadet_test_run (void *cls,
304 &cadet_connect_adapter, 310 &cadet_connect_adapter,
305 &cadet_disconnect_adapter, 311 &cadet_disconnect_adapter,
306 newctx); 312 newctx);
307 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "op handle %p\n", ctx->ops[i]); 313 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
314 "op handle %p\n",
315 ctx->ops[i]);
308 } 316 }
309} 317}
310 318
@@ -340,8 +348,10 @@ GNUNET_CADET_TEST_ruN (const char *testname,
340 348
341 ctx = GNUNET_new (struct GNUNET_CADET_TEST_Context); 349 ctx = GNUNET_new (struct GNUNET_CADET_TEST_Context);
342 ctx->num_peers = num_peers; 350 ctx->num_peers = num_peers;
343 ctx->ops = GNUNET_new_array (num_peers, struct GNUNET_TESTBED_Operation *); 351 ctx->ops = GNUNET_new_array (num_peers,
344 ctx->cadets = GNUNET_new_array (num_peers, struct GNUNET_CADET_Handle *); 352 struct GNUNET_TESTBED_Operation *);
353 ctx->cadets = GNUNET_new_array (num_peers,
354 struct GNUNET_CADET_Handle *);
345 ctx->app_main = tmain; 355 ctx->app_main = tmain;
346 ctx->app_main_cls = tmain_cls; 356 ctx->app_main_cls = tmain_cls;
347 ctx->connects = connects; 357 ctx->connects = connects;
@@ -352,12 +362,12 @@ GNUNET_CADET_TEST_ruN (const char *testname,
352 ctx->port_count = 0; 362 ctx->port_count = 0;
353 while (NULL != ctx->ports[ctx->port_count]) 363 while (NULL != ctx->ports[ctx->port_count])
354 ctx->port_count++; 364 ctx->port_count++;
355
356 GNUNET_TESTBED_test_run (testname, 365 GNUNET_TESTBED_test_run (testname,
357 cfgfile, 366 cfgfile,
358 num_peers, 367 num_peers,
359 0LL, NULL, NULL, 368 0LL, NULL, NULL,
360 &cadet_test_run, ctx); 369 &cadet_test_run,
370 ctx);
361} 371}
362 372
363/* end of cadet_test_lib.c */ 373/* end of cadet_test_lib.c */
diff --git a/src/cadet/cadet_test_lib.h b/src/cadet/cadet_test_lib.h
index 4b3a6b18d..3a43d3ded 100644
--- a/src/cadet/cadet_test_lib.h
+++ b/src/cadet/cadet_test_lib.h
@@ -2,20 +2,18 @@
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2012,2017 GNUnet e.V. 3 Copyright (C) 2012,2017 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 it
6 it under the terms of the GNU General Public License as published 6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation; either version 3, or (at your 7 by the Free Software Foundation, either version 3 of the License,
8 option) any later version. 8 or (at your option) any later version.
9 9
10 GNUnet is distributed in the hope that it will be useful, but 10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details. 13 Affero General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU Affero General Public License
16 along with GNUnet; see the file COPYING. If not, write to the 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/ 17*/
20/** 18/**
21 * @file cadet/cadet_test_lib.h 19 * @file cadet/cadet_test_lib.h
diff --git a/src/cadet/gnunet-cadet-profiler.c b/src/cadet/gnunet-cadet-profiler.c
index 15da05b6d..784ee662a 100644
--- a/src/cadet/gnunet-cadet-profiler.c
+++ b/src/cadet/gnunet-cadet-profiler.c
@@ -2,20 +2,18 @@
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2011 GNUnet e.V. 3 Copyright (C) 2011 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 it
6 it under the terms of the GNU General Public License as published 6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation; either version 3, or (at your 7 by the Free Software Foundation, either version 3 of the License,
8 option) any later version. 8 or (at your option) any later version.
9 9
10 GNUnet is distributed in the hope that it will be useful, but 10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details. 13 Affero General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU Affero General Public License
16 along with GNUnet; see the file COPYING. If not, write to the 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/ 17*/
20/** 18/**
21 * @file cadet/gnunet-cadet-profiler.c 19 * @file cadet/gnunet-cadet-profiler.c
diff --git a/src/cadet/gnunet-cadet.c b/src/cadet/gnunet-cadet.c
index a9b02714b..13b04b885 100644
--- a/src/cadet/gnunet-cadet.c
+++ b/src/cadet/gnunet-cadet.c
@@ -2,20 +2,18 @@
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2012, 2017 GNUnet e.V. 3 Copyright (C) 2012, 2017 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 it
6 it under the terms of the GNU General Public License as published 6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation; either version 3, or (at your 7 by the Free Software Foundation, either version 3 of the License,
8 option) any later version. 8 or (at your option) any later version.
9 9
10 GNUnet is distributed in the hope that it will be useful, but 10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details. 13 Affero General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU Affero General Public License
16 along with GNUnet; see the file COPYING. If not, write to the 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/ 17*/
20 18
21/** 19/**
@@ -29,6 +27,7 @@
29#include "gnunet_cadet_service.h" 27#include "gnunet_cadet_service.h"
30#include "cadet.h" 28#include "cadet.h"
31 29
30#define STREAM_BUFFER_SIZE 1024 // Pakets
32 31
33/** 32/**
34 * Option -P. 33 * Option -P.
@@ -125,6 +124,8 @@ static struct GNUNET_SCHEDULER_Task *rd_task;
125 */ 124 */
126static struct GNUNET_SCHEDULER_Task *job; 125static struct GNUNET_SCHEDULER_Task *job;
127 126
127static unsigned int sent_pkt;
128
128 129
129/** 130/**
130 * Wait for input on STDIO and send it out over the #ch. 131 * Wait for input on STDIO and send it out over the #ch.
@@ -198,6 +199,11 @@ shutdown_task (void *cls)
198{ 199{
199 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 200 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
200 "Shutdown\n"); 201 "Shutdown\n");
202 if (NULL != lp)
203 {
204 GNUNET_CADET_close_port (lp);
205 lp = NULL;
206 }
201 if (NULL != ch) 207 if (NULL != ch)
202 { 208 {
203 GNUNET_CADET_channel_destroy (ch); 209 GNUNET_CADET_channel_destroy (ch);
@@ -225,6 +231,12 @@ shutdown_task (void *cls)
225 } 231 }
226} 232}
227 233
234void
235mq_cb(void *cls)
236{
237 listen_stdio ();
238}
239
228 240
229/** 241/**
230 * Task run in stdio mode, after some data is available at stdin. 242 * Task run in stdio mode, after some data is available at stdin.
@@ -245,6 +257,8 @@ read_stdio (void *cls)
245 60000); 257 60000);
246 if (data_size < 1) 258 if (data_size < 1)
247 { 259 {
260 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
261 "read() returned %s\n", strerror(errno));
248 GNUNET_SCHEDULER_shutdown(); 262 GNUNET_SCHEDULER_shutdown();
249 return; 263 return;
250 } 264 }
@@ -259,9 +273,21 @@ read_stdio (void *cls)
259 data_size); 273 data_size);
260 GNUNET_MQ_send (GNUNET_CADET_get_mq (ch), 274 GNUNET_MQ_send (GNUNET_CADET_get_mq (ch),
261 env); 275 env);
276
277 sent_pkt++;
278
262 if (GNUNET_NO == echo) 279 if (GNUNET_NO == echo)
263 { 280 {
264 listen_stdio (); 281 // Use MQ's notification if too much data of stdin is pooring in too fast.
282 if (STREAM_BUFFER_SIZE < sent_pkt)
283 {
284 GNUNET_MQ_notify_sent (env, mq_cb, cls);
285 sent_pkt = 0;
286 }
287 else
288 {
289 listen_stdio ();
290 }
265 } 291 }
266 else 292 else
267 { 293 {
@@ -375,6 +401,7 @@ send_echo (void *cls)
375static void 401static void
376request_dump (void *cls) 402request_dump (void *cls)
377{ 403{
404 job = NULL;
378 GNUNET_CADET_request_dump (mh); 405 GNUNET_CADET_request_dump (mh);
379 GNUNET_SCHEDULER_shutdown (); 406 GNUNET_SCHEDULER_shutdown ();
380} 407}
@@ -526,34 +553,48 @@ peer_callback (void *cls,
526 int tunnel, 553 int tunnel,
527 int neighbor, 554 int neighbor,
528 unsigned int n_paths, 555 unsigned int n_paths,
529 const struct GNUNET_PeerIdentity *paths) 556 const struct GNUNET_PeerIdentity *paths,
557 int offset,
558 int finished_with_paths)
530{ 559{
531 unsigned int i; 560 unsigned int i;
532 const struct GNUNET_PeerIdentity *p; 561 const struct GNUNET_PeerIdentity *p;
533 562
534 FPRINTF (stdout, 563
535 "%s [TUNNEL: %s, NEIGHBOR: %s, PATHS: %u]\n", 564 if (GNUNET_YES == finished_with_paths)
536 GNUNET_i2s_full (peer),
537 tunnel ? "Y" : "N",
538 neighbor ? "Y" : "N",
539 n_paths);
540 p = paths;
541 for (i = 0; i < n_paths && NULL != p;)
542 { 565 {
566 GNUNET_SCHEDULER_shutdown();
567 return;
568 }
569
570 if (offset == 0){
571 FPRINTF (stdout,
572 "%s [TUNNEL: %s, NEIGHBOR: %s, PATHS: %u]\n",
573 GNUNET_i2s_full (peer),
574 tunnel ? "Y" : "N",
575 neighbor ? "Y" : "N",
576 n_paths);
577 }else{
578 p = paths;
543 FPRINTF (stdout, 579 FPRINTF (stdout,
544 "%s ", 580 "Indirekt path with offset %u: ",
545 GNUNET_i2s (p)); 581 offset);
546 if (0 == memcmp (p, 582 for (i = 0; i <= offset && NULL != p;)
547 peer,
548 sizeof (*p)))
549 { 583 {
550 FPRINTF (stdout, "\n"); 584 FPRINTF (stdout,
551 i++; 585 "%s ",
586 GNUNET_i2s (p));
587 i++;
588 p++;
552 } 589 }
553 p++; 590
591 FPRINTF (stdout,
592 "\n");
593
554 } 594 }
595
555 596
556 GNUNET_SCHEDULER_shutdown(); 597
557} 598}
558 599
559 600
diff --git a/src/cadet/gnunet-service-cadet.c b/src/cadet/gnunet-service-cadet.c
index 20e4c363e..4568d2733 100644
--- a/src/cadet/gnunet-service-cadet.c
+++ b/src/cadet/gnunet-service-cadet.c
@@ -2,20 +2,18 @@
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2001-2013, 2017 GNUnet e.V. 3 Copyright (C) 2001-2013, 2017 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 it
6 it under the terms of the GNU General Public License as published 6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation; either version 3, or (at your 7 by the Free Software Foundation, either version 3 of the License,
8 option) any later version. 8 or (at your option) any later version.
9 9
10 GNUnet is distributed in the hope that it will be useful, but 10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details. 13 Affero General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU Affero General Public License
16 along with GNUnet; see the file COPYING. If not, write to the 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/ 17*/
20 18
21/** 19/**
@@ -763,6 +761,7 @@ handle_local_data (void *cls,
763 buf, 761 buf,
764 payload_size)) 762 payload_size))
765 { 763 {
764 GNUNET_break (0);
766 GNUNET_SERVICE_client_drop (c->client); 765 GNUNET_SERVICE_client_drop (c->client);
767 return; 766 return;
768 } 767 }
@@ -823,7 +822,7 @@ get_all_peers_iterator (void *cls,
823 struct GNUNET_CADET_LocalInfoPeer *msg; 822 struct GNUNET_CADET_LocalInfoPeer *msg;
824 823
825 env = GNUNET_MQ_msg (msg, 824 env = GNUNET_MQ_msg (msg,
826 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS); 825 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS);
827 msg->destination = *peer; 826 msg->destination = *peer;
828 msg->paths = htons (GCP_count_paths (p)); 827 msg->paths = htons (GCP_count_paths (p));
829 msg->tunnel = htons (NULL != GCP_get_tunnel (p, 828 msg->tunnel = htons (NULL != GCP_get_tunnel (p,
@@ -875,14 +874,14 @@ path_info_iterator (void *cls,
875{ 874{
876 struct GNUNET_MQ_Handle *mq = cls; 875 struct GNUNET_MQ_Handle *mq = cls;
877 struct GNUNET_MQ_Envelope *env; 876 struct GNUNET_MQ_Envelope *env;
878 struct GNUNET_MessageHeader *resp; 877 struct GNUNET_CADET_LocalInfoPeer *resp;
879 struct GNUNET_PeerIdentity *id; 878 struct GNUNET_PeerIdentity *id;
880 uint16_t path_size; 879 uint16_t path_size;
881 unsigned int i; 880 unsigned int i;
882 unsigned int path_length; 881 unsigned int path_length;
883 882
884 path_length = GCPP_get_length (path); 883 path_length = GCPP_get_length (path);
885 path_size = sizeof (struct GNUNET_PeerIdentity) * (path_length - 1); 884 path_size = sizeof (struct GNUNET_PeerIdentity) * path_length;
886 if (sizeof (*resp) + path_size > UINT16_MAX) 885 if (sizeof (*resp) + path_size > UINT16_MAX)
887 { 886 {
888 LOG (GNUNET_ERROR_TYPE_WARNING, 887 LOG (GNUNET_ERROR_TYPE_WARNING,
@@ -893,19 +892,57 @@ path_info_iterator (void *cls,
893 env = GNUNET_MQ_msg_extra (resp, 892 env = GNUNET_MQ_msg_extra (resp,
894 path_size, 893 path_size,
895 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEER); 894 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEER);
895
896
897 resp->offset = htons(off);
898 resp->finished_with_paths = htons(0);
899
896 id = (struct GNUNET_PeerIdentity *) &resp[1]; 900 id = (struct GNUNET_PeerIdentity *) &resp[1];
897 901
898 /* Don't copy first peer. First peer is always the local one. Last 902 /* Don't copy first peer. First peer is always the local one. Last
899 * peer is always the destination (leave as 0, EOL). 903 * peer is always the destination (leave as 0, EOL).
900 */ 904 */
901 for (i = 0; i < off; i++) 905 for (i = 0; i <= off; i++)
902 id[i] = *GCP_get_id (GCPP_get_peer_at_offset (path, 906 id[i] = *GCP_get_id (GCPP_get_peer_at_offset (path,
903 i + 1)); 907 i));
904 GNUNET_MQ_send (mq, 908 GNUNET_MQ_send (mq,
905 env); 909 env);
906 return GNUNET_YES; 910 return GNUNET_YES;
907} 911}
908 912
913/**
914 * Getting summary information about the number of paths and if a tunnel exists,
915 * and the indirect paths to a peer, if there are ones.
916 *
917 * @param cls Closure ().
918 * @param peer Peer ID (tunnel remote peer).
919 * @param value Peer info.
920 * @return #GNUNET_YES, to keep iterating.
921 */
922static void
923get_peer_info (void *cls,
924 const struct GNUNET_PeerIdentity *peer,
925 struct CadetPeer *p)
926{
927 struct CadetClient *c = cls;
928 struct GNUNET_MQ_Envelope *env;
929 struct GNUNET_CADET_LocalInfoPeer *msg;
930
931 env = GNUNET_MQ_msg (msg,
932 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEER);
933 msg->offset = htons(0);
934 msg->destination = *peer;
935 msg->paths = htons (GCP_count_paths (p));
936 msg->tunnel = htons (NULL != GCP_get_tunnel (p,
937 GNUNET_NO));
938 msg->finished_with_paths = htons(0);
939 GNUNET_MQ_send (c->mq,
940 env);
941 GCP_iterate_indirect_paths (p,
942 &path_info_iterator,
943 c->mq);
944}
945
909 946
910/** 947/**
911 * Handler for client's SHOW_PEER request. 948 * Handler for client's SHOW_PEER request.
@@ -920,19 +957,23 @@ handle_show_peer (void *cls,
920 struct CadetClient *c = cls; 957 struct CadetClient *c = cls;
921 struct CadetPeer *p; 958 struct CadetPeer *p;
922 struct GNUNET_MQ_Envelope *env; 959 struct GNUNET_MQ_Envelope *env;
923 struct GNUNET_MessageHeader *resp; 960 struct GNUNET_CADET_LocalInfoPeer *resp;
924 961
925 p = GCP_get (&msg->peer, 962 p = GCP_get (&msg->peer,
926 GNUNET_NO); 963 GNUNET_NO);
927 if (NULL != p) 964 if (NULL != p){
928 GCP_iterate_paths (p, 965 get_peer_info(c, &(msg->peer), p);
929 &path_info_iterator, 966 }
930 c->mq); 967
931 /* Send message with 0/0 to indicate the end */ 968
932 env = GNUNET_MQ_msg (resp, 969 env = GNUNET_MQ_msg (resp,
933 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEER_END); 970 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEER);
971 resp->finished_with_paths = htons(1);
972 resp->destination = msg->peer;
973
934 GNUNET_MQ_send (c->mq, 974 GNUNET_MQ_send (c->mq,
935 env); 975 env);
976
936 GNUNET_SERVICE_client_continue (c->client); 977 GNUNET_SERVICE_client_continue (c->client);
937} 978}
938 979
diff --git a/src/cadet/gnunet-service-cadet.h b/src/cadet/gnunet-service-cadet.h
index 162867823..5587755d1 100644
--- a/src/cadet/gnunet-service-cadet.h
+++ b/src/cadet/gnunet-service-cadet.h
@@ -3,20 +3,18 @@
3 This file is part of GNUnet. 3 This file is part of GNUnet.
4 Copyright (C) 2001-2017 GNUnet e.V. 4 Copyright (C) 2001-2017 GNUnet e.V.
5 5
6 GNUnet is free software; you can redistribute it and/or modify 6 GNUnet is free software: you can redistribute it and/or modify it
7 it under the terms of the GNU General Public License as published 7 under the terms of the GNU Affero General Public License as published
8 by the Free Software Foundation; either version 3, or (at your 8 by the Free Software Foundation, either version 3 of the License,
9 option) any later version. 9 or (at your option) any later version.
10 10
11 GNUnet is distributed in the hope that it will be useful, but 11 GNUnet is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of 12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details. 14 Affero General Public License for more details.
15 15
16 You should have received a copy of the GNU General Public License 16 You should have received a copy of the GNU Affero General Public License
17 along with GNUnet; see the file COPYING. If not, write to the 17 along with this program. If not, see <http://www.gnu.org/licenses/>.
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 Boston, MA 02110-1301, USA.
20*/ 18*/
21 19
22/** 20/**
diff --git a/src/cadet/gnunet-service-cadet_channel.c b/src/cadet/gnunet-service-cadet_channel.c
index 1a2b32be0..06711dc8b 100644
--- a/src/cadet/gnunet-service-cadet_channel.c
+++ b/src/cadet/gnunet-service-cadet_channel.c
@@ -2,20 +2,18 @@
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2001-2017 GNUnet e.V. 3 Copyright (C) 2001-2017 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 it
6 it under the terms of the GNU General Public License as published 6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation; either version 3, or (at your 7 by the Free Software Foundation, either version 3 of the License,
8 option) any later version. 8 or (at your option) any later version.
9 9
10 GNUnet is distributed in the hope that it will be useful, but 10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details. 13 Affero General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU Affero General Public License
16 along with GNUnet; see the file COPYING. If not, write to the 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/ 17*/
20/** 18/**
21 * @file cadet/gnunet-service-cadet_channel.c 19 * @file cadet/gnunet-service-cadet_channel.c
@@ -411,7 +409,7 @@ GCCH_2s (const struct CadetChannel *ch)
411 409
412 410
413/** 411/**
414 * Hash the @a port and @a initiator and @a listener to 412 * Hash the @a port and @a initiator and @a listener to
415 * calculate the "challenge" @a h_port we send to the other 413 * calculate the "challenge" @a h_port we send to the other
416 * peer on #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN. 414 * peer on #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN.
417 * 415 *
@@ -1186,7 +1184,7 @@ GCCH_handle_channel_open_ack (struct CadetChannel *ch,
1186 port, 1184 port,
1187 sizeof (struct GNUNET_HashCode))) 1185 sizeof (struct GNUNET_HashCode)))
1188 { 1186 {
1189 /* Other peer failed to provide the right port, 1187 /* Other peer failed to provide the right port,
1190 refuse connection. */ 1188 refuse connection. */
1191 GNUNET_break_op (0); 1189 GNUNET_break_op (0);
1192 return; 1190 return;
@@ -1279,8 +1277,7 @@ GCCH_handle_channel_plaintext_data (struct CadetChannel *ch,
1279 uint32_t delta; 1277 uint32_t delta;
1280 1278
1281 GNUNET_assert (GNUNET_NO == ch->is_loopback); 1279 GNUNET_assert (GNUNET_NO == ch->is_loopback);
1282 if ( (GNUNET_YES == ch->destroy) && 1280 if ( (NULL == ch->owner) &&
1283 (NULL == ch->owner) &&
1284 (NULL == ch->dest) ) 1281 (NULL == ch->dest) )
1285 { 1282 {
1286 /* This client is gone, but we still have messages to send to 1283 /* This client is gone, but we still have messages to send to
@@ -1290,8 +1287,9 @@ GCCH_handle_channel_plaintext_data (struct CadetChannel *ch,
1290 "Dropping incoming payload on %s as this end is already closed\n", 1287 "Dropping incoming payload on %s as this end is already closed\n",
1291 GCCH_2s (ch)); 1288 GCCH_2s (ch));
1292 /* send back DESTROY notification to stop further retransmissions! */ 1289 /* send back DESTROY notification to stop further retransmissions! */
1293 GCT_send_channel_destroy (ch->t, 1290 if (GNUNET_YES == ch->destroy)
1294 ch->ctn); 1291 GCT_send_channel_destroy (ch->t,
1292 ch->ctn);
1295 return; 1293 return;
1296 } 1294 }
1297 payload_size = ntohs (msg->header.size) - sizeof (*msg); 1295 payload_size = ntohs (msg->header.size) - sizeof (*msg);
@@ -1822,7 +1820,7 @@ GCCH_handle_local_data (struct CadetChannel *ch,
1822{ 1820{
1823 struct CadetReliableMessage *crm; 1821 struct CadetReliableMessage *crm;
1824 1822
1825 if (ch->pending_messages > ch->max_pending_messages) 1823 if (ch->pending_messages >= ch->max_pending_messages)
1826 { 1824 {
1827 GNUNET_break (0); 1825 GNUNET_break (0);
1828 return GNUNET_SYSERR; 1826 return GNUNET_SYSERR;
diff --git a/src/cadet/gnunet-service-cadet_channel.h b/src/cadet/gnunet-service-cadet_channel.h
index 16517c457..b9d09b8d1 100644
--- a/src/cadet/gnunet-service-cadet_channel.h
+++ b/src/cadet/gnunet-service-cadet_channel.h
@@ -2,20 +2,18 @@
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2001-2017 GNUnet e.V. 3 Copyright (C) 2001-2017 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 it
6 it under the terms of the GNU General Public License as published 6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation; either version 3, or (at your 7 by the Free Software Foundation, either version 3 of the License,
8 option) any later version. 8 or (at your option) any later version.
9 9
10 GNUnet is distributed in the hope that it will be useful, but 10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details. 13 Affero General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU Affero General Public License
16 along with GNUnet; see the file COPYING. If not, write to the 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/ 17*/
20 18
21/** 19/**
diff --git a/src/cadet/gnunet-service-cadet_connection.c b/src/cadet/gnunet-service-cadet_connection.c
index 82ab5cc2c..b4f1d3734 100644
--- a/src/cadet/gnunet-service-cadet_connection.c
+++ b/src/cadet/gnunet-service-cadet_connection.c
@@ -2,20 +2,18 @@
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2001-2017 GNUnet e.V. 3 Copyright (C) 2001-2017 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 it
6 it under the terms of the GNU General Public License as published 6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation; either version 3, or (at your 7 by the Free Software Foundation, either version 3 of the License,
8 option) any later version. 8 or (at your option) any later version.
9 9
10 GNUnet is distributed in the hope that it will be useful, but 10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details. 13 Affero General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU Affero General Public License
16 along with GNUnet; see the file COPYING. If not, write to the 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/ 17*/
20 18
21/** 19/**
@@ -39,6 +37,13 @@
39 37
40 38
41/** 39/**
40 * How long do we wait initially before retransmitting the KX?
41 * TODO: replace by 2 RTT if/once we have connection-level RTT data!
42 */
43#define INITIAL_CONNECTION_CREATE_RETRY_DELAY GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MILLISECONDS, 200)
44
45
46/**
42 * All the states a connection can be in. 47 * All the states a connection can be in.
43 */ 48 */
44enum CadetConnectionState 49enum CadetConnectionState
@@ -134,6 +139,16 @@ struct CadetConnection
134 struct GNUNET_TIME_Relative retry_delay; 139 struct GNUNET_TIME_Relative retry_delay;
135 140
136 /** 141 /**
142 * Earliest time for re-trying CREATE
143 */
144 struct GNUNET_TIME_Absolute create_at;
145
146 /**
147 * Earliest time for re-trying CREATE_ACK
148 */
149 struct GNUNET_TIME_Absolute create_ack_at;
150
151 /**
137 * Performance metrics for this connection. 152 * Performance metrics for this connection.
138 */ 153 */
139 struct CadetConnectionMetrics metrics; 154 struct CadetConnectionMetrics metrics;
@@ -482,8 +497,9 @@ GCC_latency_observed (const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid,
482 497
483 498
484/** 499/**
485 * A #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE_ACK was received for this connection, implying 500 * A #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE_ACK was received for
486 * that the end-to-end connection is up. Process it. 501 * this connection, implying that the end-to-end connection is up.
502 * Process it.
487 * 503 *
488 * @param cc the connection that got the ACK. 504 * @param cc the connection that got the ACK.
489 */ 505 */
@@ -525,6 +541,11 @@ void
525GCC_handle_kx (struct CadetConnection *cc, 541GCC_handle_kx (struct CadetConnection *cc,
526 const struct GNUNET_CADET_TunnelKeyExchangeMessage *msg) 542 const struct GNUNET_CADET_TunnelKeyExchangeMessage *msg)
527{ 543{
544 LOG (GNUNET_ERROR_TYPE_DEBUG,
545 "Received KX message with ephermal %s on CC %s in state %d\n",
546 GNUNET_e2s (&msg->ephemeral_key),
547 GNUNET_sh2s (&cc->cid.connection_of_tunnel),
548 cc->state);
528 if (CADET_CONNECTION_SENT == cc->state) 549 if (CADET_CONNECTION_SENT == cc->state)
529 { 550 {
530 /* We didn't get the CADET_CONNECTION_CREATE_ACK, but instead got payload. That's fine, 551 /* We didn't get the CADET_CONNECTION_CREATE_ACK, but instead got payload. That's fine,
@@ -549,6 +570,11 @@ void
549GCC_handle_kx_auth (struct CadetConnection *cc, 570GCC_handle_kx_auth (struct CadetConnection *cc,
550 const struct GNUNET_CADET_TunnelKeyExchangeAuthMessage *msg) 571 const struct GNUNET_CADET_TunnelKeyExchangeAuthMessage *msg)
551{ 572{
573 LOG (GNUNET_ERROR_TYPE_DEBUG,
574 "Received KX AUTH message with ephermal %s on CC %s in state %d\n",
575 GNUNET_e2s (&msg->kx.ephemeral_key),
576 GNUNET_sh2s (&cc->cid.connection_of_tunnel),
577 cc->state);
552 if (CADET_CONNECTION_SENT == cc->state) 578 if (CADET_CONNECTION_SENT == cc->state)
553 { 579 {
554 /* We didn't get the CADET_CONNECTION_CREATE_ACK, but instead got payload. That's fine, 580 /* We didn't get the CADET_CONNECTION_CREATE_ACK, but instead got payload. That's fine,
@@ -601,25 +627,26 @@ send_create (void *cls)
601 struct GNUNET_CADET_ConnectionCreateMessage *create_msg; 627 struct GNUNET_CADET_ConnectionCreateMessage *create_msg;
602 struct GNUNET_PeerIdentity *pids; 628 struct GNUNET_PeerIdentity *pids;
603 struct GNUNET_MQ_Envelope *env; 629 struct GNUNET_MQ_Envelope *env;
604 unsigned int path_length;
605 630
606 cc->task = NULL; 631 cc->task = NULL;
607 GNUNET_assert (GNUNET_YES == cc->mqm_ready); 632 GNUNET_assert (GNUNET_YES == cc->mqm_ready);
608 path_length = GCPP_get_length (cc->path);
609 env = GNUNET_MQ_msg_extra (create_msg, 633 env = GNUNET_MQ_msg_extra (create_msg,
610 (1 + path_length) * sizeof (struct GNUNET_PeerIdentity), 634 (2 + cc->off) * sizeof (struct GNUNET_PeerIdentity),
611 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE); 635 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE);
612 create_msg->options = htonl ((uint32_t) cc->options); 636 create_msg->options = htonl ((uint32_t) cc->options);
613 create_msg->cid = cc->cid; 637 create_msg->cid = cc->cid;
614 pids = (struct GNUNET_PeerIdentity *) &create_msg[1]; 638 pids = (struct GNUNET_PeerIdentity *) &create_msg[1];
615 pids[0] = my_full_id; 639 pids[0] = my_full_id;
616 for (unsigned int i=0;i<path_length;i++) 640 for (unsigned int i=0;i<=cc->off;i++)
617 pids[i + 1] = *GCP_get_id (GCPP_get_peer_at_offset (cc->path, 641 pids[i + 1] = *GCP_get_id (GCPP_get_peer_at_offset (cc->path,
618 i)); 642 i));
619 LOG (GNUNET_ERROR_TYPE_DEBUG, 643 LOG (GNUNET_ERROR_TYPE_DEBUG,
620 "Sending CADET_CONNECTION_CREATE message for %s\n", 644 "Sending CADET_CONNECTION_CREATE message for %s with %u hops\n",
621 GCC_2s (cc)); 645 GCC_2s (cc),
646 cc->off + 2);
622 cc->env = env; 647 cc->env = env;
648 cc->retry_delay = GNUNET_TIME_STD_BACKOFF (cc->retry_delay);
649 cc->create_at = GNUNET_TIME_relative_to_absolute (cc->retry_delay);
623 update_state (cc, 650 update_state (cc,
624 CADET_CONNECTION_SENT, 651 CADET_CONNECTION_SENT,
625 GNUNET_NO); 652 GNUNET_NO);
@@ -641,7 +668,6 @@ send_create_ack (void *cls)
641 struct GNUNET_MQ_Envelope *env; 668 struct GNUNET_MQ_Envelope *env;
642 669
643 cc->task = NULL; 670 cc->task = NULL;
644 GNUNET_assert (CADET_CONNECTION_CREATE_RECEIVED == cc->state);
645 LOG (GNUNET_ERROR_TYPE_DEBUG, 671 LOG (GNUNET_ERROR_TYPE_DEBUG,
646 "Sending CONNECTION_CREATE_ACK message for %s\n", 672 "Sending CONNECTION_CREATE_ACK message for %s\n",
647 GCC_2s (cc)); 673 GCC_2s (cc));
@@ -650,9 +676,16 @@ send_create_ack (void *cls)
650 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE_ACK); 676 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE_ACK);
651 ack_msg->cid = cc->cid; 677 ack_msg->cid = cc->cid;
652 cc->env = env; 678 cc->env = env;
653 update_state (cc, 679 cc->retry_delay = GNUNET_TIME_STD_BACKOFF (cc->retry_delay);
654 CADET_CONNECTION_READY, 680 cc->create_ack_at = GNUNET_TIME_relative_to_absolute (cc->retry_delay);
655 GNUNET_NO); 681 if (CADET_CONNECTION_CREATE_RECEIVED == cc->state)
682 update_state (cc,
683 CADET_CONNECTION_READY,
684 GNUNET_NO);
685 if (CADET_CONNECTION_READY == cc->state)
686 cc->task = GNUNET_SCHEDULER_add_delayed (keepalive_period,
687 &send_keepalive,
688 cc);
656 GCP_send (cc->mq_man, 689 GCP_send (cc->mq_man,
657 env); 690 env);
658} 691}
@@ -681,8 +714,9 @@ GCC_handle_duplicate_create (struct CadetConnection *cc)
681 cc->mqm_ready); 714 cc->mqm_ready);
682 if (NULL != cc->task) 715 if (NULL != cc->task)
683 GNUNET_SCHEDULER_cancel (cc->task); 716 GNUNET_SCHEDULER_cancel (cc->task);
684 cc->task = GNUNET_SCHEDULER_add_now (&send_create_ack, 717 cc->task = GNUNET_SCHEDULER_add_at (cc->create_ack_at,
685 cc); 718 &send_create_ack,
719 cc);
686 } 720 }
687 else 721 else
688 { 722 {
@@ -721,7 +755,7 @@ manage_first_hop_mq (void *cls,
721 update_state (cc, 755 update_state (cc,
722 CADET_CONNECTION_NEW, 756 CADET_CONNECTION_NEW,
723 GNUNET_NO); 757 GNUNET_NO);
724 cc->retry_delay = GNUNET_TIME_UNIT_ZERO; 758 cc->retry_delay = INITIAL_CONNECTION_CREATE_RETRY_DELAY;
725 if (NULL != cc->task) 759 if (NULL != cc->task)
726 { 760 {
727 GNUNET_SCHEDULER_cancel (cc->task); 761 GNUNET_SCHEDULER_cancel (cc->task);
@@ -741,8 +775,9 @@ manage_first_hop_mq (void *cls,
741 { 775 {
742 case CADET_CONNECTION_NEW: 776 case CADET_CONNECTION_NEW:
743 /* Transmit immediately */ 777 /* Transmit immediately */
744 cc->task = GNUNET_SCHEDULER_add_now (&send_create, 778 cc->task = GNUNET_SCHEDULER_add_at (cc->create_at,
745 cc); 779 &send_create,
780 cc);
746 break; 781 break;
747 case CADET_CONNECTION_SENDING_CREATE: 782 case CADET_CONNECTION_SENDING_CREATE:
748 /* Should not be possible to be called in this state. */ 783 /* Should not be possible to be called in this state. */
@@ -750,16 +785,16 @@ manage_first_hop_mq (void *cls,
750 break; 785 break;
751 case CADET_CONNECTION_SENT: 786 case CADET_CONNECTION_SENT:
752 /* Retry a bit later... */ 787 /* Retry a bit later... */
753 cc->retry_delay = GNUNET_TIME_STD_BACKOFF (cc->retry_delay); 788 cc->task = GNUNET_SCHEDULER_add_at (cc->create_at,
754 cc->task = GNUNET_SCHEDULER_add_delayed (cc->retry_delay, 789 &send_create,
755 &send_create, 790 cc);
756 cc);
757 break; 791 break;
758 case CADET_CONNECTION_CREATE_RECEIVED: 792 case CADET_CONNECTION_CREATE_RECEIVED:
759 /* We got the 'CREATE' (incoming connection), should send the CREATE_ACK */ 793 /* We got the 'CREATE' (incoming connection), should send the CREATE_ACK */
760 cc->metrics.age = GNUNET_TIME_absolute_get (); 794 cc->metrics.age = GNUNET_TIME_absolute_get ();
761 cc->task = GNUNET_SCHEDULER_add_now (&send_create_ack, 795 cc->task = GNUNET_SCHEDULER_add_at (cc->create_ack_at,
762 cc); 796 &send_create_ack,
797 cc);
763 break; 798 break;
764 case CADET_CONNECTION_READY: 799 case CADET_CONNECTION_READY:
765 if ( (NULL == cc->keepalive_qe) && 800 if ( (NULL == cc->keepalive_qe) &&
@@ -814,6 +849,8 @@ connection_create (struct CadetPeer *destination,
814 cc->state = init_state; 849 cc->state = init_state;
815 cc->ct = ct; 850 cc->ct = ct;
816 cc->cid = *cid; 851 cc->cid = *cid;
852 cc->retry_delay = GNUNET_TIME_relative_multiply (INITIAL_CONNECTION_CREATE_RETRY_DELAY,
853 off);
817 GNUNET_assert (GNUNET_OK == 854 GNUNET_assert (GNUNET_OK ==
818 GNUNET_CONTAINER_multishortmap_put (connections, 855 GNUNET_CONTAINER_multishortmap_put (connections,
819 &GCC_get_id (cc)->connection_of_tunnel, 856 &GCC_get_id (cc)->connection_of_tunnel,
@@ -824,9 +861,10 @@ connection_create (struct CadetPeer *destination,
824 cc->path = path; 861 cc->path = path;
825 cc->off = off; 862 cc->off = off;
826 LOG (GNUNET_ERROR_TYPE_DEBUG, 863 LOG (GNUNET_ERROR_TYPE_DEBUG,
827 "Creating %s using path %s\n", 864 "Creating %s using path %s (offset: %u)\n",
828 GCC_2s (cc), 865 GCC_2s (cc),
829 GCPP_2s (path)); 866 GCPP_2s (path),
867 off);
830 GCPP_add_connection (path, 868 GCPP_add_connection (path,
831 off, 869 off,
832 cc); 870 cc);
@@ -834,7 +872,6 @@ connection_create (struct CadetPeer *destination,
834 GCP_add_connection (GCPP_get_peer_at_offset (path, 872 GCP_add_connection (GCPP_get_peer_at_offset (path,
835 i), 873 i),
836 cc); 874 cc);
837
838 first_hop = GCPP_get_peer_at_offset (path, 875 first_hop = GCPP_get_peer_at_offset (path,
839 0); 876 0);
840 cc->mq_man = GCP_request_mq (first_hop, 877 cc->mq_man = GCP_request_mq (first_hop,
@@ -1001,11 +1038,14 @@ GCC_transmit (struct CadetConnection *cc,
1001 * Obtain the path used by this connection. 1038 * Obtain the path used by this connection.
1002 * 1039 *
1003 * @param cc connection 1040 * @param cc connection
1041 * @param off[out] set to the length of the path we use
1004 * @return path to @a cc 1042 * @return path to @a cc
1005 */ 1043 */
1006struct CadetPeerPath * 1044struct CadetPeerPath *
1007GCC_get_path (struct CadetConnection *cc) 1045GCC_get_path (struct CadetConnection *cc,
1046 unsigned int *off)
1008{ 1047{
1048 *off = cc->off;
1009 return cc->path; 1049 return cc->path;
1010} 1050}
1011 1051
diff --git a/src/cadet/gnunet-service-cadet_connection.h b/src/cadet/gnunet-service-cadet_connection.h
index fdb184366..fe59ebb77 100644
--- a/src/cadet/gnunet-service-cadet_connection.h
+++ b/src/cadet/gnunet-service-cadet_connection.h
@@ -3,20 +3,18 @@
3 This file is part of GNUnet. 3 This file is part of GNUnet.
4 Copyright (C) 2001-2017 GNUnet e.V. 4 Copyright (C) 2001-2017 GNUnet e.V.
5 5
6 GNUnet is free software; you can redistribute it and/or modify 6 GNUnet is free software: you can redistribute it and/or modify it
7 it under the terms of the GNU General Public License as published 7 under the terms of the GNU Affero General Public License as published
8 by the Free Software Foundation; either version 3, or (at your 8 by the Free Software Foundation, either version 3 of the License,
9 option) any later version. 9 or (at your option) any later version.
10 10
11 GNUnet is distributed in the hope that it will be useful, but 11 GNUnet is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of 12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details. 14 Affero General Public License for more details.
15 15
16 You should have received a copy of the GNU General Public License 16 You should have received a copy of the GNU Affero General Public License
17 along with GNUnet; see the file COPYING. If not, write to the 17 along with this program. If not, see <http://www.gnu.org/licenses/>.
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 Boston, MA 02110-1301, USA.
20*/ 18*/
21 19
22/** 20/**
@@ -300,10 +298,12 @@ GCC_get_ct (struct CadetConnection *cc);
300 * Obtain the path used by this connection. 298 * Obtain the path used by this connection.
301 * 299 *
302 * @param cc connection 300 * @param cc connection
301 * @param off[out] set to offset in this path where the connection @a cc ends
303 * @return path to @a cc 302 * @return path to @a cc
304 */ 303 */
305struct CadetPeerPath * 304struct CadetPeerPath *
306GCC_get_path (struct CadetConnection *cc); 305GCC_get_path (struct CadetConnection *cc,
306 unsigned int *off);
307 307
308 308
309/** 309/**
diff --git a/src/cadet/gnunet-service-cadet_core.c b/src/cadet/gnunet-service-cadet_core.c
index 84aff1857..64c86d7d4 100644
--- a/src/cadet/gnunet-service-cadet_core.c
+++ b/src/cadet/gnunet-service-cadet_core.c
@@ -2,20 +2,18 @@
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2017 GNUnet e.V. 3 Copyright (C) 2017 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 it
6 it under the terms of the GNU General Public License as published 6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation; either version 3, or (at your 7 by the Free Software Foundation, either version 3 of the License,
8 option) any later version. 8 or (at your option) any later version.
9 9
10 GNUnet is distributed in the hope that it will be useful, but 10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details. 13 Affero General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU Affero General Public License
16 along with GNUnet; see the file COPYING. If not, write to the 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/ 17*/
20 18
21/** 19/**
@@ -406,6 +404,28 @@ route_message (struct CadetPeer *prev,
406 (NULL != dir->env_head) ) 404 (NULL != dir->env_head) )
407 discard_buffer (dir, 405 discard_buffer (dir,
408 dir->env_head); 406 dir->env_head);
407 /* Check for duplicates */
408 for (const struct GNUNET_MQ_Envelope *env = dir->env_head;
409 NULL != env;
410 env = GNUNET_MQ_env_next (env))
411 {
412 const struct GNUNET_MessageHeader *hdr = GNUNET_MQ_env_get_msg (env);
413
414 if ( (hdr->size == msg->size) &&
415 (0 == memcmp (hdr,
416 msg,
417 ntohs (msg->size))) )
418 {
419 LOG (GNUNET_ERROR_TYPE_DEBUG,
420 "Received duplicate of message already in buffer, dropping\n");
421 GNUNET_STATISTICS_update (stats,
422 "# messages dropped due to duplicate in buffer",
423 1,
424 GNUNET_NO);
425 return;
426 }
427 }
428
409 rung = dir->rung; 429 rung = dir->rung;
410 if (cur_buffers == max_buffers) 430 if (cur_buffers == max_buffers)
411 { 431 {
@@ -434,7 +454,7 @@ route_message (struct CadetPeer *prev,
434 GNUNET_CONTAINER_DLL_remove (rung->rd_head, 454 GNUNET_CONTAINER_DLL_remove (rung->rd_head,
435 rung->rd_tail, 455 rung->rd_tail,
436 dir); 456 dir);
437 /* make 'nxt' point to the next higher rung, creat if necessary */ 457 /* make 'nxt' point to the next higher rung, create if necessary */
438 nxt = rung->next; 458 nxt = rung->next;
439 if ( (NULL == nxt) || 459 if ( (NULL == nxt) ||
440 (rung->rung_off + 1 != nxt->rung_off) ) 460 (rung->rung_off + 1 != nxt->rung_off) )
@@ -631,7 +651,7 @@ timeout_cb (void *cls)
631 NULL); 651 NULL);
632 return; 652 return;
633 } 653 }
634 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 654 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
635 "Sending BROKEN due to timeout (%s was last use, %s linger)\n", 655 "Sending BROKEN due to timeout (%s was last use, %s linger)\n",
636 GNUNET_STRINGS_absolute_time_to_string (r->last_use), 656 GNUNET_STRINGS_absolute_time_to_string (r->last_use),
637 GNUNET_STRINGS_relative_time_to_string (linger, 657 GNUNET_STRINGS_relative_time_to_string (linger,
@@ -693,7 +713,7 @@ dir_ready_cb (void *cls,
693 return; 713 return;
694 } 714 }
695 odir = (dir == &route->next) ? &route->prev : &route->next; 715 odir = (dir == &route->next) ? &route->prev : &route->next;
696 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 716 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
697 "Sending BROKEN due to MQ going down\n"); 717 "Sending BROKEN due to MQ going down\n");
698 send_broken (&route->next, 718 send_broken (&route->next,
699 &route->cid, 719 &route->cid,
@@ -781,31 +801,45 @@ handle_connection_create (void *cls,
781 if (0 == path_length) 801 if (0 == path_length)
782 { 802 {
783 LOG (GNUNET_ERROR_TYPE_DEBUG, 803 LOG (GNUNET_ERROR_TYPE_DEBUG,
784 "Dropping CADET_CONNECTION_CREATE with empty path\n"); 804 "Dropping CADET_CONNECTION_CREATE with empty path\n");
785 GNUNET_break_op (0); 805 GNUNET_break_op (0);
786 return; 806 return;
787 } 807 }
808 LOG (GNUNET_ERROR_TYPE_DEBUG,
809 "Handling CADET_CONNECTION_CREATE from %s for CID %s with %u hops\n",
810 GCP_2s (sender),
811 GNUNET_sh2s (&msg->cid.connection_of_tunnel),
812 path_length);
788 /* Check for loops */ 813 /* Check for loops */
789 struct GNUNET_CONTAINER_MultiPeerMap *map; 814 {
790 map = GNUNET_CONTAINER_multipeermap_create (path_length * 2, 815 struct GNUNET_CONTAINER_MultiPeerMap *map;
791 GNUNET_YES); 816
792 GNUNET_assert (NULL != map); 817 map = GNUNET_CONTAINER_multipeermap_create (path_length * 2,
793 for (off = 0; off < path_length; off++) { 818 GNUNET_YES);
794 if (GNUNET_SYSERR == 819 GNUNET_assert (NULL != map);
795 GNUNET_CONTAINER_multipeermap_put (map, 820 for (unsigned int i=0;i<path_length;i++)
796 &pids[off], 821 {
797 NULL,
798 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)) {
799 /* bogus request */
800 GNUNET_CONTAINER_multipeermap_destroy (map);
801 LOG (GNUNET_ERROR_TYPE_DEBUG, 822 LOG (GNUNET_ERROR_TYPE_DEBUG,
802 "Dropping CADET_CONNECTION_CREATE with cyclic path\n"); 823 "CADET_CONNECTION_CREATE has peer %s at offset %u\n",
803 GNUNET_break_op (0); 824 GNUNET_i2s (&pids[i]),
804 return; 825 i);
826 if (GNUNET_SYSERR ==
827 GNUNET_CONTAINER_multipeermap_put (map,
828 &pids[i],
829 NULL,
830 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
831 {
832 /* bogus request */
833 GNUNET_CONTAINER_multipeermap_destroy (map);
834 LOG (GNUNET_ERROR_TYPE_DEBUG,
835 "Dropping CADET_CONNECTION_CREATE with cyclic path\n");
836 GNUNET_break_op (0);
837 return;
838 }
805 } 839 }
840 GNUNET_CONTAINER_multipeermap_destroy (map);
806 } 841 }
807 GNUNET_CONTAINER_multipeermap_destroy (map); 842 /* Initiator is at offset 0, find us */
808 /* Initiator is at offset 0. */
809 for (off=1;off<path_length;off++) 843 for (off=1;off<path_length;off++)
810 if (0 == memcmp (&my_full_id, 844 if (0 == memcmp (&my_full_id,
811 &pids[off], 845 &pids[off],
@@ -814,7 +848,7 @@ handle_connection_create (void *cls,
814 if (off == path_length) 848 if (off == path_length)
815 { 849 {
816 LOG (GNUNET_ERROR_TYPE_DEBUG, 850 LOG (GNUNET_ERROR_TYPE_DEBUG,
817 "Dropping CADET_CONNECTION_CREATE without us in the path\n"); 851 "Dropping CADET_CONNECTION_CREATE without us in the path\n");
818 GNUNET_break_op (0); 852 GNUNET_break_op (0);
819 return; 853 return;
820 } 854 }
@@ -823,14 +857,15 @@ handle_connection_create (void *cls,
823 GNUNET_NO)) 857 GNUNET_NO))
824 { 858 {
825 LOG (GNUNET_ERROR_TYPE_DEBUG, 859 LOG (GNUNET_ERROR_TYPE_DEBUG,
826 "Dropping CADET_CONNECTION_CREATE without sender in the path\n"); 860 "Dropping CADET_CONNECTION_CREATE without sender at previous hop in the path\n");
827 GNUNET_break_op (0); 861 GNUNET_break_op (0);
828 return; 862 return;
829 } 863 }
830 if (NULL != 864 if (NULL !=
831 get_route (&msg->cid)) 865 (route = get_route (&msg->cid)))
832 { 866 {
833 /* Duplicate CREATE, pass it on, previous one might have been lost! */ 867 /* Duplicate CREATE, pass it on, previous one might have been lost! */
868
834 LOG (GNUNET_ERROR_TYPE_DEBUG, 869 LOG (GNUNET_ERROR_TYPE_DEBUG,
835 "Passing on duplicate CADET_CONNECTION_CREATE message on connection %s\n", 870 "Passing on duplicate CADET_CONNECTION_CREATE message on connection %s\n",
836 GNUNET_sh2s (&msg->cid.connection_of_tunnel)); 871 GNUNET_sh2s (&msg->cid.connection_of_tunnel));
@@ -859,7 +894,7 @@ handle_connection_create (void *cls,
859 origin = GCP_get (&pids[0], 894 origin = GCP_get (&pids[0],
860 GNUNET_YES); 895 GNUNET_YES);
861 LOG (GNUNET_ERROR_TYPE_DEBUG, 896 LOG (GNUNET_ERROR_TYPE_DEBUG,
862 "Received CADET_CONNECTION_CREATE message from %s for connection %s, building inverse path\n", 897 "I am destination for CADET_CONNECTION_CREATE message from %s for connection %s, building inverse path\n",
863 GCP_2s (origin), 898 GCP_2s (origin),
864 GNUNET_sh2s (&msg->cid.connection_of_tunnel)); 899 GNUNET_sh2s (&msg->cid.connection_of_tunnel));
865 path = GCPP_get_path_from_route (path_length - 1, 900 path = GCPP_get_path_from_route (path_length - 1,
@@ -949,6 +984,10 @@ handle_connection_create (void *cls,
949 3), 984 3),
950 &timeout_cb, 985 &timeout_cb,
951 NULL); 986 NULL);
987 /* also pass CREATE message along to next hop */
988 route_message (sender,
989 &msg->cid,
990 &msg->header);
952} 991}
953 992
954 993
@@ -970,7 +1009,9 @@ handle_connection_create_ack (void *cls,
970 if (NULL != cc) 1009 if (NULL != cc)
971 { 1010 {
972 /* verify ACK came from the right direction */ 1011 /* verify ACK came from the right direction */
973 struct CadetPeerPath *path = GCC_get_path (cc); 1012 unsigned int len;
1013 struct CadetPeerPath *path = GCC_get_path (cc,
1014 &len);
974 1015
975 if (peer != 1016 if (peer !=
976 GCPP_get_peer_at_offset (path, 1017 GCPP_get_peer_at_offset (path,
@@ -1014,7 +1055,9 @@ handle_connection_broken (void *cls,
1014 if (NULL != cc) 1055 if (NULL != cc)
1015 { 1056 {
1016 /* verify message came from the right direction */ 1057 /* verify message came from the right direction */
1017 struct CadetPeerPath *path = GCC_get_path (cc); 1058 unsigned int len;
1059 struct CadetPeerPath *path = GCC_get_path (cc,
1060 &len);
1018 1061
1019 if (peer != 1062 if (peer !=
1020 GCPP_get_peer_at_offset (path, 1063 GCPP_get_peer_at_offset (path,
@@ -1063,7 +1106,9 @@ handle_connection_destroy (void *cls,
1063 if (NULL != cc) 1106 if (NULL != cc)
1064 { 1107 {
1065 /* verify message came from the right direction */ 1108 /* verify message came from the right direction */
1066 struct CadetPeerPath *path = GCC_get_path (cc); 1109 unsigned int len;
1110 struct CadetPeerPath *path = GCC_get_path (cc,
1111 &len);
1067 1112
1068 if (peer != 1113 if (peer !=
1069 GCPP_get_peer_at_offset (path, 1114 GCPP_get_peer_at_offset (path,
@@ -1108,11 +1153,19 @@ handle_tunnel_kx (void *cls,
1108 struct CadetConnection *cc; 1153 struct CadetConnection *cc;
1109 1154
1110 /* First, check if message belongs to a connection that ends here. */ 1155 /* First, check if message belongs to a connection that ends here. */
1156 LOG (GNUNET_ERROR_TYPE_DEBUG,
1157 "Routing KX with ephemeral %s on CID %s\n",
1158 GNUNET_e2s (&msg->ephemeral_key),
1159 GNUNET_sh2s (&msg->cid.connection_of_tunnel));
1160
1161
1111 cc = GCC_lookup (&msg->cid); 1162 cc = GCC_lookup (&msg->cid);
1112 if (NULL != cc) 1163 if (NULL != cc)
1113 { 1164 {
1114 /* verify message came from the right direction */ 1165 /* verify message came from the right direction */
1115 struct CadetPeerPath *path = GCC_get_path (cc); 1166 unsigned int len;
1167 struct CadetPeerPath *path = GCC_get_path (cc,
1168 &len);
1116 1169
1117 if (peer != 1170 if (peer !=
1118 GCPP_get_peer_at_offset (path, 1171 GCPP_get_peer_at_offset (path,
@@ -1152,7 +1205,9 @@ handle_tunnel_kx_auth (void *cls,
1152 if (NULL != cc) 1205 if (NULL != cc)
1153 { 1206 {
1154 /* verify message came from the right direction */ 1207 /* verify message came from the right direction */
1155 struct CadetPeerPath *path = GCC_get_path (cc); 1208 unsigned int len;
1209 struct CadetPeerPath *path = GCC_get_path (cc,
1210 &len);
1156 1211
1157 if (peer != 1212 if (peer !=
1158 GCPP_get_peer_at_offset (path, 1213 GCPP_get_peer_at_offset (path,
@@ -1208,7 +1263,9 @@ handle_tunnel_encrypted (void *cls,
1208 if (NULL != cc) 1263 if (NULL != cc)
1209 { 1264 {
1210 /* verify message came from the right direction */ 1265 /* verify message came from the right direction */
1211 struct CadetPeerPath *path = GCC_get_path (cc); 1266 unsigned int len;
1267 struct CadetPeerPath *path = GCC_get_path (cc,
1268 &len);
1212 1269
1213 if (peer != 1270 if (peer !=
1214 GCPP_get_peer_at_offset (path, 1271 GCPP_get_peer_at_offset (path,
diff --git a/src/cadet/gnunet-service-cadet_core.h b/src/cadet/gnunet-service-cadet_core.h
index 65b0a6ba5..b528961b0 100644
--- a/src/cadet/gnunet-service-cadet_core.h
+++ b/src/cadet/gnunet-service-cadet_core.h
@@ -2,20 +2,18 @@
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2017 GNUnet e.V. 3 Copyright (C) 2017 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 it
6 it under the terms of the GNU General Public License as published 6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation; either version 3, or (at your 7 by the Free Software Foundation, either version 3 of the License,
8 option) any later version. 8 or (at your option) any later version.
9 9
10 GNUnet is distributed in the hope that it will be useful, but 10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details. 13 Affero General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU Affero General Public License
16 along with GNUnet; see the file COPYING. If not, write to the 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/ 17*/
20 18
21/** 19/**
diff --git a/src/cadet/gnunet-service-cadet_dht.c b/src/cadet/gnunet-service-cadet_dht.c
index f00c0caf3..b4fed66c0 100644
--- a/src/cadet/gnunet-service-cadet_dht.c
+++ b/src/cadet/gnunet-service-cadet_dht.c
@@ -2,20 +2,18 @@
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2013, 2017 GNUnet e.V. 3 Copyright (C) 2013, 2017 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 it
6 it under the terms of the GNU General Public License as published 6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation; either version 3, or (at your 7 by the Free Software Foundation, either version 3 of the License,
8 option) any later version. 8 or (at your option) any later version.
9 9
10 GNUnet is distributed in the hope that it will be useful, but 10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details. 13 Affero General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU Affero General Public License
16 along with GNUnet; see the file COPYING. If not, write to the 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/ 17*/
20/** 18/**
21 * @file cadet/gnunet-service-cadet_dht.c 19 * @file cadet/gnunet-service-cadet_dht.c
diff --git a/src/cadet/gnunet-service-cadet_dht.h b/src/cadet/gnunet-service-cadet_dht.h
index 5d7ab29a0..7fe1f0c0b 100644
--- a/src/cadet/gnunet-service-cadet_dht.h
+++ b/src/cadet/gnunet-service-cadet_dht.h
@@ -2,20 +2,18 @@
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2013, 2017 GNUnet e.V. 3 Copyright (C) 2013, 2017 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 it
6 it under the terms of the GNU General Public License as published 6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation; either version 3, or (at your 7 by the Free Software Foundation, either version 3 of the License,
8 option) any later version. 8 or (at your option) any later version.
9 9
10 GNUnet is distributed in the hope that it will be useful, but 10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details. 13 Affero General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU Affero General Public License
16 along with GNUnet; see the file COPYING. If not, write to the 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/ 17*/
20 18
21/** 19/**
diff --git a/src/cadet/gnunet-service-cadet_hello.c b/src/cadet/gnunet-service-cadet_hello.c
index 6d85de39f..0061bddc2 100644
--- a/src/cadet/gnunet-service-cadet_hello.c
+++ b/src/cadet/gnunet-service-cadet_hello.c
@@ -2,30 +2,25 @@
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2014, 2017 GNUnet e.V. 3 Copyright (C) 2014, 2017 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 it
6 it under the terms of the GNU General Public License as published 6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation; either version 3, or (at your 7 by the Free Software Foundation, either version 3 of the License,
8 option) any later version. 8 or (at your option) any later version.
9 9
10 GNUnet is distributed in the hope that it will be useful, but 10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details. 13 Affero General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU Affero General Public License
16 along with GNUnet; see the file COPYING. If not, write to the 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/ 17*/
20/** 18/**
21 * @file cadet/gnunet-service-cadet_hello.c 19 * @file cadet/gnunet-service-cadet_hello.c
22 * @brief spread knowledge about how to contact other peers from PEERINFO 20 * @brief spread knowledge about how to contact us (get HELLO from peerinfo),
21 * and remember HELLOs of other peers we have an interest in
23 * @author Bartlomiej Polot 22 * @author Bartlomiej Polot
24 * @author Christian Grothoff 23 * @author Christian Grothoff
25 *
26 * TODO:
27 * - is most of this necessary/helpful?
28 * - should we not simply restrict this to OUR hello?
29 */ 24 */
30#include "platform.h" 25#include "platform.h"
31#include "gnunet_util_lib.h" 26#include "gnunet_util_lib.h"
diff --git a/src/cadet/gnunet-service-cadet_hello.h b/src/cadet/gnunet-service-cadet_hello.h
index 4291ae985..be7fdf1ce 100644
--- a/src/cadet/gnunet-service-cadet_hello.h
+++ b/src/cadet/gnunet-service-cadet_hello.h
@@ -2,20 +2,18 @@
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2014, 2017 GNUnet e.V. 3 Copyright (C) 2014, 2017 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 it
6 it under the terms of the GNU General Public License as published 6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation; either version 3, or (at your 7 by the Free Software Foundation, either version 3 of the License,
8 option) any later version. 8 or (at your option) any later version.
9 9
10 GNUnet is distributed in the hope that it will be useful, but 10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details. 13 Affero General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU Affero General Public License
16 along with GNUnet; see the file COPYING. If not, write to the 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/ 17*/
20 18
21/** 19/**
diff --git a/src/cadet/gnunet-service-cadet_paths.c b/src/cadet/gnunet-service-cadet_paths.c
index b443cf9e8..593617ff6 100644
--- a/src/cadet/gnunet-service-cadet_paths.c
+++ b/src/cadet/gnunet-service-cadet_paths.c
@@ -2,24 +2,22 @@
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2001-2017 GNUnet e.V. 3 Copyright (C) 2001-2017 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 it
6 it under the terms of the GNU General Public License as published 6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation; either version 3, or (at your 7 by the Free Software Foundation, either version 3 of the License,
8 option) any later version. 8 or (at your option) any later version.
9 9
10 GNUnet is distributed in the hope that it will be useful, but 10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details. 13 Affero General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU Affero General Public License
16 along with GNUnet; see the file COPYING. If not, write to the 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/ 17*/
20/** 18/**
21 * @file cadet/gnunet-service-cadet_paths.c 19 * @file cadet/gnunet-service-cadet_paths.c
22 * @brief Information we track per path. 20 * @brief Information we track per path.
23 * @author Bartlomiej Polot 21 * @author Bartlomiej Polot
24 * @author Christian Grothoff 22 * @author Christian Grothoff
25 */ 23 */
@@ -146,7 +144,7 @@ GCPP_add_connection (struct CadetPeerPath *path,
146 struct CadetPeerPathEntry *entry; 144 struct CadetPeerPathEntry *entry;
147 145
148 LOG (GNUNET_ERROR_TYPE_DEBUG, 146 LOG (GNUNET_ERROR_TYPE_DEBUG,
149 "Adding connection %s to path %s at offset %u\n", 147 "Adding %s to path %s at offset %u\n",
150 GCC_2s (cc), 148 GCC_2s (cc),
151 GCPP_2s (path), 149 GCPP_2s (path),
152 off); 150 off);
diff --git a/src/cadet/gnunet-service-cadet_paths.h b/src/cadet/gnunet-service-cadet_paths.h
index 6b7bef640..2625253fb 100644
--- a/src/cadet/gnunet-service-cadet_paths.h
+++ b/src/cadet/gnunet-service-cadet_paths.h
@@ -3,20 +3,18 @@
3 This file is part of GNUnet. 3 This file is part of GNUnet.
4 Copyright (C) 2001-2017 GNUnet e.V. 4 Copyright (C) 2001-2017 GNUnet e.V.
5 5
6 GNUnet is free software; you can redistribute it and/or modify 6 GNUnet is free software: you can redistribute it and/or modify it
7 it under the terms of the GNU General Public License as published 7 under the terms of the GNU Affero General Public License as published
8 by the Free Software Foundation; either version 3, or (at your 8 by the Free Software Foundation, either version 3 of the License,
9 option) any later version. 9 or (at your option) any later version.
10 10
11 GNUnet is distributed in the hope that it will be useful, but 11 GNUnet is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of 12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details. 14 Affero General Public License for more details.
15 15
16 You should have received a copy of the GNU General Public License 16 You should have received a copy of the GNU Affero General Public License
17 along with GNUnet; see the file COPYING. If not, write to the 17 along with this program. If not, see <http://www.gnu.org/licenses/>.
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 Boston, MA 02110-1301, USA.
20*/ 18*/
21 19
22/** 20/**
diff --git a/src/cadet/gnunet-service-cadet_peer.c b/src/cadet/gnunet-service-cadet_peer.c
index 05555e693..b375d51ca 100644
--- a/src/cadet/gnunet-service-cadet_peer.c
+++ b/src/cadet/gnunet-service-cadet_peer.c
@@ -2,20 +2,18 @@
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2001-2017 GNUnet e.V. 3 Copyright (C) 2001-2017 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 it
6 it under the terms of the GNU General Public License as published 6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation; either version 3, or (at your 7 by the Free Software Foundation, either version 3 of the License,
8 option) any later version. 8 or (at your option) any later version.
9 9
10 GNUnet is distributed in the hope that it will be useful, but 10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details. 13 Affero General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU Affero General Public License
16 along with GNUnet; see the file COPYING. If not, write to the 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/ 17*/
20 18
21/** 19/**
@@ -242,12 +240,25 @@ struct CadetPeer
242const char * 240const char *
243GCP_2s (const struct CadetPeer *cp) 241GCP_2s (const struct CadetPeer *cp)
244{ 242{
245 static char buf[32]; 243 static char buf[5];
246 244 char *ret;
247 GNUNET_snprintf (buf, 245
248 sizeof (buf), 246 if ((NULL == cp) ||
249 "P(%s)", 247 (NULL == &cp->pid.public_key))
250 GNUNET_i2s (&cp->pid)); 248 return "NULL";
249
250
251 ret = GNUNET_CRYPTO_eddsa_public_key_to_string (&cp->pid.public_key);
252
253 if (NULL == ret)
254 return "NULL";
255
256
257 strncpy (buf,
258 ret,
259 sizeof (buf) - 1);
260 GNUNET_free (ret);
261 buf[4] = '\0';
251 return buf; 262 return buf;
252} 263}
253 264
@@ -649,6 +660,27 @@ mqm_execute (struct GCP_MessageQueueManager *mqm)
649 } 660 }
650 else 661 else
651 { 662 {
663 {
664 const struct GNUNET_MessageHeader *mh;
665
666 mh = GNUNET_MQ_env_get_msg (mqm->env);
667 switch (ntohs (mh->type))
668 {
669 case GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX:
670 {
671 const struct GNUNET_CADET_TunnelKeyExchangeMessage *msg
672 = (const struct GNUNET_CADET_TunnelKeyExchangeMessage *) mh;
673 LOG (GNUNET_ERROR_TYPE_DEBUG,
674 "P2P forwarding KX with ephemeral %s to %s on CID %s\n",
675 GNUNET_e2s (&msg->ephemeral_key),
676 GCP_2s (cp),
677 GNUNET_sh2s (&msg->cid.connection_of_tunnel));
678 }
679 break;
680 default:
681 break;
682 }
683 }
652 LOG (GNUNET_ERROR_TYPE_DEBUG, 684 LOG (GNUNET_ERROR_TYPE_DEBUG,
653 "Sending to peer %s from MQM %p\n", 685 "Sending to peer %s from MQM %p\n",
654 GCP_2s (cp), 686 GCP_2s (cp),
@@ -1044,7 +1076,7 @@ GCP_add_connection (struct CadetPeer *cp,
1044 struct CadetConnection *cc) 1076 struct CadetConnection *cc)
1045{ 1077{
1046 LOG (GNUNET_ERROR_TYPE_DEBUG, 1078 LOG (GNUNET_ERROR_TYPE_DEBUG,
1047 "Adding connection %s to peer %s\n", 1079 "Adding %s to peer %s\n",
1048 GCC_2s (cc), 1080 GCC_2s (cc),
1049 GCP_2s (cp)); 1081 GCP_2s (cp));
1050 GNUNET_assert (GNUNET_OK == 1082 GNUNET_assert (GNUNET_OK ==
@@ -1185,6 +1217,8 @@ GCP_iterate_paths (struct CadetPeer *cp,
1185 (NULL == cp->core_mq) ? "" : " including direct link"); 1217 (NULL == cp->core_mq) ? "" : " including direct link");
1186 if (NULL != cp->core_mq) 1218 if (NULL != cp->core_mq)
1187 { 1219 {
1220 /* FIXME: this branch seems to duplicate the
1221 i=0 case below (direct link). Leave out!??? -CG */
1188 struct CadetPeerPath *path; 1222 struct CadetPeerPath *path;
1189 1223
1190 path = GCPP_get_path_from_route (1, 1224 path = GCPP_get_path_from_route (1,
@@ -1213,6 +1247,41 @@ GCP_iterate_paths (struct CadetPeer *cp,
1213 return ret; 1247 return ret;
1214} 1248}
1215 1249
1250/**
1251 * Iterate over the paths to a peer without direct link.
1252 *
1253 * @param cp Peer to get path info.
1254 * @param callback Function to call for every path.
1255 * @param callback_cls Closure for @a callback.
1256 * @return Number of iterated paths.
1257 */
1258unsigned int
1259GCP_iterate_indirect_paths (struct CadetPeer *cp,
1260 GCP_PathIterator callback,
1261 void *callback_cls)
1262{
1263 unsigned int ret = 0;
1264
1265 LOG (GNUNET_ERROR_TYPE_DEBUG,
1266 "Iterating over paths to peer %s without direct link\n",
1267 GCP_2s (cp));
1268 for (unsigned int i=1;i<cp->path_dll_length;i++)
1269 {
1270 for (struct CadetPeerPathEntry *pe = cp->path_heads[i];
1271 NULL != pe;
1272 pe = pe->next)
1273 {
1274 ret++;
1275 if (GNUNET_NO ==
1276 callback (callback_cls,
1277 pe->path,
1278 i))
1279 return ret;
1280 }
1281 }
1282 return ret;
1283}
1284
1216 1285
1217/** 1286/**
1218 * Iterate over the paths to @a cp where 1287 * Iterate over the paths to @a cp where
diff --git a/src/cadet/gnunet-service-cadet_peer.h b/src/cadet/gnunet-service-cadet_peer.h
index baa87ea87..3b8b31b9a 100644
--- a/src/cadet/gnunet-service-cadet_peer.h
+++ b/src/cadet/gnunet-service-cadet_peer.h
@@ -2,20 +2,18 @@
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2001-2017 GNUnet e.V. 3 Copyright (C) 2001-2017 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 it
6 it under the terms of the GNU General Public License as published 6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation; either version 3, or (at your 7 by the Free Software Foundation, either version 3 of the License,
8 option) any later version. 8 or (at your option) any later version.
9 9
10 GNUnet is distributed in the hope that it will be useful, but 10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details. 13 Affero General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU Affero General Public License
16 along with GNUnet; see the file COPYING. If not, write to the 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/ 17*/
20 18
21/** 19/**
@@ -141,6 +139,19 @@ GCP_iterate_paths (struct CadetPeer *cp,
141 GCP_PathIterator callback, 139 GCP_PathIterator callback,
142 void *callback_cls); 140 void *callback_cls);
143 141
142/**
143 * Iterate over the paths to a peer without direct link.
144 *
145 * @param cp Peer to get path info.
146 * @param callback Function to call for every path.
147 * @param callback_cls Closure for @a callback.
148 * @return Number of iterated paths.
149 */
150unsigned int
151GCP_iterate_indirect_paths (struct CadetPeer *cp,
152 GCP_PathIterator callback,
153 void *callback_cls);
154
144 155
145/** 156/**
146 * Iterate over the paths to @a peer where 157 * Iterate over the paths to @a peer where
diff --git a/src/cadet/gnunet-service-cadet_tunnels.c b/src/cadet/gnunet-service-cadet_tunnels.c
index fb91a4a6a..1e7a8e086 100644
--- a/src/cadet/gnunet-service-cadet_tunnels.c
+++ b/src/cadet/gnunet-service-cadet_tunnels.c
@@ -1,21 +1,19 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2013, 2017 GNUnet e.V. 3 Copyright (C) 2013, 2017, 2018 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 it
6 it under the terms of the GNU General Public License as published 6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation; either version 3, or (at your 7 by the Free Software Foundation, either version 3 of the License,
8 option) any later version. 8 or (at your option) any later version.
9 9
10 GNUnet is distributed in the hope that it will be useful, but 10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details. 13 Affero General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU Affero General Public License
16 along with GNUnet; see the file COPYING. If not, write to the 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/ 17*/
20/** 18/**
21 * @file cadet/gnunet-service-cadet_tunnels.c 19 * @file cadet/gnunet-service-cadet_tunnels.c
@@ -187,6 +185,12 @@ struct CadetTunnelAxolotl
187 struct GNUNET_CRYPTO_EcdhePublicKey DHRr; 185 struct GNUNET_CRYPTO_EcdhePublicKey DHRr;
188 186
189 /** 187 /**
188 * Last ephemeral public key received from the other peer,
189 * for duplicate detection.
190 */
191 struct GNUNET_CRYPTO_EcdhePublicKey last_ephemeral;
192
193 /**
190 * Time when the current ratchet expires and a new one is triggered 194 * Time when the current ratchet expires and a new one is triggered
191 * (if @e ratchet_allowed is #GNUNET_YES). 195 * (if @e ratchet_allowed is #GNUNET_YES).
192 */ 196 */
@@ -453,6 +457,29 @@ struct CadetTunnel
453 457
454 458
455/** 459/**
460 * Am I Alice or Betty (some call her Bob), or talking to myself?
461 *
462 * @param other the other peer
463 * @return #GNUNET_YES for Alice, #GNUNET_NO for Betty, #GNUNET_SYSERR if talking to myself
464 */
465static int
466alice_or_betty (const struct GNUNET_PeerIdentity *other)
467{
468 if (0 > GNUNET_CRYPTO_cmp_peer_identity (&my_full_id,
469 other))
470 return GNUNET_YES;
471 else if (0 < GNUNET_CRYPTO_cmp_peer_identity (&my_full_id,
472 other))
473 return GNUNET_NO;
474 else
475 {
476 GNUNET_break_op (0);
477 return GNUNET_SYSERR;
478 }
479}
480
481
482/**
456 * Connection @a ct is now unready, clear it's ready flag 483 * Connection @a ct is now unready, clear it's ready flag
457 * and move it from the ready DLL to the busy DLL. 484 * and move it from the ready DLL to the busy DLL.
458 * 485 *
@@ -1318,6 +1345,8 @@ send_kx (struct CadetTunnel *t,
1318 struct GNUNET_CADET_TunnelKeyExchangeMessage *msg; 1345 struct GNUNET_CADET_TunnelKeyExchangeMessage *msg;
1319 enum GNUNET_CADET_KX_Flags flags; 1346 enum GNUNET_CADET_KX_Flags flags;
1320 1347
1348 if (GNUNET_YES != alice_or_betty (GCP_get_id (t->destination)))
1349 return; /* only Alice may send KX */
1321 if ( (NULL == ct) || 1350 if ( (NULL == ct) ||
1322 (GNUNET_NO == ct->is_ready) ) 1351 (GNUNET_NO == ct->is_ready) )
1323 ct = get_ready_connection (t); 1352 ct = get_ready_connection (t);
@@ -1331,11 +1360,6 @@ send_kx (struct CadetTunnel *t,
1331 return; 1360 return;
1332 } 1361 }
1333 cc = ct->cc; 1362 cc = ct->cc;
1334 LOG (GNUNET_ERROR_TYPE_DEBUG,
1335 "Sending KX on %s via %s in state %s\n",
1336 GCT_2s (t),
1337 GCC_2s (cc),
1338 estate2s (t->estate));
1339 env = GNUNET_MQ_msg (msg, 1363 env = GNUNET_MQ_msg (msg,
1340 GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX); 1364 GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX);
1341 flags = GNUNET_CADET_KX_FLAG_FORCE_REPLY; /* always for KX */ 1365 flags = GNUNET_CADET_KX_FLAG_FORCE_REPLY; /* always for KX */
@@ -1343,6 +1367,15 @@ send_kx (struct CadetTunnel *t,
1343 msg->cid = *GCC_get_id (cc); 1367 msg->cid = *GCC_get_id (cc);
1344 GNUNET_CRYPTO_ecdhe_key_get_public (&ax->kx_0, 1368 GNUNET_CRYPTO_ecdhe_key_get_public (&ax->kx_0,
1345 &msg->ephemeral_key); 1369 &msg->ephemeral_key);
1370#if DEBUG_KX
1371 msg->ephemeral_key_XXX = ax->kx_0;
1372 msg->private_key_XXX = *my_private_key;
1373#endif
1374 LOG (GNUNET_ERROR_TYPE_DEBUG,
1375 "Sending KX message to %s with ephemeral %s on CID %s\n",
1376 GCT_2s (t),
1377 GNUNET_e2s (&msg->ephemeral_key),
1378 GNUNET_sh2s (&msg->cid.connection_of_tunnel));
1346 GNUNET_CRYPTO_ecdhe_key_get_public (&ax->DHRs, 1379 GNUNET_CRYPTO_ecdhe_key_get_public (&ax->DHRs,
1347 &msg->ratchet_key); 1380 &msg->ratchet_key);
1348 mark_connection_unready (ct); 1381 mark_connection_unready (ct);
@@ -1356,6 +1389,10 @@ send_kx (struct CadetTunnel *t,
1356 CADET_TUNNEL_KEY_AX_SENT_AND_RECV); 1389 CADET_TUNNEL_KEY_AX_SENT_AND_RECV);
1357 GCC_transmit (cc, 1390 GCC_transmit (cc,
1358 env); 1391 env);
1392 GNUNET_STATISTICS_update (stats,
1393 "# KX transmitted",
1394 1,
1395 GNUNET_NO);
1359} 1396}
1360 1397
1361 1398
@@ -1394,11 +1431,6 @@ send_kx_auth (struct CadetTunnel *t,
1394 } 1431 }
1395 t->kx_auth_requested = GNUNET_NO; /* clear flag */ 1432 t->kx_auth_requested = GNUNET_NO; /* clear flag */
1396 cc = ct->cc; 1433 cc = ct->cc;
1397 LOG (GNUNET_ERROR_TYPE_DEBUG,
1398 "Sending KX_AUTH on %s using %s\n",
1399 GCT_2s (t),
1400 GCC_2s (ct->cc));
1401
1402 env = GNUNET_MQ_msg (msg, 1434 env = GNUNET_MQ_msg (msg,
1403 GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX_AUTH); 1435 GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX_AUTH);
1404 flags = GNUNET_CADET_KX_FLAG_NONE; 1436 flags = GNUNET_CADET_KX_FLAG_NONE;
@@ -1410,11 +1442,21 @@ send_kx_auth (struct CadetTunnel *t,
1410 &msg->kx.ephemeral_key); 1442 &msg->kx.ephemeral_key);
1411 GNUNET_CRYPTO_ecdhe_key_get_public (&ax->DHRs, 1443 GNUNET_CRYPTO_ecdhe_key_get_public (&ax->DHRs,
1412 &msg->kx.ratchet_key); 1444 &msg->kx.ratchet_key);
1445#if DEBUG_KX
1446 msg->kx.ephemeral_key_XXX = ax->kx_0;
1447 msg->kx.private_key_XXX = *my_private_key;
1448 msg->r_ephemeral_key_XXX = ax->last_ephemeral;
1449#endif
1450 LOG (GNUNET_ERROR_TYPE_DEBUG,
1451 "Sending KX_AUTH message to %s with ephemeral %s on CID %s\n",
1452 GCT_2s (t),
1453 GNUNET_e2s (&msg->kx.ephemeral_key),
1454 GNUNET_sh2s (&msg->kx.cid.connection_of_tunnel));
1455
1413 /* Compute authenticator (this is the main difference to #send_kx()) */ 1456 /* Compute authenticator (this is the main difference to #send_kx()) */
1414 GNUNET_CRYPTO_hash (&ax->RK, 1457 GNUNET_CRYPTO_hash (&ax->RK,
1415 sizeof (ax->RK), 1458 sizeof (ax->RK),
1416 &msg->auth); 1459 &msg->auth);
1417
1418 /* Compute when to be triggered again; actual job will 1460 /* Compute when to be triggered again; actual job will
1419 be scheduled via #connection_ready_cb() */ 1461 be scheduled via #connection_ready_cb() */
1420 t->kx_retry_delay 1462 t->kx_retry_delay
@@ -1429,9 +1471,12 @@ send_kx_auth (struct CadetTunnel *t,
1429 if (CADET_TUNNEL_KEY_OK != t->estate) 1471 if (CADET_TUNNEL_KEY_OK != t->estate)
1430 GCT_change_estate (t, 1472 GCT_change_estate (t,
1431 CADET_TUNNEL_KEY_AX_AUTH_SENT); 1473 CADET_TUNNEL_KEY_AX_AUTH_SENT);
1432
1433 GCC_transmit (cc, 1474 GCC_transmit (cc,
1434 env); 1475 env);
1476 GNUNET_STATISTICS_update (stats,
1477 "# KX_AUTH transmitted",
1478 1,
1479 GNUNET_NO);
1435} 1480}
1436 1481
1437 1482
@@ -1476,66 +1521,57 @@ update_ax_by_kx (struct CadetTunnelAxolotl *ax,
1476 const char salt[] = "CADET Axolotl salt"; 1521 const char salt[] = "CADET Axolotl salt";
1477 int am_I_alice; 1522 int am_I_alice;
1478 1523
1479 if (0 > GNUNET_CRYPTO_cmp_peer_identity (&my_full_id, 1524 if (GNUNET_SYSERR == (am_I_alice = alice_or_betty (pid)))
1480 pid))
1481 am_I_alice = GNUNET_YES;
1482 else if (0 < GNUNET_CRYPTO_cmp_peer_identity (&my_full_id,
1483 pid))
1484 am_I_alice = GNUNET_NO;
1485 else
1486 { 1525 {
1487 GNUNET_break_op (0); 1526 GNUNET_break_op (0);
1488 return GNUNET_SYSERR; 1527 return GNUNET_SYSERR;
1489 } 1528 }
1490
1491 if (0 == memcmp (&ax->DHRr, 1529 if (0 == memcmp (&ax->DHRr,
1492 ratchet_key, 1530 ratchet_key,
1493 sizeof (*ratchet_key))) 1531 sizeof (*ratchet_key)))
1494 { 1532 {
1533 GNUNET_STATISTICS_update (stats,
1534 "# Ratchet key already known",
1535 1,
1536 GNUNET_NO);
1495 LOG (GNUNET_ERROR_TYPE_DEBUG, 1537 LOG (GNUNET_ERROR_TYPE_DEBUG,
1496 "Ratchet key already known. Ignoring KX.\n"); 1538 "Ratchet key already known. Ignoring KX.\n");
1497 return GNUNET_NO; 1539 return GNUNET_NO;
1498 } 1540 }
1499 1541
1500 ax->DHRr = *ratchet_key; 1542 ax->DHRr = *ratchet_key;
1501 1543 ax->last_ephemeral = *ephemeral_key;
1502 /* ECDH A B0 */ 1544 /* ECDH A B0 */
1503 if (GNUNET_YES == am_I_alice) 1545 if (GNUNET_YES == am_I_alice)
1504 { 1546 {
1505 GNUNET_CRYPTO_eddsa_ecdh (my_private_key, /* A */ 1547 GNUNET_CRYPTO_eddsa_ecdh (my_private_key, /* a */
1506 ephemeral_key, /* B0 */ 1548 ephemeral_key, /* B0 */
1507 &key_material[0]); 1549 &key_material[0]);
1508 } 1550 }
1509 else 1551 else
1510 { 1552 {
1511 GNUNET_CRYPTO_ecdh_eddsa (&ax->kx_0, /* B0 */ 1553 GNUNET_CRYPTO_ecdh_eddsa (&ax->kx_0, /* b0 */
1512 &pid->public_key, /* A */ 1554 &pid->public_key, /* A */
1513 &key_material[0]); 1555 &key_material[0]);
1514 } 1556 }
1515
1516 /* ECDH A0 B */ 1557 /* ECDH A0 B */
1517 if (GNUNET_YES == am_I_alice) 1558 if (GNUNET_YES == am_I_alice)
1518 { 1559 {
1519 GNUNET_CRYPTO_ecdh_eddsa (&ax->kx_0, /* A0 */ 1560 GNUNET_CRYPTO_ecdh_eddsa (&ax->kx_0, /* a0 */
1520 &pid->public_key, /* B */ 1561 &pid->public_key, /* B */
1521 &key_material[1]); 1562 &key_material[1]);
1522 } 1563 }
1523 else 1564 else
1524 { 1565 {
1525 GNUNET_CRYPTO_eddsa_ecdh (my_private_key, /* A */ 1566 GNUNET_CRYPTO_eddsa_ecdh (my_private_key, /* b */
1526 ephemeral_key, /* B0 */ 1567 ephemeral_key, /* A0 */
1527 &key_material[1]); 1568 &key_material[1]);
1528
1529
1530 } 1569 }
1531 1570
1532 /* ECDH A0 B0 */ 1571 /* ECDH A0 B0 */
1533 /* (This is the triple-DH, we could probably safely skip this, 1572 GNUNET_CRYPTO_ecc_ecdh (&ax->kx_0, /* a0 or b0 */
1534 as A0/B0 are already in the key material.) */ 1573 ephemeral_key, /* B0 or A0 */
1535 GNUNET_CRYPTO_ecc_ecdh (&ax->kx_0, /* A0 or B0 */
1536 ephemeral_key, /* B0 or A0 */
1537 &key_material[2]); 1574 &key_material[2]);
1538
1539 /* KDF */ 1575 /* KDF */
1540 GNUNET_CRYPTO_kdf (keys, sizeof (keys), 1576 GNUNET_CRYPTO_kdf (keys, sizeof (keys),
1541 salt, sizeof (salt), 1577 salt, sizeof (salt),
@@ -1547,7 +1583,11 @@ update_ax_by_kx (struct CadetTunnelAxolotl *ax,
1547 sizeof (ax->RK))) 1583 sizeof (ax->RK)))
1548 { 1584 {
1549 LOG (GNUNET_ERROR_TYPE_DEBUG, 1585 LOG (GNUNET_ERROR_TYPE_DEBUG,
1550 "Root key of handshake already known. Ignoring KX.\n"); 1586 "Root key already known. Ignoring KX.\n");
1587 GNUNET_STATISTICS_update (stats,
1588 "# Root key already known",
1589 1,
1590 GNUNET_NO);
1551 return GNUNET_NO; 1591 return GNUNET_NO;
1552 } 1592 }
1553 1593
@@ -1592,75 +1632,75 @@ retry_kx (void *cls)
1592 GCT_2s (t), 1632 GCT_2s (t),
1593 estate2s (t->estate)); 1633 estate2s (t->estate));
1594 switch (t->estate) 1634 switch (t->estate)
1595 {
1596 case CADET_TUNNEL_KEY_UNINITIALIZED: /* first attempt */
1597 case CADET_TUNNEL_KEY_AX_SENT: /* trying again */
1598 send_kx (t,
1599 NULL,
1600 &t->ax);
1601 break;
1602 case CADET_TUNNEL_KEY_AX_RECV:
1603 case CADET_TUNNEL_KEY_AX_SENT_AND_RECV:
1604 /* We are responding, so only require reply
1605 if WE have a channel waiting. */
1606 if (NULL != t->unverified_ax)
1607 {
1608 /* Send AX_AUTH so we might get this one verified */
1609 ax = t->unverified_ax;
1610 }
1611 else
1612 {
1613 /* How can this be? */
1614 GNUNET_break (0);
1615 ax = &t->ax;
1616 }
1617 send_kx_auth (t,
1618 NULL,
1619 ax,
1620 (0 == GCT_count_channels (t))
1621 ? GNUNET_NO
1622 : GNUNET_YES);
1623 break;
1624 case CADET_TUNNEL_KEY_AX_AUTH_SENT:
1625 /* We are responding, so only require reply
1626 if WE have a channel waiting. */
1627 if (NULL != t->unverified_ax)
1628 {
1629 /* Send AX_AUTH so we might get this one verified */
1630 ax = t->unverified_ax;
1631 }
1632 else
1633 {
1634 /* How can this be? */
1635 GNUNET_break (0);
1636 ax = &t->ax;
1637 }
1638 send_kx_auth (t,
1639 NULL,
1640 ax,
1641 (0 == GCT_count_channels (t))
1642 ? GNUNET_NO
1643 : GNUNET_YES);
1644 break;
1645 case CADET_TUNNEL_KEY_OK:
1646 /* Must have been the *other* peer asking us to
1647 respond with a KX_AUTH. */
1648 if (NULL != t->unverified_ax)
1649 { 1635 {
1650 /* Sending AX_AUTH in response to AX so we might get this one verified */ 1636 case CADET_TUNNEL_KEY_UNINITIALIZED: /* first attempt */
1651 ax = t->unverified_ax; 1637 case CADET_TUNNEL_KEY_AX_SENT: /* trying again */
1652 } 1638 send_kx (t,
1653 else 1639 NULL,
1654 { 1640 &t->ax);
1655 /* Sending AX_AUTH in response to AX_AUTH */ 1641 break;
1656 ax = &t->ax; 1642 case CADET_TUNNEL_KEY_AX_RECV:
1643 case CADET_TUNNEL_KEY_AX_SENT_AND_RECV:
1644 /* We are responding, so only require reply
1645 if WE have a channel waiting. */
1646 if (NULL != t->unverified_ax)
1647 {
1648 /* Send AX_AUTH so we might get this one verified */
1649 ax = t->unverified_ax;
1650 }
1651 else
1652 {
1653 /* How can this be? */
1654 GNUNET_break (0);
1655 ax = &t->ax;
1656 }
1657 send_kx_auth (t,
1658 NULL,
1659 ax,
1660 (0 == GCT_count_channels (t))
1661 ? GNUNET_NO
1662 : GNUNET_YES);
1663 break;
1664 case CADET_TUNNEL_KEY_AX_AUTH_SENT:
1665 /* We are responding, so only require reply
1666 if WE have a channel waiting. */
1667 if (NULL != t->unverified_ax)
1668 {
1669 /* Send AX_AUTH so we might get this one verified */
1670 ax = t->unverified_ax;
1671 }
1672 else
1673 {
1674 /* How can this be? */
1675 GNUNET_break (0);
1676 ax = &t->ax;
1677 }
1678 send_kx_auth (t,
1679 NULL,
1680 ax,
1681 (0 == GCT_count_channels (t))
1682 ? GNUNET_NO
1683 : GNUNET_YES);
1684 break;
1685 case CADET_TUNNEL_KEY_OK:
1686 /* Must have been the *other* peer asking us to
1687 respond with a KX_AUTH. */
1688 if (NULL != t->unverified_ax)
1689 {
1690 /* Sending AX_AUTH in response to AX so we might get this one verified */
1691 ax = t->unverified_ax;
1692 }
1693 else
1694 {
1695 /* Sending AX_AUTH in response to AX_AUTH */
1696 ax = &t->ax;
1697 }
1698 send_kx_auth (t,
1699 NULL,
1700 ax,
1701 GNUNET_NO);
1702 break;
1657 } 1703 }
1658 send_kx_auth (t,
1659 NULL,
1660 ax,
1661 GNUNET_NO);
1662 break;
1663 }
1664} 1704}
1665 1705
1666 1706
@@ -1677,76 +1717,117 @@ GCT_handle_kx (struct CadetTConnection *ct,
1677 const struct GNUNET_CADET_TunnelKeyExchangeMessage *msg) 1717 const struct GNUNET_CADET_TunnelKeyExchangeMessage *msg)
1678{ 1718{
1679 struct CadetTunnel *t = ct->t; 1719 struct CadetTunnel *t = ct->t;
1680 struct CadetTunnelAxolotl *ax;
1681 int ret; 1720 int ret;
1682 1721
1683 if (0 == 1722 GNUNET_STATISTICS_update (stats,
1684 memcmp (&t->ax.DHRr, 1723 "# KX received",
1685 &msg->ratchet_key, 1724 1,
1686 sizeof (msg->ratchet_key))) 1725 GNUNET_NO);
1726 if (GNUNET_YES ==
1727 alice_or_betty (GCP_get_id (t->destination)))
1687 { 1728 {
1688 LOG (GNUNET_ERROR_TYPE_DEBUG, 1729 /* Betty/Bob is not allowed to send KX! */
1689 "Got duplicate KX. Firing back KX_AUTH.\n"); 1730 GNUNET_break_op (0);
1690 send_kx_auth (t,
1691 ct,
1692 &t->ax,
1693 GNUNET_NO);
1694 return; 1731 return;
1695 } 1732 }
1733 LOG (GNUNET_ERROR_TYPE_DEBUG,
1734 "Received KX message from %s with ephemeral %s from %s on connection %s\n",
1735 GCT_2s (t),
1736 GNUNET_e2s (&msg->ephemeral_key),
1737 GNUNET_i2s (GCP_get_id (t->destination)),
1738 GCC_2s (ct->cc));
1739#if 1
1740 if ( (0 ==
1741 memcmp (&t->ax.DHRr,
1742 &msg->ratchet_key,
1743 sizeof (msg->ratchet_key))) &&
1744 (0 ==
1745 memcmp (&t->ax.last_ephemeral,
1746 &msg->ephemeral_key,
1747 sizeof (msg->ephemeral_key))) )
1696 1748
1749 {
1750 GNUNET_STATISTICS_update (stats,
1751 "# Duplicate KX received",
1752 1,
1753 GNUNET_NO);
1754 send_kx_auth (t,
1755 ct,
1756 &t->ax,
1757 GNUNET_NO);
1758 return;
1759 }
1760#endif
1697 /* We only keep ONE unverified KX around, so if there is an existing one, 1761 /* We only keep ONE unverified KX around, so if there is an existing one,
1698 clean it up. */ 1762 clean it up. */
1699 if (NULL != t->unverified_ax) 1763 if (NULL != t->unverified_ax)
1700 { 1764 {
1701 if (0 == 1765 if ( (0 ==
1702 memcmp (&t->unverified_ax->DHRr, 1766 memcmp (&t->unverified_ax->DHRr,
1703 &msg->ratchet_key, 1767 &msg->ratchet_key,
1704 sizeof (msg->ratchet_key))) 1768 sizeof (msg->ratchet_key))) &&
1769 (0 ==
1770 memcmp (&t->unverified_ax->last_ephemeral,
1771 &msg->ephemeral_key,
1772 sizeof (msg->ephemeral_key))) )
1705 { 1773 {
1706 LOG (GNUNET_ERROR_TYPE_DEBUG, 1774 GNUNET_STATISTICS_update (stats,
1707 "Got duplicate unverified KX on %s. Fire back KX_AUTH again.\n", 1775 "# Duplicate unverified KX received",
1708 GCT_2s (t)); 1776 1,
1777 GNUNET_NO);
1778#if 1
1709 send_kx_auth (t, 1779 send_kx_auth (t,
1710 ct, 1780 ct,
1711 t->unverified_ax, 1781 t->unverified_ax,
1712 GNUNET_NO); 1782 GNUNET_NO);
1713 return; 1783 return;
1784#endif
1714 } 1785 }
1715 LOG (GNUNET_ERROR_TYPE_DEBUG, 1786 LOG (GNUNET_ERROR_TYPE_DEBUG,
1716 "Dropping old unverified KX state. Got a fresh KX for %s.\n", 1787 "Dropping old unverified KX state.\n");
1717 GCT_2s (t)); 1788 GNUNET_STATISTICS_update (stats,
1789 "# Unverified KX dropped for fresh KX",
1790 1,
1791 GNUNET_NO);
1792 GNUNET_break (NULL == t->unverified_ax->skipped_head);
1718 memset (t->unverified_ax, 1793 memset (t->unverified_ax,
1719 0, 1794 0,
1720 sizeof (struct CadetTunnelAxolotl)); 1795 sizeof (struct CadetTunnelAxolotl));
1721 t->unverified_ax->DHRs = t->ax.DHRs;
1722 t->unverified_ax->kx_0 = t->ax.kx_0;
1723 } 1796 }
1724 else 1797 else
1725 { 1798 {
1726 LOG (GNUNET_ERROR_TYPE_DEBUG, 1799 LOG (GNUNET_ERROR_TYPE_DEBUG,
1727 "Creating fresh unverified KX for %s.\n", 1800 "Creating fresh unverified KX for %s\n",
1728 GCT_2s (t)); 1801 GCT_2s (t));
1802 GNUNET_STATISTICS_update (stats,
1803 "# Fresh KX setup",
1804 1,
1805 GNUNET_NO);
1729 t->unverified_ax = GNUNET_new (struct CadetTunnelAxolotl); 1806 t->unverified_ax = GNUNET_new (struct CadetTunnelAxolotl);
1730 t->unverified_ax->DHRs = t->ax.DHRs;
1731 t->unverified_ax->kx_0 = t->ax.kx_0;
1732 } 1807 }
1733 /* Set as the 'current' RK/DHRr the one we are currently using, 1808 /* Set as the 'current' RK/DHRr the one we are currently using,
1734 so that the duplicate-detection logic of 1809 so that the duplicate-detection logic of
1735 #update_ax_by_kx can work. */ 1810 #update_ax_by_kx can work. */
1736 t->unverified_ax->RK = t->ax.RK; 1811 t->unverified_ax->RK = t->ax.RK;
1737 t->unverified_ax->DHRr = t->ax.DHRr; 1812 t->unverified_ax->DHRr = t->ax.DHRr;
1813 t->unverified_ax->DHRs = t->ax.DHRs;
1814 t->unverified_ax->kx_0 = t->ax.kx_0;
1738 t->unverified_attempts = 0; 1815 t->unverified_attempts = 0;
1739 ax = t->unverified_ax;
1740 1816
1741 /* Update 'ax' by the new key material */ 1817 /* Update 'ax' by the new key material */
1742 ret = update_ax_by_kx (ax, 1818 ret = update_ax_by_kx (t->unverified_ax,
1743 GCP_get_id (t->destination), 1819 GCP_get_id (t->destination),
1744 &msg->ephemeral_key, 1820 &msg->ephemeral_key,
1745 &msg->ratchet_key); 1821 &msg->ratchet_key);
1746 GNUNET_break (GNUNET_SYSERR != ret); 1822 GNUNET_break (GNUNET_SYSERR != ret);
1747 if (GNUNET_OK != ret) 1823 if (GNUNET_OK != ret)
1824 {
1825 GNUNET_STATISTICS_update (stats,
1826 "# Useless KX",
1827 1,
1828 GNUNET_NO);
1748 return; /* duplicate KX, nothing to do */ 1829 return; /* duplicate KX, nothing to do */
1749 1830 }
1750 /* move ahead in our state machine */ 1831 /* move ahead in our state machine */
1751 if (CADET_TUNNEL_KEY_UNINITIALIZED == t->estate) 1832 if (CADET_TUNNEL_KEY_UNINITIALIZED == t->estate)
1752 GCT_change_estate (t, 1833 GCT_change_estate (t,
@@ -1767,6 +1848,75 @@ GCT_handle_kx (struct CadetTConnection *ct,
1767} 1848}
1768 1849
1769 1850
1851#if DEBUG_KX
1852static void
1853check_ee (const struct GNUNET_CRYPTO_EcdhePrivateKey *e1,
1854 const struct GNUNET_CRYPTO_EcdhePrivateKey *e2)
1855{
1856 struct GNUNET_CRYPTO_EcdhePublicKey p1;
1857 struct GNUNET_CRYPTO_EcdhePublicKey p2;
1858 struct GNUNET_HashCode hc1;
1859 struct GNUNET_HashCode hc2;
1860
1861 GNUNET_CRYPTO_ecdhe_key_get_public (e1,
1862 &p1);
1863 GNUNET_CRYPTO_ecdhe_key_get_public (e2,
1864 &p2);
1865 GNUNET_assert (GNUNET_OK ==
1866 GNUNET_CRYPTO_ecc_ecdh (e1,
1867 &p2,
1868 &hc1));
1869 GNUNET_assert (GNUNET_OK ==
1870 GNUNET_CRYPTO_ecc_ecdh (e2,
1871 &p1,
1872 &hc2));
1873 GNUNET_break (0 == memcmp (&hc1,
1874 &hc2,
1875 sizeof (hc1)));
1876}
1877
1878
1879static void
1880check_ed (const struct GNUNET_CRYPTO_EcdhePrivateKey *e1,
1881 const struct GNUNET_CRYPTO_EddsaPrivateKey *e2)
1882{
1883 struct GNUNET_CRYPTO_EcdhePublicKey p1;
1884 struct GNUNET_CRYPTO_EddsaPublicKey p2;
1885 struct GNUNET_HashCode hc1;
1886 struct GNUNET_HashCode hc2;
1887
1888 GNUNET_CRYPTO_ecdhe_key_get_public (e1,
1889 &p1);
1890 GNUNET_CRYPTO_eddsa_key_get_public (e2,
1891 &p2);
1892 GNUNET_assert (GNUNET_OK ==
1893 GNUNET_CRYPTO_ecdh_eddsa (e1,
1894 &p2,
1895 &hc1));
1896 GNUNET_assert (GNUNET_OK ==
1897 GNUNET_CRYPTO_eddsa_ecdh (e2,
1898 &p1,
1899 &hc2));
1900 GNUNET_break (0 == memcmp (&hc1,
1901 &hc2,
1902 sizeof (hc1)));
1903}
1904
1905
1906static void
1907test_crypto_bug (const struct GNUNET_CRYPTO_EcdhePrivateKey *e1,
1908 const struct GNUNET_CRYPTO_EcdhePrivateKey *e2,
1909 const struct GNUNET_CRYPTO_EddsaPrivateKey *d1,
1910 const struct GNUNET_CRYPTO_EddsaPrivateKey *d2)
1911{
1912 check_ee (e1, e2);
1913 check_ed (e1, d2);
1914 check_ed (e2, d1);
1915}
1916
1917#endif
1918
1919
1770/** 1920/**
1771 * Handle KX_AUTH message. 1921 * Handle KX_AUTH message.
1772 * 1922 *
@@ -1782,6 +1932,10 @@ GCT_handle_kx_auth (struct CadetTConnection *ct,
1782 struct GNUNET_HashCode kx_auth; 1932 struct GNUNET_HashCode kx_auth;
1783 int ret; 1933 int ret;
1784 1934
1935 GNUNET_STATISTICS_update (stats,
1936 "# KX_AUTH received",
1937 1,
1938 GNUNET_NO);
1785 if ( (CADET_TUNNEL_KEY_UNINITIALIZED == t->estate) || 1939 if ( (CADET_TUNNEL_KEY_UNINITIALIZED == t->estate) ||
1786 (CADET_TUNNEL_KEY_AX_RECV == t->estate) ) 1940 (CADET_TUNNEL_KEY_AX_RECV == t->estate) )
1787 { 1941 {
@@ -1792,9 +1946,9 @@ GCT_handle_kx_auth (struct CadetTConnection *ct,
1792 return; 1946 return;
1793 } 1947 }
1794 LOG (GNUNET_ERROR_TYPE_DEBUG, 1948 LOG (GNUNET_ERROR_TYPE_DEBUG,
1795 "Handling KX_AUTH message for %s\n", 1949 "Handling KX_AUTH message from %s with ephemeral %s\n",
1796 GCT_2s (t)); 1950 GCT_2s (t),
1797 1951 GNUNET_e2s (&msg->kx.ephemeral_key));
1798 /* We do everything in ax_tmp until we've checked the authentication 1952 /* We do everything in ax_tmp until we've checked the authentication
1799 so we don't clobber anything we care about by accident. */ 1953 so we don't clobber anything we care about by accident. */
1800 ax_tmp = t->ax; 1954 ax_tmp = t->ax;
@@ -1828,9 +1982,39 @@ GCT_handle_kx_auth (struct CadetTConnection *ct,
1828 "# KX_AUTH not using our last KX received (auth failure)", 1982 "# KX_AUTH not using our last KX received (auth failure)",
1829 1, 1983 1,
1830 GNUNET_NO); 1984 GNUNET_NO);
1831 send_kx (t, 1985 LOG (GNUNET_ERROR_TYPE_WARNING,
1832 ct, 1986 "KX AUTH missmatch!\n");
1833 &t->ax); 1987#if DEBUG_KX
1988 {
1989 struct GNUNET_CRYPTO_EcdhePublicKey ephemeral_key;
1990
1991 GNUNET_CRYPTO_ecdhe_key_get_public (&ax_tmp.kx_0,
1992 &ephemeral_key);
1993 if (0 != memcmp (&ephemeral_key,
1994 &msg->r_ephemeral_key_XXX,
1995 sizeof (ephemeral_key)))
1996 {
1997 LOG (GNUNET_ERROR_TYPE_WARNING,
1998 "My ephemeral is %s!\n",
1999 GNUNET_e2s (&ephemeral_key));
2000 LOG (GNUNET_ERROR_TYPE_WARNING,
2001 "Response is for ephemeral %s!\n",
2002 GNUNET_e2s (&msg->r_ephemeral_key_XXX));
2003 }
2004 else
2005 {
2006 test_crypto_bug (&ax_tmp.kx_0,
2007 &msg->kx.ephemeral_key_XXX,
2008 my_private_key,
2009 &msg->kx.private_key_XXX);
2010 }
2011 }
2012#endif
2013 if (NULL == t->kx_task)
2014 t->kx_task
2015 = GNUNET_SCHEDULER_add_at (t->next_kx_attempt,
2016 &retry_kx,
2017 t);
1834 return; 2018 return;
1835 } 2019 }
1836 /* Yep, we're good. */ 2020 /* Yep, we're good. */
@@ -1862,6 +2046,13 @@ GCT_handle_kx_auth (struct CadetTConnection *ct,
1862 Nothing to do here. */ 2046 Nothing to do here. */
1863 break; 2047 break;
1864 } 2048 }
2049 if (0 != (GNUNET_CADET_KX_FLAG_FORCE_REPLY & ntohl (msg->kx.flags)))
2050 {
2051 send_kx_auth (t,
2052 NULL,
2053 &t->ax,
2054 GNUNET_NO);
2055 }
1865} 2056}
1866 2057
1867 2058
@@ -2236,8 +2427,8 @@ connection_ready_cb (void *cls,
2236 { 2427 {
2237 case CADET_TUNNEL_KEY_UNINITIALIZED: 2428 case CADET_TUNNEL_KEY_UNINITIALIZED:
2238 /* Do not begin KX if WE have no channels waiting! */ 2429 /* Do not begin KX if WE have no channels waiting! */
2239 if (0 == GCT_count_channels (t)) 2430 if (0 != GNUNET_TIME_absolute_get_remaining (t->next_kx_attempt).rel_value_us)
2240 return; 2431 return; /* wait for timeout before retrying */
2241 /* We are uninitialized, just transmit immediately, 2432 /* We are uninitialized, just transmit immediately,
2242 without undue delay. */ 2433 without undue delay. */
2243 if (NULL != t->kx_task) 2434 if (NULL != t->kx_task)
@@ -2248,6 +2439,15 @@ connection_ready_cb (void *cls,
2248 send_kx (t, 2439 send_kx (t,
2249 ct, 2440 ct,
2250 &t->ax); 2441 &t->ax);
2442 if ( (0 ==
2443 GCT_count_channels (t)) &&
2444 (NULL == t->destroy_task) )
2445 {
2446 t->destroy_task
2447 = GNUNET_SCHEDULER_add_delayed (IDLE_DESTROY_DELAY,
2448 &destroy_tunnel,
2449 t);
2450 }
2251 break; 2451 break;
2252 case CADET_TUNNEL_KEY_AX_RECV: 2452 case CADET_TUNNEL_KEY_AX_RECV:
2253 case CADET_TUNNEL_KEY_AX_SENT: 2453 case CADET_TUNNEL_KEY_AX_SENT:
@@ -2263,6 +2463,8 @@ connection_ready_cb (void *cls,
2263 case CADET_TUNNEL_KEY_OK: 2463 case CADET_TUNNEL_KEY_OK:
2264 if (GNUNET_YES == t->kx_auth_requested) 2464 if (GNUNET_YES == t->kx_auth_requested)
2265 { 2465 {
2466 if (0 != GNUNET_TIME_absolute_get_remaining (t->next_kx_attempt).rel_value_us)
2467 return; /* wait for timeout */
2266 if (NULL != t->kx_task) 2468 if (NULL != t->kx_task)
2267 { 2469 {
2268 GNUNET_SCHEDULER_cancel (t->kx_task); 2470 GNUNET_SCHEDULER_cancel (t->kx_task);
@@ -2370,15 +2572,21 @@ evaluate_connection (void *cls,
2370{ 2572{
2371 struct EvaluationSummary *es = cls; 2573 struct EvaluationSummary *es = cls;
2372 struct CadetConnection *cc = ct->cc; 2574 struct CadetConnection *cc = ct->cc;
2373 struct CadetPeerPath *ps = GCC_get_path (cc); 2575 unsigned int ct_length;
2576 struct CadetPeerPath *ps;
2374 const struct CadetConnectionMetrics *metrics; 2577 const struct CadetConnectionMetrics *metrics;
2375 GNUNET_CONTAINER_HeapCostType ct_desirability; 2578 GNUNET_CONTAINER_HeapCostType ct_desirability;
2376 struct GNUNET_TIME_Relative uptime; 2579 struct GNUNET_TIME_Relative uptime;
2377 struct GNUNET_TIME_Relative last_use; 2580 struct GNUNET_TIME_Relative last_use;
2378 uint32_t ct_length;
2379 double score; 2581 double score;
2380 double success_rate; 2582 double success_rate;
2381 2583
2584 ps = GCC_get_path (cc,
2585 &ct_length);
2586 LOG (GNUNET_ERROR_TYPE_DEBUG,
2587 "Evaluating path %s of existing %s\n",
2588 GCPP_2s (ps),
2589 GCC_2s (cc));
2382 if (ps == es->path) 2590 if (ps == es->path)
2383 { 2591 {
2384 LOG (GNUNET_ERROR_TYPE_DEBUG, 2592 LOG (GNUNET_ERROR_TYPE_DEBUG,
@@ -2387,8 +2595,39 @@ evaluate_connection (void *cls,
2387 es->duplicate = GNUNET_YES; 2595 es->duplicate = GNUNET_YES;
2388 return; 2596 return;
2389 } 2597 }
2598 if (NULL != es->path)
2599 {
2600 int duplicate = GNUNET_YES;
2601
2602 for (unsigned int i=0;i<ct_length;i++)
2603 {
2604 GNUNET_assert (GCPP_get_length (es->path) > i);
2605 if (GCPP_get_peer_at_offset (es->path,
2606 i) !=
2607 GCPP_get_peer_at_offset (ps,
2608 i))
2609 {
2610 duplicate = GNUNET_NO;
2611 break;
2612 }
2613 }
2614 if (GNUNET_YES == duplicate)
2615 {
2616 LOG (GNUNET_ERROR_TYPE_DEBUG,
2617 "Ignoring overlapping path %s.\n",
2618 GCPP_2s (es->path));
2619 es->duplicate = GNUNET_YES;
2620 return;
2621 }
2622 else
2623 {
2624 LOG (GNUNET_ERROR_TYPE_DEBUG,
2625 "Known path %s differs from proposed path\n",
2626 GCPP_2s (ps));
2627 }
2628 }
2629
2390 ct_desirability = GCPP_get_desirability (ps); 2630 ct_desirability = GCPP_get_desirability (ps);
2391 ct_length = GCPP_get_length (ps);
2392 metrics = GCC_get_metrics (cc); 2631 metrics = GCC_get_metrics (cc);
2393 uptime = GNUNET_TIME_absolute_get_duration (metrics->age); 2632 uptime = GNUNET_TIME_absolute_get_duration (metrics->age);
2394 last_use = GNUNET_TIME_absolute_get_duration (metrics->last_use); 2633 last_use = GNUNET_TIME_absolute_get_duration (metrics->last_use);
@@ -2437,6 +2676,8 @@ consider_path_cb (void *cls,
2437 struct CadetTConnection *ct; 2676 struct CadetTConnection *ct;
2438 2677
2439 GNUNET_assert (off < GCPP_get_length (path)); 2678 GNUNET_assert (off < GCPP_get_length (path));
2679 GNUNET_assert (GCPP_get_peer_at_offset (path,
2680 off) == t->destination);
2440 es.min_length = UINT_MAX; 2681 es.min_length = UINT_MAX;
2441 es.max_length = 0; 2682 es.max_length = 0;
2442 es.max_desire = 0; 2683 es.max_desire = 0;
@@ -2446,6 +2687,13 @@ consider_path_cb (void *cls,
2446 es.worst = NULL; 2687 es.worst = NULL;
2447 2688
2448 /* Compute evaluation summary over existing connections. */ 2689 /* Compute evaluation summary over existing connections. */
2690 LOG (GNUNET_ERROR_TYPE_DEBUG,
2691 "Evaluating proposed path %s for target %s\n",
2692 GCPP_2s (path),
2693 GCT_2s (t));
2694 /* FIXME: suspect this does not ACTUALLY iterate
2695 over all existing paths, otherwise dup detection
2696 should work!!! */
2449 GCT_iterate_connections (t, 2697 GCT_iterate_connections (t,
2450 &evaluate_connection, 2698 &evaluate_connection,
2451 &es); 2699 &es);
@@ -2590,9 +2838,10 @@ GCT_consider_path (struct CadetTunnel *t,
2590 unsigned int off) 2838 unsigned int off)
2591{ 2839{
2592 LOG (GNUNET_ERROR_TYPE_DEBUG, 2840 LOG (GNUNET_ERROR_TYPE_DEBUG,
2593 "Considering %s for %s\n", 2841 "Considering %s for %s (offset %u)\n",
2594 GCPP_2s (p), 2842 GCPP_2s (p),
2595 GCT_2s (t)); 2843 GCT_2s (t),
2844 off);
2596 (void) consider_path_cb (t, 2845 (void) consider_path_cb (t,
2597 p, 2846 p,
2598 off); 2847 off);
diff --git a/src/cadet/gnunet-service-cadet_tunnels.h b/src/cadet/gnunet-service-cadet_tunnels.h
index 4a3619ab6..492eb6d24 100644
--- a/src/cadet/gnunet-service-cadet_tunnels.h
+++ b/src/cadet/gnunet-service-cadet_tunnels.h
@@ -3,20 +3,18 @@
3 This file is part of GNUnet. 3 This file is part of GNUnet.
4 Copyright (C) 2001-2017 GNUnet e.V. 4 Copyright (C) 2001-2017 GNUnet e.V.
5 5
6 GNUnet is free software; you can redistribute it and/or modify 6 GNUnet is free software: you can redistribute it and/or modify it
7 it under the terms of the GNU General Public License as published 7 under the terms of the GNU Affero General Public License as published
8 by the Free Software Foundation; either version 3, or (at your 8 by the Free Software Foundation, either version 3 of the License,
9 option) any later version. 9 or (at your option) any later version.
10 10
11 GNUnet is distributed in the hope that it will be useful, but 11 GNUnet is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of 12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details. 14 Affero General Public License for more details.
15 15
16 You should have received a copy of the GNU General Public License 16 You should have received a copy of the GNU Affero General Public License
17 along with GNUnet; see the file COPYING. If not, write to the 17 along with this program. If not, see <http://www.gnu.org/licenses/>.
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 Boston, MA 02110-1301, USA.
20*/ 18*/
21 19
22/** 20/**
diff --git a/src/cadet/test_cadet.c b/src/cadet/test_cadet.c
index b9f177652..76ff258e0 100644
--- a/src/cadet/test_cadet.c
+++ b/src/cadet/test_cadet.c
@@ -2,20 +2,18 @@
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2011, 2017 GNUnet e.V. 3 Copyright (C) 2011, 2017 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 it
6 it under the terms of the GNU General Public License as published 6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation; either version 3, or (at your 7 by the Free Software Foundation, either version 3 of the License,
8 option) any later version. 8 or (at your option) any later version.
9 9
10 GNUnet is distributed in the hope that it will be useful, but 10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details. 13 Affero General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU Affero General Public License
16 along with GNUnet; see the file COPYING. If not, write to the 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/ 17*/
20/** 18/**
21 * @file cadet/test_cadet.c 19 * @file cadet/test_cadet.c
@@ -72,6 +70,7 @@ struct CadetTestChannelWrapper
72#define SPEED_ACK 4 70#define SPEED_ACK 4
73#define SPEED_REL 8 71#define SPEED_REL 8
74#define P2P_SIGNAL 10 72#define P2P_SIGNAL 10
73#define REOPEN 11
75 74
76/** 75/**
77 * Which test are we running? 76 * Which test are we running?
@@ -179,6 +178,11 @@ struct GNUNET_CADET_TEST_Context *test_ctx;
179static struct GNUNET_SCHEDULER_Task *disconnect_task; 178static struct GNUNET_SCHEDULER_Task *disconnect_task;
180 179
181/** 180/**
181 * Task called to reconnect peers.
182 */
183static struct GNUNET_SCHEDULER_Task *reconnect_task;
184
185/**
182 * Task To perform tests 186 * Task To perform tests
183 */ 187 */
184static struct GNUNET_SCHEDULER_Task *test_task; 188static struct GNUNET_SCHEDULER_Task *test_task;
@@ -376,7 +380,8 @@ stats_cont (void *cls,
376 "KA sent: %u, KA received: %u\n", 380 "KA sent: %u, KA received: %u\n",
377 ka_sent, 381 ka_sent,
378 ka_received); 382 ka_received);
379 if ((KEEPALIVE == test) && ((ka_sent < 2) || (ka_sent > ka_received + 1))) 383 if ((KEEPALIVE == test || REOPEN == test) &&
384 ((ka_sent < 2) || (ka_sent > ka_received + 1)))
380 { 385 {
381 GNUNET_break (0); 386 GNUNET_break (0);
382 ok--; 387 ok--;
@@ -402,8 +407,11 @@ stats_cont (void *cls,
402 * @return #GNUNET_OK to continue, #GNUNET_SYSERR to abort iteration 407 * @return #GNUNET_OK to continue, #GNUNET_SYSERR to abort iteration
403 */ 408 */
404static int 409static int
405stats_iterator (void *cls, const struct GNUNET_TESTBED_Peer *peer, 410stats_iterator (void *cls,
406 const char *subsystem, const char *name, uint64_t value, 411 const struct GNUNET_TESTBED_Peer *peer,
412 const char *subsystem,
413 const char *name,
414 uint64_t value,
407 int is_persistent) 415 int is_persistent)
408{ 416{
409 static const char *s_sent = "# keepalives sent"; 417 static const char *s_sent = "# keepalives sent";
@@ -458,6 +466,152 @@ gather_stats_and_exit (void *cls)
458 466
459 467
460/** 468/**
469 * Send a message on the channel with the appropriate size and payload.
470 *
471 * Update the appropriate *_sent counter.
472 *
473 * @param channel Channel to send the message on.
474 */
475static void
476send_test_message (struct GNUNET_CADET_Channel *channel);
477
478/**
479 * Check if payload is sane (size contains payload).
480 *
481 * @param cls should match #ch
482 * @param message The actual message.
483 * @return #GNUNET_OK to keep the channel open,
484 * #GNUNET_SYSERR to close it (signal serious error).
485 */
486static int
487check_data (void *cls,
488 const struct GNUNET_MessageHeader *message);
489
490/**
491 * Function is called whenever a message is received.
492 *
493 * @param cls closure (set from GNUNET_CADET_connect(), peer number)
494 * @param message the actual message
495 */
496static void
497handle_data (void *cls,
498 const struct GNUNET_MessageHeader *message);
499
500/**
501 * Function called whenever an MQ-channel is destroyed, even if the destruction
502 * was requested by #GNUNET_CADET_channel_destroy.
503 * It must NOT call #GNUNET_CADET_channel_destroy on the channel.
504 *
505 * It should clean up any associated state, including cancelling any pending
506 * transmission on this channel.
507 *
508 * @param cls Channel closure (channel wrapper).
509 * @param channel Connection to the other end (henceforth invalid).
510 */
511static void
512disconnect_handler (void *cls,
513 const struct GNUNET_CADET_Channel *channel);
514
515
516/**
517 * Task to reconnect to other peer.
518 *
519 * @param cls Closure (line from which the task was scheduled).
520 */
521static void
522reconnect_op (void *cls)
523{
524 struct GNUNET_MQ_MessageHandler handlers[] = {
525 GNUNET_MQ_hd_var_size (data,
526 GNUNET_MESSAGE_TYPE_DUMMY,
527 struct GNUNET_MessageHeader,
528 NULL),
529 GNUNET_MQ_handler_end ()
530 };
531 long l = (long) cls;
532 struct CadetTestChannelWrapper *ch;
533 enum GNUNET_CADET_ChannelOption flags;
534
535 reconnect_task = NULL;
536 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
537 "reconnecting from line %ld\n",
538 l);
539 if (NULL != outgoing_ch)
540 {
541 GNUNET_CADET_channel_destroy (outgoing_ch);
542 outgoing_ch = NULL;
543 }
544 flags = GNUNET_CADET_OPTION_DEFAULT;
545 ch = GNUNET_new (struct CadetTestChannelWrapper);
546 outgoing_ch = GNUNET_CADET_channel_create (h1,
547 ch,
548 p_id[1],
549 &port,
550 flags,
551 NULL,
552 &disconnect_handler,
553 handlers);
554 ch->ch = outgoing_ch;
555 send_test_message (outgoing_ch);
556}
557
558/**
559 * Function called whenever an MQ-channel is destroyed, even if the destruction
560 * was requested by #GNUNET_CADET_channel_destroy.
561 * It must NOT call #GNUNET_CADET_channel_destroy on the channel.
562 *
563 * It should clean up any associated state, including cancelling any pending
564 * transmission on this channel.
565 *
566 * @param cls Channel closure (channel wrapper).
567 * @param channel Connection to the other end (henceforth invalid).
568 */
569static void
570disconnect_handler (void *cls,
571 const struct GNUNET_CADET_Channel *channel)
572{
573 struct CadetTestChannelWrapper *ch_w = cls;
574
575 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
576 "Channel disconnected at %d\n",
577 ok);
578 GNUNET_assert (ch_w->ch == channel);
579 if (channel == incoming_ch)
580 {
581 ok++;
582 incoming_ch = NULL;
583 }
584 else if (outgoing_ch == channel)
585 {
586 if (P2P_SIGNAL == test)
587 {
588 ok++;
589 }
590 outgoing_ch = NULL;
591 }
592 else
593 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
594 "Unknown channel! %p\n",
595 channel);
596 if (NULL != disconnect_task && REOPEN != test)
597 {
598 GNUNET_SCHEDULER_cancel (disconnect_task);
599 disconnect_task =
600 GNUNET_SCHEDULER_add_now (&gather_stats_and_exit,
601 (void *) __LINE__);
602 }
603 else if (NULL != reconnect_task && REOPEN == test)
604 {
605 GNUNET_SCHEDULER_cancel (reconnect_task);
606 reconnect_task =
607 GNUNET_SCHEDULER_add_now (&reconnect_op,
608 (void *) __LINE__);
609 }
610 GNUNET_free (ch_w);
611}
612
613
614/**
461 * Abort test: schedule disconnect and shutdown immediately 615 * Abort test: schedule disconnect and shutdown immediately
462 * 616 *
463 * @param line Line in the code the abort is requested from (__LINE__). 617 * @param line Line in the code the abort is requested from (__LINE__).
@@ -535,6 +689,14 @@ send_test_message (struct GNUNET_CADET_Channel *channel)
535 { 689 {
536 payload = data_sent; 690 payload = data_sent;
537 } 691 }
692 else if (REOPEN == test)
693 {
694 payload = data_sent;
695 data_sent++;
696 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
697 "Sending DATA %u [%d bytes]\n",
698 data_sent, size);
699 }
538 else 700 else
539 { 701 {
540 GNUNET_assert (0); 702 GNUNET_assert (0);
@@ -614,10 +776,9 @@ reschedule_timeout_task (long line)
614 * #GNUNET_SYSERR to close it (signal serious error). 776 * #GNUNET_SYSERR to close it (signal serious error).
615 */ 777 */
616static int 778static int
617check_data (void *cls, const struct GNUNET_MessageHeader *message) 779check_data (void *cls,
780 const struct GNUNET_MessageHeader *message)
618{ 781{
619 if (sizeof (struct GNUNET_MessageHeader) >= ntohs (message->size))
620 return GNUNET_SYSERR;
621 return GNUNET_OK; /* all is well-formed */ 782 return GNUNET_OK; /* all is well-formed */
622} 783}
623 784
@@ -646,24 +807,33 @@ handle_data (void *cls,
646 807
647 if (channel == outgoing_ch) 808 if (channel == outgoing_ch)
648 { 809 {
649 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Root client got a message.\n"); 810 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
811 "Root client got a message.\n");
650 } 812 }
651 else if (channel == incoming_ch) 813 else if (channel == incoming_ch)
652 { 814 {
653 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Leaf client got a message.\n"); 815 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
816 "Leaf client got a message.\n");
654 } 817 }
655 else 818 else
656 { 819 {
657 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unknown channel %p.\n", channel); 820 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
821 "Unknown channel %p.\n",
822 channel);
658 GNUNET_assert (0); 823 GNUNET_assert (0);
659 } 824 }
660 825
661 GNUNET_log (GNUNET_ERROR_TYPE_INFO, " ok: (%d/%d)\n", ok, ok_goal); 826 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
827 " ok: (%d/%d)\n",
828 ok,
829 ok_goal);
662 data = (uint32_t *) &message[1]; 830 data = (uint32_t *) &message[1];
663 payload = ntohl (*data); 831 payload = ntohl (*data);
664 if (payload == *counter) 832 if (payload == *counter)
665 { 833 {
666 GNUNET_log (GNUNET_ERROR_TYPE_INFO, " payload as expected: %u\n", payload); 834 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
835 " payload as expected: %u\n",
836 payload);
667 } 837 }
668 else 838 else
669 { 839 {
@@ -679,7 +849,8 @@ handle_data (void *cls,
679 if (SPEED == test) 849 if (SPEED == test)
680 { 850 {
681 GNUNET_assert (incoming_ch == channel); 851 GNUNET_assert (incoming_ch == channel);
682 send_next_msg_task = GNUNET_SCHEDULER_add_now (&send_next_msg, NULL); 852 send_next_msg_task = GNUNET_SCHEDULER_add_now (&send_next_msg,
853 NULL);
683 return; 854 return;
684 } 855 }
685 } 856 }
@@ -740,7 +911,8 @@ handle_data (void *cls,
740 * received on the @a channel. 911 * received on the @a channel.
741 */ 912 */
742static void * 913static void *
743connect_handler (void *cls, struct GNUNET_CADET_Channel *channel, 914connect_handler (void *cls,
915 struct GNUNET_CADET_Channel *channel,
744 const struct GNUNET_PeerIdentity *source) 916 const struct GNUNET_PeerIdentity *source)
745{ 917{
746 struct CadetTestChannelWrapper *ch; 918 struct CadetTestChannelWrapper *ch;
@@ -748,15 +920,20 @@ connect_handler (void *cls, struct GNUNET_CADET_Channel *channel,
748 920
749 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 921 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
750 "Incoming channel from %s to %ld: %p\n", 922 "Incoming channel from %s to %ld: %p\n",
751 GNUNET_i2s (source), peer, channel); 923 GNUNET_i2s (source),
924 peer,
925 channel);
752 ok++; 926 ok++;
753 GNUNET_log (GNUNET_ERROR_TYPE_INFO, " ok: %d\n", ok); 927 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
928 " ok: %d\n",
929 ok);
754 if (peer == peers_requested - 1) 930 if (peer == peers_requested - 1)
755 { 931 {
756 if (NULL != incoming_ch) 932 if (NULL != incoming_ch)
757 { 933 {
758 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 934 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
759 "Duplicate incoming channel for client %lu\n", (long) cls); 935 "Duplicate incoming channel for client %lu\n",
936 (long) cls);
760 GNUNET_assert (0); 937 GNUNET_assert (0);
761 } 938 }
762 incoming_ch = channel; 939 incoming_ch = channel;
@@ -764,16 +941,33 @@ connect_handler (void *cls, struct GNUNET_CADET_Channel *channel,
764 else 941 else
765 { 942 {
766 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 943 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
767 "Incoming channel for unexpected peer #%lu\n", (long) cls); 944 "Incoming channel for unexpected peer #%lu\n",
945 (long) cls);
768 GNUNET_assert (0); 946 GNUNET_assert (0);
769 } 947 }
770 if (NULL != disconnect_task) 948 if (NULL != disconnect_task && REOPEN != test)
771 { 949 {
772 GNUNET_SCHEDULER_cancel (disconnect_task); 950 GNUNET_SCHEDULER_cancel (disconnect_task);
773 disconnect_task = GNUNET_SCHEDULER_add_delayed (short_time, 951 disconnect_task = GNUNET_SCHEDULER_add_delayed (short_time,
774 &gather_stats_and_exit, 952 &gather_stats_and_exit,
775 (void *) __LINE__); 953 (void *) __LINE__);
776 } 954 }
955 else if ((NULL != disconnect_task) && (REOPEN == test))
956 {
957 GNUNET_SCHEDULER_cancel (disconnect_task);
958 disconnect_task = GNUNET_SCHEDULER_add_delayed (
959 GNUNET_TIME_relative_multiply (short_time, 2),
960 &gather_stats_and_exit,
961 (void *) __LINE__);
962 }
963
964 if ((NULL != reconnect_task) && (REOPEN == test))
965 {
966 GNUNET_SCHEDULER_cancel (reconnect_task);
967 reconnect_task = GNUNET_SCHEDULER_add_delayed (short_time,
968 &reconnect_op,
969 (void *) __LINE__);
970 }
777 971
778 /* TODO: cannot return channel as-is, in order to unify the data handlers */ 972 /* TODO: cannot return channel as-is, in order to unify the data handlers */
779 ch = GNUNET_new (struct CadetTestChannelWrapper); 973 ch = GNUNET_new (struct CadetTestChannelWrapper);
@@ -784,55 +978,6 @@ connect_handler (void *cls, struct GNUNET_CADET_Channel *channel,
784 978
785 979
786/** 980/**
787 * Function called whenever an MQ-channel is destroyed, even if the destruction
788 * was requested by #GNUNET_CADET_channel_destroy.
789 * It must NOT call #GNUNET_CADET_channel_destroy on the channel.
790 *
791 * It should clean up any associated state, including cancelling any pending
792 * transmission on this channel.
793 *
794 * @param cls Channel closure (channel wrapper).
795 * @param channel Connection to the other end (henceforth invalid).
796 */
797static void
798disconnect_handler (void *cls,
799 const struct GNUNET_CADET_Channel *channel)
800{
801 struct CadetTestChannelWrapper *ch_w = cls;
802
803 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
804 "Channel disconnected at %d\n",
805 ok);
806 GNUNET_assert (ch_w->ch == channel);
807 if (channel == incoming_ch)
808 {
809 ok++;
810 incoming_ch = NULL;
811 }
812 else if (outgoing_ch == channel)
813 {
814 if (P2P_SIGNAL == test)
815 {
816 ok++;
817 }
818 outgoing_ch = NULL;
819 }
820 else
821 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
822 "Unknown channel! %p\n",
823 channel);
824 if (NULL != disconnect_task)
825 {
826 GNUNET_SCHEDULER_cancel (disconnect_task);
827 disconnect_task =
828 GNUNET_SCHEDULER_add_now (&gather_stats_and_exit,
829 (void *) __LINE__);
830 }
831 GNUNET_free (ch_w);
832}
833
834
835/**
836 * START THE TESTCASE ITSELF, AS WE ARE CONNECTED TO THE CADET SERVICES. 981 * START THE TESTCASE ITSELF, AS WE ARE CONNECTED TO THE CADET SERVICES.
837 * 982 *
838 * Testcase continues when the root receives confirmation of connected peers, 983 * Testcase continues when the root receives confirmation of connected peers,
@@ -854,7 +999,7 @@ start_test (void *cls)
854 enum GNUNET_CADET_ChannelOption flags; 999 enum GNUNET_CADET_ChannelOption flags;
855 1000
856 test_task = NULL; 1001 test_task = NULL;
857 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "start_test\n"); 1002 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "start_test: %s\n", test_name);
858 if (NULL != disconnect_task) 1003 if (NULL != disconnect_task)
859 { 1004 {
860 GNUNET_SCHEDULER_cancel (disconnect_task); 1005 GNUNET_SCHEDULER_cancel (disconnect_task);
@@ -886,7 +1031,6 @@ start_test (void *cls)
886 if (KEEPALIVE == test) 1031 if (KEEPALIVE == test)
887 return; /* Don't send any data. */ 1032 return; /* Don't send any data. */
888 1033
889
890 data_received = 0; 1034 data_received = 0;
891 data_sent = 0; 1035 data_sent = 0;
892 ack_received = 0; 1036 ack_received = 0;
@@ -895,6 +1039,18 @@ start_test (void *cls)
895 "Sending data initializer on channel %p...\n", 1039 "Sending data initializer on channel %p...\n",
896 outgoing_ch); 1040 outgoing_ch);
897 send_test_message (outgoing_ch); 1041 send_test_message (outgoing_ch);
1042 if (REOPEN == test)
1043 {
1044 reconnect_task = GNUNET_SCHEDULER_add_delayed (short_time,
1045 &reconnect_op,
1046 (void *) __LINE__);
1047 GNUNET_SCHEDULER_cancel (disconnect_task);
1048 disconnect_task = GNUNET_SCHEDULER_add_delayed (
1049 GNUNET_TIME_relative_multiply (short_time, 2),
1050 &gather_stats_and_exit,
1051 (void *) __LINE__);
1052 }
1053
898} 1054}
899 1055
900 1056
@@ -1003,7 +1159,6 @@ main (int argc, char *argv[])
1003 "short_time", 1159 "short_time",
1004 gettext_noop ("set short timeout"), 1160 gettext_noop ("set short timeout"),
1005 &short_time), 1161 &short_time),
1006
1007 GNUNET_GETOPT_option_uint ('m', 1162 GNUNET_GETOPT_option_uint ('m',
1008 "messages", 1163 "messages",
1009 "NUM_MESSAGES", 1164 "NUM_MESSAGES",
@@ -1039,6 +1194,11 @@ main (int argc, char *argv[])
1039 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "5 PEER LINE\n"); 1194 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "5 PEER LINE\n");
1040 peers_requested = 5; 1195 peers_requested = 5;
1041 } 1196 }
1197 else if (strstr (argv[0], "_6_") != NULL)
1198 {
1199 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "6 PEER LINE\n");
1200 peers_requested = 6;
1201 }
1042 else 1202 else
1043 { 1203 {
1044 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "SIZE UNKNOWN, USING 2\n"); 1204 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "SIZE UNKNOWN, USING 2\n");
@@ -1106,6 +1266,17 @@ main (int argc, char *argv[])
1106 */ 1266 */
1107 ok_goal = 2; 1267 ok_goal = 2;
1108 } 1268 }
1269 else if (strstr (argv[0], "_reopen") != NULL)
1270 {
1271 test = REOPEN;
1272 test_name = "reopen";
1273 ///* Test is supposed to generate the following callbacks:
1274 // * 1 incoming channel (@dest)
1275 // * [wait]
1276 // * 1 received channel destroy (@dest)
1277 // */
1278 ok_goal = 7;
1279 }
1109 else 1280 else
1110 { 1281 {
1111 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "UNKNOWN\n"); 1282 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "UNKNOWN\n");
diff --git a/src/cadet/test_cadet.conf b/src/cadet/test_cadet.conf
index b6e6c6ae3..5ad67fec2 100644
--- a/src/cadet/test_cadet.conf
+++ b/src/cadet/test_cadet.conf
@@ -59,7 +59,7 @@ BLUETOOTH_QUOTA_OUT = unlimited
59USE_EPHEMERAL_KEYS = NO 59USE_EPHEMERAL_KEYS = NO
60 60
61[PATHS] 61[PATHS]
62GNUNET_TEST_HOME = /tmp/test-cadet/ 62GNUNET_TEST_HOME = $GNUNET_TMP/test-cadet/
63 63
64[peerinfo] 64[peerinfo]
65NO_IO = YES 65NO_IO = YES
@@ -68,33 +68,33 @@ NO_IO = YES
68WORKBITS = 0 68WORKBITS = 0
69 69
70[hostlist] 70[hostlist]
71FORCESTART = NO 71IMMEDIATE_START = NO
72AUTOSTART = NO 72START_ON_DEMAND = NO
73 73
74[fs] 74[fs]
75FORCESTART = NO 75IMMEDIATE_START = NO
76AUTOSTART = NO 76START_ON_DEMAND = NO
77 77
78[vpn] 78[vpn]
79FORCESTART = NO 79IMMEDIATE_START = NO
80AUTOSTART = NO 80START_ON_DEMAND = NO
81 81
82[revocation] 82[revocation]
83FORCESTART = NO 83IMMEDIATE_START = NO
84AUTOSTART = NO 84START_ON_DEMAND = NO
85 85
86[gns] 86[gns]
87FORCESTART = NO 87IMMEDIATE_START = NO
88AUTOSTART = NO 88START_ON_DEMAND = NO
89 89
90[namestore] 90[namestore]
91FORCESTART = NO 91IMMEDIATE_START = NO
92AUTOSTART = NO 92START_ON_DEMAND = NO
93 93
94[namecache] 94[namecache]
95FORCESTART = NO 95IMMEDIATE_START = NO
96AUTOSTART = NO 96START_ON_DEMAND = NO
97 97
98[topology] 98[topology]
99FORCESTART = NO 99IMMEDIATE_START = NO
100AUTOSTART = NO 100START_ON_DEMAND = NO
diff --git a/src/cadet/test_cadet_flow.c b/src/cadet/test_cadet_flow.c
new file mode 100644
index 000000000..4645ea840
--- /dev/null
+++ b/src/cadet/test_cadet_flow.c
@@ -0,0 +1,886 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2011, 2017 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your 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 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17*/
18/**
19 * @file cadet/test_cadet_flow.c
20 * @author Bart Polot
21 * @author Christian Grothoff
22 * @brief Test for flow control of CADET service
23 */
24#include <stdio.h>
25#include "platform.h"
26#include "cadet_test_lib.h"
27#include "gnunet_cadet_service.h"
28#include "gnunet_statistics_service.h"
29#include <gauger.h>
30
31
32/**
33 * Ugly workaround to unify data handlers on incoming and outgoing channels.
34 */
35struct CadetTestChannelWrapper
36{
37 /**
38 * Channel pointer.
39 */
40 struct GNUNET_CADET_Channel *ch;
41};
42
43/**
44 * How many messages to send by default.
45 */
46#define TOTAL_PACKETS_DEFAULT 500
47
48/**
49 * How long until we give up on connecting the peers?
50 */
51#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 120)
52
53/**
54 * Time to wait by default for stuff that should be rather fast.
55 */
56#define SHORT_TIME GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 20)
57
58/**
59 * How fast do we send messages?
60 */
61#define SEND_INTERVAL GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 10)
62
63
64/**
65 * How many packets to send.
66 */
67static unsigned int total_packets = TOTAL_PACKETS_DEFAULT;
68
69/**
70 * Time to wait for fast operations.
71 */
72static struct GNUNET_TIME_Relative short_time;
73
74/**
75 * Size of each test packet's payload
76 */
77static size_t size_payload = sizeof (uint32_t);
78
79/**
80 * Operation to get peer ids.
81 */
82static struct GNUNET_TESTBED_Operation *t_op[2];
83
84/**
85 * Peer ids.
86 */
87static struct GNUNET_PeerIdentity *p_id[2];
88
89/**
90 * Port ID
91 */
92static struct GNUNET_HashCode port;
93
94/**
95 * Peer ids counter.
96 */
97static unsigned int p_ids;
98
99/**
100 * Is the setup initialized?
101 */
102static int initialized;
103
104/**
105 * Number of payload packes sent.
106 */
107static int data_sent;
108
109/**
110 * Number of payload packets received.
111 */
112static int data_received;
113
114/**
115 * Number of payload packed acknowledgements sent.
116 */
117static int ack_sent;
118
119/**
120 * Number of payload packed explicitly (app level) acknowledged.
121 */
122static int ack_received;
123
124/**
125 * Total number of peers asked to run.
126 */
127static unsigned int peers_requested = 2;
128
129/**
130 * Number of currently running peers (should be same as @c peers_requested).
131 */
132static unsigned int peers_running;
133
134/**
135 * Test context (to shut down).
136 */
137struct GNUNET_CADET_TEST_Context *test_ctx;
138
139/**
140 * Task called to disconnect peers.
141 */
142static struct GNUNET_SCHEDULER_Task *disconnect_task;
143
144/**
145 * Task To perform tests
146 */
147static struct GNUNET_SCHEDULER_Task *test_task;
148
149/**
150 * Task runnining #send_next_msg().
151 */
152static struct GNUNET_SCHEDULER_Task *send_next_msg_task;
153
154/**
155 * Cadet handle for the root peer
156 */
157static struct GNUNET_CADET_Handle *h1;
158
159/**
160 * Cadet handle for the first leaf peer
161 */
162static struct GNUNET_CADET_Handle *h2;
163
164/**
165 * Channel handle for the root peer
166 */
167static struct GNUNET_CADET_Channel *outgoing_ch;
168
169/**
170 * Channel handle for the dest peer
171 */
172static struct GNUNET_CADET_Channel *incoming_ch;
173
174/**
175 * Time we started the data transmission (after channel has been established
176 * and initilized).
177 */
178static struct GNUNET_TIME_Absolute start_time;
179
180/**
181 * Peers handle.
182 */
183static struct GNUNET_TESTBED_Peer **testbed_peers;
184
185/**
186 * Statistics operation handle.
187 */
188static struct GNUNET_TESTBED_Operation *stats_op;
189
190/**
191 * Keepalives sent.
192 */
193static unsigned int ka_sent;
194
195/**
196 * Keepalives received.
197 */
198static unsigned int ka_received;
199
200/**
201 * How many messages were dropped by CADET because of full buffers?
202 */
203static unsigned int msg_dropped;
204
205
206/**
207 * Show the results of the test (banwidth acheived) and log them to GAUGER
208 */
209static void
210show_end_data (void)
211{
212 static struct GNUNET_TIME_Absolute end_time;
213 static struct GNUNET_TIME_Relative total_time;
214
215 end_time = GNUNET_TIME_absolute_get ();
216 total_time = GNUNET_TIME_absolute_get_difference (start_time, end_time);
217 FPRINTF (stderr,
218 "\nResults of test \"%s\"\n",
219 test_name);
220 FPRINTF (stderr,
221 "Test time %s\n",
222 GNUNET_STRINGS_relative_time_to_string (total_time, GNUNET_YES));
223 FPRINTF (stderr,
224 "Test bandwidth: %f kb/s\n",
225 4 * total_packets * 1.0 / (total_time.rel_value_us / 1000)); // 4bytes * ms
226 FPRINTF (stderr,
227 "Test throughput: %f packets/s\n\n",
228 total_packets * 1000.0 / (total_time.rel_value_us / 1000)); // packets * ms
229 GAUGER ("CADET",
230 test_name,
231 total_packets * 1000.0 / (total_time.rel_value_us / 1000),
232 "packets/s");
233}
234
235
236/**
237 * Shut down peergroup, clean up.
238 *
239 * @param cls Closure (unused).
240 * @param tc Task Context.
241 */
242static void
243shutdown_task (void *cls)
244{
245 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
246 "Ending test.\n");
247 if (NULL != send_next_msg_task)
248 {
249 GNUNET_SCHEDULER_cancel (send_next_msg_task);
250 send_next_msg_task = NULL;
251 }
252 if (NULL != test_task)
253 {
254 GNUNET_SCHEDULER_cancel (test_task);
255 test_task = NULL;
256 }
257 for (unsigned int i = 0; i < 2; i++)
258 GNUNET_TESTBED_operation_done (t_op[i]);
259 if (NULL != outgoing_ch)
260 {
261 GNUNET_CADET_channel_destroy (outgoing_ch);
262 outgoing_ch = NULL;
263 }
264 if (NULL != incoming_ch)
265 {
266 GNUNET_CADET_channel_destroy (incoming_ch);
267 incoming_ch = NULL;
268 }
269 GNUNET_CADET_TEST_cleanup (test_ctx);
270}
271
272
273/**
274 * Stats callback. Finish the stats testbed operation and when all stats have
275 * been iterated, shutdown the test.
276 *
277 * @param cls Closure (line number from which termination was requested).
278 * @param op the operation that has been finished
279 * @param emsg error message in case the operation has failed; will be NULL if
280 * operation has executed successfully.
281 */
282static void
283stats_cont (void *cls,
284 struct GNUNET_TESTBED_Operation *op,
285 const char *emsg)
286{
287 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
288 "KA sent: %u, KA received: %u\n",
289 ka_sent,
290 ka_received);
291 if ((KEEPALIVE == test) && ((ka_sent < 2) || (ka_sent > ka_received + 1)))
292 {
293 GNUNET_break (0);
294 ok--;
295 }
296 GNUNET_TESTBED_operation_done (stats_op);
297
298 if (NULL != disconnect_task)
299 GNUNET_SCHEDULER_cancel (disconnect_task);
300 disconnect_task = GNUNET_SCHEDULER_add_now (&disconnect_cadet_peers,
301 cls);
302}
303
304
305/**
306 * Process statistic values.
307 *
308 * @param cls closure (line number, unused)
309 * @param peer the peer the statistic belong to
310 * @param subsystem name of subsystem that created the statistic
311 * @param name the name of the datum
312 * @param value the current value
313 * @param is_persistent #GNUNET_YES if the value is persistent, #GNUNET_NO if not
314 * @return #GNUNET_OK to continue, #GNUNET_SYSERR to abort iteration
315 */
316static int
317stats_iterator (void *cls,
318 const struct GNUNET_TESTBED_Peer *peer,
319 const char *subsystem,
320 const char *name,
321 uint64_t value,
322 int is_persistent)
323{
324 static const char *s_sent = "# keepalives sent";
325 static const char *s_recv = "# keepalives received";
326 static const char *rdrops = "# messages dropped due to full buffer";
327 static const char *cdrops = "# messages dropped due to slow client";
328 uint32_t i;
329
330 i = GNUNET_TESTBED_get_index (peer);
331 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "STATS PEER %u - %s [%s]: %llu\n", i,
332 subsystem, name, (unsigned long long) value);
333 if (0 == strncmp (s_sent, name, strlen (s_sent)) && 0 == i)
334 ka_sent = value;
335 if (0 == strncmp (s_recv, name, strlen (s_recv)) && peers_requested - 1 == i)
336 ka_received = value;
337 if (0 == strncmp (rdrops, name, strlen (rdrops)))
338 msg_dropped += value;
339 if (0 == strncmp (cdrops, name, strlen (cdrops)))
340 msg_dropped += value;
341
342 return GNUNET_OK;
343}
344
345
346/**
347 * Task to gather all statistics.
348 *
349 * @param cls Closure (line from which the task was scheduled).
350 */
351static void
352gather_stats_and_exit (void *cls)
353{
354 long l = (long) cls;
355
356 disconnect_task = NULL;
357 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
358 "gathering statistics from line %ld\n",
359 l);
360 if (NULL != outgoing_ch)
361 {
362 GNUNET_CADET_channel_destroy (outgoing_ch);
363 outgoing_ch = NULL;
364 }
365 stats_op = GNUNET_TESTBED_get_statistics (peers_running,
366 testbed_peers,
367 "cadet",
368 NULL,
369 &stats_iterator,
370 stats_cont,
371 cls);
372}
373
374
375/**
376 * Abort test: schedule disconnect and shutdown immediately
377 *
378 * @param line Line in the code the abort is requested from (__LINE__).
379 */
380static void
381abort_test (long line)
382{
383 if (NULL != disconnect_task)
384 {
385 GNUNET_SCHEDULER_cancel (disconnect_task);
386 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
387 "Aborting test from %ld\n",
388 line);
389 disconnect_task =
390 GNUNET_SCHEDULER_add_now (&disconnect_cadet_peers,
391 (void *) line);
392 }
393}
394
395
396/**
397 * Send a message on the channel with the appropriate size and payload.
398 *
399 * Update the appropriate *_sent counter.
400 *
401 * @param channel Channel to send the message on.
402 */
403static void
404send_test_message (struct GNUNET_CADET_Channel *channel)
405{
406 struct GNUNET_MQ_Envelope *env;
407 struct GNUNET_MessageHeader *msg;
408 uint32_t *data;
409 int payload;
410 int size;
411
412 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
413 "Sending test message on channel %p\n",
414 channel);
415 size = size_payload;
416 if (GNUNET_NO == initialized)
417 {
418 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending INITIALIZER\n");
419 size += 1000;
420 payload = data_sent;
421 if (SPEED_ACK == test) // FIXME unify SPEED_ACK with an initializer
422 data_sent++;
423 }
424 else if (SPEED == test || SPEED_ACK == test)
425 {
426 if (get_target_channel() == channel)
427 {
428 payload = ack_sent;
429 size += ack_sent;
430 ack_sent++;
431 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
432 "Sending ACK %u [%d bytes]\n",
433 payload, size);
434 }
435 else
436 {
437 payload = data_sent;
438 size += data_sent;
439 data_sent++;
440 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
441 "Sending DATA %u [%d bytes]\n",
442 data_sent, size);
443 }
444 }
445 else if (FORWARD == test)
446 {
447 payload = ack_sent;
448 }
449 else if (P2P_SIGNAL == test)
450 {
451 payload = data_sent;
452 }
453 else
454 {
455 GNUNET_assert (0);
456 }
457 env = GNUNET_MQ_msg_extra (msg, size, GNUNET_MESSAGE_TYPE_DUMMY);
458
459 data = (uint32_t *) &msg[1];
460 *data = htonl (payload);
461 GNUNET_MQ_send (GNUNET_CADET_get_mq (channel), env);
462}
463
464
465/**
466 * Task to request a new data transmission in a SPEED test, without waiting
467 * for previous messages to be sent/arrrive.
468 *
469 * @param cls Closure (unused).
470 */
471static void
472send_next_msg (void *cls)
473{
474 struct GNUNET_CADET_Channel *channel;
475
476 send_next_msg_task = NULL;
477 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
478 "Sending next message: %d\n",
479 data_sent);
480
481 channel = GNUNET_YES == test_backwards ? incoming_ch : outgoing_ch;
482 GNUNET_assert (NULL != channel);
483 GNUNET_assert (SPEED == test);
484 send_test_message (channel);
485 if (data_sent < total_packets)
486 {
487 /* SPEED test: Send all messages as soon as possible */
488 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
489 "Scheduling message %d\n",
490 data_sent + 1);
491 send_next_msg_task =
492 GNUNET_SCHEDULER_add_delayed (SEND_INTERVAL,
493 &send_next_msg,
494 NULL);
495 }
496}
497
498
499/**
500 * Check if payload is sane (size contains payload).
501 *
502 * @param cls should match #ch
503 * @param message The actual message.
504 * @return #GNUNET_OK to keep the channel open,
505 * #GNUNET_SYSERR to close it (signal serious error).
506 */
507static int
508check_data (void *cls,
509 const struct GNUNET_MessageHeader *message)
510{
511 return GNUNET_OK; /* all is well-formed */
512}
513
514
515/**
516 * Function is called whenever a message is received.
517 *
518 * @param cls closure (set from GNUNET_CADET_connect(), peer number)
519 * @param message the actual message
520 */
521static void
522handle_data (void *cls,
523 const struct GNUNET_MessageHeader *message)
524{
525 struct CadetTestChannelWrapper *ch = cls;
526 struct GNUNET_CADET_Channel *channel = ch->ch;
527 uint32_t *data;
528 uint32_t payload;
529 int *counter;
530
531 GNUNET_CADET_receive_done (channel);
532 counter = get_target_channel () == channel ? &data_received : &ack_received;
533 if (channel == outgoing_ch)
534 {
535 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
536 "Root client got a message.\n");
537 }
538 else if (channel == incoming_ch)
539 {
540 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
541 "Leaf client got a message.\n");
542 }
543 else
544 {
545 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
546 "Unknown channel %p.\n",
547 channel);
548 GNUNET_assert (0);
549 }
550
551 data = (uint32_t *) &message[1];
552 payload = ntohl (*data);
553 if (payload == *counter)
554 {
555 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
556 "Payload as expected: %u\n",
557 payload);
558 }
559 else
560 {
561 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
562 "Received payload %u, expected: %u\n",
563 payload, *counter);
564 }
565 (*counter)++;
566 if (get_target_channel () == channel) /* Got "data" */
567 {
568 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
569 " received data %u\n",
570 data_received);
571 if (data_received < total_packets)
572 return;
573 }
574 else /* Got "ack" */
575 {
576 if (SPEED_ACK == test || SPEED == test)
577 {
578 GNUNET_log (GNUNET_ERROR_TYPE_INFO, " received ack %u\n", ack_received);
579 /* Send more data */
580 send_test_message (channel);
581 if (ack_received < total_packets && SPEED != test)
582 return;
583 if (ok == 2 && SPEED == test)
584 return;
585 show_end_data ();
586 }
587 if (test == P2P_SIGNAL)
588 {
589 GNUNET_CADET_channel_destroy (incoming_ch);
590 incoming_ch = NULL;
591 }
592 else
593 {
594 GNUNET_CADET_channel_destroy (outgoing_ch);
595 outgoing_ch = NULL;
596 }
597 }
598}
599
600
601/**
602 * Method called whenever a peer connects to a port in MQ-based CADET.
603 *
604 * @param cls Closure from #GNUNET_CADET_open_port (peer # as long).
605 * @param channel New handle to the channel.
606 * @param source Peer that started this channel.
607 * @return Closure for the incoming @a channel. It's given to:
608 * - The #GNUNET_CADET_DisconnectEventHandler (given to
609 * #GNUNET_CADET_open_port) when the channel dies.
610 * - Each the #GNUNET_MQ_MessageCallback handlers for each message
611 * received on the @a channel.
612 */
613static void *
614connect_handler (void *cls,
615 struct GNUNET_CADET_Channel *channel,
616 const struct GNUNET_PeerIdentity *source)
617{
618 struct CadetTestChannelWrapper *ch;
619 long peer = (long) cls;
620
621 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
622 "Incoming channel from %s to %ld: %p\n",
623 GNUNET_i2s (source),
624 peer,
625 channel);
626 if (peer == peers_requested - 1)
627 {
628 if (NULL != incoming_ch)
629 {
630 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
631 "Duplicate incoming channel for client %lu\n",
632 (long) cls);
633 GNUNET_assert (0);
634 }
635 incoming_ch = channel;
636 }
637 else
638 {
639 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
640 "Incoming channel for unexpected peer #%lu\n",
641 (long) cls);
642 GNUNET_assert (0);
643 }
644 ch = GNUNET_new (struct CadetTestChannelWrapper);
645 ch->ch = channel;
646
647 return ch;
648}
649
650
651/**
652 * Function called whenever an MQ-channel is destroyed, even if the destruction
653 * was requested by #GNUNET_CADET_channel_destroy.
654 * It must NOT call #GNUNET_CADET_channel_destroy on the channel.
655 *
656 * It should clean up any associated state, including cancelling any pending
657 * transmission on this channel.
658 *
659 * @param cls Channel closure (channel wrapper).
660 * @param channel Connection to the other end (henceforth invalid).
661 */
662static void
663disconnect_handler (void *cls,
664 const struct GNUNET_CADET_Channel *channel)
665{
666 struct CadetTestChannelWrapper *ch_w = cls;
667
668 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
669 "Channel disconnected at %d\n",
670 ok);
671 GNUNET_assert (ch_w->ch == channel);
672 if (channel == incoming_ch)
673 incoming_ch = NULL;
674 else if (outgoing_ch == channel)
675 outgoing_ch = NULL;
676 else
677 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
678 "Disconnect on unknown channel %p\n",
679 channel);
680 if (NULL != disconnect_task)
681 GNUNET_SCHEDULER_cancel (disconnect_task);
682 disconnect_task = GNUNET_SCHEDULER_add_now (&gather_stats_and_exit,
683 (void *) __LINE__);
684 GNUNET_free (ch_w);
685}
686
687
688/**
689 * Start the testcase, we know the peers and have handles to CADET.
690 *
691 * Testcase continues when the root receives confirmation of connected peers,
692 * on callback function ch.
693 *
694 * @param cls Closure (unused).
695 */
696static void
697start_test (void *cls)
698{
699 struct GNUNET_MQ_MessageHandler handlers[] = {
700 GNUNET_MQ_hd_var_size (data,
701 GNUNET_MESSAGE_TYPE_DUMMY,
702 struct GNUNET_MessageHeader,
703 NULL),
704 GNUNET_MQ_handler_end ()
705 };
706 struct CadetTestChannelWrapper *ch;
707 enum GNUNET_CADET_ChannelOption flags;
708
709 test_task = NULL;
710 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
711 "In start_test\n");
712 start_time = GNUNET_TIME_absolute_get ();
713 ch = GNUNET_new (struct CadetTestChannelWrapper);
714 outgoing_ch = GNUNET_CADET_channel_create (h1,
715 ch,
716 p_id[1],
717 &port,
718 flags,
719 NULL,
720 &disconnect_handler,
721 handlers);
722 ch->ch = outgoing_ch;
723 GNUNET_assert (NULL == disconnect_task);
724 disconnect_task
725 = GNUNET_SCHEDULER_add_delayed (short_time,
726 &gather_stats_and_exit,
727 (void *) __LINE__);
728 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
729 "Sending data initializer on channel %p...\n",
730 outgoing_ch);
731 send_test_message (outgoing_ch);
732}
733
734
735/**
736 * Callback to be called when the requested peer information is available
737 *
738 * @param cls the closure from GNUNET_TESTBED_peer_get_information()
739 * @param op the operation this callback corresponds to
740 * @param pinfo the result; will be NULL if the operation has failed
741 * @param emsg error message if the operation has failed;
742 * NULL if the operation is successfull
743 */
744static void
745pi_cb (void *cls,
746 struct GNUNET_TESTBED_Operation *op,
747 const struct GNUNET_TESTBED_PeerInformation *pinfo,
748 const char *emsg)
749{
750 long i = (long) cls;
751
752 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
753 "ID callback for %ld\n",
754 i);
755 if ( (NULL == pinfo) ||
756 (NULL != emsg) )
757 {
758 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
759 "pi_cb: %s\n",
760 emsg);
761 abort_test (__LINE__);
762 return;
763 }
764 p_id[i] = pinfo->result.id;
765 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
766 "id: %s\n",
767 GNUNET_i2s (p_id[i]));
768 p_ids++;
769 if (p_ids < 2)
770 return;
771 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
772 "Got all IDs, starting test\n");
773 test_task = GNUNET_SCHEDULER_add_now (&start_test,
774 NULL);
775}
776
777
778/**
779 * test main: start test when all peers are connected
780 *
781 * @param cls Closure.
782 * @param ctx Argument to give to GNUNET_CADET_TEST_cleanup on test end.
783 * @param num_peers Number of peers that are running.
784 * @param peers Array of peers.
785 * @param cadets Handle to each of the CADETs of the peers.
786 */
787static void
788tmain (void *cls,
789 struct GNUNET_CADET_TEST_Context *ctx,
790 unsigned int num_peers,
791 struct GNUNET_TESTBED_Peer **peers,
792 struct GNUNET_CADET_Handle **cadets)
793{
794 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
795 "test main\n");
796 test_ctx = ctx;
797 peers_running = num_peers;
798 GNUNET_assert (peers_running == peers_requested);
799 testbed_peers = peers;
800 h1 = cadets[0];
801 h2 = cadets[num_peers - 1];
802 GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
803 NULL);
804 p_ids = 0;
805 t_op[0] = GNUNET_TESTBED_peer_get_information (peers[0],
806 GNUNET_TESTBED_PIT_IDENTITY,
807 &pi_cb,
808 (void *) 0L);
809 t_op[1] = GNUNET_TESTBED_peer_get_information (peers[num_peers - 1],
810 GNUNET_TESTBED_PIT_IDENTITY,
811 &pi_cb,
812 (void *) 1L);
813 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
814 "requested peer ids\n");
815}
816
817
818/**
819 * Main: start test
820 */
821int
822main (int argc,
823 char *argv[])
824{
825 static const struct GNUNET_HashCode *ports[2];
826 struct GNUNET_MQ_MessageHandler handlers[] = {
827 GNUNET_MQ_hd_var_size (data,
828 GNUNET_MESSAGE_TYPE_DUMMY,
829 struct GNUNET_MessageHeader,
830 NULL),
831 GNUNET_MQ_handler_end ()
832 };
833 const char *config_file = "test_cadet.conf";
834 char port_id[] = "test port";
835 struct GNUNET_GETOPT_CommandLineOption options[] = {
836 GNUNET_GETOPT_option_relative_time ('t',
837 "time",
838 "short_time",
839 gettext_noop ("set short timeout"),
840 &short_time),
841 GNUNET_GETOPT_option_uint ('m',
842 "messages",
843 "NUM_MESSAGES",
844 gettext_noop ("set number of messages to send"),
845 &total_packets),
846 GNUNET_GETOPT_option_uint ('p',
847 "peers",
848 "NUM_PEERS",
849 gettext_noop ("number of peers to launch"),
850 &peers_requested),
851 GNUNET_GETOPT_OPTION_END
852 };
853
854 GNUNET_log_setup ("test-cadet-flow",
855 "DEBUG",
856 NULL);
857 total_packets = TOTAL_PACKETS;
858 short_time = SHORT_TIME;
859 if (-1 == GNUNET_GETOPT_run (argv[0],
860 options,
861 argc,
862 argv))
863 {
864 FPRINTF (stderr,
865 "test failed: problem with CLI parameters\n");
866 return 1;
867 }
868 GNUNET_CRYPTO_hash (port_id,
869 sizeof (port_id),
870 &port);
871 ports[0] = &port;
872 ports[1] = NULL;
873 GNUNET_CADET_TEST_ruN ("test_cadet_flow",
874 config_file,
875 peers_requested,
876 &tmain,
877 NULL, /* tmain cls */
878 &connect_handler,
879 NULL,
880 &disconnect_handler,
881 handlers,
882 ports);
883 return 0;
884}
885
886/* end of test_cadet_flow.c */
diff --git a/src/cadet/test_cadet_local_mq.c b/src/cadet/test_cadet_local_mq.c
index 3089c7fbb..2e9cfa918 100644
--- a/src/cadet/test_cadet_local_mq.c
+++ b/src/cadet/test_cadet_local_mq.c
@@ -2,24 +2,22 @@
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2017 GNUnet e.V. 3 Copyright (C) 2017 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 it
6 it under the terms of the GNU General Public License as published 6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation; either version 3, or (at your 7 by the Free Software Foundation, either version 3 of the License,
8 option) any later version. 8 or (at your option) any later version.
9 9
10 GNUnet is distributed in the hope that it will be useful, but 10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details. 13 Affero General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU Affero General Public License
16 along with GNUnet; see the file COPYING. If not, write to the 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/ 17*/
20 18
21/** 19/**
22 * @file cadet/test_cadet_local.c 20 * @file cadet/test_cadet_local_mq.c
23 * @brief test cadet local: test of cadet channels with just one peer 21 * @brief test cadet local: test of cadet channels with just one peer
24 * @author Bartlomiej Polot 22 * @author Bartlomiej Polot
25 */ 23 */
@@ -123,7 +121,9 @@ do_shutdown (void *cls)
123static void 121static void
124do_abort (void *cls) 122do_abort (void *cls)
125{ 123{
126 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "ABORT from line %ld\n", (long) cls); 124 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
125 "ABORT from line %ld\n",
126 (long) cls);
127 result = GNUNET_SYSERR; 127 result = GNUNET_SYSERR;
128 abort_task = NULL; 128 abort_task = NULL;
129 GNUNET_SCHEDULER_shutdown (); 129 GNUNET_SCHEDULER_shutdown ();
@@ -148,7 +148,8 @@ connected (void *cls,
148{ 148{
149 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 149 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
150 "connected %s, cls: %p\n", 150 "connected %s, cls: %p\n",
151 GNUNET_i2s(source), cls); 151 GNUNET_i2s(source),
152 cls);
152 return channel; 153 return channel;
153} 154}
154 155
@@ -206,7 +207,8 @@ handle_data_received (void *cls,
206static void 207static void
207message_sent (void *cls) 208message_sent (void *cls)
208{ 209{
209 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "message sent\n"); 210 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
211 "message sent\n");
210} 212}
211 213
212 214