aboutsummaryrefslogtreecommitdiff
path: root/src/cadet/gnunet-service-cadet_connection.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cadet/gnunet-service-cadet_connection.c')
-rw-r--r--src/cadet/gnunet-service-cadet_connection.c114
1 files changed, 77 insertions, 37 deletions
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