diff options
author | Christian Grothoff <christian@grothoff.org> | 2017-03-26 04:14:43 +0200 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2017-03-26 04:14:43 +0200 |
commit | 7978b76868ba81efaa4b65b47a54ee55cd092382 (patch) | |
tree | 7248f8a1c07364ba66435fe31d915e50df138d4c /src/cadet/gnunet-service-cadet_channel.c | |
parent | 9cfc671375ef346c3ff40fbcdd7c2c090972072a (diff) | |
download | gnunet-7978b76868ba81efaa4b65b47a54ee55cd092382.tar.gz gnunet-7978b76868ba81efaa4b65b47a54ee55cd092382.zip |
implement #4973
Diffstat (limited to 'src/cadet/gnunet-service-cadet_channel.c')
-rw-r--r-- | src/cadet/gnunet-service-cadet_channel.c | 106 |
1 files changed, 82 insertions, 24 deletions
diff --git a/src/cadet/gnunet-service-cadet_channel.c b/src/cadet/gnunet-service-cadet_channel.c index 68e29b66b..739b68228 100644 --- a/src/cadet/gnunet-service-cadet_channel.c +++ b/src/cadet/gnunet-service-cadet_channel.c | |||
@@ -303,6 +303,11 @@ struct CadetChannel | |||
303 | struct GNUNET_HashCode port; | 303 | struct GNUNET_HashCode port; |
304 | 304 | ||
305 | /** | 305 | /** |
306 | * Hash'ed port of the channel with initiator and destination PID. | ||
307 | */ | ||
308 | struct GNUNET_HashCode h_port; | ||
309 | |||
310 | /** | ||
306 | * Counter for exponential backoff. | 311 | * Counter for exponential backoff. |
307 | */ | 312 | */ |
308 | struct GNUNET_TIME_Relative retry_time; | 313 | struct GNUNET_TIME_Relative retry_time; |
@@ -406,6 +411,37 @@ GCCH_2s (const struct CadetChannel *ch) | |||
406 | 411 | ||
407 | 412 | ||
408 | /** | 413 | /** |
414 | * Hash the @a port and @a initiator and @a listener to | ||
415 | * calculate the "challenge" @a h_port we send to the other | ||
416 | * peer on #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN. | ||
417 | * | ||
418 | * @param[out] h_port set to the hash of @a port, @a initiator and @a listener | ||
419 | * @param port cadet port, as seen by CADET clients | ||
420 | * @param listener peer that is listining on @a port | ||
421 | */ | ||
422 | void | ||
423 | GCCH_hash_port (struct GNUNET_HashCode *h_port, | ||
424 | const struct GNUNET_HashCode *port, | ||
425 | const struct GNUNET_PeerIdentity *listener) | ||
426 | { | ||
427 | struct GNUNET_HashContext *hc; | ||
428 | |||
429 | hc = GNUNET_CRYPTO_hash_context_start (); | ||
430 | GNUNET_CRYPTO_hash_context_read (hc, | ||
431 | port, | ||
432 | sizeof (*port)); | ||
433 | GNUNET_CRYPTO_hash_context_read (hc, | ||
434 | listener, | ||
435 | sizeof (*listener)); | ||
436 | GNUNET_CRYPTO_hash_context_finish (hc, | ||
437 | h_port); | ||
438 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
439 | "Calculated port hash %s\n", | ||
440 | GNUNET_h2s (h_port)); | ||
441 | } | ||
442 | |||
443 | |||
444 | /** | ||
409 | * Get the channel's public ID. | 445 | * Get the channel's public ID. |
410 | * | 446 | * |
411 | * @param ch Channel. | 447 | * @param ch Channel. |
@@ -566,7 +602,7 @@ send_channel_open (void *cls) | |||
566 | msgcc.header.size = htons (sizeof (msgcc)); | 602 | msgcc.header.size = htons (sizeof (msgcc)); |
567 | msgcc.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN); | 603 | msgcc.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN); |
568 | msgcc.opt = htonl (options); | 604 | msgcc.opt = htonl (options); |
569 | msgcc.port = ch->port; | 605 | msgcc.h_port = ch->h_port; |
570 | msgcc.ctn = ch->ctn; | 606 | msgcc.ctn = ch->ctn; |
571 | ch->state = CADET_CHANNEL_OPEN_SENT; | 607 | ch->state = CADET_CHANNEL_OPEN_SENT; |
572 | if (NULL != ch->last_control_qe) | 608 | if (NULL != ch->last_control_qe) |
@@ -635,21 +671,24 @@ GCCH_channel_local_new (struct CadetClient *owner, | |||
635 | ch->max_pending_messages = (ch->nobuffer) ? 1 : 4; /* FIXME: 4!? Do not hardcode! */ | 671 | ch->max_pending_messages = (ch->nobuffer) ? 1 : 4; /* FIXME: 4!? Do not hardcode! */ |
636 | ch->owner = ccco; | 672 | ch->owner = ccco; |
637 | ch->port = *port; | 673 | ch->port = *port; |
674 | GCCH_hash_port (&ch->h_port, | ||
675 | port, | ||
676 | GCP_get_id (destination)); | ||
638 | if (0 == memcmp (&my_full_id, | 677 | if (0 == memcmp (&my_full_id, |
639 | GCP_get_id (destination), | 678 | GCP_get_id (destination), |
640 | sizeof (struct GNUNET_PeerIdentity))) | 679 | sizeof (struct GNUNET_PeerIdentity))) |
641 | { | 680 | { |
642 | struct CadetClient *c; | 681 | struct OpenPort *op; |
643 | 682 | ||
644 | ch->is_loopback = GNUNET_YES; | 683 | ch->is_loopback = GNUNET_YES; |
645 | c = GNUNET_CONTAINER_multihashmap_get (open_ports, | 684 | op = GNUNET_CONTAINER_multihashmap_get (open_ports, |
646 | port); | 685 | &ch->h_port); |
647 | if (NULL == c) | 686 | if (NULL == op) |
648 | { | 687 | { |
649 | /* port closed, wait for it to possibly open */ | 688 | /* port closed, wait for it to possibly open */ |
650 | ch->state = CADET_CHANNEL_LOOSE; | 689 | ch->state = CADET_CHANNEL_LOOSE; |
651 | (void) GNUNET_CONTAINER_multihashmap_put (loose_channels, | 690 | (void) GNUNET_CONTAINER_multihashmap_put (loose_channels, |
652 | port, | 691 | &ch->h_port, |
653 | ch, | 692 | ch, |
654 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); | 693 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); |
655 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 694 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
@@ -659,7 +698,8 @@ GCCH_channel_local_new (struct CadetClient *owner, | |||
659 | else | 698 | else |
660 | { | 699 | { |
661 | GCCH_bind (ch, | 700 | GCCH_bind (ch, |
662 | c); | 701 | op->c, |
702 | &op->port); | ||
663 | } | 703 | } |
664 | } | 704 | } |
665 | else | 705 | else |
@@ -709,21 +749,21 @@ timeout_closed_cb (void *cls) | |||
709 | * | 749 | * |
710 | * @param t tunnel to the remote peer | 750 | * @param t tunnel to the remote peer |
711 | * @param ctn identifier of this channel in the tunnel | 751 | * @param ctn identifier of this channel in the tunnel |
712 | * @param port desired local port | 752 | * @param h_port desired hash of local port |
713 | * @param options options for the channel | 753 | * @param options options for the channel |
714 | * @return handle to the new channel | 754 | * @return handle to the new channel |
715 | */ | 755 | */ |
716 | struct CadetChannel * | 756 | struct CadetChannel * |
717 | GCCH_channel_incoming_new (struct CadetTunnel *t, | 757 | GCCH_channel_incoming_new (struct CadetTunnel *t, |
718 | struct GNUNET_CADET_ChannelTunnelNumber ctn, | 758 | struct GNUNET_CADET_ChannelTunnelNumber ctn, |
719 | const struct GNUNET_HashCode *port, | 759 | const struct GNUNET_HashCode *h_port, |
720 | uint32_t options) | 760 | uint32_t options) |
721 | { | 761 | { |
722 | struct CadetChannel *ch; | 762 | struct CadetChannel *ch; |
723 | struct CadetClient *c; | 763 | struct OpenPort *op; |
724 | 764 | ||
725 | ch = GNUNET_new (struct CadetChannel); | 765 | ch = GNUNET_new (struct CadetChannel); |
726 | ch->port = *port; | 766 | ch->h_port = *h_port; |
727 | ch->t = t; | 767 | ch->t = t; |
728 | ch->ctn = ctn; | 768 | ch->ctn = ctn; |
729 | ch->retry_time = CADET_INITIAL_RETRANSMIT_TIME; | 769 | ch->retry_time = CADET_INITIAL_RETRANSMIT_TIME; |
@@ -736,14 +776,14 @@ GCCH_channel_incoming_new (struct CadetTunnel *t, | |||
736 | 1, | 776 | 1, |
737 | GNUNET_NO); | 777 | GNUNET_NO); |
738 | 778 | ||
739 | c = GNUNET_CONTAINER_multihashmap_get (open_ports, | 779 | op = GNUNET_CONTAINER_multihashmap_get (open_ports, |
740 | port); | 780 | h_port); |
741 | if (NULL == c) | 781 | if (NULL == op) |
742 | { | 782 | { |
743 | /* port closed, wait for it to possibly open */ | 783 | /* port closed, wait for it to possibly open */ |
744 | ch->state = CADET_CHANNEL_LOOSE; | 784 | ch->state = CADET_CHANNEL_LOOSE; |
745 | (void) GNUNET_CONTAINER_multihashmap_put (loose_channels, | 785 | (void) GNUNET_CONTAINER_multihashmap_put (loose_channels, |
746 | port, | 786 | &ch->h_port, |
747 | ch, | 787 | ch, |
748 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); | 788 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); |
749 | GNUNET_assert (NULL == ch->retry_control_task); | 789 | GNUNET_assert (NULL == ch->retry_control_task); |
@@ -759,7 +799,8 @@ GCCH_channel_incoming_new (struct CadetTunnel *t, | |||
759 | else | 799 | else |
760 | { | 800 | { |
761 | GCCH_bind (ch, | 801 | GCCH_bind (ch, |
762 | c); | 802 | op->c, |
803 | &op->port); | ||
763 | } | 804 | } |
764 | GNUNET_STATISTICS_update (stats, | 805 | GNUNET_STATISTICS_update (stats, |
765 | "# channels", | 806 | "# channels", |
@@ -830,7 +871,7 @@ static void | |||
830 | send_open_ack (void *cls) | 871 | send_open_ack (void *cls) |
831 | { | 872 | { |
832 | struct CadetChannel *ch = cls; | 873 | struct CadetChannel *ch = cls; |
833 | struct GNUNET_CADET_ChannelManageMessage msg; | 874 | struct GNUNET_CADET_ChannelOpenAckMessage msg; |
834 | 875 | ||
835 | ch->retry_control_task = NULL; | 876 | ch->retry_control_task = NULL; |
836 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 877 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
@@ -840,6 +881,7 @@ send_open_ack (void *cls) | |||
840 | msg.header.size = htons (sizeof (msg)); | 881 | msg.header.size = htons (sizeof (msg)); |
841 | msg.reserved = htonl (0); | 882 | msg.reserved = htonl (0); |
842 | msg.ctn = ch->ctn; | 883 | msg.ctn = ch->ctn; |
884 | msg.port = ch->port; | ||
843 | if (NULL != ch->last_control_qe) | 885 | if (NULL != ch->last_control_qe) |
844 | GCT_send_cancel (ch->last_control_qe); | 886 | GCT_send_cancel (ch->last_control_qe); |
845 | ch->last_control_qe = GCT_send (ch->t, | 887 | ch->last_control_qe = GCT_send (ch->t, |
@@ -928,11 +970,13 @@ send_ack_to_client (struct CadetChannel *ch, | |||
928 | * request and establish the link with the client. | 970 | * request and establish the link with the client. |
929 | * | 971 | * |
930 | * @param ch open incoming channel | 972 | * @param ch open incoming channel |
931 | * @param c client listening on the respective port | 973 | * @param c client listening on the respective @a port |
974 | * @param port the port @a is listening on | ||
932 | */ | 975 | */ |
933 | void | 976 | void |
934 | GCCH_bind (struct CadetChannel *ch, | 977 | GCCH_bind (struct CadetChannel *ch, |
935 | struct CadetClient *c) | 978 | struct CadetClient *c, |
979 | const struct GNUNET_HashCode *port) | ||
936 | { | 980 | { |
937 | uint32_t options; | 981 | uint32_t options; |
938 | struct CadetChannelClient *cccd; | 982 | struct CadetChannelClient *cccd; |
@@ -959,6 +1003,7 @@ GCCH_bind (struct CadetChannel *ch, | |||
959 | cccd = GNUNET_new (struct CadetChannelClient); | 1003 | cccd = GNUNET_new (struct CadetChannelClient); |
960 | GNUNET_assert (NULL == ch->dest); | 1004 | GNUNET_assert (NULL == ch->dest); |
961 | ch->dest = cccd; | 1005 | ch->dest = cccd; |
1006 | ch->port = *port; | ||
962 | cccd->c = c; | 1007 | cccd->c = c; |
963 | cccd->client_ready = GNUNET_YES; | 1008 | cccd->client_ready = GNUNET_YES; |
964 | cccd->ccn = GSC_bind (c, | 1009 | cccd->ccn = GSC_bind (c, |
@@ -967,7 +1012,7 @@ GCCH_bind (struct CadetChannel *ch, | |||
967 | ? GCP_get (&my_full_id, | 1012 | ? GCP_get (&my_full_id, |
968 | GNUNET_YES) | 1013 | GNUNET_YES) |
969 | : GCT_get_destination (ch->t), | 1014 | : GCT_get_destination (ch->t), |
970 | &ch->port, | 1015 | port, |
971 | options); | 1016 | options); |
972 | GNUNET_assert (ntohl (cccd->ccn.channel_of_client) < | 1017 | GNUNET_assert (ntohl (cccd->ccn.channel_of_client) < |
973 | GNUNET_CADET_LOCAL_CHANNEL_ID_CLI); | 1018 | GNUNET_CADET_LOCAL_CHANNEL_ID_CLI); |
@@ -976,7 +1021,8 @@ GCCH_bind (struct CadetChannel *ch, | |||
976 | { | 1021 | { |
977 | ch->state = CADET_CHANNEL_OPEN_SENT; | 1022 | ch->state = CADET_CHANNEL_OPEN_SENT; |
978 | GCCH_handle_channel_open_ack (ch, | 1023 | GCCH_handle_channel_open_ack (ch, |
979 | NULL); | 1024 | NULL, |
1025 | port); | ||
980 | } | 1026 | } |
981 | else | 1027 | else |
982 | { | 1028 | { |
@@ -1092,7 +1138,7 @@ GCCH_channel_local_destroy (struct CadetChannel *ch, | |||
1092 | target, but that never went anywhere. Nothing to do here. */ | 1138 | target, but that never went anywhere. Nothing to do here. */ |
1093 | break; | 1139 | break; |
1094 | case CADET_CHANNEL_LOOSE: | 1140 | case CADET_CHANNEL_LOOSE: |
1095 | GSC_drop_loose_channel (&ch->port, | 1141 | GSC_drop_loose_channel (&ch->h_port, |
1096 | ch); | 1142 | ch); |
1097 | break; | 1143 | break; |
1098 | default: | 1144 | default: |
@@ -1107,14 +1153,17 @@ GCCH_channel_local_destroy (struct CadetChannel *ch, | |||
1107 | 1153 | ||
1108 | /** | 1154 | /** |
1109 | * We got an acknowledgement for the creation of the channel | 1155 | * We got an acknowledgement for the creation of the channel |
1110 | * (the port is open on the other side). Begin transmissions. | 1156 | * (the port is open on the other side). Verify that the |
1157 | * other end really has the right port, and begin transmissions. | ||
1111 | * | 1158 | * |
1112 | * @param ch channel to destroy | 1159 | * @param ch channel to destroy |
1113 | * @param cti identifier of the connection that delivered the message | 1160 | * @param cti identifier of the connection that delivered the message |
1161 | * @param port port number (needed to verify receiver knows the port) | ||
1114 | */ | 1162 | */ |
1115 | void | 1163 | void |
1116 | GCCH_handle_channel_open_ack (struct CadetChannel *ch, | 1164 | GCCH_handle_channel_open_ack (struct CadetChannel *ch, |
1117 | const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti) | 1165 | const struct GNUNET_CADET_ConnectionTunnelIdentifier *cti, |
1166 | const struct GNUNET_HashCode *port) | ||
1118 | { | 1167 | { |
1119 | switch (ch->state) | 1168 | switch (ch->state) |
1120 | { | 1169 | { |
@@ -1133,6 +1182,15 @@ GCCH_handle_channel_open_ack (struct CadetChannel *ch, | |||
1133 | GNUNET_break_op (0); | 1182 | GNUNET_break_op (0); |
1134 | return; | 1183 | return; |
1135 | } | 1184 | } |
1185 | if (0 != memcmp (&ch->port, | ||
1186 | port, | ||
1187 | sizeof (struct GNUNET_HashCode))) | ||
1188 | { | ||
1189 | /* Other peer failed to provide the right port, | ||
1190 | refuse connection. */ | ||
1191 | GNUNET_break_op (0); | ||
1192 | return; | ||
1193 | } | ||
1136 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1194 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1137 | "Received CHANNEL_OPEN_ACK for waiting %s, entering READY state\n", | 1195 | "Received CHANNEL_OPEN_ACK for waiting %s, entering READY state\n", |
1138 | GCCH_2s (ch)); | 1196 | GCCH_2s (ch)); |