aboutsummaryrefslogtreecommitdiff
path: root/src/cadet
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2018-05-20 00:35:13 +0200
committerChristian Grothoff <christian@grothoff.org>2018-05-20 00:36:20 +0200
commit0be37e812d034754eb725701f237fbc81b973904 (patch)
treec50481209ec97b5dbbd075489255477c5e761d3d /src/cadet
parentc227e3f00efb4b3677e9b85c0273a7bf5fbcb4a9 (diff)
downloadgnunet-0be37e812d034754eb725701f237fbc81b973904.tar.gz
gnunet-0be37e812d034754eb725701f237fbc81b973904.zip
fix off-by-one error in cadet connection construction, also enforce better timeouts for retransmissions of handshake
Diffstat (limited to 'src/cadet')
-rw-r--r--src/cadet/cadet_protocol.h33
-rw-r--r--src/cadet/gnunet-service-cadet_connection.c96
-rw-r--r--src/cadet/gnunet-service-cadet_connection.h4
-rw-r--r--src/cadet/gnunet-service-cadet_core.c117
-rw-r--r--src/cadet/gnunet-service-cadet_paths.c2
-rw-r--r--src/cadet/gnunet-service-cadet_peer.c38
-rw-r--r--src/cadet/gnunet-service-cadet_tunnels.c190
7 files changed, 407 insertions, 73 deletions
diff --git a/src/cadet/cadet_protocol.h b/src/cadet/cadet_protocol.h
index de0cec5d0..d4a40f9e5 100644
--- a/src/cadet/cadet_protocol.h
+++ b/src/cadet/cadet_protocol.h
@@ -28,6 +28,14 @@
28#ifndef CADET_PROTOCOL_H_ 28#ifndef CADET_PROTOCOL_H_
29#define CADET_PROTOCOL_H_ 29#define CADET_PROTOCOL_H_
30 30
31/**
32 * At best, enable when debugging #5328!
33 */
34#define DEBUG_KX 0
35#if DEBUG_KX
36#warning NEVER run this in production! KX debugging is on!
37#endif
38
31#include "platform.h" 39#include "platform.h"
32#include "gnunet_util_lib.h" 40#include "gnunet_util_lib.h"
33#include "cadet.h" 41#include "cadet.h"
@@ -234,6 +242,22 @@ struct GNUNET_CADET_TunnelKeyExchangeMessage
234 */ 242 */
235 struct GNUNET_CRYPTO_EcdhePublicKey ephemeral_key; 243 struct GNUNET_CRYPTO_EcdhePublicKey ephemeral_key;
236 244
245#if DEBUG_KX
246 /**
247 * Sender's ephemeral public ECC key encoded in a
248 * format suitable for network transmission, as created
249 * using 'gcry_sexp_sprint'.
250 */
251 struct GNUNET_CRYPTO_EcdhePrivateKey ephemeral_key_XXX; // for debugging KX-crypto!
252
253 /**
254 * Sender's ephemeral public ECC key encoded in a
255 * format suitable for network transmission, as created
256 * using 'gcry_sexp_sprint'.
257 */
258 struct GNUNET_CRYPTO_EddsaPrivateKey private_key_XXX; // for debugging KX-crypto!
259#endif
260
237 /** 261 /**
238 * Sender's next ephemeral public ECC key encoded in a 262 * Sender's next ephemeral public ECC key encoded in a
239 * format suitable for network transmission, as created 263 * format suitable for network transmission, as created
@@ -256,6 +280,15 @@ struct GNUNET_CADET_TunnelKeyExchangeAuthMessage
256 */ 280 */
257 struct GNUNET_CADET_TunnelKeyExchangeMessage kx; 281 struct GNUNET_CADET_TunnelKeyExchangeMessage kx;
258 282
283#if DEBUG_KX
284 /**
285 * Received ephemeral public ECC key encoded in a
286 * format suitable for network transmission, as created
287 * using 'gcry_sexp_sprint'.
288 */
289 struct GNUNET_CRYPTO_EcdhePublicKey r_ephemeral_key_XXX; // for debugging KX-crypto!
290#endif
291
259 /** 292 /**
260 * KDF-proof that sender could compute the 3-DH, used in lieu of a 293 * KDF-proof that sender could compute the 3-DH, used in lieu of a
261 * signature or payload data. 294 * signature or payload data.
diff --git a/src/cadet/gnunet-service-cadet_connection.c b/src/cadet/gnunet-service-cadet_connection.c
index 82ab5cc2c..9ff62b29f 100644
--- a/src/cadet/gnunet-service-cadet_connection.c
+++ b/src/cadet/gnunet-service-cadet_connection.c
@@ -39,6 +39,13 @@
39 39
40 40
41/** 41/**
42 * How long do we wait initially before retransmitting the KX?
43 * TODO: replace by 2 RTT if/once we have connection-level RTT data!
44 */
45#define INITIAL_CONNECTION_CREATE_RETRY_DELAY GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MILLISECONDS, 200)
46
47
48/**
42 * All the states a connection can be in. 49 * All the states a connection can be in.
43 */ 50 */
44enum CadetConnectionState 51enum CadetConnectionState
@@ -134,6 +141,16 @@ struct CadetConnection
134 struct GNUNET_TIME_Relative retry_delay; 141 struct GNUNET_TIME_Relative retry_delay;
135 142
136 /** 143 /**
144 * Earliest time for re-trying CREATE
145 */
146 struct GNUNET_TIME_Absolute create_at;
147
148 /**
149 * Earliest time for re-trying CREATE_ACK
150 */
151 struct GNUNET_TIME_Absolute create_ack_at;
152
153 /**
137 * Performance metrics for this connection. 154 * Performance metrics for this connection.
138 */ 155 */
139 struct CadetConnectionMetrics metrics; 156 struct CadetConnectionMetrics metrics;
@@ -482,8 +499,9 @@ GCC_latency_observed (const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid,
482 499
483 500
484/** 501/**
485 * A #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE_ACK was received for this connection, implying 502 * A #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE_ACK was received for
486 * that the end-to-end connection is up. Process it. 503 * this connection, implying that the end-to-end connection is up.
504 * Process it.
487 * 505 *
488 * @param cc the connection that got the ACK. 506 * @param cc the connection that got the ACK.
489 */ 507 */
@@ -525,6 +543,11 @@ void
525GCC_handle_kx (struct CadetConnection *cc, 543GCC_handle_kx (struct CadetConnection *cc,
526 const struct GNUNET_CADET_TunnelKeyExchangeMessage *msg) 544 const struct GNUNET_CADET_TunnelKeyExchangeMessage *msg)
527{ 545{
546 LOG (GNUNET_ERROR_TYPE_DEBUG,
547 "Received KX message with ephermal %s on CC %s in state %d\n",
548 GNUNET_e2s (&msg->ephemeral_key),
549 GNUNET_sh2s (&cc->cid.connection_of_tunnel),
550 cc->state);
528 if (CADET_CONNECTION_SENT == cc->state) 551 if (CADET_CONNECTION_SENT == cc->state)
529 { 552 {
530 /* We didn't get the CADET_CONNECTION_CREATE_ACK, but instead got payload. That's fine, 553 /* We didn't get the CADET_CONNECTION_CREATE_ACK, but instead got payload. That's fine,
@@ -549,6 +572,11 @@ void
549GCC_handle_kx_auth (struct CadetConnection *cc, 572GCC_handle_kx_auth (struct CadetConnection *cc,
550 const struct GNUNET_CADET_TunnelKeyExchangeAuthMessage *msg) 573 const struct GNUNET_CADET_TunnelKeyExchangeAuthMessage *msg)
551{ 574{
575 LOG (GNUNET_ERROR_TYPE_DEBUG,
576 "Received KX AUTH message with ephermal %s on CC %s in state %d\n",
577 GNUNET_e2s (&msg->kx.ephemeral_key),
578 GNUNET_sh2s (&cc->cid.connection_of_tunnel),
579 cc->state);
552 if (CADET_CONNECTION_SENT == cc->state) 580 if (CADET_CONNECTION_SENT == cc->state)
553 { 581 {
554 /* We didn't get the CADET_CONNECTION_CREATE_ACK, but instead got payload. That's fine, 582 /* We didn't get the CADET_CONNECTION_CREATE_ACK, but instead got payload. That's fine,
@@ -601,25 +629,26 @@ send_create (void *cls)
601 struct GNUNET_CADET_ConnectionCreateMessage *create_msg; 629 struct GNUNET_CADET_ConnectionCreateMessage *create_msg;
602 struct GNUNET_PeerIdentity *pids; 630 struct GNUNET_PeerIdentity *pids;
603 struct GNUNET_MQ_Envelope *env; 631 struct GNUNET_MQ_Envelope *env;
604 unsigned int path_length;
605 632
606 cc->task = NULL; 633 cc->task = NULL;
607 GNUNET_assert (GNUNET_YES == cc->mqm_ready); 634 GNUNET_assert (GNUNET_YES == cc->mqm_ready);
608 path_length = GCPP_get_length (cc->path);
609 env = GNUNET_MQ_msg_extra (create_msg, 635 env = GNUNET_MQ_msg_extra (create_msg,
610 (1 + path_length) * sizeof (struct GNUNET_PeerIdentity), 636 (2 + cc->off) * sizeof (struct GNUNET_PeerIdentity),
611 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE); 637 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE);
612 create_msg->options = htonl ((uint32_t) cc->options); 638 create_msg->options = htonl ((uint32_t) cc->options);
613 create_msg->cid = cc->cid; 639 create_msg->cid = cc->cid;
614 pids = (struct GNUNET_PeerIdentity *) &create_msg[1]; 640 pids = (struct GNUNET_PeerIdentity *) &create_msg[1];
615 pids[0] = my_full_id; 641 pids[0] = my_full_id;
616 for (unsigned int i=0;i<path_length;i++) 642 for (unsigned int i=0;i<=cc->off;i++)
617 pids[i + 1] = *GCP_get_id (GCPP_get_peer_at_offset (cc->path, 643 pids[i + 1] = *GCP_get_id (GCPP_get_peer_at_offset (cc->path,
618 i)); 644 i));
619 LOG (GNUNET_ERROR_TYPE_DEBUG, 645 LOG (GNUNET_ERROR_TYPE_DEBUG,
620 "Sending CADET_CONNECTION_CREATE message for %s\n", 646 "Sending CADET_CONNECTION_CREATE message for %s with %u hops\n",
621 GCC_2s (cc)); 647 GCC_2s (cc),
648 cc->off + 2);
622 cc->env = env; 649 cc->env = env;
650 cc->retry_delay = GNUNET_TIME_STD_BACKOFF (cc->retry_delay);
651 cc->create_at = GNUNET_TIME_relative_to_absolute (cc->retry_delay);
623 update_state (cc, 652 update_state (cc,
624 CADET_CONNECTION_SENT, 653 CADET_CONNECTION_SENT,
625 GNUNET_NO); 654 GNUNET_NO);
@@ -641,7 +670,6 @@ send_create_ack (void *cls)
641 struct GNUNET_MQ_Envelope *env; 670 struct GNUNET_MQ_Envelope *env;
642 671
643 cc->task = NULL; 672 cc->task = NULL;
644 GNUNET_assert (CADET_CONNECTION_CREATE_RECEIVED == cc->state);
645 LOG (GNUNET_ERROR_TYPE_DEBUG, 673 LOG (GNUNET_ERROR_TYPE_DEBUG,
646 "Sending CONNECTION_CREATE_ACK message for %s\n", 674 "Sending CONNECTION_CREATE_ACK message for %s\n",
647 GCC_2s (cc)); 675 GCC_2s (cc));
@@ -650,9 +678,16 @@ send_create_ack (void *cls)
650 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE_ACK); 678 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE_ACK);
651 ack_msg->cid = cc->cid; 679 ack_msg->cid = cc->cid;
652 cc->env = env; 680 cc->env = env;
653 update_state (cc, 681 cc->retry_delay = GNUNET_TIME_STD_BACKOFF (cc->retry_delay);
654 CADET_CONNECTION_READY, 682 cc->create_ack_at = GNUNET_TIME_relative_to_absolute (cc->retry_delay);
655 GNUNET_NO); 683 if (CADET_CONNECTION_CREATE_RECEIVED == cc->state)
684 update_state (cc,
685 CADET_CONNECTION_READY,
686 GNUNET_NO);
687 if (CADET_CONNECTION_READY == cc->state)
688 cc->task = GNUNET_SCHEDULER_add_delayed (keepalive_period,
689 &send_keepalive,
690 cc);
656 GCP_send (cc->mq_man, 691 GCP_send (cc->mq_man,
657 env); 692 env);
658} 693}
@@ -681,8 +716,9 @@ GCC_handle_duplicate_create (struct CadetConnection *cc)
681 cc->mqm_ready); 716 cc->mqm_ready);
682 if (NULL != cc->task) 717 if (NULL != cc->task)
683 GNUNET_SCHEDULER_cancel (cc->task); 718 GNUNET_SCHEDULER_cancel (cc->task);
684 cc->task = GNUNET_SCHEDULER_add_now (&send_create_ack, 719 cc->task = GNUNET_SCHEDULER_add_at (cc->create_ack_at,
685 cc); 720 &send_create_ack,
721 cc);
686 } 722 }
687 else 723 else
688 { 724 {
@@ -721,7 +757,7 @@ manage_first_hop_mq (void *cls,
721 update_state (cc, 757 update_state (cc,
722 CADET_CONNECTION_NEW, 758 CADET_CONNECTION_NEW,
723 GNUNET_NO); 759 GNUNET_NO);
724 cc->retry_delay = GNUNET_TIME_UNIT_ZERO; 760 cc->retry_delay = INITIAL_CONNECTION_CREATE_RETRY_DELAY;
725 if (NULL != cc->task) 761 if (NULL != cc->task)
726 { 762 {
727 GNUNET_SCHEDULER_cancel (cc->task); 763 GNUNET_SCHEDULER_cancel (cc->task);
@@ -741,8 +777,9 @@ manage_first_hop_mq (void *cls,
741 { 777 {
742 case CADET_CONNECTION_NEW: 778 case CADET_CONNECTION_NEW:
743 /* Transmit immediately */ 779 /* Transmit immediately */
744 cc->task = GNUNET_SCHEDULER_add_now (&send_create, 780 cc->task = GNUNET_SCHEDULER_add_at (cc->create_at,
745 cc); 781 &send_create,
782 cc);
746 break; 783 break;
747 case CADET_CONNECTION_SENDING_CREATE: 784 case CADET_CONNECTION_SENDING_CREATE:
748 /* Should not be possible to be called in this state. */ 785 /* Should not be possible to be called in this state. */
@@ -750,16 +787,16 @@ manage_first_hop_mq (void *cls,
750 break; 787 break;
751 case CADET_CONNECTION_SENT: 788 case CADET_CONNECTION_SENT:
752 /* Retry a bit later... */ 789 /* Retry a bit later... */
753 cc->retry_delay = GNUNET_TIME_STD_BACKOFF (cc->retry_delay); 790 cc->task = GNUNET_SCHEDULER_add_at (cc->create_at,
754 cc->task = GNUNET_SCHEDULER_add_delayed (cc->retry_delay, 791 &send_create,
755 &send_create, 792 cc);
756 cc);
757 break; 793 break;
758 case CADET_CONNECTION_CREATE_RECEIVED: 794 case CADET_CONNECTION_CREATE_RECEIVED:
759 /* We got the 'CREATE' (incoming connection), should send the CREATE_ACK */ 795 /* We got the 'CREATE' (incoming connection), should send the CREATE_ACK */
760 cc->metrics.age = GNUNET_TIME_absolute_get (); 796 cc->metrics.age = GNUNET_TIME_absolute_get ();
761 cc->task = GNUNET_SCHEDULER_add_now (&send_create_ack, 797 cc->task = GNUNET_SCHEDULER_add_at (cc->create_ack_at,
762 cc); 798 &send_create_ack,
799 cc);
763 break; 800 break;
764 case CADET_CONNECTION_READY: 801 case CADET_CONNECTION_READY:
765 if ( (NULL == cc->keepalive_qe) && 802 if ( (NULL == cc->keepalive_qe) &&
@@ -814,6 +851,8 @@ connection_create (struct CadetPeer *destination,
814 cc->state = init_state; 851 cc->state = init_state;
815 cc->ct = ct; 852 cc->ct = ct;
816 cc->cid = *cid; 853 cc->cid = *cid;
854 cc->retry_delay = GNUNET_TIME_relative_multiply (INITIAL_CONNECTION_CREATE_RETRY_DELAY,
855 off);
817 GNUNET_assert (GNUNET_OK == 856 GNUNET_assert (GNUNET_OK ==
818 GNUNET_CONTAINER_multishortmap_put (connections, 857 GNUNET_CONTAINER_multishortmap_put (connections,
819 &GCC_get_id (cc)->connection_of_tunnel, 858 &GCC_get_id (cc)->connection_of_tunnel,
@@ -824,9 +863,10 @@ connection_create (struct CadetPeer *destination,
824 cc->path = path; 863 cc->path = path;
825 cc->off = off; 864 cc->off = off;
826 LOG (GNUNET_ERROR_TYPE_DEBUG, 865 LOG (GNUNET_ERROR_TYPE_DEBUG,
827 "Creating %s using path %s\n", 866 "Creating %s using path %s (offset: %u)\n",
828 GCC_2s (cc), 867 GCC_2s (cc),
829 GCPP_2s (path)); 868 GCPP_2s (path),
869 off);
830 GCPP_add_connection (path, 870 GCPP_add_connection (path,
831 off, 871 off,
832 cc); 872 cc);
@@ -834,7 +874,6 @@ connection_create (struct CadetPeer *destination,
834 GCP_add_connection (GCPP_get_peer_at_offset (path, 874 GCP_add_connection (GCPP_get_peer_at_offset (path,
835 i), 875 i),
836 cc); 876 cc);
837
838 first_hop = GCPP_get_peer_at_offset (path, 877 first_hop = GCPP_get_peer_at_offset (path,
839 0); 878 0);
840 cc->mq_man = GCP_request_mq (first_hop, 879 cc->mq_man = GCP_request_mq (first_hop,
@@ -1001,11 +1040,14 @@ GCC_transmit (struct CadetConnection *cc,
1001 * Obtain the path used by this connection. 1040 * Obtain the path used by this connection.
1002 * 1041 *
1003 * @param cc connection 1042 * @param cc connection
1043 * @param off[out] set to the length of the path we use
1004 * @return path to @a cc 1044 * @return path to @a cc
1005 */ 1045 */
1006struct CadetPeerPath * 1046struct CadetPeerPath *
1007GCC_get_path (struct CadetConnection *cc) 1047GCC_get_path (struct CadetConnection *cc,
1048 unsigned int *off)
1008{ 1049{
1050 *off = cc->off;
1009 return cc->path; 1051 return cc->path;
1010} 1052}
1011 1053
diff --git a/src/cadet/gnunet-service-cadet_connection.h b/src/cadet/gnunet-service-cadet_connection.h
index fdb184366..1c0475d40 100644
--- a/src/cadet/gnunet-service-cadet_connection.h
+++ b/src/cadet/gnunet-service-cadet_connection.h
@@ -300,10 +300,12 @@ GCC_get_ct (struct CadetConnection *cc);
300 * Obtain the path used by this connection. 300 * Obtain the path used by this connection.
301 * 301 *
302 * @param cc connection 302 * @param cc connection
303 * @param off[out] set to offset in this path where the connection @a cc ends
303 * @return path to @a cc 304 * @return path to @a cc
304 */ 305 */
305struct CadetPeerPath * 306struct CadetPeerPath *
306GCC_get_path (struct CadetConnection *cc); 307GCC_get_path (struct CadetConnection *cc,
308 unsigned int *off);
307 309
308 310
309/** 311/**
diff --git a/src/cadet/gnunet-service-cadet_core.c b/src/cadet/gnunet-service-cadet_core.c
index 84aff1857..06d1fe3cc 100644
--- a/src/cadet/gnunet-service-cadet_core.c
+++ b/src/cadet/gnunet-service-cadet_core.c
@@ -406,6 +406,28 @@ route_message (struct CadetPeer *prev,
406 (NULL != dir->env_head) ) 406 (NULL != dir->env_head) )
407 discard_buffer (dir, 407 discard_buffer (dir,
408 dir->env_head); 408 dir->env_head);
409 /* Check for duplicates */
410 for (const struct GNUNET_MQ_Envelope *env = dir->env_head;
411 NULL != env;
412 env = GNUNET_MQ_env_next (env))
413 {
414 const struct GNUNET_MessageHeader *hdr = GNUNET_MQ_env_get_msg (env);
415
416 if ( (hdr->size == msg->size) &&
417 (0 == memcmp (hdr,
418 msg,
419 ntohs (msg->size))) )
420 {
421 LOG (GNUNET_ERROR_TYPE_DEBUG,
422 "Received duplicate of message already in buffer, dropping\n");
423 GNUNET_STATISTICS_update (stats,
424 "# messages dropped due to duplicate in buffer",
425 1,
426 GNUNET_NO);
427 return;
428 }
429 }
430
409 rung = dir->rung; 431 rung = dir->rung;
410 if (cur_buffers == max_buffers) 432 if (cur_buffers == max_buffers)
411 { 433 {
@@ -434,7 +456,7 @@ route_message (struct CadetPeer *prev,
434 GNUNET_CONTAINER_DLL_remove (rung->rd_head, 456 GNUNET_CONTAINER_DLL_remove (rung->rd_head,
435 rung->rd_tail, 457 rung->rd_tail,
436 dir); 458 dir);
437 /* make 'nxt' point to the next higher rung, creat if necessary */ 459 /* make 'nxt' point to the next higher rung, create if necessary */
438 nxt = rung->next; 460 nxt = rung->next;
439 if ( (NULL == nxt) || 461 if ( (NULL == nxt) ||
440 (rung->rung_off + 1 != nxt->rung_off) ) 462 (rung->rung_off + 1 != nxt->rung_off) )
@@ -781,31 +803,45 @@ handle_connection_create (void *cls,
781 if (0 == path_length) 803 if (0 == path_length)
782 { 804 {
783 LOG (GNUNET_ERROR_TYPE_DEBUG, 805 LOG (GNUNET_ERROR_TYPE_DEBUG,
784 "Dropping CADET_CONNECTION_CREATE with empty path\n"); 806 "Dropping CADET_CONNECTION_CREATE with empty path\n");
785 GNUNET_break_op (0); 807 GNUNET_break_op (0);
786 return; 808 return;
787 } 809 }
810 LOG (GNUNET_ERROR_TYPE_DEBUG,
811 "Handling CADET_CONNECTION_CREATE from %s for CID %s with %u hops\n",
812 GCP_2s (sender),
813 GNUNET_sh2s (&msg->cid.connection_of_tunnel),
814 path_length);
788 /* Check for loops */ 815 /* Check for loops */
789 struct GNUNET_CONTAINER_MultiPeerMap *map; 816 {
790 map = GNUNET_CONTAINER_multipeermap_create (path_length * 2, 817 struct GNUNET_CONTAINER_MultiPeerMap *map;
791 GNUNET_YES); 818
792 GNUNET_assert (NULL != map); 819 map = GNUNET_CONTAINER_multipeermap_create (path_length * 2,
793 for (off = 0; off < path_length; off++) { 820 GNUNET_YES);
794 if (GNUNET_SYSERR == 821 GNUNET_assert (NULL != map);
795 GNUNET_CONTAINER_multipeermap_put (map, 822 for (unsigned int i=0;i<path_length;i++)
796 &pids[off], 823 {
797 NULL,
798 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)) {
799 /* bogus request */
800 GNUNET_CONTAINER_multipeermap_destroy (map);
801 LOG (GNUNET_ERROR_TYPE_DEBUG, 824 LOG (GNUNET_ERROR_TYPE_DEBUG,
802 "Dropping CADET_CONNECTION_CREATE with cyclic path\n"); 825 "CADET_CONNECTION_CREATE has peer %s at offset %u\n",
803 GNUNET_break_op (0); 826 GNUNET_i2s (&pids[i]),
804 return; 827 i);
828 if (GNUNET_SYSERR ==
829 GNUNET_CONTAINER_multipeermap_put (map,
830 &pids[i],
831 NULL,
832 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
833 {
834 /* bogus request */
835 GNUNET_CONTAINER_multipeermap_destroy (map);
836 LOG (GNUNET_ERROR_TYPE_DEBUG,
837 "Dropping CADET_CONNECTION_CREATE with cyclic path\n");
838 GNUNET_break_op (0);
839 return;
840 }
805 } 841 }
842 GNUNET_CONTAINER_multipeermap_destroy (map);
806 } 843 }
807 GNUNET_CONTAINER_multipeermap_destroy (map); 844 /* Initiator is at offset 0, find us */
808 /* Initiator is at offset 0. */
809 for (off=1;off<path_length;off++) 845 for (off=1;off<path_length;off++)
810 if (0 == memcmp (&my_full_id, 846 if (0 == memcmp (&my_full_id,
811 &pids[off], 847 &pids[off],
@@ -814,7 +850,7 @@ handle_connection_create (void *cls,
814 if (off == path_length) 850 if (off == path_length)
815 { 851 {
816 LOG (GNUNET_ERROR_TYPE_DEBUG, 852 LOG (GNUNET_ERROR_TYPE_DEBUG,
817 "Dropping CADET_CONNECTION_CREATE without us in the path\n"); 853 "Dropping CADET_CONNECTION_CREATE without us in the path\n");
818 GNUNET_break_op (0); 854 GNUNET_break_op (0);
819 return; 855 return;
820 } 856 }
@@ -823,14 +859,15 @@ handle_connection_create (void *cls,
823 GNUNET_NO)) 859 GNUNET_NO))
824 { 860 {
825 LOG (GNUNET_ERROR_TYPE_DEBUG, 861 LOG (GNUNET_ERROR_TYPE_DEBUG,
826 "Dropping CADET_CONNECTION_CREATE without sender in the path\n"); 862 "Dropping CADET_CONNECTION_CREATE without sender at previous hop in the path\n");
827 GNUNET_break_op (0); 863 GNUNET_break_op (0);
828 return; 864 return;
829 } 865 }
830 if (NULL != 866 if (NULL !=
831 get_route (&msg->cid)) 867 (route = get_route (&msg->cid)))
832 { 868 {
833 /* Duplicate CREATE, pass it on, previous one might have been lost! */ 869 /* Duplicate CREATE, pass it on, previous one might have been lost! */
870
834 LOG (GNUNET_ERROR_TYPE_DEBUG, 871 LOG (GNUNET_ERROR_TYPE_DEBUG,
835 "Passing on duplicate CADET_CONNECTION_CREATE message on connection %s\n", 872 "Passing on duplicate CADET_CONNECTION_CREATE message on connection %s\n",
836 GNUNET_sh2s (&msg->cid.connection_of_tunnel)); 873 GNUNET_sh2s (&msg->cid.connection_of_tunnel));
@@ -859,7 +896,7 @@ handle_connection_create (void *cls,
859 origin = GCP_get (&pids[0], 896 origin = GCP_get (&pids[0],
860 GNUNET_YES); 897 GNUNET_YES);
861 LOG (GNUNET_ERROR_TYPE_DEBUG, 898 LOG (GNUNET_ERROR_TYPE_DEBUG,
862 "Received CADET_CONNECTION_CREATE message from %s for connection %s, building inverse path\n", 899 "I am destination for CADET_CONNECTION_CREATE message from %s for connection %s, building inverse path\n",
863 GCP_2s (origin), 900 GCP_2s (origin),
864 GNUNET_sh2s (&msg->cid.connection_of_tunnel)); 901 GNUNET_sh2s (&msg->cid.connection_of_tunnel));
865 path = GCPP_get_path_from_route (path_length - 1, 902 path = GCPP_get_path_from_route (path_length - 1,
@@ -949,6 +986,10 @@ handle_connection_create (void *cls,
949 3), 986 3),
950 &timeout_cb, 987 &timeout_cb,
951 NULL); 988 NULL);
989 /* also pass CREATE message along to next hop */
990 route_message (sender,
991 &msg->cid,
992 &msg->header);
952} 993}
953 994
954 995
@@ -970,7 +1011,9 @@ handle_connection_create_ack (void *cls,
970 if (NULL != cc) 1011 if (NULL != cc)
971 { 1012 {
972 /* verify ACK came from the right direction */ 1013 /* verify ACK came from the right direction */
973 struct CadetPeerPath *path = GCC_get_path (cc); 1014 unsigned int len;
1015 struct CadetPeerPath *path = GCC_get_path (cc,
1016 &len);
974 1017
975 if (peer != 1018 if (peer !=
976 GCPP_get_peer_at_offset (path, 1019 GCPP_get_peer_at_offset (path,
@@ -1014,7 +1057,9 @@ handle_connection_broken (void *cls,
1014 if (NULL != cc) 1057 if (NULL != cc)
1015 { 1058 {
1016 /* verify message came from the right direction */ 1059 /* verify message came from the right direction */
1017 struct CadetPeerPath *path = GCC_get_path (cc); 1060 unsigned int len;
1061 struct CadetPeerPath *path = GCC_get_path (cc,
1062 &len);
1018 1063
1019 if (peer != 1064 if (peer !=
1020 GCPP_get_peer_at_offset (path, 1065 GCPP_get_peer_at_offset (path,
@@ -1063,7 +1108,9 @@ handle_connection_destroy (void *cls,
1063 if (NULL != cc) 1108 if (NULL != cc)
1064 { 1109 {
1065 /* verify message came from the right direction */ 1110 /* verify message came from the right direction */
1066 struct CadetPeerPath *path = GCC_get_path (cc); 1111 unsigned int len;
1112 struct CadetPeerPath *path = GCC_get_path (cc,
1113 &len);
1067 1114
1068 if (peer != 1115 if (peer !=
1069 GCPP_get_peer_at_offset (path, 1116 GCPP_get_peer_at_offset (path,
@@ -1108,11 +1155,19 @@ handle_tunnel_kx (void *cls,
1108 struct CadetConnection *cc; 1155 struct CadetConnection *cc;
1109 1156
1110 /* First, check if message belongs to a connection that ends here. */ 1157 /* First, check if message belongs to a connection that ends here. */
1158 LOG (GNUNET_ERROR_TYPE_DEBUG,
1159 "Routing KX with ephemeral %s on CID %s\n",
1160 GNUNET_e2s (&msg->ephemeral_key),
1161 GNUNET_sh2s (&msg->cid.connection_of_tunnel));
1162
1163
1111 cc = GCC_lookup (&msg->cid); 1164 cc = GCC_lookup (&msg->cid);
1112 if (NULL != cc) 1165 if (NULL != cc)
1113 { 1166 {
1114 /* verify message came from the right direction */ 1167 /* verify message came from the right direction */
1115 struct CadetPeerPath *path = GCC_get_path (cc); 1168 unsigned int len;
1169 struct CadetPeerPath *path = GCC_get_path (cc,
1170 &len);
1116 1171
1117 if (peer != 1172 if (peer !=
1118 GCPP_get_peer_at_offset (path, 1173 GCPP_get_peer_at_offset (path,
@@ -1152,7 +1207,9 @@ handle_tunnel_kx_auth (void *cls,
1152 if (NULL != cc) 1207 if (NULL != cc)
1153 { 1208 {
1154 /* verify message came from the right direction */ 1209 /* verify message came from the right direction */
1155 struct CadetPeerPath *path = GCC_get_path (cc); 1210 unsigned int len;
1211 struct CadetPeerPath *path = GCC_get_path (cc,
1212 &len);
1156 1213
1157 if (peer != 1214 if (peer !=
1158 GCPP_get_peer_at_offset (path, 1215 GCPP_get_peer_at_offset (path,
@@ -1208,7 +1265,9 @@ handle_tunnel_encrypted (void *cls,
1208 if (NULL != cc) 1265 if (NULL != cc)
1209 { 1266 {
1210 /* verify message came from the right direction */ 1267 /* verify message came from the right direction */
1211 struct CadetPeerPath *path = GCC_get_path (cc); 1268 unsigned int len;
1269 struct CadetPeerPath *path = GCC_get_path (cc,
1270 &len);
1212 1271
1213 if (peer != 1272 if (peer !=
1214 GCPP_get_peer_at_offset (path, 1273 GCPP_get_peer_at_offset (path,
diff --git a/src/cadet/gnunet-service-cadet_paths.c b/src/cadet/gnunet-service-cadet_paths.c
index b443cf9e8..5218d0848 100644
--- a/src/cadet/gnunet-service-cadet_paths.c
+++ b/src/cadet/gnunet-service-cadet_paths.c
@@ -146,7 +146,7 @@ GCPP_add_connection (struct CadetPeerPath *path,
146 struct CadetPeerPathEntry *entry; 146 struct CadetPeerPathEntry *entry;
147 147
148 LOG (GNUNET_ERROR_TYPE_DEBUG, 148 LOG (GNUNET_ERROR_TYPE_DEBUG,
149 "Adding connection %s to path %s at offset %u\n", 149 "Adding %s to path %s at offset %u\n",
150 GCC_2s (cc), 150 GCC_2s (cc),
151 GCPP_2s (path), 151 GCPP_2s (path),
152 off); 152 off);
diff --git a/src/cadet/gnunet-service-cadet_peer.c b/src/cadet/gnunet-service-cadet_peer.c
index 05555e693..35e2c6148 100644
--- a/src/cadet/gnunet-service-cadet_peer.c
+++ b/src/cadet/gnunet-service-cadet_peer.c
@@ -242,12 +242,15 @@ struct CadetPeer
242const char * 242const char *
243GCP_2s (const struct CadetPeer *cp) 243GCP_2s (const struct CadetPeer *cp)
244{ 244{
245 static char buf[32]; 245 static char buf[5];
246 246 char *ret;
247 GNUNET_snprintf (buf, 247
248 sizeof (buf), 248 ret = GNUNET_CRYPTO_eddsa_public_key_to_string (&cp->pid.public_key);
249 "P(%s)", 249 strncpy (buf,
250 GNUNET_i2s (&cp->pid)); 250 ret,
251 sizeof (buf) - 1);
252 GNUNET_free (ret);
253 buf[4] = '\0';
251 return buf; 254 return buf;
252} 255}
253 256
@@ -649,6 +652,27 @@ mqm_execute (struct GCP_MessageQueueManager *mqm)
649 } 652 }
650 else 653 else
651 { 654 {
655 {
656 const struct GNUNET_MessageHeader *mh;
657
658 mh = GNUNET_MQ_env_get_msg (mqm->env);
659 switch (ntohs (mh->type))
660 {
661 case GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX:
662 {
663 const struct GNUNET_CADET_TunnelKeyExchangeMessage *msg
664 = (const struct GNUNET_CADET_TunnelKeyExchangeMessage *) mh;
665 LOG (GNUNET_ERROR_TYPE_DEBUG,
666 "P2P forwarding KX with ephemeral %s to %s on CID %s\n",
667 GNUNET_e2s (&msg->ephemeral_key),
668 GCP_2s (cp),
669 GNUNET_sh2s (&msg->cid.connection_of_tunnel));
670 }
671 break;
672 default:
673 break;
674 }
675 }
652 LOG (GNUNET_ERROR_TYPE_DEBUG, 676 LOG (GNUNET_ERROR_TYPE_DEBUG,
653 "Sending to peer %s from MQM %p\n", 677 "Sending to peer %s from MQM %p\n",
654 GCP_2s (cp), 678 GCP_2s (cp),
@@ -1044,7 +1068,7 @@ GCP_add_connection (struct CadetPeer *cp,
1044 struct CadetConnection *cc) 1068 struct CadetConnection *cc)
1045{ 1069{
1046 LOG (GNUNET_ERROR_TYPE_DEBUG, 1070 LOG (GNUNET_ERROR_TYPE_DEBUG,
1047 "Adding connection %s to peer %s\n", 1071 "Adding %s to peer %s\n",
1048 GCC_2s (cc), 1072 GCC_2s (cc),
1049 GCP_2s (cp)); 1073 GCP_2s (cp));
1050 GNUNET_assert (GNUNET_OK == 1074 GNUNET_assert (GNUNET_OK ==
diff --git a/src/cadet/gnunet-service-cadet_tunnels.c b/src/cadet/gnunet-service-cadet_tunnels.c
index 75d454522..dbd84a818 100644
--- a/src/cadet/gnunet-service-cadet_tunnels.c
+++ b/src/cadet/gnunet-service-cadet_tunnels.c
@@ -1369,6 +1369,15 @@ send_kx (struct CadetTunnel *t,
1369 msg->cid = *GCC_get_id (cc); 1369 msg->cid = *GCC_get_id (cc);
1370 GNUNET_CRYPTO_ecdhe_key_get_public (&ax->kx_0, 1370 GNUNET_CRYPTO_ecdhe_key_get_public (&ax->kx_0,
1371 &msg->ephemeral_key); 1371 &msg->ephemeral_key);
1372#if DEBUG_KX
1373 msg->ephemeral_key_XXX = ax->kx_0;
1374 msg->private_key_XXX = *my_private_key;
1375#endif
1376 LOG (GNUNET_ERROR_TYPE_DEBUG,
1377 "Sending KX message to %s with ephemeral %s on CID %s\n",
1378 GCT_2s (t),
1379 GNUNET_e2s (&msg->ephemeral_key),
1380 GNUNET_sh2s (&msg->cid.connection_of_tunnel));
1372 GNUNET_CRYPTO_ecdhe_key_get_public (&ax->DHRs, 1381 GNUNET_CRYPTO_ecdhe_key_get_public (&ax->DHRs,
1373 &msg->ratchet_key); 1382 &msg->ratchet_key);
1374 mark_connection_unready (ct); 1383 mark_connection_unready (ct);
@@ -1435,6 +1444,17 @@ send_kx_auth (struct CadetTunnel *t,
1435 &msg->kx.ephemeral_key); 1444 &msg->kx.ephemeral_key);
1436 GNUNET_CRYPTO_ecdhe_key_get_public (&ax->DHRs, 1445 GNUNET_CRYPTO_ecdhe_key_get_public (&ax->DHRs,
1437 &msg->kx.ratchet_key); 1446 &msg->kx.ratchet_key);
1447#if DEBUG_KX
1448 msg->kx.ephemeral_key_XXX = ax->kx_0;
1449 msg->kx.private_key_XXX = *my_private_key;
1450 msg->r_ephemeral_key_XXX = ax->last_ephemeral;
1451#endif
1452 LOG (GNUNET_ERROR_TYPE_DEBUG,
1453 "Sending KX_AUTH message to %s with ephemeral %s on CID %s\n",
1454 GCT_2s (t),
1455 GNUNET_e2s (&msg->kx.ephemeral_key),
1456 GNUNET_sh2s (&msg->kx.cid.connection_of_tunnel));
1457
1438 /* Compute authenticator (this is the main difference to #send_kx()) */ 1458 /* Compute authenticator (this is the main difference to #send_kx()) */
1439 GNUNET_CRYPTO_hash (&ax->RK, 1459 GNUNET_CRYPTO_hash (&ax->RK,
1440 sizeof (ax->RK), 1460 sizeof (ax->RK),
@@ -1705,12 +1725,19 @@ GCT_handle_kx (struct CadetTConnection *ct,
1705 "# KX received", 1725 "# KX received",
1706 1, 1726 1,
1707 GNUNET_NO); 1727 GNUNET_NO);
1708 if (GNUNET_YES == alice_or_bob (GCP_get_id (t->destination))) 1728 if (GNUNET_YES ==
1729 alice_or_bob (GCP_get_id (t->destination)))
1709 { 1730 {
1710 /* Bob is not allowed to send KX! */ 1731 /* Bob is not allowed to send KX! */
1711 GNUNET_break_op (0); 1732 GNUNET_break_op (0);
1712 return; 1733 return;
1713 } 1734 }
1735 LOG (GNUNET_ERROR_TYPE_DEBUG,
1736 "Received KX message from %s with ephemeral %s from %s on connection %s\n",
1737 GCT_2s (t),
1738 GNUNET_e2s (&msg->ephemeral_key),
1739 GNUNET_i2s (GCP_get_id (t->destination)),
1740 GCC_2s (ct->cc));
1714#if 1 1741#if 1
1715 if ( (0 == 1742 if ( (0 ==
1716 memcmp (&t->ax.DHRr, 1743 memcmp (&t->ax.DHRr,
@@ -1823,6 +1850,75 @@ GCT_handle_kx (struct CadetTConnection *ct,
1823} 1850}
1824 1851
1825 1852
1853#if DEBUG_KX
1854static void
1855check_ee (const struct GNUNET_CRYPTO_EcdhePrivateKey *e1,
1856 const struct GNUNET_CRYPTO_EcdhePrivateKey *e2)
1857{
1858 struct GNUNET_CRYPTO_EcdhePublicKey p1;
1859 struct GNUNET_CRYPTO_EcdhePublicKey p2;
1860 struct GNUNET_HashCode hc1;
1861 struct GNUNET_HashCode hc2;
1862
1863 GNUNET_CRYPTO_ecdhe_key_get_public (e1,
1864 &p1);
1865 GNUNET_CRYPTO_ecdhe_key_get_public (e2,
1866 &p2);
1867 GNUNET_assert (GNUNET_OK ==
1868 GNUNET_CRYPTO_ecc_ecdh (e1,
1869 &p2,
1870 &hc1));
1871 GNUNET_assert (GNUNET_OK ==
1872 GNUNET_CRYPTO_ecc_ecdh (e2,
1873 &p1,
1874 &hc2));
1875 GNUNET_break (0 == memcmp (&hc1,
1876 &hc2,
1877 sizeof (hc1)));
1878}
1879
1880
1881static void
1882check_ed (const struct GNUNET_CRYPTO_EcdhePrivateKey *e1,
1883 const struct GNUNET_CRYPTO_EddsaPrivateKey *e2)
1884{
1885 struct GNUNET_CRYPTO_EcdhePublicKey p1;
1886 struct GNUNET_CRYPTO_EddsaPublicKey p2;
1887 struct GNUNET_HashCode hc1;
1888 struct GNUNET_HashCode hc2;
1889
1890 GNUNET_CRYPTO_ecdhe_key_get_public (e1,
1891 &p1);
1892 GNUNET_CRYPTO_eddsa_key_get_public (e2,
1893 &p2);
1894 GNUNET_assert (GNUNET_OK ==
1895 GNUNET_CRYPTO_ecdh_eddsa (e1,
1896 &p2,
1897 &hc1));
1898 GNUNET_assert (GNUNET_OK ==
1899 GNUNET_CRYPTO_eddsa_ecdh (e2,
1900 &p1,
1901 &hc2));
1902 GNUNET_break (0 == memcmp (&hc1,
1903 &hc2,
1904 sizeof (hc1)));
1905}
1906
1907
1908static void
1909test_crypto_bug (const struct GNUNET_CRYPTO_EcdhePrivateKey *e1,
1910 const struct GNUNET_CRYPTO_EcdhePrivateKey *e2,
1911 const struct GNUNET_CRYPTO_EddsaPrivateKey *d1,
1912 const struct GNUNET_CRYPTO_EddsaPrivateKey *d2)
1913{
1914 check_ee (e1, e2);
1915 check_ed (e1, d2);
1916 check_ed (e2, d1);
1917}
1918
1919#endif
1920
1921
1826/** 1922/**
1827 * Handle KX_AUTH message. 1923 * Handle KX_AUTH message.
1828 * 1924 *
@@ -1852,8 +1948,9 @@ GCT_handle_kx_auth (struct CadetTConnection *ct,
1852 return; 1948 return;
1853 } 1949 }
1854 LOG (GNUNET_ERROR_TYPE_DEBUG, 1950 LOG (GNUNET_ERROR_TYPE_DEBUG,
1855 "Handling KX_AUTH message for %s\n", 1951 "Handling KX_AUTH message from %s with ephemeral %s\n",
1856 GCT_2s (t)); 1952 GCT_2s (t),
1953 GNUNET_e2s (&msg->kx.ephemeral_key));
1857 /* We do everything in ax_tmp until we've checked the authentication 1954 /* We do everything in ax_tmp until we've checked the authentication
1858 so we don't clobber anything we care about by accident. */ 1955 so we don't clobber anything we care about by accident. */
1859 ax_tmp = t->ax; 1956 ax_tmp = t->ax;
@@ -1889,6 +1986,32 @@ GCT_handle_kx_auth (struct CadetTConnection *ct,
1889 GNUNET_NO); 1986 GNUNET_NO);
1890 LOG (GNUNET_ERROR_TYPE_WARNING, 1987 LOG (GNUNET_ERROR_TYPE_WARNING,
1891 "KX AUTH missmatch!\n"); 1988 "KX AUTH missmatch!\n");
1989#if DEBUG_KX
1990 {
1991 struct GNUNET_CRYPTO_EcdhePublicKey ephemeral_key;
1992
1993 GNUNET_CRYPTO_ecdhe_key_get_public (&ax_tmp.kx_0,
1994 &ephemeral_key);
1995 if (0 != memcmp (&ephemeral_key,
1996 &msg->r_ephemeral_key_XXX,
1997 sizeof (ephemeral_key)))
1998 {
1999 LOG (GNUNET_ERROR_TYPE_WARNING,
2000 "My ephemeral is %s!\n",
2001 GNUNET_e2s (&ephemeral_key));
2002 LOG (GNUNET_ERROR_TYPE_WARNING,
2003 "Response is for ephemeral %s!\n",
2004 GNUNET_e2s (&msg->r_ephemeral_key_XXX));
2005 }
2006 else
2007 {
2008 test_crypto_bug (&ax_tmp.kx_0,
2009 &msg->kx.ephemeral_key_XXX,
2010 my_private_key,
2011 &msg->kx.private_key_XXX);
2012 }
2013 }
2014#endif
1892 if (NULL == t->kx_task) 2015 if (NULL == t->kx_task)
1893 t->kx_task 2016 t->kx_task
1894 = GNUNET_SCHEDULER_add_at (t->next_kx_attempt, 2017 = GNUNET_SCHEDULER_add_at (t->next_kx_attempt,
@@ -2301,6 +2424,8 @@ connection_ready_cb (void *cls,
2301 /* Do not begin KX if WE have no channels waiting! */ 2424 /* Do not begin KX if WE have no channels waiting! */
2302 if (0 == GCT_count_channels (t)) 2425 if (0 == GCT_count_channels (t))
2303 return; 2426 return;
2427 if (0 != GNUNET_TIME_absolute_get_remaining (t->next_kx_attempt).rel_value_us)
2428 return; /* wait for timeout before retrying */
2304 /* We are uninitialized, just transmit immediately, 2429 /* We are uninitialized, just transmit immediately,
2305 without undue delay. */ 2430 without undue delay. */
2306 if (NULL != t->kx_task) 2431 if (NULL != t->kx_task)
@@ -2326,6 +2451,8 @@ connection_ready_cb (void *cls,
2326 case CADET_TUNNEL_KEY_OK: 2451 case CADET_TUNNEL_KEY_OK:
2327 if (GNUNET_YES == t->kx_auth_requested) 2452 if (GNUNET_YES == t->kx_auth_requested)
2328 { 2453 {
2454 if (0 != GNUNET_TIME_absolute_get_remaining (t->next_kx_attempt).rel_value_us)
2455 return; /* wait for timeout */
2329 if (NULL != t->kx_task) 2456 if (NULL != t->kx_task)
2330 { 2457 {
2331 GNUNET_SCHEDULER_cancel (t->kx_task); 2458 GNUNET_SCHEDULER_cancel (t->kx_task);
@@ -2433,15 +2560,21 @@ evaluate_connection (void *cls,
2433{ 2560{
2434 struct EvaluationSummary *es = cls; 2561 struct EvaluationSummary *es = cls;
2435 struct CadetConnection *cc = ct->cc; 2562 struct CadetConnection *cc = ct->cc;
2436 struct CadetPeerPath *ps = GCC_get_path (cc); 2563 unsigned int ct_length;
2564 struct CadetPeerPath *ps;
2437 const struct CadetConnectionMetrics *metrics; 2565 const struct CadetConnectionMetrics *metrics;
2438 GNUNET_CONTAINER_HeapCostType ct_desirability; 2566 GNUNET_CONTAINER_HeapCostType ct_desirability;
2439 struct GNUNET_TIME_Relative uptime; 2567 struct GNUNET_TIME_Relative uptime;
2440 struct GNUNET_TIME_Relative last_use; 2568 struct GNUNET_TIME_Relative last_use;
2441 uint32_t ct_length;
2442 double score; 2569 double score;
2443 double success_rate; 2570 double success_rate;
2444 2571
2572 ps = GCC_get_path (cc,
2573 &ct_length);
2574 LOG (GNUNET_ERROR_TYPE_DEBUG,
2575 "Evaluating path %s of existing %s\n",
2576 GCPP_2s (ps),
2577 GCC_2s (cc));
2445 if (ps == es->path) 2578 if (ps == es->path)
2446 { 2579 {
2447 LOG (GNUNET_ERROR_TYPE_DEBUG, 2580 LOG (GNUNET_ERROR_TYPE_DEBUG,
@@ -2450,8 +2583,39 @@ evaluate_connection (void *cls,
2450 es->duplicate = GNUNET_YES; 2583 es->duplicate = GNUNET_YES;
2451 return; 2584 return;
2452 } 2585 }
2586 if (NULL != es->path)
2587 {
2588 int duplicate = GNUNET_YES;
2589
2590 for (unsigned int i=0;i<ct_length;i++)
2591 {
2592 GNUNET_assert (GCPP_get_length (es->path) > i);
2593 if (GCPP_get_peer_at_offset (es->path,
2594 i) !=
2595 GCPP_get_peer_at_offset (ps,
2596 i))
2597 {
2598 duplicate = GNUNET_NO;
2599 break;
2600 }
2601 }
2602 if (GNUNET_YES == duplicate)
2603 {
2604 LOG (GNUNET_ERROR_TYPE_DEBUG,
2605 "Ignoring overlapping path %s.\n",
2606 GCPP_2s (es->path));
2607 es->duplicate = GNUNET_YES;
2608 return;
2609 }
2610 else
2611 {
2612 LOG (GNUNET_ERROR_TYPE_DEBUG,
2613 "Known path %s differs from proposed path\n",
2614 GCPP_2s (ps));
2615 }
2616 }
2617
2453 ct_desirability = GCPP_get_desirability (ps); 2618 ct_desirability = GCPP_get_desirability (ps);
2454 ct_length = GCPP_get_length (ps);
2455 metrics = GCC_get_metrics (cc); 2619 metrics = GCC_get_metrics (cc);
2456 uptime = GNUNET_TIME_absolute_get_duration (metrics->age); 2620 uptime = GNUNET_TIME_absolute_get_duration (metrics->age);
2457 last_use = GNUNET_TIME_absolute_get_duration (metrics->last_use); 2621 last_use = GNUNET_TIME_absolute_get_duration (metrics->last_use);
@@ -2500,6 +2664,8 @@ consider_path_cb (void *cls,
2500 struct CadetTConnection *ct; 2664 struct CadetTConnection *ct;
2501 2665
2502 GNUNET_assert (off < GCPP_get_length (path)); 2666 GNUNET_assert (off < GCPP_get_length (path));
2667 GNUNET_assert (GCPP_get_peer_at_offset (path,
2668 off) == t->destination);
2503 es.min_length = UINT_MAX; 2669 es.min_length = UINT_MAX;
2504 es.max_length = 0; 2670 es.max_length = 0;
2505 es.max_desire = 0; 2671 es.max_desire = 0;
@@ -2509,6 +2675,13 @@ consider_path_cb (void *cls,
2509 es.worst = NULL; 2675 es.worst = NULL;
2510 2676
2511 /* Compute evaluation summary over existing connections. */ 2677 /* Compute evaluation summary over existing connections. */
2678 LOG (GNUNET_ERROR_TYPE_DEBUG,
2679 "Evaluating proposed path %s for target %s\n",
2680 GCPP_2s (path),
2681 GCT_2s (t));
2682 /* FIXME: suspect this does not ACTUALLY iterate
2683 over all existing paths, otherwise dup detection
2684 should work!!! */
2512 GCT_iterate_connections (t, 2685 GCT_iterate_connections (t,
2513 &evaluate_connection, 2686 &evaluate_connection,
2514 &es); 2687 &es);
@@ -2653,9 +2826,10 @@ GCT_consider_path (struct CadetTunnel *t,
2653 unsigned int off) 2826 unsigned int off)
2654{ 2827{
2655 LOG (GNUNET_ERROR_TYPE_DEBUG, 2828 LOG (GNUNET_ERROR_TYPE_DEBUG,
2656 "Considering %s for %s\n", 2829 "Considering %s for %s (offset %u)\n",
2657 GCPP_2s (p), 2830 GCPP_2s (p),
2658 GCT_2s (t)); 2831 GCT_2s (t),
2832 off);
2659 (void) consider_path_cb (t, 2833 (void) consider_path_cb (t,
2660 p, 2834 p,
2661 off); 2835 off);