aboutsummaryrefslogtreecommitdiff
path: root/src/cadet/gnunet-service-cadet_channel.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2017-03-26 04:14:43 +0200
committerChristian Grothoff <christian@grothoff.org>2017-03-26 04:14:43 +0200
commit7978b76868ba81efaa4b65b47a54ee55cd092382 (patch)
tree7248f8a1c07364ba66435fe31d915e50df138d4c /src/cadet/gnunet-service-cadet_channel.c
parent9cfc671375ef346c3ff40fbcdd7c2c090972072a (diff)
downloadgnunet-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.c106
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 */
422void
423GCCH_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 */
716struct CadetChannel * 756struct CadetChannel *
717GCCH_channel_incoming_new (struct CadetTunnel *t, 757GCCH_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
830send_open_ack (void *cls) 871send_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 */
933void 976void
934GCCH_bind (struct CadetChannel *ch, 977GCCH_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 */
1115void 1163void
1116GCCH_handle_channel_open_ack (struct CadetChannel *ch, 1164GCCH_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));