aboutsummaryrefslogtreecommitdiff
path: root/src/cadet/gnunet-service-cadet_connection.c
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/gnunet-service-cadet_connection.c
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/gnunet-service-cadet_connection.c')
-rw-r--r--src/cadet/gnunet-service-cadet_connection.c96
1 files changed, 69 insertions, 27 deletions
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