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