aboutsummaryrefslogtreecommitdiff
path: root/src/service/cadet/gnunet-service-cadet.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/service/cadet/gnunet-service-cadet.c')
-rw-r--r--src/service/cadet/gnunet-service-cadet.c1376
1 files changed, 1376 insertions, 0 deletions
diff --git a/src/service/cadet/gnunet-service-cadet.c b/src/service/cadet/gnunet-service-cadet.c
new file mode 100644
index 000000000..620e43cc8
--- /dev/null
+++ b/src/service/cadet/gnunet-service-cadet.c
@@ -0,0 +1,1376 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2001-2013, 2017 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
21/**
22 * @file cadet/gnunet-service-cadet.c
23 * @brief GNUnet CADET service with encryption
24 * @author Bartlomiej Polot
25 * @author Christian Grothoff
26 *
27 * Dictionary:
28 * - peer: other cadet instance. If there is direct connection it's a neighbor.
29 * - path: series of directly connected peer from one peer to another.
30 * - connection: path which is being used in a tunnel.
31 * - tunnel: encrypted connection to a peer, neighbor or not.
32 * - channel: logical link between two clients, on the same or different peers.
33 * have properties like reliability.
34 */
35#include "platform.h"
36#include "gnunet_util_lib.h"
37#include "cadet.h"
38#include "gnunet_statistics_service.h"
39#include "gnunet_transport_application_service.h"
40#include "gnunet-service-cadet.h"
41#include "gnunet-service-cadet_channel.h"
42#include "gnunet-service-cadet_connection.h"
43#include "gnunet-service-cadet_core.h"
44#include "gnunet-service-cadet_dht.h"
45#include "gnunet-service-cadet_hello.h"
46#include "gnunet-service-cadet_tunnels.h"
47#include "gnunet-service-cadet_peer.h"
48#include "gnunet-service-cadet_paths.h"
49#include "gnunet_constants.h"
50
51
52#define LOG(level, ...) GNUNET_log (level, __VA_ARGS__)
53
54
55/**
56 * Struct containing information about a client of the service
57 */
58struct CadetClient
59{
60 /**
61 * Linked list next
62 */
63 struct CadetClient *next;
64
65 /**
66 * Linked list prev
67 */
68 struct CadetClient *prev;
69
70 /**
71 * Tunnels that belong to this client, indexed by local id,
72 * value is a `struct CadetChannel`.
73 */
74 struct GNUNET_CONTAINER_MultiHashMap32 *channels;
75
76 /**
77 * Handle to communicate with the client
78 */
79 struct GNUNET_MQ_Handle *mq;
80
81 /**
82 * Client handle.
83 */
84 struct GNUNET_SERVICE_Client *client;
85
86 /**
87 * Ports that this client has declared interest in.
88 * Indexed by port, contains `struct OpenPort`
89 */
90 struct GNUNET_CONTAINER_MultiHashMap *ports;
91
92 /**
93 * Channel ID to use for the next incoming channel for this client.
94 * Wraps around (in theory).
95 */
96 struct GNUNET_CADET_ClientChannelNumber next_ccn;
97
98 /**
99 * ID of the client, mainly for debug messages. Purely internal to this file.
100 */
101 unsigned int id;
102};
103
104
105/******************************************************************************/
106/*********************** GLOBAL VARIABLES ****************************/
107/******************************************************************************/
108
109/****************************** Global variables ******************************/
110
111/**
112 * Handle to our configuration.
113 */
114const struct GNUNET_CONFIGURATION_Handle *cfg;
115
116/**
117 * Handle to the statistics service.
118 */
119struct GNUNET_STATISTICS_Handle *stats;
120
121/**
122 * Handle to Transport service.
123 */
124struct GNUNET_TRANSPORT_ApplicationHandle *transport;
125
126/**
127 * Local peer own ID.
128 */
129struct GNUNET_PeerIdentity my_full_id;
130
131/**
132 * Own private key.
133 */
134struct GNUNET_CRYPTO_EddsaPrivateKey *my_private_key;
135
136/**
137 * Signal that shutdown is happening: prevent recovery measures.
138 */
139int shutting_down;
140
141/**
142 * DLL with all the clients, head.
143 */
144static struct CadetClient *clients_head;
145
146/**
147 * DLL with all the clients, tail.
148 */
149static struct CadetClient *clients_tail;
150
151/**
152 * Next ID to assign to a client.
153 */
154static unsigned int next_client_id;
155
156/**
157 * All ports clients of this peer have opened. Maps from
158 * a hashed port to a `struct OpenPort`.
159 */
160struct GNUNET_CONTAINER_MultiHashMap *open_ports;
161
162/**
163 * Map from ports to channels where the ports were closed at the
164 * time we got the inbound connection.
165 * Indexed by h_port, contains `struct CadetChannel`.
166 */
167struct GNUNET_CONTAINER_MultiHashMap *loose_channels;
168
169/**
170 * Map from PIDs to `struct CadetPeer` entries.
171 */
172struct GNUNET_CONTAINER_MultiPeerMap *peers;
173
174/**
175 * Map from `struct GNUNET_CADET_ConnectionTunnelIdentifier`
176 * hash codes to `struct CadetConnection` objects.
177 */
178struct GNUNET_CONTAINER_MultiShortmap *connections;
179
180/**
181 * How many messages are needed to trigger an AXOLOTL ratchet advance.
182 */
183unsigned long long ratchet_messages;
184
185/**
186 * How long until we trigger a ratched advance due to time.
187 */
188struct GNUNET_TIME_Relative ratchet_time;
189
190/**
191 * How frequently do we send KEEPALIVE messages on idle connections?
192 */
193struct GNUNET_TIME_Relative keepalive_period;
194
195/**
196 * Set to non-zero values to create random drops to test retransmissions.
197 */
198unsigned long long drop_percent;
199
200
201/**
202 * Send a message to a client.
203 *
204 * @param c client to get the message
205 * @param env envelope with the message
206 */
207void
208GSC_send_to_client (struct CadetClient *c,
209 struct GNUNET_MQ_Envelope *env)
210{
211 GNUNET_MQ_send (c->mq,
212 env);
213}
214
215
216/**
217 * Return identifier for a client as a string.
218 *
219 * @param c client to identify
220 * @return string for debugging
221 */
222const char *
223GSC_2s (struct CadetClient *c)
224{
225 static char buf[32];
226
227 GNUNET_snprintf (buf,
228 sizeof(buf),
229 "Client(%u)",
230 c->id);
231 return buf;
232}
233
234
235/**
236 * Lookup channel of client @a c by @a ccn.
237 *
238 * @param c client to look in
239 * @param ccn channel ID to look up
240 * @return NULL if no such channel exists
241 */
242static struct CadetChannel *
243lookup_channel (struct CadetClient *c,
244 struct GNUNET_CADET_ClientChannelNumber ccn)
245{
246 return GNUNET_CONTAINER_multihashmap32_get (c->channels,
247 ntohl (ccn.channel_of_client));
248}
249
250
251/**
252 * Obtain the next LID to use for incoming connections to
253 * the given client.
254 *
255 * @param c client handle
256 */
257static struct GNUNET_CADET_ClientChannelNumber
258client_get_next_ccn (struct CadetClient *c)
259{
260 struct GNUNET_CADET_ClientChannelNumber ccn = c->next_ccn;
261
262 /* increment until we have a free one... */
263 while (NULL !=
264 lookup_channel (c,
265 ccn))
266 {
267 ccn.channel_of_client
268 = htonl (1 + (ntohl (ccn.channel_of_client)));
269 if (ntohl (ccn.channel_of_client) >=
270 GNUNET_CADET_LOCAL_CHANNEL_ID_CLI)
271 ccn.channel_of_client = htonl (0);
272 }
273 c->next_ccn.channel_of_client
274 = htonl (1 + (ntohl (ccn.channel_of_client)));
275 return ccn;
276}
277
278
279/**
280 * Bind incoming channel to this client, and notify client about
281 * incoming connection. Caller is responsible for notifying the other
282 * peer about our acceptance of the channel.
283 *
284 * @param c client to bind to
285 * @param ch channel to be bound
286 * @param dest peer that establishes the connection
287 * @param port port number
288 * @param options options
289 * @return local channel number assigned to the new client
290 */
291struct GNUNET_CADET_ClientChannelNumber
292GSC_bind (struct CadetClient *c,
293 struct CadetChannel *ch,
294 struct CadetPeer *dest,
295 const struct GNUNET_HashCode *port,
296 uint32_t options)
297{
298 struct GNUNET_MQ_Envelope *env;
299 struct GNUNET_CADET_LocalChannelCreateMessage *cm;
300 struct GNUNET_CADET_ClientChannelNumber ccn;
301
302 ccn = client_get_next_ccn (c);
303 GNUNET_assert (GNUNET_YES ==
304 GNUNET_CONTAINER_multihashmap32_put (c->channels,
305 ntohl (
306 ccn.channel_of_client),
307 ch,
308 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
309 LOG (GNUNET_ERROR_TYPE_DEBUG,
310 "Accepting incoming %s from %s on open port %s (%u), assigning ccn %X\n",
311 GCCH_2s (ch),
312 GCP_2s (dest),
313 GNUNET_h2s (port),
314 (uint32_t) ntohl (options),
315 (uint32_t) ntohl (ccn.channel_of_client));
316 /* notify local client about incoming connection! */
317 env = GNUNET_MQ_msg (cm,
318 GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_CREATE);
319 cm->ccn = ccn;
320 cm->port = *port;
321 cm->opt = htonl (options);
322 cm->peer = *GCP_get_id (dest);
323 GSC_send_to_client (c,
324 env);
325 return ccn;
326}
327
328
329/**
330 * Callback invoked on all peers to destroy all tunnels
331 * that may still exist.
332 *
333 * @param cls NULL
334 * @param pid identify of a peer
335 * @param value a `struct CadetPeer` that may still have a tunnel
336 * @return #GNUNET_OK (iterate over all entries)
337 */
338static int
339destroy_tunnels_now (void *cls,
340 const struct GNUNET_PeerIdentity *pid,
341 void *value)
342{
343 struct CadetPeer *cp = value;
344 struct CadetTunnel *t = GCP_get_tunnel (cp,
345 GNUNET_NO);
346
347 if (NULL != t)
348 GCT_destroy_tunnel_now (t);
349 return GNUNET_OK;
350}
351
352
353/**
354 * Callback invoked on all peers to destroy all tunnels
355 * that may still exist.
356 *
357 * @param cls NULL
358 * @param pid identify of a peer
359 * @param value a `struct CadetPeer` that may still have a tunnel
360 * @return #GNUNET_OK (iterate over all entries)
361 */
362static int
363destroy_paths_now (void *cls,
364 const struct GNUNET_PeerIdentity *pid,
365 void *value)
366{
367 struct CadetPeer *cp = value;
368
369 GCP_drop_owned_paths (cp);
370 return GNUNET_OK;
371}
372
373
374/**
375 * Shutdown everything once the clients have disconnected.
376 */
377static void
378shutdown_rest ()
379{
380 if (NULL != stats)
381 {
382 GNUNET_STATISTICS_destroy (stats,
383 GNUNET_NO);
384 stats = NULL;
385 }
386 /* Destroy tunnels. Note that all channels must be destroyed first! */
387 GCP_iterate_all (&destroy_tunnels_now,
388 NULL);
389 /* All tunnels, channels, connections and CORE must be down before this point. */
390 GCP_iterate_all (&destroy_paths_now,
391 NULL);
392 /* All paths, tunnels, channels, connections and CORE must be down before this point. */
393 GCP_destroy_all_peers ();
394 if (NULL != open_ports)
395 {
396 GNUNET_CONTAINER_multihashmap_destroy (open_ports);
397 open_ports = NULL;
398 }
399 if (NULL != loose_channels)
400 {
401 GNUNET_CONTAINER_multihashmap_destroy (loose_channels);
402 loose_channels = NULL;
403 }
404 if (NULL != peers)
405 {
406 GNUNET_CONTAINER_multipeermap_destroy (peers);
407 peers = NULL;
408 }
409 if (NULL != connections)
410 {
411 GNUNET_CONTAINER_multishortmap_destroy (connections);
412 connections = NULL;
413 }
414 if (NULL != transport)
415 {
416 GNUNET_TRANSPORT_application_done (transport);
417 transport = NULL;
418 }
419 GCD_shutdown ();
420 GCH_shutdown ();
421 GNUNET_free (my_private_key);
422 my_private_key = NULL;
423}
424
425
426/**
427 * Task run during shutdown.
428 *
429 * @param cls unused
430 */
431static void
432shutdown_task (void *cls)
433{
434 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
435 "Shutting down\n");
436 shutting_down = GNUNET_YES;
437 GCO_shutdown ();
438 if (NULL == clients_head)
439 shutdown_rest ();
440}
441
442
443/**
444 * We had a remote connection @a value to port @a h_port before
445 * client @a cls opened port @a port. Bind them now.
446 *
447 * @param cls the `struct CadetClient`
448 * @param port the hashed port
449 * @param value the `struct CadetChannel`
450 * @return #GNUNET_YES (iterate over all such channels)
451 */
452static int
453bind_loose_channel (void *cls,
454 const struct GNUNET_HashCode *port,
455 void *value)
456{
457 struct OpenPort *op = cls;
458 struct CadetChannel *ch = value;
459
460 GCCH_bind (ch,
461 op->c,
462 &op->port);
463 GNUNET_assert (GNUNET_YES ==
464 GNUNET_CONTAINER_multihashmap_remove (loose_channels,
465 &op->h_port,
466 ch));
467 return GNUNET_YES;
468}
469
470
471/**
472 * Handle port open request. Creates a mapping from the
473 * port to the respective client and checks whether we have
474 * loose channels trying to bind to the port. If so, those
475 * are bound.
476 *
477 * @param cls Identification of the client.
478 * @param pmsg The actual message.
479 */
480static void
481handle_port_open (void *cls,
482 const struct GNUNET_CADET_PortMessage *pmsg)
483{
484 struct CadetClient *c = cls;
485 struct OpenPort *op;
486
487 LOG (GNUNET_ERROR_TYPE_DEBUG,
488 "Open port %s requested by %s\n",
489 GNUNET_h2s (&pmsg->port),
490 GSC_2s (c));
491 if (NULL == c->ports)
492 c->ports = GNUNET_CONTAINER_multihashmap_create (4,
493 GNUNET_NO);
494 op = GNUNET_new (struct OpenPort);
495 op->c = c;
496 op->port = pmsg->port;
497 GCCH_hash_port (&op->h_port,
498 &pmsg->port,
499 &my_full_id);
500 if (GNUNET_OK !=
501 GNUNET_CONTAINER_multihashmap_put (c->ports,
502 &op->port,
503 op,
504 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
505 {
506 GNUNET_break (0);
507 GNUNET_SERVICE_client_drop (c->client);
508 return;
509 }
510 (void) GNUNET_CONTAINER_multihashmap_put (open_ports,
511 &op->h_port,
512 op,
513 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
514 GNUNET_CONTAINER_multihashmap_get_multiple (loose_channels,
515 &op->h_port,
516 &bind_loose_channel,
517 op);
518 GNUNET_SERVICE_client_continue (c->client);
519}
520
521
522/**
523 * Handler for port close requests. Marks this port as closed
524 * (unless of course we have another client with the same port
525 * open). Note that existing channels accepted on the port are
526 * not affected.
527 *
528 * @param cls Identification of the client.
529 * @param pmsg The actual message.
530 */
531static void
532handle_port_close (void *cls,
533 const struct GNUNET_CADET_PortMessage *pmsg)
534{
535 struct CadetClient *c = cls;
536 struct OpenPort *op;
537
538 LOG (GNUNET_ERROR_TYPE_DEBUG,
539 "Closing port %s as requested by %s\n",
540 GNUNET_h2s (&pmsg->port),
541 GSC_2s (c));
542 if (NULL == c->ports)
543 {
544 /* Client closed a port despite _never_ having opened one? */
545 GNUNET_break (0);
546 GNUNET_SERVICE_client_drop (c->client);
547 return;
548 }
549 op = GNUNET_CONTAINER_multihashmap_get (c->ports,
550 &pmsg->port);
551 if (NULL == op)
552 {
553 GNUNET_break (0);
554 GNUNET_SERVICE_client_drop (c->client);
555 return;
556 }
557 GNUNET_assert (GNUNET_YES ==
558 GNUNET_CONTAINER_multihashmap_remove (c->ports,
559 &op->port,
560 op));
561 GNUNET_assert (GNUNET_YES ==
562 GNUNET_CONTAINER_multihashmap_remove (open_ports,
563 &op->h_port,
564 op));
565 GNUNET_free (op);
566 GNUNET_SERVICE_client_continue (c->client);
567}
568
569
570/**
571 * Handler for requests for us creating a new channel to another peer and port.
572 *
573 * @param cls Identification of the client.
574 * @param tcm The actual message.
575 */
576static void
577handle_channel_create (void *cls,
578 const struct GNUNET_CADET_LocalChannelCreateMessage *tcm)
579{
580 struct CadetClient *c = cls;
581 struct CadetChannel *ch;
582
583 if (ntohl (tcm->ccn.channel_of_client) < GNUNET_CADET_LOCAL_CHANNEL_ID_CLI)
584 {
585 /* Channel ID not in allowed range. */
586 LOG (GNUNET_ERROR_TYPE_DEBUG,"Channel ID not in allowed range.");
587 GNUNET_break (0);
588 GNUNET_SERVICE_client_drop (c->client);
589 return;
590 }
591 ch = lookup_channel (c,
592 tcm->ccn);
593 if (NULL != ch)
594 {
595 /* Channel ID already in use. Not allowed. */
596 LOG (GNUNET_ERROR_TYPE_DEBUG,"Channel ID already in use. Not allowed.");
597 GNUNET_break (0);
598 GNUNET_SERVICE_client_drop (c->client);
599 return;
600 }
601 LOG (GNUNET_ERROR_TYPE_DEBUG,
602 "New channel to %s at port %s requested by %s\n",
603 GNUNET_i2s (&tcm->peer),
604 GNUNET_h2s (&tcm->port),
605 GSC_2s (c));
606
607 /* Create channel */
608 ch = GCCH_channel_local_new (c,
609 tcm->ccn,
610 GCP_get (&tcm->peer,
611 GNUNET_YES),
612 &tcm->port,
613 ntohl (tcm->opt));
614 if (NULL == ch)
615 {
616 GNUNET_break (0);
617 GNUNET_SERVICE_client_drop (c->client);
618 return;
619 }
620 GNUNET_assert (GNUNET_YES ==
621 GNUNET_CONTAINER_multihashmap32_put (c->channels,
622 ntohl (
623 tcm->ccn.
624 channel_of_client),
625 ch,
626 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
627
628 GNUNET_SERVICE_client_continue (c->client);
629}
630
631
632/**
633 * Handler for requests of destroying an existing channel.
634 *
635 * @param cls client identification of the client
636 * @param msg the actual message
637 */
638static void
639handle_channel_destroy (void *cls,
640 const struct
641 GNUNET_CADET_LocalChannelDestroyMessage *msg)
642{
643 struct CadetClient *c = cls;
644 struct CadetChannel *ch;
645
646 ch = lookup_channel (c,
647 msg->ccn);
648 if (NULL == ch)
649 {
650 /* Client attempted to destroy unknown channel.
651 Can happen if the other side went down at the same time.*/
652 LOG (GNUNET_ERROR_TYPE_DEBUG,
653 "%s tried to destroy unknown channel %X\n",
654 GSC_2s (c),
655 (uint32_t) ntohl (msg->ccn.channel_of_client));
656 GNUNET_SERVICE_client_continue (c->client);
657 return;
658 }
659 LOG (GNUNET_ERROR_TYPE_DEBUG,
660 "%s is destroying %s\n",
661 GSC_2s (c),
662 GCCH_2s (ch));
663 GNUNET_assert (GNUNET_YES ==
664 GNUNET_CONTAINER_multihashmap32_remove (c->channels,
665 ntohl (
666 msg->ccn.
667 channel_of_client),
668 ch));
669 GCCH_channel_local_destroy (ch,
670 c,
671 msg->ccn);
672 GNUNET_SERVICE_client_continue (c->client);
673}
674
675
676/**
677 * Check for client traffic data message is well-formed.
678 *
679 * @param cls identification of the client
680 * @param msg the actual message
681 * @return #GNUNET_OK if @a msg is OK, #GNUNET_SYSERR if not
682 */
683static int
684check_local_data (void *cls,
685 const struct GNUNET_CADET_LocalData *msg)
686{
687 size_t payload_size;
688 size_t payload_claimed_size;
689 const char *buf;
690 struct GNUNET_MessageHeader pa;
691
692 /* FIXME: what is the format we shall allow for @a msg?
693 ONE payload item or multiple? Seems current cadet_api
694 at least in theory allows more than one. Next-gen
695 cadet_api will likely no more, so we could then
696 simplify this mess again. *//* Sanity check for message size */payload_size = ntohs (msg->header.size) - sizeof(*msg);
697 buf = (const char *) &msg[1];
698 while (payload_size >= sizeof(struct GNUNET_MessageHeader))
699 {
700 /* need to memcpy() for alignment */
701 GNUNET_memcpy (&pa,
702 buf,
703 sizeof(pa));
704 payload_claimed_size = ntohs (pa.size);
705 if ((payload_size < payload_claimed_size) ||
706 (payload_claimed_size < sizeof(struct GNUNET_MessageHeader)) ||
707 (GNUNET_CONSTANTS_MAX_CADET_MESSAGE_SIZE < payload_claimed_size))
708 {
709 GNUNET_break (0);
710 LOG (GNUNET_ERROR_TYPE_DEBUG,
711 "Local data of %u total size had sub-message %u at %u with %u bytes\n",
712 ntohs (msg->header.size),
713 ntohs (pa.type),
714 (unsigned int) (buf - (const char *) &msg[1]),
715 (unsigned int) payload_claimed_size);
716 return GNUNET_SYSERR;
717 }
718 payload_size -= payload_claimed_size;
719 buf += payload_claimed_size;
720 }
721 if (0 != payload_size)
722 {
723 GNUNET_break_op (0);
724 return GNUNET_SYSERR;
725 }
726 return GNUNET_OK;
727}
728
729
730/**
731 * Handler for client payload traffic to be send on a channel to
732 * another peer.
733 *
734 * @param cls identification of the client
735 * @param msg the actual message
736 */
737static void
738handle_local_data (void *cls,
739 const struct GNUNET_CADET_LocalData *msg)
740{
741 struct CadetClient *c = cls;
742 struct CadetChannel *ch;
743 size_t payload_size;
744 const char *buf;
745
746 ch = lookup_channel (c,
747 msg->ccn);
748 if (NULL == ch)
749 {
750 /* Channel does not exist (anymore) */
751 LOG (GNUNET_ERROR_TYPE_WARNING,
752 "Dropping payload for channel %u from client (channel unknown, other endpoint may have disconnected)\n",
753 (unsigned int) ntohl (msg->ccn.channel_of_client));
754 GNUNET_SERVICE_client_continue (c->client);
755 return;
756 }
757 payload_size = ntohs (msg->header.size) - sizeof(*msg);
758 GNUNET_STATISTICS_update (stats,
759 "# payload received from clients",
760 payload_size,
761 GNUNET_NO);
762 buf = (const char *) &msg[1];
763 LOG (GNUNET_ERROR_TYPE_DEBUG,
764 "Received %u bytes payload from %s for %s\n",
765 (unsigned int) payload_size,
766 GSC_2s (c),
767 GCCH_2s (ch));
768 if (GNUNET_OK !=
769 GCCH_handle_local_data (ch,
770 msg->ccn,
771 buf,
772 payload_size))
773 {
774 GNUNET_break (0);
775 GNUNET_SERVICE_client_drop (c->client);
776 return;
777 }
778 GNUNET_SERVICE_client_continue (c->client);
779}
780
781
782/**
783 * Handler for client's ACKs for payload traffic.
784 *
785 * @param cls identification of the client.
786 * @param msg The actual message.
787 */
788static void
789handle_local_ack (void *cls,
790 const struct GNUNET_CADET_LocalAck *msg)
791{
792 struct CadetClient *c = cls;
793 struct CadetChannel *ch;
794
795 ch = lookup_channel (c,
796 msg->ccn);
797 if (NULL == ch)
798 {
799 /* Channel does not exist (anymore) */
800 LOG (GNUNET_ERROR_TYPE_WARNING,
801 "Ignoring local ACK for channel %u from client (channel unknown, other endpoint may have disconnected)\n",
802 (unsigned int) ntohl (msg->ccn.channel_of_client));
803 GNUNET_SERVICE_client_continue (c->client);
804 return;
805 }
806 LOG (GNUNET_ERROR_TYPE_DEBUG,
807 "Got a local ACK from %s for %s\n",
808 GSC_2s (c),
809 GCCH_2s (ch));
810 GCCH_handle_local_ack (ch,
811 msg->ccn);
812 GNUNET_SERVICE_client_continue (c->client);
813}
814
815
816/**
817 * Iterator over all peers to send a monitoring client info about each peer.
818 *
819 * @param cls Closure ().
820 * @param peer Peer ID (tunnel remote peer).
821 * @param value Peer info.
822 * @return #GNUNET_YES, to keep iterating.
823 */
824static int
825get_all_peers_iterator (void *cls,
826 const struct GNUNET_PeerIdentity *peer,
827 void *value)
828{
829 struct CadetClient *c = cls;
830 struct CadetPeer *p = value;
831 struct GNUNET_MQ_Envelope *env;
832 struct GNUNET_CADET_LocalInfoPeers *msg;
833
834 env = GNUNET_MQ_msg (msg,
835 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS);
836 msg->destination = *peer;
837 msg->paths = htons (GCP_count_paths (p));
838 msg->tunnel = htons (NULL != GCP_get_tunnel (p,
839 GNUNET_NO));
840 msg->best_path_length = htonl (0); // FIXME: get length of shortest known path!
841 GNUNET_MQ_send (c->mq,
842 env);
843 return GNUNET_YES;
844}
845
846
847/**
848 * Handler for client's INFO PEERS request.
849 *
850 * @param cls Identification of the client.
851 * @param message The actual message.
852 */
853static void
854handle_get_peers (void *cls,
855 const struct GNUNET_MessageHeader *message)
856{
857 struct CadetClient *c = cls;
858 struct GNUNET_MQ_Envelope *env;
859 struct GNUNET_MessageHeader *reply;
860
861 GCP_iterate_all (&get_all_peers_iterator,
862 c);
863 env = GNUNET_MQ_msg (reply,
864 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS_END);
865 GNUNET_MQ_send (c->mq,
866 env);
867 GNUNET_SERVICE_client_continue (c->client);
868}
869
870
871/**
872 * Iterator over all paths of a peer to build an InfoPeer message.
873 * Message contains blocks of peers, first not included.
874 *
875 * @param cls message queue for transmission
876 * @param path Path itself
877 * @param off offset of the peer on @a path
878 * @return #GNUNET_YES if should keep iterating.
879 * #GNUNET_NO otherwise.
880 */
881static int
882path_info_iterator (void *cls,
883 struct CadetPeerPath *path,
884 unsigned int off)
885{
886 struct GNUNET_MQ_Handle *mq = cls;
887 struct GNUNET_MQ_Envelope *env;
888 struct GNUNET_CADET_LocalInfoPath *resp;
889 struct GNUNET_PeerIdentity *id;
890 size_t path_size;
891 unsigned int path_length;
892
893 path_length = GCPP_get_length (path);
894 path_size = sizeof(struct GNUNET_PeerIdentity) * path_length;
895 if (sizeof(*resp) + path_size > UINT16_MAX)
896 {
897 /* try just giving the relevant path */
898 path_length = GNUNET_MIN ((UINT16_MAX - sizeof(*resp)) / sizeof(struct
899 GNUNET_PeerIdentity),
900 off);
901 path_size = sizeof(struct GNUNET_PeerIdentity) * path_length;
902 }
903 if (sizeof(*resp) + path_size > UINT16_MAX)
904 {
905 LOG (GNUNET_ERROR_TYPE_WARNING,
906 "Path of %u entries is too long for info message\n",
907 path_length);
908 return GNUNET_YES;
909 }
910 env = GNUNET_MQ_msg_extra (resp,
911 path_size,
912 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PATH);
913 id = (struct GNUNET_PeerIdentity *) &resp[1];
914
915 /* Don't copy first peer. First peer is always the local one. Last
916 * peer is always the destination (leave as 0, EOL).
917 */
918 for (unsigned int i = 0; i < path_length; i++)
919 id[i] = *GCP_get_id (GCPP_get_peer_at_offset (path,
920 i));
921 resp->off = htonl (off);
922 GNUNET_MQ_send (mq,
923 env);
924 return GNUNET_YES;
925}
926
927
928/**
929 * Handler for client's #GNUNET_MESSAGE_TYPE_CADET_LOCAL_REQUEST_INFO_PATH request.
930 *
931 * @param cls Identification of the client.
932 * @param msg The actual message.
933 */
934static void
935handle_show_path (void *cls,
936 const struct GNUNET_CADET_RequestPathInfoMessage *msg)
937{
938 struct CadetClient *c = cls;
939 struct CadetPeer *p;
940 struct GNUNET_MQ_Envelope *env;
941 struct GNUNET_MessageHeader *resp;
942
943 p = GCP_get (&msg->peer,
944 GNUNET_NO);
945 if (NULL != p)
946 GCP_iterate_indirect_paths (p,
947 &path_info_iterator,
948 c->mq);
949 env = GNUNET_MQ_msg (resp,
950 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PATH_END);
951 GNUNET_MQ_send (c->mq,
952 env);
953 GNUNET_SERVICE_client_continue (c->client);
954}
955
956
957/**
958 * Iterator over all tunnels to send a monitoring client info about each tunnel.
959 *
960 * @param cls Closure ().
961 * @param peer Peer ID (tunnel remote peer).
962 * @param value a `struct CadetPeer`
963 * @return #GNUNET_YES, to keep iterating.
964 */
965static int
966get_all_tunnels_iterator (void *cls,
967 const struct GNUNET_PeerIdentity *peer,
968 void *value)
969{
970 struct CadetClient *c = cls;
971 struct CadetPeer *p = value;
972 struct GNUNET_MQ_Envelope *env;
973 struct GNUNET_CADET_LocalInfoTunnel *msg;
974 struct CadetTunnel *t;
975
976 t = GCP_get_tunnel (p,
977 GNUNET_NO);
978 if (NULL == t)
979 return GNUNET_YES;
980 env = GNUNET_MQ_msg (msg,
981 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNELS);
982 msg->destination = *peer;
983 msg->channels = htonl (GCT_count_channels (t));
984 msg->connections = htonl (GCT_count_any_connections (t));
985 msg->cstate = htons (0);
986 msg->estate = htons ((uint16_t) GCT_get_estate (t));
987 GNUNET_MQ_send (c->mq,
988 env);
989 return GNUNET_YES;
990}
991
992
993/**
994 * Handler for client's #GNUNET_MESSAGE_TYPE_CADET_LOCAL_REQUEST_INFO_TUNNELS request.
995 *
996 * @param cls client Identification of the client.
997 * @param message The actual message.
998 */
999static void
1000handle_info_tunnels (void *cls,
1001 const struct GNUNET_MessageHeader *message)
1002{
1003 struct CadetClient *c = cls;
1004 struct GNUNET_MQ_Envelope *env;
1005 struct GNUNET_MessageHeader *reply;
1006
1007 GCP_iterate_all (&get_all_tunnels_iterator,
1008 c);
1009 env = GNUNET_MQ_msg (reply,
1010 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNELS_END);
1011 GNUNET_MQ_send (c->mq,
1012 env);
1013 GNUNET_SERVICE_client_continue (c->client);
1014}
1015
1016
1017/**
1018 * Handler for client's #GNUNET_MESSAGE_TYPE_CADET_DROP_CADET_MESSAGE request.
1019 *
1020 * @param cls client Identification of the client.
1021 * @param message The actual message.
1022 */
1023static void
1024handle_drop_message (void *cls,
1025 const struct GNUNET_CADET_RequestDropCadetMessage *message)
1026{
1027 struct CadetClient *c = cls;
1028 struct CadetChannel *ch;
1029
1030 ch = lookup_channel (c,
1031 message->ccn);
1032
1033 if (NULL != ch)
1034 GCCH_assign_type_to_drop (ch, message);
1035
1036 GNUNET_SERVICE_client_continue (c->client);
1037}
1038
1039
1040/**
1041 * Callback called when a client connects to the service.
1042 *
1043 * @param cls closure for the service
1044 * @param client the new client that connected to the service
1045 * @param mq the message queue used to send messages to the client
1046 * @return @a c
1047 */
1048static void *
1049client_connect_cb (void *cls,
1050 struct GNUNET_SERVICE_Client *client,
1051 struct GNUNET_MQ_Handle *mq)
1052{
1053 struct CadetClient *c;
1054
1055 c = GNUNET_new (struct CadetClient);
1056 c->client = client;
1057 c->mq = mq;
1058 c->id = next_client_id++; /* overflow not important: just for debug */
1059 c->channels
1060 = GNUNET_CONTAINER_multihashmap32_create (32);
1061 GNUNET_CONTAINER_DLL_insert (clients_head,
1062 clients_tail,
1063 c);
1064 GNUNET_STATISTICS_update (stats,
1065 "# clients",
1066 +1,
1067 GNUNET_NO);
1068 LOG (GNUNET_ERROR_TYPE_DEBUG,
1069 "%s connected\n",
1070 GSC_2s (c));
1071 return c;
1072}
1073
1074
1075/**
1076 * A channel was destroyed by the other peer. Tell our client.
1077 *
1078 * @param c client that lost a channel
1079 * @param ccn channel identification number for the client
1080 * @param ch the channel object
1081 */
1082void
1083GSC_handle_remote_channel_destroy (struct CadetClient *c,
1084 struct GNUNET_CADET_ClientChannelNumber ccn,
1085 struct CadetChannel *ch)
1086{
1087 struct GNUNET_MQ_Envelope *env;
1088 struct GNUNET_CADET_LocalChannelDestroyMessage *tdm;
1089
1090 env = GNUNET_MQ_msg (tdm,
1091 GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_DESTROY);
1092 tdm->ccn = ccn;
1093 GSC_send_to_client (c,
1094 env);
1095 GNUNET_assert (GNUNET_YES ==
1096 GNUNET_CONTAINER_multihashmap32_remove (c->channels,
1097 ntohl (
1098 ccn.channel_of_client),
1099 ch));
1100}
1101
1102
1103void
1104GSC_drop_loose_channel (const struct GNUNET_HashCode *h_port,
1105 struct CadetChannel *ch)
1106{
1107 GNUNET_assert (GNUNET_YES ==
1108 GNUNET_CONTAINER_multihashmap_remove (loose_channels,
1109 h_port,
1110 ch));
1111}
1112
1113
1114/**
1115 * Iterator for deleting each channel whose client endpoint disconnected.
1116 *
1117 * @param cls Closure (client that has disconnected).
1118 * @param key The local channel id in host byte order
1119 * @param value The value stored at the key (channel to destroy).
1120 * @return #GNUNET_OK, keep iterating.
1121 */
1122static int
1123channel_destroy_iterator (void *cls,
1124 uint32_t key,
1125 void *value)
1126{
1127 struct CadetClient *c = cls;
1128 struct GNUNET_CADET_ClientChannelNumber ccn;
1129 struct CadetChannel *ch = value;
1130
1131 LOG (GNUNET_ERROR_TYPE_DEBUG,
1132 "Destroying %s, due to %s disconnecting.\n",
1133 GCCH_2s (ch),
1134 GSC_2s (c));
1135 ccn.channel_of_client = htonl (key);
1136 GNUNET_assert (GNUNET_YES ==
1137 GNUNET_CONTAINER_multihashmap32_remove (c->channels,
1138 key,
1139 ch));
1140 GCCH_channel_local_destroy (ch,
1141 c,
1142 ccn);
1143 return GNUNET_OK;
1144}
1145
1146
1147/**
1148 * Remove client's ports from the global hashmap on disconnect.
1149 *
1150 * @param cls the `struct CadetClient`
1151 * @param port the port.
1152 * @param value the `struct OpenPort` to remove
1153 * @return #GNUNET_OK, keep iterating.
1154 */
1155static int
1156client_release_ports (void *cls,
1157 const struct GNUNET_HashCode *port,
1158 void *value)
1159{
1160 struct CadetClient *c = cls;
1161 struct OpenPort *op = value;
1162
1163 GNUNET_assert (c == op->c);
1164 LOG (GNUNET_ERROR_TYPE_DEBUG,
1165 "Closing port %s due to %s disconnect.\n",
1166 GNUNET_h2s (port),
1167 GSC_2s (c));
1168 GNUNET_assert (GNUNET_YES ==
1169 GNUNET_CONTAINER_multihashmap_remove (open_ports,
1170 &op->h_port,
1171 op));
1172 GNUNET_assert (GNUNET_YES ==
1173 GNUNET_CONTAINER_multihashmap_remove (c->ports,
1174 port,
1175 op));
1176 GNUNET_free (op);
1177 return GNUNET_OK;
1178}
1179
1180
1181/**
1182 * Callback called when a client disconnected from the service
1183 *
1184 * @param cls closure for the service
1185 * @param client the client that disconnected
1186 * @param internal_cls should be equal to @a c
1187 */
1188static void
1189client_disconnect_cb (void *cls,
1190 struct GNUNET_SERVICE_Client *client,
1191 void *internal_cls)
1192{
1193 struct CadetClient *c = internal_cls;
1194
1195 GNUNET_assert (c->client == client);
1196 LOG (GNUNET_ERROR_TYPE_DEBUG,
1197 "%s is disconnecting.\n",
1198 GSC_2s (c));
1199 if (NULL != c->channels)
1200 {
1201 GNUNET_CONTAINER_multihashmap32_iterate (c->channels,
1202 &channel_destroy_iterator,
1203 c);
1204 GNUNET_assert (0 == GNUNET_CONTAINER_multihashmap32_size (c->channels));
1205 GNUNET_CONTAINER_multihashmap32_destroy (c->channels);
1206 }
1207 if (NULL != c->ports)
1208 {
1209 GNUNET_CONTAINER_multihashmap_iterate (c->ports,
1210 &client_release_ports,
1211 c);
1212 GNUNET_CONTAINER_multihashmap_destroy (c->ports);
1213 }
1214 GNUNET_CONTAINER_DLL_remove (clients_head,
1215 clients_tail,
1216 c);
1217 GNUNET_STATISTICS_update (stats,
1218 "# clients",
1219 -1,
1220 GNUNET_NO);
1221 GNUNET_free (c);
1222 if ((NULL == clients_head) &&
1223 (GNUNET_YES == shutting_down))
1224 shutdown_rest ();
1225}
1226
1227
1228/**
1229 * Setup CADET internals.
1230 *
1231 * @param cls closure
1232 * @param c configuration to use
1233 */
1234static void
1235run (void *cls,
1236 const struct GNUNET_CONFIGURATION_Handle *c,
1237 struct GNUNET_SERVICE_Handle *service)
1238{
1239 cfg = c;
1240 if (GNUNET_OK !=
1241 GNUNET_CONFIGURATION_get_value_number (c,
1242 "CADET",
1243 "RATCHET_MESSAGES",
1244 &ratchet_messages))
1245 {
1246 GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_WARNING,
1247 "CADET",
1248 "RATCHET_MESSAGES",
1249 "needs to be a number");
1250 ratchet_messages = 64;
1251 }
1252 if (GNUNET_OK !=
1253 GNUNET_CONFIGURATION_get_value_time (c,
1254 "CADET",
1255 "RATCHET_TIME",
1256 &ratchet_time))
1257 {
1258 GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_WARNING,
1259 "CADET",
1260 "RATCHET_TIME",
1261 "need delay value");
1262 ratchet_time = GNUNET_TIME_UNIT_HOURS;
1263 }
1264 if (GNUNET_OK !=
1265 GNUNET_CONFIGURATION_get_value_time (c,
1266 "CADET",
1267 "REFRESH_CONNECTION_TIME",
1268 &keepalive_period))
1269 {
1270 GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_WARNING,
1271 "CADET",
1272 "REFRESH_CONNECTION_TIME",
1273 "need delay value");
1274 keepalive_period = GNUNET_TIME_UNIT_MINUTES;
1275 }
1276 if (GNUNET_OK !=
1277 GNUNET_CONFIGURATION_get_value_number (c,
1278 "CADET",
1279 "DROP_PERCENT",
1280 &drop_percent))
1281 {
1282 drop_percent = 0;
1283 }
1284 else
1285 {
1286 LOG (GNUNET_ERROR_TYPE_WARNING, "**************************************\n");
1287 LOG (GNUNET_ERROR_TYPE_WARNING, "Cadet is running with DROP enabled.\n");
1288 LOG (GNUNET_ERROR_TYPE_WARNING, "This is NOT a good idea!\n");
1289 LOG (GNUNET_ERROR_TYPE_WARNING, "Remove DROP_PERCENT from config file.\n");
1290 LOG (GNUNET_ERROR_TYPE_WARNING, "**************************************\n");
1291 }
1292 my_private_key = GNUNET_CRYPTO_eddsa_key_create_from_configuration (c);
1293 if (NULL == my_private_key)
1294 {
1295 GNUNET_break (0);
1296 GNUNET_SCHEDULER_shutdown ();
1297 return;
1298 }
1299 GNUNET_CRYPTO_eddsa_key_get_public (my_private_key,
1300 &my_full_id.public_key);
1301 stats = GNUNET_STATISTICS_create ("cadet",
1302 c);
1303 GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
1304 NULL);
1305 transport = GNUNET_TRANSPORT_application_init (c);
1306 /* FIXME: optimize code to allow GNUNET_YES here! */
1307 open_ports = GNUNET_CONTAINER_multihashmap_create (16,
1308 GNUNET_NO);
1309 loose_channels = GNUNET_CONTAINER_multihashmap_create (16,
1310 GNUNET_NO);
1311 peers = GNUNET_CONTAINER_multipeermap_create (16,
1312 GNUNET_YES);
1313 connections = GNUNET_CONTAINER_multishortmap_create (256,
1314 GNUNET_YES);
1315 GCH_init (c);
1316 GCD_init (c);
1317 GCO_init (c);
1318 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1319 "CADET started for peer %s\n",
1320 GNUNET_i2s (&my_full_id));
1321}
1322
1323
1324/**
1325 * Define "main" method using service macro.
1326 */
1327GNUNET_SERVICE_MAIN
1328 ("cadet",
1329 GNUNET_SERVICE_OPTION_NONE,
1330 &run,
1331 &client_connect_cb,
1332 &client_disconnect_cb,
1333 NULL,
1334 GNUNET_MQ_hd_fixed_size (port_open,
1335 GNUNET_MESSAGE_TYPE_CADET_LOCAL_PORT_OPEN,
1336 struct GNUNET_CADET_PortMessage,
1337 NULL),
1338 GNUNET_MQ_hd_fixed_size (port_close,
1339 GNUNET_MESSAGE_TYPE_CADET_LOCAL_PORT_CLOSE,
1340 struct GNUNET_CADET_PortMessage,
1341 NULL),
1342 GNUNET_MQ_hd_fixed_size (channel_create,
1343 GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_CREATE,
1344 struct GNUNET_CADET_LocalChannelCreateMessage,
1345 NULL),
1346 GNUNET_MQ_hd_fixed_size (channel_destroy,
1347 GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_DESTROY,
1348 struct GNUNET_CADET_LocalChannelDestroyMessage,
1349 NULL),
1350 GNUNET_MQ_hd_var_size (local_data,
1351 GNUNET_MESSAGE_TYPE_CADET_LOCAL_DATA,
1352 struct GNUNET_CADET_LocalData,
1353 NULL),
1354 GNUNET_MQ_hd_fixed_size (local_ack,
1355 GNUNET_MESSAGE_TYPE_CADET_LOCAL_ACK,
1356 struct GNUNET_CADET_LocalAck,
1357 NULL),
1358 GNUNET_MQ_hd_fixed_size (get_peers,
1359 GNUNET_MESSAGE_TYPE_CADET_LOCAL_REQUEST_INFO_PEERS,
1360 struct GNUNET_MessageHeader,
1361 NULL),
1362 GNUNET_MQ_hd_fixed_size (show_path,
1363 GNUNET_MESSAGE_TYPE_CADET_LOCAL_REQUEST_INFO_PATH,
1364 struct GNUNET_CADET_RequestPathInfoMessage,
1365 NULL),
1366 GNUNET_MQ_hd_fixed_size (info_tunnels,
1367 GNUNET_MESSAGE_TYPE_CADET_LOCAL_REQUEST_INFO_TUNNELS,
1368 struct GNUNET_MessageHeader,
1369 NULL),
1370 GNUNET_MQ_hd_fixed_size (drop_message,
1371 GNUNET_MESSAGE_TYPE_CADET_DROP_CADET_MESSAGE,
1372 struct GNUNET_CADET_RequestDropCadetMessage,
1373 NULL),
1374 GNUNET_MQ_handler_end ());
1375
1376/* end of gnunet-service-cadet-new.c */