aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2017-01-22 22:30:58 +0100
committerChristian Grothoff <christian@grothoff.org>2017-01-22 22:30:58 +0100
commit37b981ae53b24155cc237eb1650c3457768d7c54 (patch)
treedc16daf51925a61c946dd0288f752bb95382b23e
parentfdaf23f67b365e78c06724ae6c48464d5131d4e1 (diff)
downloadgnunet-37b981ae53b24155cc237eb1650c3457768d7c54.tar.gz
gnunet-37b981ae53b24155cc237eb1650c3457768d7c54.zip
correctly handle assignment of cid during channel open, send channel open ack, and detect duplicate open
-rw-r--r--src/cadet/gnunet-service-cadet-new_channel.c124
-rw-r--r--src/cadet/gnunet-service-cadet-new_channel.h11
-rw-r--r--src/cadet/gnunet-service-cadet-new_tunnels.c65
3 files changed, 148 insertions, 52 deletions
diff --git a/src/cadet/gnunet-service-cadet-new_channel.c b/src/cadet/gnunet-service-cadet-new_channel.c
index 425422cb6..08704152b 100644
--- a/src/cadet/gnunet-service-cadet-new_channel.c
+++ b/src/cadet/gnunet-service-cadet-new_channel.c
@@ -212,7 +212,12 @@ struct CadetChannel
212 /** 212 /**
213 * Task to resend/poll in case no ACK is received. 213 * Task to resend/poll in case no ACK is received.
214 */ 214 */
215 struct GNUNET_SCHEDULER_Task *retry_task; 215 struct GNUNET_SCHEDULER_Task *retry_control_task;
216
217 /**
218 * Task to resend/poll in case no ACK is received.
219 */
220 struct GNUNET_SCHEDULER_Task *retry_data_task;
216 221
217 /** 222 /**
218 * Last time the channel was used 223 * Last time the channel was used
@@ -385,10 +390,15 @@ channel_destroy (struct CadetChannel *ch)
385 GCT_send_cancel (ch->last_control_qe); 390 GCT_send_cancel (ch->last_control_qe);
386 ch->last_control_qe = NULL; 391 ch->last_control_qe = NULL;
387 } 392 }
388 if (NULL != ch->retry_task) 393 if (NULL != ch->retry_data_task)
394 {
395 GNUNET_SCHEDULER_cancel (ch->retry_data_task);
396 ch->retry_data_task = NULL;
397 }
398 if (NULL != ch->retry_control_task)
389 { 399 {
390 GNUNET_SCHEDULER_cancel (ch->retry_task); 400 GNUNET_SCHEDULER_cancel (ch->retry_control_task);
391 ch->retry_task = NULL; 401 ch->retry_control_task = NULL;
392 } 402 }
393 GCT_remove_channel (ch->t, 403 GCT_remove_channel (ch->t,
394 ch, 404 ch,
@@ -420,9 +430,10 @@ channel_open_sent_cb (void *cls)
420 GNUNET_assert (NULL != ch->last_control_qe); 430 GNUNET_assert (NULL != ch->last_control_qe);
421 ch->last_control_qe = NULL; 431 ch->last_control_qe = NULL;
422 ch->retry_time = GNUNET_TIME_STD_BACKOFF (ch->retry_time); 432 ch->retry_time = GNUNET_TIME_STD_BACKOFF (ch->retry_time);
423 ch->retry_task = GNUNET_SCHEDULER_add_delayed (ch->retry_time, 433 ch->retry_control_task
424 &send_channel_open, 434 = GNUNET_SCHEDULER_add_delayed (ch->retry_time,
425 ch); 435 &send_channel_open,
436 ch);
426} 437}
427 438
428 439
@@ -438,7 +449,7 @@ send_channel_open (void *cls)
438 struct GNUNET_CADET_ChannelOpenMessage msgcc; 449 struct GNUNET_CADET_ChannelOpenMessage msgcc;
439 uint32_t options; 450 uint32_t options;
440 451
441 ch->retry_task = NULL; 452 ch->retry_control_task = NULL;
442 LOG (GNUNET_ERROR_TYPE_DEBUG, 453 LOG (GNUNET_ERROR_TYPE_DEBUG,
443 "Sending CHANNEL_OPEN message for %s\n", 454 "Sending CHANNEL_OPEN message for %s\n",
444 GCCH_2s (ch)); 455 GCCH_2s (ch));
@@ -475,9 +486,10 @@ send_channel_open (void *cls)
475void 486void
476GCCH_tunnel_up (struct CadetChannel *ch) 487GCCH_tunnel_up (struct CadetChannel *ch)
477{ 488{
478 GNUNET_assert (NULL == ch->retry_task); 489 GNUNET_assert (NULL == ch->retry_control_task);
479 ch->retry_task = GNUNET_SCHEDULER_add_now (&send_channel_open, 490 ch->retry_control_task
480 ch); 491 = GNUNET_SCHEDULER_add_now (&send_channel_open,
492 ch);
481} 493}
482 494
483 495
@@ -518,7 +530,7 @@ GCCH_channel_local_new (struct CadetClient *owner,
518 1, 530 1,
519 GNUNET_NO); 531 GNUNET_NO);
520 LOG (GNUNET_ERROR_TYPE_DEBUG, 532 LOG (GNUNET_ERROR_TYPE_DEBUG,
521 "Created channel to port %s at peer %s for client %s using tunnel %s\n", 533 "Created channel to port %s at peer %s for %s using %s\n",
522 GNUNET_h2s (port), 534 GNUNET_h2s (port),
523 GCP_2s (destination), 535 GCP_2s (destination),
524 GSC_2s (owner), 536 GSC_2s (owner),
@@ -538,7 +550,7 @@ timeout_closed_cb (void *cls)
538{ 550{
539 struct CadetChannel *ch = cls; 551 struct CadetChannel *ch = cls;
540 552
541 ch->retry_task = NULL; 553 ch->retry_control_task = NULL;
542 LOG (GNUNET_ERROR_TYPE_DEBUG, 554 LOG (GNUNET_ERROR_TYPE_DEBUG,
543 "Closing incoming channel to port %s from peer %s due to timeout\n", 555 "Closing incoming channel to port %s from peer %s due to timeout\n",
544 GNUNET_h2s (&ch->port), 556 GNUNET_h2s (&ch->port),
@@ -588,9 +600,10 @@ GCCH_channel_incoming_new (struct CadetTunnel *t,
588 port, 600 port,
589 ch, 601 ch,
590 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); 602 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
591 ch->retry_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT_CLOSED_PORT, 603 ch->retry_control_task
592 &timeout_closed_cb, 604 = GNUNET_SCHEDULER_add_delayed (TIMEOUT_CLOSED_PORT,
593 ch); 605 &timeout_closed_cb,
606 ch);
594 LOG (GNUNET_ERROR_TYPE_DEBUG, 607 LOG (GNUNET_ERROR_TYPE_DEBUG,
595 "Created loose incoming channel to port %s from peer %s\n", 608 "Created loose incoming channel to port %s from peer %s\n",
596 GNUNET_h2s (&ch->port), 609 GNUNET_h2s (&ch->port),
@@ -657,12 +670,55 @@ send_channel_data_ack (struct CadetChannel *ch)
657 * @param cls the `struct CadetChannel` 670 * @param cls the `struct CadetChannel`
658 */ 671 */
659static void 672static void
660send_connect_ack (void *cls) 673send_open_ack (void *cls)
661{ 674{
662 struct CadetChannel *ch = cls; 675 struct CadetChannel *ch = cls;
676 struct GNUNET_CADET_ChannelManageMessage msg;
677
678 LOG (GNUNET_ERROR_TYPE_DEBUG,
679 "Sending CHANNEL_OPEN_ACK on channel %s\n",
680 GCCH_2s (ch));
681 ch->retry_control_task = NULL;
682 msg.header.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK);
683 msg.header.size = htons (sizeof (msg));
684 msg.reserved = htonl (0);
685 msg.ctn = ch->ctn;
686 if (NULL != ch->last_control_qe)
687 GCT_send_cancel (ch->last_control_qe);
688 ch->last_control_qe = GCT_send (ch->t,
689 &msg.header,
690 &send_ack_cb,
691 ch);
692}
663 693
664 ch->retry_task = NULL; 694
665 send_channel_data_ack (ch); 695/**
696 * We got a #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN message again for
697 * this channel. If the binding was successful, (re)transmit the
698 * #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK.
699 *
700 * @param ch channel that got the duplicate open
701 */
702void
703GCCH_handle_duplicate_open (struct CadetChannel *ch)
704{
705 if (NULL == ch->dest)
706 {
707 LOG (GNUNET_ERROR_TYPE_DEBUG,
708 "Ignoring duplicate channel OPEN on %s: port is closed\n",
709 GCCH_2s (ch));
710 return;
711 }
712 if (NULL != ch->retry_control_task)
713 {
714 LOG (GNUNET_ERROR_TYPE_DEBUG,
715 "Ignoring duplicate channel OPEN on %s: control message is pending\n",
716 GCCH_2s (ch));
717 return;
718 }
719 ch->retry_control_task
720 = GNUNET_SCHEDULER_add_now (&send_open_ack,
721 ch);
666} 722}
667 723
668 724
@@ -704,16 +760,16 @@ GCCH_bind (struct CadetChannel *ch,
704 uint32_t options; 760 uint32_t options;
705 761
706 LOG (GNUNET_ERROR_TYPE_DEBUG, 762 LOG (GNUNET_ERROR_TYPE_DEBUG,
707 "Binding %s from tunnel %s to port %s of client %s\n", 763 "Binding %s from %s to port %s of %s\n",
708 GCCH_2s (ch), 764 GCCH_2s (ch),
709 GCT_2s (ch->t), 765 GCT_2s (ch->t),
710 GNUNET_h2s (&ch->port), 766 GNUNET_h2s (&ch->port),
711 GSC_2s (c)); 767 GSC_2s (c));
712 if (NULL != ch->retry_task) 768 if (NULL != ch->retry_control_task)
713 { 769 {
714 /* there might be a timeout task here */ 770 /* there might be a timeout task here */
715 GNUNET_SCHEDULER_cancel (ch->retry_task); 771 GNUNET_SCHEDULER_cancel (ch->retry_control_task);
716 ch->retry_task = NULL; 772 ch->retry_control_task = NULL;
717 } 773 }
718 options = 0; 774 options = 0;
719 if (ch->nobuffer) 775 if (ch->nobuffer)
@@ -731,8 +787,9 @@ GCCH_bind (struct CadetChannel *ch,
731 ch->mid_recv.mid = htonl (1); /* The CONNECT counts as message 0! */ 787 ch->mid_recv.mid = htonl (1); /* The CONNECT counts as message 0! */
732 788
733 /* notify other peer that we accepted the connection */ 789 /* notify other peer that we accepted the connection */
734 ch->retry_task = GNUNET_SCHEDULER_add_now (&send_connect_ack, 790 ch->retry_control_task
735 ch); 791 = GNUNET_SCHEDULER_add_now (&send_open_ack,
792 ch);
736 /* give client it's initial supply of ACKs */ 793 /* give client it's initial supply of ACKs */
737 env = GNUNET_MQ_msg (tcm, 794 env = GNUNET_MQ_msg (tcm,
738 GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_CREATE); 795 GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_CREATE);
@@ -833,8 +890,8 @@ GCCH_handle_channel_open_ack (struct CadetChannel *ch)
833 LOG (GNUNET_ERROR_TYPE_DEBUG, 890 LOG (GNUNET_ERROR_TYPE_DEBUG,
834 "Received channel OPEN_ACK for waiting %s, entering READY state\n", 891 "Received channel OPEN_ACK for waiting %s, entering READY state\n",
835 GCCH_2s (ch)); 892 GCCH_2s (ch));
836 GNUNET_SCHEDULER_cancel (ch->retry_task); 893 GNUNET_SCHEDULER_cancel (ch->retry_control_task);
837 ch->retry_task = NULL; 894 ch->retry_control_task = NULL;
838 ch->state = CADET_CHANNEL_READY; 895 ch->state = CADET_CHANNEL_READY;
839 /* On first connect, send client as many ACKs as we allow messages 896 /* On first connect, send client as many ACKs as we allow messages
840 to be buffered! */ 897 to be buffered! */
@@ -1062,7 +1119,7 @@ retry_transmission (void *cls)
1062 struct CadetChannel *ch = cls; 1119 struct CadetChannel *ch = cls;
1063 struct CadetReliableMessage *crm = ch->head_sent; 1120 struct CadetReliableMessage *crm = ch->head_sent;
1064 1121
1065 ch->retry_task = NULL; 1122 ch->retry_data_task = NULL;
1066 GNUNET_assert (NULL == crm->qe); 1123 GNUNET_assert (NULL == crm->qe);
1067 crm->qe = GCT_send (ch->t, 1124 crm->qe = GCT_send (ch->t,
1068 &crm->data_message.header, 1125 &crm->data_message.header,
@@ -1161,11 +1218,12 @@ data_sent_cb (void *cls)
1161 GNUNET_CONTAINER_DLL_insert (ch->head_sent, 1218 GNUNET_CONTAINER_DLL_insert (ch->head_sent,
1162 ch->tail_sent, 1219 ch->tail_sent,
1163 crm); 1220 crm);
1164 if (NULL != ch->retry_task) 1221 if (NULL != ch->retry_data_task)
1165 GNUNET_SCHEDULER_cancel (ch->retry_task); 1222 GNUNET_SCHEDULER_cancel (ch->retry_data_task);
1166 ch->retry_task = GNUNET_SCHEDULER_add_delayed (crm->retry_delay, 1223 ch->retry_data_task
1167 &retry_transmission, 1224 = GNUNET_SCHEDULER_add_delayed (crm->retry_delay,
1168 ch); 1225 &retry_transmission,
1226 ch);
1169 return; 1227 return;
1170 } 1228 }
1171 for (off = ch->head_sent; NULL != off; off = off->next) 1229 for (off = ch->head_sent; NULL != off; off = off->next)
diff --git a/src/cadet/gnunet-service-cadet-new_channel.h b/src/cadet/gnunet-service-cadet-new_channel.h
index ae4c5da5a..d4a592518 100644
--- a/src/cadet/gnunet-service-cadet-new_channel.h
+++ b/src/cadet/gnunet-service-cadet-new_channel.h
@@ -160,6 +160,17 @@ GCCH_channel_incoming_destroy (struct CadetChannel *ch);
160 160
161 161
162/** 162/**
163 * We got a #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN message again for
164 * this channel. If the binding was successful, (re)transmit the
165 * #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK.
166 *
167 * @param ch channel that got the duplicate open
168 */
169void
170GCCH_handle_duplicate_open (struct CadetChannel *ch);
171
172
173/**
163 * We got payload data for a channel. Pass it on to the client. 174 * We got payload data for a channel. Pass it on to the client.
164 * 175 *
165 * @param ch channel that got data 176 * @param ch channel that got data
diff --git a/src/cadet/gnunet-service-cadet-new_tunnels.c b/src/cadet/gnunet-service-cadet-new_tunnels.c
index 9754040cf..20ab8f4e9 100644
--- a/src/cadet/gnunet-service-cadet-new_tunnels.c
+++ b/src/cadet/gnunet-service-cadet-new_tunnels.c
@@ -1472,19 +1472,28 @@ GCT_handle_kx (struct CadetTConnection *ct,
1472static struct GNUNET_CADET_ChannelTunnelNumber 1472static struct GNUNET_CADET_ChannelTunnelNumber
1473get_next_free_ctn (struct CadetTunnel *t) 1473get_next_free_ctn (struct CadetTunnel *t)
1474{ 1474{
1475#define HIGH_BIT 0x8000000
1475 struct GNUNET_CADET_ChannelTunnelNumber ret; 1476 struct GNUNET_CADET_ChannelTunnelNumber ret;
1476 uint32_t ctn; 1477 uint32_t ctn;
1477 1478 int cmp;
1478 /* FIXME: this logic does NOT prevent both ends of the 1479 uint32_t highbit;
1479 channel from picking the same CTN! 1480
1480 Need to reserve one bit of the CTN for the 1481 cmp = GNUNET_CRYPTO_cmp_peer_identity (&my_full_id,
1481 direction, i.e. which side established the connection! */ 1482 GCP_get_id (GCT_get_destination (t)));
1483 if (0 < cmp)
1484 highbit = HIGH_BIT;
1485 else if (0 > cmp)
1486 highbit = 0;
1487 else
1488 GNUNET_assert (0); // loopback must never go here!
1482 ctn = ntohl (t->next_ctn.cn); 1489 ctn = ntohl (t->next_ctn.cn);
1483 while (NULL != 1490 while (NULL !=
1484 GNUNET_CONTAINER_multihashmap32_get (t->channels, 1491 GNUNET_CONTAINER_multihashmap32_get (t->channels,
1485 ctn)) 1492 ctn))
1486 ctn++; 1493 {
1487 t->next_ctn.cn = htonl (ctn + 1); 1494 ctn = ((ctn + 1) & (~ HIGH_BIT)) | highbit;
1495 }
1496 t->next_ctn.cn = htonl (((ctn + 1) & (~ HIGH_BIT)) | highbit);
1488 ret.cn = ntohl (ctn); 1497 ret.cn = ntohl (ctn);
1489 return ret; 1498 return ret;
1490} 1499}
@@ -2029,28 +2038,38 @@ handle_plaintext_data_ack (void *cls,
2029 * another peer. Creates the incoming channel. 2038 * another peer. Creates the incoming channel.
2030 * 2039 *
2031 * @param cls the `struct CadetTunnel` for which we decrypted the message 2040 * @param cls the `struct CadetTunnel` for which we decrypted the message
2032 * @param cc the message we received on the tunnel 2041 * @param copen the message we received on the tunnel
2033 */ 2042 */
2034static void 2043static void
2035handle_plaintext_channel_open (void *cls, 2044handle_plaintext_channel_open (void *cls,
2036 const struct GNUNET_CADET_ChannelOpenMessage *cc) 2045 const struct GNUNET_CADET_ChannelOpenMessage *copen)
2037{ 2046{
2038 struct CadetTunnel *t = cls; 2047 struct CadetTunnel *t = cls;
2039 struct CadetChannel *ch; 2048 struct CadetChannel *ch;
2040 struct GNUNET_CADET_ChannelTunnelNumber ctn;
2041 2049
2050 ch = GNUNET_CONTAINER_multihashmap32_get (t->channels,
2051 ntohl (copen->ctn.cn));
2052 if (NULL != ch)
2053 {
2054 LOG (GNUNET_ERROR_TYPE_DEBUG,
2055 "Receicved duplicate channel OPEN on port %s from %s (%s), resending ACK\n",
2056 GNUNET_h2s (&copen->port),
2057 GCT_2s (t),
2058 GCCH_2s (ch));
2059 GCCH_handle_duplicate_open (ch);
2060 return;
2061 }
2042 LOG (GNUNET_ERROR_TYPE_DEBUG, 2062 LOG (GNUNET_ERROR_TYPE_DEBUG,
2043 "Receicved channel OPEN on port %s from peer %s\n", 2063 "Receicved channel OPEN on port %s from %s\n",
2044 GNUNET_h2s (&cc->port), 2064 GNUNET_h2s (&copen->port),
2045 GCP_2s (GCT_get_destination (t))); 2065 GCT_2s (t));
2046 ctn = get_next_free_ctn (t);
2047 ch = GCCH_channel_incoming_new (t, 2066 ch = GCCH_channel_incoming_new (t,
2048 ctn, 2067 copen->ctn,
2049 &cc->port, 2068 &copen->port,
2050 ntohl (cc->opt)); 2069 ntohl (copen->opt));
2051 GNUNET_assert (GNUNET_OK == 2070 GNUNET_assert (GNUNET_OK ==
2052 GNUNET_CONTAINER_multihashmap32_put (t->channels, 2071 GNUNET_CONTAINER_multihashmap32_put (t->channels,
2053 ntohl (ctn.cn), 2072 ntohl (copen->ctn.cn),
2054 ch, 2073 ch,
2055 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); 2074 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
2056} 2075}
@@ -2110,6 +2129,10 @@ handle_plaintext_channel_open_ack (void *cls,
2110 cm->ctn); 2129 cm->ctn);
2111 return; 2130 return;
2112 } 2131 }
2132 LOG (GNUNET_ERROR_TYPE_DEBUG,
2133 "Receicved channel OPEN_ACK on channel %s from %s\n",
2134 GCCH_2s (ch),
2135 GCT_2s (t));
2113 GCCH_handle_channel_open_ack (ch); 2136 GCCH_handle_channel_open_ack (ch);
2114} 2137}
2115 2138
@@ -2139,6 +2162,10 @@ handle_plaintext_channel_destroy (void *cls,
2139 GCCH_2s (ch)); 2162 GCCH_2s (ch));
2140 return; 2163 return;
2141 } 2164 }
2165 LOG (GNUNET_ERROR_TYPE_DEBUG,
2166 "Receicved channel DESTROY on %s from %s\n",
2167 GCCH_2s (ch),
2168 GCT_2s (t));
2142 GCCH_handle_remote_destroy (ch); 2169 GCCH_handle_remote_destroy (ch);
2143} 2170}
2144 2171
@@ -2385,7 +2412,7 @@ GCT_send (struct CadetTunnel *t,
2385 2412
2386 payload_size = ntohs (message->size); 2413 payload_size = ntohs (message->size);
2387 LOG (GNUNET_ERROR_TYPE_DEBUG, 2414 LOG (GNUNET_ERROR_TYPE_DEBUG,
2388 "Encrypting %u bytes of for tunnel %s\n", 2415 "Encrypting %u bytes for tunnel %s\n",
2389 (unsigned int) payload_size, 2416 (unsigned int) payload_size,
2390 GCT_2s (t)); 2417 GCT_2s (t));
2391 env = GNUNET_MQ_msg_extra (ax_msg, 2418 env = GNUNET_MQ_msg_extra (ax_msg,