diff options
Diffstat (limited to 'src/cadet/gnunet-service-cadet_connection.c')
-rw-r--r-- | src/cadet/gnunet-service-cadet_connection.c | 114 |
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 | */ |
44 | enum CadetConnectionState | 49 | enum 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 | |||
525 | GCC_handle_kx (struct CadetConnection *cc, | 541 | GCC_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 | |||
549 | GCC_handle_kx_auth (struct CadetConnection *cc, | 570 | GCC_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 | */ |
1006 | struct CadetPeerPath * | 1044 | struct CadetPeerPath * |
1007 | GCC_get_path (struct CadetConnection *cc) | 1045 | GCC_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 | ||