summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/cadet/gnunet-service-cadet-new.c41
-rw-r--r--src/cadet/gnunet-service-cadet-new.h5
-rw-r--r--src/cadet/gnunet-service-cadet-new_channel.c145
-rw-r--r--src/cadet/gnunet-service-cadet-new_channel.h14
-rw-r--r--src/cadet/gnunet-service-cadet-new_tunnels.c24
5 files changed, 155 insertions, 74 deletions
diff --git a/src/cadet/gnunet-service-cadet-new.c b/src/cadet/gnunet-service-cadet-new.c
index bb251c307..c9a2fb437 100644
--- a/src/cadet/gnunet-service-cadet-new.c
+++ b/src/cadet/gnunet-service-cadet-new.c
@@ -131,7 +131,7 @@ struct GNUNET_PeerIdentity my_full_id;
131struct GNUNET_CRYPTO_EddsaPrivateKey *my_private_key; 131struct GNUNET_CRYPTO_EddsaPrivateKey *my_private_key;
132 132
133/** 133/**
134 * Signal that shutdown is happening: prevent recover measures. 134 * Signal that shutdown is happening: prevent recovery measures.
135 */ 135 */
136int shutting_down; 136int shutting_down;
137 137
@@ -356,17 +356,11 @@ destroy_paths_now (void *cls,
356 356
357 357
358/** 358/**
359 * Task run during shutdown. 359 * Shutdown everything once the clients have disconnected.
360 *
361 * @param cls unused
362 */ 360 */
363static void 361static void
364shutdown_task (void *cls) 362shutdown_rest ()
365{ 363{
366 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
367 "Shutting down\n");
368 shutting_down = GNUNET_YES;
369 GCO_shutdown ();
370 if (NULL != stats) 364 if (NULL != stats)
371 { 365 {
372 GNUNET_STATISTICS_destroy (stats, 366 GNUNET_STATISTICS_destroy (stats,
@@ -414,6 +408,23 @@ shutdown_task (void *cls)
414 408
415 409
416/** 410/**
411 * Task run during shutdown.
412 *
413 * @param cls unused
414 */
415static void
416shutdown_task (void *cls)
417{
418 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
419 "Shutting down\n");
420 shutting_down = GNUNET_YES;
421 GCO_shutdown ();
422 if (NULL == clients_head)
423 shutdown_rest ();
424}
425
426
427/**
417 * We had a remote connection @a value to port @a port before 428 * We had a remote connection @a value to port @a port before
418 * client @a cls opened port @a port. Bind them now. 429 * client @a cls opened port @a port. Bind them now.
419 * 430 *
@@ -608,7 +619,8 @@ handle_channel_destroy (void *cls,
608 GNUNET_CONTAINER_multihashmap32_remove (c->channels, 619 GNUNET_CONTAINER_multihashmap32_remove (c->channels,
609 ntohl (msg->ccn.channel_of_client), 620 ntohl (msg->ccn.channel_of_client),
610 ch)); 621 ch));
611 GCCH_channel_local_destroy (ch); 622 GCCH_channel_local_destroy (ch,
623 c);
612 GNUNET_SERVICE_client_continue (c->client); 624 GNUNET_SERVICE_client_continue (c->client);
613} 625}
614 626
@@ -1196,10 +1208,8 @@ channel_destroy_iterator (void *cls,
1196 GNUNET_CONTAINER_multihashmap32_remove (c->channels, 1208 GNUNET_CONTAINER_multihashmap32_remove (c->channels,
1197 key, 1209 key,
1198 ch)); 1210 ch));
1199 if (key < GNUNET_CADET_LOCAL_CHANNEL_ID_CLI) 1211 GCCH_channel_local_destroy (ch,
1200 GCCH_channel_local_destroy (ch); 1212 c);
1201 else
1202 GCCH_channel_incoming_destroy (ch);
1203 return GNUNET_OK; 1213 return GNUNET_OK;
1204} 1214}
1205 1215
@@ -1275,6 +1285,9 @@ client_disconnect_cb (void *cls,
1275 -1, 1285 -1,
1276 GNUNET_NO); 1286 GNUNET_NO);
1277 GNUNET_free (c); 1287 GNUNET_free (c);
1288 if ( (NULL == clients_head) &&
1289 (GNUNET_YES == shutting_down) )
1290 shutdown_rest ();
1278} 1291}
1279 1292
1280 1293
diff --git a/src/cadet/gnunet-service-cadet-new.h b/src/cadet/gnunet-service-cadet-new.h
index cb289e9c3..4a76c578b 100644
--- a/src/cadet/gnunet-service-cadet-new.h
+++ b/src/cadet/gnunet-service-cadet-new.h
@@ -225,6 +225,11 @@ extern unsigned long long ratchet_messages;
225 */ 225 */
226extern struct GNUNET_TIME_Relative ratchet_time; 226extern struct GNUNET_TIME_Relative ratchet_time;
227 227
228/**
229 * Signal that shutdown is happening: prevent recovery measures.
230 */
231extern int shutting_down;
232
228 233
229/** 234/**
230 * Send a message to a client. 235 * Send a message to a client.
diff --git a/src/cadet/gnunet-service-cadet-new_channel.c b/src/cadet/gnunet-service-cadet-new_channel.c
index f45c5e5ce..870732192 100644
--- a/src/cadet/gnunet-service-cadet-new_channel.c
+++ b/src/cadet/gnunet-service-cadet-new_channel.c
@@ -302,6 +302,11 @@ struct CadetChannel
302 int out_of_order; 302 int out_of_order;
303 303
304 /** 304 /**
305 * Is this channel a loopback channel, where the destination is us again?
306 */
307 int is_loopback;
308
309 /**
305 * Flag to signal the destruction of the channel. If this is set to 310 * Flag to signal the destruction of the channel. If this is set to
306 * #GNUNET_YES the channel will be destroyed once the queue is 311 * #GNUNET_YES the channel will be destroyed once the queue is
307 * empty. 312 * empty.
@@ -523,11 +528,38 @@ GCCH_channel_local_new (struct CadetClient *owner,
523 ch->owner = owner; 528 ch->owner = owner;
524 ch->ccn = ccn; 529 ch->ccn = ccn;
525 ch->port = *port; 530 ch->port = *port;
526 ch->t = GCP_get_tunnel (destination, 531 if (0 == memcmp (&my_full_id,
527 GNUNET_YES); 532 GCP_get_id (destination),
528 ch->retry_time = CADET_INITIAL_RETRANSMIT_TIME; 533 sizeof (struct GNUNET_PeerIdentity)))
529 ch->ctn = GCT_add_channel (ch->t, 534 {
530 ch); 535 ch->is_loopback = GNUNET_YES;
536 ch->dest = GNUNET_CONTAINER_multihashmap_get (open_ports,
537 port);
538 if (NULL == ch->dest)
539 {
540 /* port closed, wait for it to possibly open */
541 (void) GNUNET_CONTAINER_multihashmap_put (loose_channels,
542 port,
543 ch,
544 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
545 LOG (GNUNET_ERROR_TYPE_DEBUG,
546 "Created loose incoming loopback channel to port %s\n",
547 GNUNET_h2s (&ch->port));
548 }
549 else
550 {
551 GCCH_bind (ch,
552 ch->dest);
553 }
554 }
555 else
556 {
557 ch->t = GCP_get_tunnel (destination,
558 GNUNET_YES);
559 ch->retry_time = CADET_INITIAL_RETRANSMIT_TIME;
560 ch->ctn = GCT_add_channel (ch->t,
561 ch);
562 }
531 GNUNET_STATISTICS_update (stats, 563 GNUNET_STATISTICS_update (stats,
532 "# channels", 564 "# channels",
533 1, 565 1,
@@ -537,7 +569,7 @@ GCCH_channel_local_new (struct CadetClient *owner,
537 GNUNET_h2s (port), 569 GNUNET_h2s (port),
538 GCP_2s (destination), 570 GCP_2s (destination),
539 GSC_2s (owner), 571 GSC_2s (owner),
540 GCT_2s (ch->t)); 572 (GNUNET_YES == ch->is_loopback) ? "loopback" : GCT_2s (ch->t));
541 return ch; 573 return ch;
542} 574}
543 575
@@ -791,11 +823,18 @@ GCCH_bind (struct CadetChannel *ch,
791 &ch->port, 823 &ch->port,
792 options); 824 options);
793 ch->mid_recv.mid = htonl (1); /* The CONNECT counts as message 0! */ 825 ch->mid_recv.mid = htonl (1); /* The CONNECT counts as message 0! */
794 826 if (GNUNET_YES == ch->is_loopback)
795 /* notify other peer that we accepted the connection */ 827 {
796 ch->retry_control_task 828 ch->state = CADET_CHANNEL_OPEN_SENT;
797 = GNUNET_SCHEDULER_add_now (&send_open_ack, 829 GCCH_handle_channel_open_ack (ch);
798 ch); 830 }
831 else
832 {
833 /* notify other peer that we accepted the connection */
834 ch->retry_control_task
835 = GNUNET_SCHEDULER_add_now (&send_open_ack,
836 ch);
837 }
799 /* give client it's initial supply of ACKs */ 838 /* give client it's initial supply of ACKs */
800 env = GNUNET_MQ_msg (tcm, 839 env = GNUNET_MQ_msg (tcm,
801 GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_CREATE); 840 GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_CREATE);
@@ -812,17 +851,27 @@ GCCH_bind (struct CadetChannel *ch,
812 851
813 852
814/** 853/**
815 * Destroy locally created channel. Called by the 854 * Destroy locally created channel. Called by the local client, so no
816 * local client, so no need to tell the client. 855 * need to tell the client.
817 * 856 *
818 * @param ch channel to destroy 857 * @param ch channel to destroy
858 * @param c client that caused the destruction
819 */ 859 */
820void 860void
821GCCH_channel_local_destroy (struct CadetChannel *ch) 861GCCH_channel_local_destroy (struct CadetChannel *ch,
862 struct CadetClient *c)
822{ 863{
823 LOG (GNUNET_ERROR_TYPE_DEBUG, 864 LOG (GNUNET_ERROR_TYPE_DEBUG,
824 "Local client asks for destruction of %s which it initiated\n", 865 "%s asks for destruction of %s\n",
866 GSC_2s (c),
825 GCCH_2s (ch)); 867 GCCH_2s (ch));
868 GNUNET_assert (NULL != c);
869 if (c == ch->owner)
870 ch->owner = NULL;
871 else if (c == ch->dest)
872 ch->dest = NULL;
873 else
874 GNUNET_assert (0);
826 if (GNUNET_YES == ch->destroy) 875 if (GNUNET_YES == ch->destroy)
827 { 876 {
828 /* other end already destroyed, with the local client gone, no need 877 /* other end already destroyed, with the local client gone, no need
@@ -830,9 +879,12 @@ GCCH_channel_local_destroy (struct CadetChannel *ch)
830 channel_destroy (ch); 879 channel_destroy (ch);
831 return; 880 return;
832 } 881 }
833 if (NULL != ch->head_sent) 882 if ( (NULL != ch->head_sent) ||
883 (NULL != ch->owner) ||
884 (NULL != ch->dest) )
834 { 885 {
835 /* allow send queue to train first */ 886 /* Wait for other end to destroy us as well,
887 and otherwise allow send queue to be transmitted first */
836 ch->destroy = GNUNET_YES; 888 ch->destroy = GNUNET_YES;
837 return; 889 return;
838 } 890 }
@@ -840,39 +892,7 @@ GCCH_channel_local_destroy (struct CadetChannel *ch)
840 if (CADET_CHANNEL_NEW != ch->state) 892 if (CADET_CHANNEL_NEW != ch->state)
841 GCT_send_channel_destroy (ch->t, 893 GCT_send_channel_destroy (ch->t,
842 ch->ctn); 894 ch->ctn);
843 /* Now finish our clean up */
844 channel_destroy (ch);
845}
846
847
848/**
849 * Destroy channel that was incoming. Called by the
850 * local client, so no need to tell the client.
851 *
852 * @param ch channel to destroy
853 */
854void
855GCCH_channel_incoming_destroy (struct CadetChannel *ch)
856{
857 LOG (GNUNET_ERROR_TYPE_DEBUG,
858 "Local client asks for destruction of %s which it accepted\n",
859 GCCH_2s (ch));
860 if (GNUNET_YES == ch->destroy)
861 {
862 /* other end already destroyed, with the remote client gone, no need
863 to finish transmissions, just destroy immediately. */
864 channel_destroy (ch);
865 return;
866 }
867 if (NULL != ch->head_recv)
868 {
869 /* allow local client to see all data first */
870 ch->destroy = GNUNET_YES;
871 return;
872 }
873 /* Nothing left to do, just finish destruction */ 895 /* Nothing left to do, just finish destruction */
874 GCT_send_channel_destroy (ch->t,
875 ch->ctn);
876 channel_destroy (ch); 896 channel_destroy (ch);
877} 897}
878 898
@@ -980,6 +1000,12 @@ GCCH_handle_channel_plaintext_data (struct CadetChannel *ch,
980 "Receicved %u bytes of application data on %s\n", 1000 "Receicved %u bytes of application data on %s\n",
981 (unsigned int) payload_size, 1001 (unsigned int) payload_size,
982 GCCH_2s (ch)); 1002 GCCH_2s (ch));
1003 if (GNUNET_YES == ch->is_loopback)
1004 {
1005 GNUNET_break (0); // FIXME: not implemented
1006 return;
1007 }
1008
983 env = GNUNET_MQ_msg_extra (ld, 1009 env = GNUNET_MQ_msg_extra (ld,
984 payload_size, 1010 payload_size,
985 GNUNET_MESSAGE_TYPE_CADET_LOCAL_DATA); 1011 GNUNET_MESSAGE_TYPE_CADET_LOCAL_DATA);
@@ -1054,6 +1080,7 @@ GCCH_handle_channel_plaintext_data_ack (struct CadetChannel *ch,
1054{ 1080{
1055 struct CadetReliableMessage *crm; 1081 struct CadetReliableMessage *crm;
1056 1082
1083 GNUNET_break (GNUNET_NO == ch->is_loopback);
1057 if (GNUNET_NO == ch->reliable) 1084 if (GNUNET_NO == ch->reliable)
1058 { 1085 {
1059 /* not expecting ACKs on unreliable channel, odd */ 1086 /* not expecting ACKs on unreliable channel, odd */
@@ -1104,9 +1131,23 @@ GCCH_handle_channel_plaintext_data_ack (struct CadetChannel *ch,
1104void 1131void
1105GCCH_handle_remote_destroy (struct CadetChannel *ch) 1132GCCH_handle_remote_destroy (struct CadetChannel *ch)
1106{ 1133{
1134 GNUNET_break (GNUNET_NO == ch->is_loopback);
1107 LOG (GNUNET_ERROR_TYPE_DEBUG, 1135 LOG (GNUNET_ERROR_TYPE_DEBUG,
1108 "Received remote channel DESTROY for %s\n", 1136 "Received remote channel DESTROY for %s\n",
1109 GCCH_2s (ch)); 1137 GCCH_2s (ch));
1138 if (GNUNET_YES == ch->destroy)
1139 {
1140 /* Local client already gone, this is instant-death. */
1141 channel_destroy (ch);
1142 return;
1143 }
1144 if (NULL != ch->head_recv)
1145 {
1146 LOG (GNUNET_ERROR_TYPE_WARNING,
1147 "Lost end of transmission due to remote shutdown on channel %s\n",
1148 GCCH_2s (ch));
1149 /* FIXME: change API to notify client about truncated transmission! */
1150 }
1110 ch->destroy = GNUNET_YES; 1151 ch->destroy = GNUNET_YES;
1111 GSC_handle_remote_channel_destroy ((NULL != ch->owner) ? ch->owner : ch->dest, 1152 GSC_handle_remote_channel_destroy ((NULL != ch->owner) ? ch->owner : ch->dest,
1112 ch->ccn, 1153 ch->ccn,
@@ -1290,6 +1331,12 @@ GCCH_handle_local_data (struct CadetChannel *ch,
1290 } 1331 }
1291 ch->pending_messages++; 1332 ch->pending_messages++;
1292 1333
1334 if (GNUNET_YES == ch->is_loopback)
1335 {
1336 GNUNET_break (0); // fIXME: not implemented
1337 return GNUNET_SYSERR;
1338 }
1339
1293 /* Everything is correct, send the message. */ 1340 /* Everything is correct, send the message. */
1294 crm = GNUNET_malloc (sizeof (*crm) + buf_len); 1341 crm = GNUNET_malloc (sizeof (*crm) + buf_len);
1295 crm->ch = ch; 1342 crm->ch = ch;
diff --git a/src/cadet/gnunet-service-cadet-new_channel.h b/src/cadet/gnunet-service-cadet-new_channel.h
index 3a931499e..a473fd3e4 100644
--- a/src/cadet/gnunet-service-cadet-new_channel.h
+++ b/src/cadet/gnunet-service-cadet-new_channel.h
@@ -113,9 +113,11 @@ GCCH_bind (struct CadetChannel *ch,
113 * local client, so no need to tell the client. 113 * local client, so no need to tell the client.
114 * 114 *
115 * @param ch channel to destroy 115 * @param ch channel to destroy
116 * @param c client that caused the destruction
116 */ 117 */
117void 118void
118GCCH_channel_local_destroy (struct CadetChannel *ch); 119GCCH_channel_local_destroy (struct CadetChannel *ch,
120 struct CadetClient *c);
119 121
120 122
121/** 123/**
@@ -150,16 +152,6 @@ GCCH_channel_incoming_new (struct CadetTunnel *t,
150 152
151 153
152/** 154/**
153 * Destroy channel that was incoming. Called by the
154 * local client, so no need to tell the client.
155 *
156 * @param ch channel to destroy
157 */
158void
159GCCH_channel_incoming_destroy (struct CadetChannel *ch);
160
161
162/**
163 * We got a #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN message again for 155 * We got a #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN message again for
164 * this channel. If the binding was successful, (re)transmit the 156 * this channel. If the binding was successful, (re)transmit the
165 * #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK. 157 * #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK.
diff --git a/src/cadet/gnunet-service-cadet-new_tunnels.c b/src/cadet/gnunet-service-cadet-new_tunnels.c
index 20ab8f4e9..b85f1b321 100644
--- a/src/cadet/gnunet-service-cadet-new_tunnels.c
+++ b/src/cadet/gnunet-service-cadet-new_tunnels.c
@@ -1624,6 +1624,26 @@ GCT_remove_channel (struct CadetTunnel *t,
1624 1624
1625 1625
1626/** 1626/**
1627 * Destroy remaining channels during shutdown.
1628 *
1629 * @param cls the `struct CadetTunnel` of the channel
1630 * @param key key of the channel
1631 * @param value the `struct CadetChannel`
1632 * @return #GNUNET_OK (continue to iterate)
1633 */
1634static int
1635destroy_remaining_channels (void *cls,
1636 uint32_t key,
1637 void *value)
1638{
1639 struct CadetChannel *ch = value;
1640
1641 GCCH_handle_remote_destroy (ch);
1642 return GNUNET_OK;
1643}
1644
1645
1646/**
1627 * Destroys the tunnel @a t now, without delay. Used during shutdown. 1647 * Destroys the tunnel @a t now, without delay. Used during shutdown.
1628 * 1648 *
1629 * @param t tunnel to destroy 1649 * @param t tunnel to destroy
@@ -1631,6 +1651,10 @@ GCT_remove_channel (struct CadetTunnel *t,
1631void 1651void
1632GCT_destroy_tunnel_now (struct CadetTunnel *t) 1652GCT_destroy_tunnel_now (struct CadetTunnel *t)
1633{ 1653{
1654 GNUNET_assert (GNUNET_YES == shutting_down);
1655 GNUNET_CONTAINER_multihashmap32_iterate (t->channels,
1656 &destroy_remaining_channels,
1657 t);
1634 GNUNET_assert (0 == 1658 GNUNET_assert (0 ==
1635 GNUNET_CONTAINER_multihashmap32_size (t->channels)); 1659 GNUNET_CONTAINER_multihashmap32_size (t->channels));
1636 if (NULL != t->destroy_task) 1660 if (NULL != t->destroy_task)