aboutsummaryrefslogtreecommitdiff
path: root/src/transport/gnunet-service-tng.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/transport/gnunet-service-tng.c')
-rw-r--r--src/transport/gnunet-service-tng.c719
1 files changed, 719 insertions, 0 deletions
diff --git a/src/transport/gnunet-service-tng.c b/src/transport/gnunet-service-tng.c
new file mode 100644
index 000000000..8cbca3188
--- /dev/null
+++ b/src/transport/gnunet-service-tng.c
@@ -0,0 +1,719 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2010-2016, 2018 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/**
19 * @file transport/gnunet-service-transport.c
20 * @brief main for gnunet-service-transport
21 * @author Christian Grothoff
22 */
23#include "platform.h"
24#include "gnunet_util_lib.h"
25#include "gnunet_statistics_service.h"
26#include "gnunet_transport_service.h"
27#include "gnunet_peerinfo_service.h"
28#include "gnunet_ats_service.h"
29#include "gnunet-service-transport.h"
30#include "transport.h"
31
32
33/**
34 * How many messages can we have pending for a given client process
35 * before we start to drop incoming messages? We typically should
36 * have only one client and so this would be the primary buffer for
37 * messages, so the number should be chosen rather generously.
38 *
39 * The expectation here is that most of the time the queue is large
40 * enough so that a drop is virtually never required. Note that
41 * this value must be about as large as 'TOTAL_MSGS' in the
42 * 'test_transport_api_reliability.c', otherwise that testcase may
43 * fail.
44 */
45#define MAX_PENDING (128 * 1024)
46
47
48/**
49 * What type of client is the `struct TransportClient` about?
50 */
51enum ClientType
52{
53 /**
54 * We do not know yet (client is fresh).
55 */
56 CT_NONE = 0,
57
58 /**
59 * Is the CORE service, we need to forward traffic to it.
60 */
61 CT_CORE = 1,
62
63 /**
64 * It is a monitor, forward monitor data.
65 */
66 CT_MONITOR = 2,
67
68 /**
69 * It is a communicator, use for communication.
70 */
71 CT_COMMUNICATOR = 3
72};
73
74
75/**
76 * Client connected to the transport service.
77 */
78struct TransportClient
79{
80
81 /**
82 * Kept in a DLL.
83 */
84 struct TransportClient *next;
85
86 /**
87 * Kept in a DLL.
88 */
89 struct TransportClient *prev;
90
91 /**
92 * Handle to the client.
93 */
94 struct GNUNET_SERVICE_Client *client;
95
96 /**
97 * Message queue to the client.
98 */
99 struct GNUNET_MQ_Handle *mq;
100
101 /**
102 * What type of client is this?
103 */
104 enum ClientType type;
105
106 union
107 {
108
109 /**
110 * Peer identity to monitor the addresses of.
111 * Zero to monitor all neighbours. Valid if
112 * @e type is #CT_MONITOR.
113 */
114 struct GNUNET_PeerIdentity monitor_peer;
115
116 /**
117 * If @e type is #CT_COMMUNICATOR, this communicator
118 * supports communicating using these addresses.
119 */
120 const char *address_prefix;
121
122 } details;
123
124};
125
126
127/**
128 * Head of linked list of all clients to this service.
129 */
130static struct TransportClient *clients_head;
131
132/**
133 * Tail of linked list of all clients to this service.
134 */
135static struct TransportClient *clients_tail;
136
137/**
138 * Statistics handle.
139 */
140struct GNUNET_STATISTICS_Handle *GST_stats;
141
142/**
143 * Configuration handle.
144 */
145const struct GNUNET_CONFIGURATION_Handle *GST_cfg;
146
147/**
148 * Configuration handle.
149 */
150struct GNUNET_PeerIdentity GST_my_identity;
151
152/**
153 * Handle to peerinfo service.
154 */
155struct GNUNET_PEERINFO_Handle *GST_peerinfo;
156
157/**
158 * Our private key.
159 */
160struct GNUNET_CRYPTO_EddsaPrivateKey *GST_my_private_key;
161
162
163/**
164 * Called whenever a client connects. Allocates our
165 * data structures associated with that client.
166 *
167 * @param cls closure, NULL
168 * @param client identification of the client
169 * @param mq message queue for the client
170 * @return our `struct TransportClient`
171 */
172static void *
173client_connect_cb (void *cls,
174 struct GNUNET_SERVICE_Client *client,
175 struct GNUNET_MQ_Handle *mq)
176{
177 struct TransportClient *tc;
178
179 tc = GNUNET_new (struct TransportClient);
180 tc->client = client;
181 tc->mq = mq;
182 GNUNET_CONTAINER_DLL_insert (clients_head,
183 clients_tail,
184 tc);
185 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
186 "Client %p connected\n",
187 tc);
188 return tc;
189}
190
191
192/**
193 * Called whenever a client is disconnected. Frees our
194 * resources associated with that client.
195 *
196 * @param cls closure, NULL
197 * @param client identification of the client
198 * @param app_ctx our `struct TransportClient`
199 */
200static void
201client_disconnect_cb (void *cls,
202 struct GNUNET_SERVICE_Client *client,
203 void *app_ctx)
204{
205 struct TransportClient *tc = app_ctx;
206
207 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
208 "Client %p disconnected, cleaning up.\n",
209 tc);
210 GNUNET_CONTAINER_DLL_remove (clients_head,
211 clients_tail,
212 tc);
213 switch (tc->type)
214 {
215 case CT_NONE:
216 break;
217 case CT_CORE:
218 break;
219 case CT_MONITOR:
220 break;
221 case CT_COMMUNICATOR:
222 break;
223 }
224 GNUNET_free (tc);
225}
226
227
228/**
229 * Initialize a "CORE" client. We got a start message from this
230 * client, so add it to the list of clients for broadcasting of
231 * inbound messages.
232 *
233 * @param cls the client
234 * @param start the start message that was sent
235 */
236static void
237handle_client_start (void *cls,
238 const struct StartMessage *start)
239{
240 struct TransportClient *tc = cls;
241 const struct GNUNET_MessageHeader *hello;
242 uint32_t options;
243
244 options = ntohl (start->options);
245 if ( (0 != (1 & options)) &&
246 (0 !=
247 memcmp (&start->self,
248 &GST_my_identity,
249 sizeof (struct GNUNET_PeerIdentity)) ) )
250 {
251 /* client thinks this is a different peer, reject */
252 GNUNET_break (0);
253 GNUNET_SERVICE_client_drop (tc->client);
254 return;
255 }
256 if (CT_NONE != tc->type)
257 {
258 GNUNET_break (0);
259 GNUNET_SERVICE_client_drop (tc->client);
260 return;
261 }
262 tc->type = CT_CORE;
263#if 0
264 hello = GST_hello_get ();
265 if (NULL != hello)
266 unicast (tc,
267 hello,
268 GNUNET_NO);
269#endif
270 GNUNET_SERVICE_client_continue (tc->client);
271}
272
273
274/**
275 * Client sent us a HELLO. Check the request.
276 *
277 * @param cls the client
278 * @param message the HELLO message
279 */
280static int
281check_client_hello (void *cls,
282 const struct GNUNET_MessageHeader *message)
283{
284 (void) cls;
285 return GNUNET_OK; /* FIXME: check here? */
286}
287
288
289/**
290 * Client sent us a HELLO. Process the request.
291 *
292 * @param cls the client
293 * @param message the HELLO message
294 */
295static void
296handle_client_hello (void *cls,
297 const struct GNUNET_MessageHeader *message)
298{
299 struct TransportClient *tc = cls;
300
301 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
302 "Received HELLO message\n");
303 GNUNET_SERVICE_client_continue (tc->client);
304}
305
306
307/**
308 * Client asked for transmission to a peer. Process the request.
309 *
310 * @param cls the client
311 * @param obm the send message that was sent
312 */
313static int
314check_client_send (void *cls,
315 const struct OutboundMessage *obm)
316{
317 uint16_t size;
318 const struct GNUNET_MessageHeader *obmm;
319
320 (void) cls;
321 size = ntohs (obm->header.size) - sizeof (struct OutboundMessage);
322 if (size < sizeof (struct GNUNET_MessageHeader))
323 {
324 GNUNET_break (0);
325 return GNUNET_SYSERR;
326 }
327 obmm = (const struct GNUNET_MessageHeader *) &obm[1];
328 if (size != ntohs (obmm->size))
329 {
330 GNUNET_break (0);
331 return GNUNET_SYSERR;
332 }
333 return GNUNET_OK;
334}
335
336
337/**
338 * Client asked for transmission to a peer. Process the request.
339 *
340 * @param cls the client
341 * @param obm the send message that was sent
342 */
343static void
344handle_client_send (void *cls,
345 const struct OutboundMessage *obm)
346{
347 struct TransportClient *tc = cls;
348 const struct GNUNET_MessageHeader *obmm;
349
350 obmm = (const struct GNUNET_MessageHeader *) &obm[1];
351}
352
353
354/**
355 * Communicator started. Test message is well-formed.
356 *
357 * @param cls the client
358 * @param cam the send message that was sent
359 */
360static int
361check_communicator_available (void *cls,
362 const struct GNUNET_TRANSPORT_CommunicatorAvailableMessage *cam)
363{
364 const char *addr;
365 uint16_t size;
366
367 (void) cls;
368 size = ntohs (cam->header.size) - sizeof (*cam);
369 if (0 == size)
370 return GNUNET_OK; /* receive-only communicator */
371 addr = (const char *) &cam[1];
372 if ('\0' != addr[size-1])
373 {
374 GNUNET_break (0);
375 return GNUNET_SYSERR;
376 }
377 return GNUNET_OK;
378}
379
380
381/**
382 * Communicator started. Process the request.
383 *
384 * @param cls the client
385 * @param cam the send message that was sent
386 */
387static void
388handle_communicator_available (void *cls,
389 const struct GNUNET_TRANSPORT_CommunicatorAvailableMessage *cam)
390{
391 struct TransportClient *tc = cls;
392 uint16_t size;
393
394 if (CT_NONE != tc->type)
395 {
396 GNUNET_break (0);
397 GNUNET_SERVICE_client_drop (tc->client);
398 return;
399 }
400 tc->type = CT_COMMUNICATOR;
401 size = ntohs (cam->header.size) - sizeof (*cam);
402 if (0 == size)
403 return GNUNET_OK; /* receive-only communicator */
404 tc->details.address_prefix = GNUNET_strdup ((const char *) &cam[1]);
405 GNUNET_SERVICE_client_continue (tc->client);
406}
407
408
409/**
410 * Address of our peer added. Test message is well-formed.
411 *
412 * @param cls the client
413 * @param aam the send message that was sent
414 */
415static int
416check_add_address (void *cls,
417 const struct GNUNET_TRANSPORT_AddAddressMessage *aam)
418{
419 const char *addr;
420 uint16_t size;
421
422 (void) cls;
423 size = ntohs (aam->header.size) - sizeof (*aam);
424 if (0 == size)
425 {
426 GNUNET_break (0);
427 return GNUNET_SYSERR;
428 }
429 addr = (const char *) &cam[1];
430 if ('\0' != addr[size-1])
431 {
432 GNUNET_break (0);
433 return GNUNET_SYSERR;
434 }
435 return GNUNET_OK;
436}
437
438
439/**
440 * Address of our peer added. Process the request.
441 *
442 * @param cls the client
443 * @param aam the send message that was sent
444 */
445static void
446handle_add_address (void *cls,
447 const struct GNUNET_TRANSPORT_AddAddressMessage *aam)
448{
449 struct TransportClient *tc = cls;
450
451 GNUNET_SERVICE_client_continue (tc->client);
452}
453
454
455/**
456 * Address of our peer deleted. Process the request.
457 *
458 * @param cls the client
459 * @param dam the send message that was sent
460 */
461static void
462handle_del_address (void *cls,
463 const struct GNUNET_TRANSPORT_DelAddressMessage *dam)
464{
465 struct TransportClient *tc = cls;
466
467 GNUNET_SERVICE_client_continue (tc->client);
468}
469
470
471/**
472 * Client asked for transmission to a peer. Process the request.
473 *
474 * @param cls the client
475 * @param obm the send message that was sent
476 */
477static int
478check_incoming_msg (void *cls,
479 const struct GNUNET_TRANSPORT_IncomingMessage *im)
480{
481 uint16_t size;
482 const struct GNUNET_MessageHeader *obmm;
483
484 (void) cls;
485 size = ntohs (im->header.size) - sizeof (*im);
486 if (size < sizeof (struct GNUNET_MessageHeader))
487 {
488 GNUNET_break (0);
489 return GNUNET_SYSERR;
490 }
491 obmm = (const struct GNUNET_MessageHeader *) &im[1];
492 if (size != ntohs (obmm->size))
493 {
494 GNUNET_break (0);
495 return GNUNET_SYSERR;
496 }
497 return GNUNET_OK;
498}
499
500
501/**
502 * Incoming meessage. Process the request.
503 *
504 * @param cls the client
505 * @param im the send message that was received
506 */
507static void
508handle_incoming_msg (void *cls,
509 const struct GNUNET_TRANSPORT_IncomingMessage *im)
510{
511 struct TransportClient *tc = cls;
512
513 GNUNET_SERVICE_client_continue (tc->client);
514}
515
516
517/**
518 * New queue became available. Check message.
519 *
520 * @param cls the client
521 * @param aqm the send message that was sent
522 */
523static int
524check_add_queue_message (void *cls,
525 const struct GNUNET_TRANSPORT_AddQueueMessage *aqm)
526{
527 const char *addr;
528 uint16_t size;
529
530 (void) cls;
531 size = ntohs (aqm->header.size) - sizeof (*aqm);
532 if (0 == size)
533 {
534 GNUNET_break (0);
535 return GNUNET_SYSERR;
536 }
537 addr = (const char *) &aqm[1];
538 if ('\0' != addr[size-1])
539 {
540 GNUNET_break (0);
541 return GNUNET_SYSERR;
542 }
543 return GNUNET_OK;
544}
545
546
547/**
548 * New queue became available. Process the request.
549 *
550 * @param cls the client
551 * @param aqm the send message that was sent
552 */
553static void
554handle_add_queue_message (void *cls,
555 const struct GNUNET_TRANSPORT_AddQueueMessage *aqm)
556{
557 struct TransportClient *tc = cls;
558
559 GNUNET_SERVICE_client_continue (tc->client);
560}
561
562
563/**
564 * Queue to a peer went down. Process the request.
565 *
566 * @param cls the client
567 * @param dqm the send message that was sent
568 */
569static void
570handle_del_queue_message (void *cls,
571 const struct GNUNET_TRANSPORT_DelQueueMessage *dqm)
572{
573 struct TransportClient *tc = cls;
574
575 GNUNET_SERVICE_client_continue (tc->client);
576}
577
578
579/**
580 * Message was transmitted. Process the request.
581 *
582 * @param cls the client
583 * @param sma the send message that was sent
584 */
585static void
586handle_send_message_ack (void *cls,
587 const struct GNUNET_TRANSPORT_SendMessageToAck *sma)
588{
589 struct TransportClient *tc = cls;
590
591 GNUNET_SERVICE_client_continue (tc->client);
592}
593
594
595/**
596 * Function called when the service shuts down. Unloads our plugins
597 * and cancels pending validations.
598 *
599 * @param cls closure, unused
600 */
601static void
602shutdown_task (void *cls)
603{
604 (void) cls;
605
606 if (NULL != GST_stats)
607 {
608 GNUNET_STATISTICS_destroy (GST_stats,
609 GNUNET_NO);
610 GST_stats = NULL;
611 }
612 if (NULL != GST_my_private_key)
613 {
614 GNUNET_free (GST_my_private_key);
615 GST_my_private_key = NULL;
616 }
617}
618
619
620/**
621 * Initiate transport service.
622 *
623 * @param cls closure
624 * @param c configuration to use
625 * @param service the initialized service
626 */
627static void
628run (void *cls,
629 const struct GNUNET_CONFIGURATION_Handle *c,
630 struct GNUNET_SERVICE_Handle *service)
631{
632 /* setup globals */
633 GST_cfg = c;
634 if (GNUNET_OK !=
635 GNUNET_CONFIGURATION_get_value_time (c,
636 "transport",
637 "HELLO_EXPIRATION",
638 &hello_expiration))
639 {
640 hello_expiration = GNUNET_CONSTANTS_HELLO_ADDRESS_EXPIRATION;
641 }
642 GST_my_private_key = GNUNET_CRYPTO_eddsa_key_create_from_configuration (cfg);
643 if (NULL == GST_my_private_key)
644 {
645 GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
646 _("Transport service is lacking key configuration settings. Exiting.\n"));
647 GNUNET_SCHEDULER_shutdown ();
648 return;
649 }
650 GNUNET_CRYPTO_eddsa_key_get_public (GST_my_private_key,
651 &GST_my_identity.public_key);
652 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
653 "My identity is `%s'\n",
654 GNUNET_i2s_full (&GST_my_identity));
655
656 GST_stats = GNUNET_STATISTICS_create ("transport",
657 GST_cfg);
658 GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
659 NULL);
660 /* start subsystems */
661}
662
663
664/**
665 * Define "main" method using service macro.
666 */
667GNUNET_SERVICE_MAIN
668("transport",
669 GNUNET_SERVICE_OPTION_NONE,
670 &run,
671 &client_connect_cb,
672 &client_disconnect_cb,
673 NULL,
674 /* communication with core */
675 GNUNET_MQ_hd_fixed_size (client_start,
676 GNUNET_MESSAGE_TYPE_TRANSPORT_START,
677 struct StartMessage,
678 NULL),
679 GNUNET_MQ_hd_var_size (client_hello,
680 GNUNET_MESSAGE_TYPE_HELLO,
681 struct GNUNET_MessageHeader,
682 NULL),
683 GNUNET_MQ_hd_var_size (client_send,
684 GNUNET_MESSAGE_TYPE_TRANSPORT_SEND,
685 struct OutboundMessage,
686 NULL),
687 /* communication with communicators */
688 GNUNET_MQ_hd_var_size (communicator_available,
689 GNUNET_MESSAGE_TYPE_TRANSPORT_NEW_COMMUNICATOR,
690 struct GNUNET_TRANSPORT_CommunicatorAvailableMessage,
691 NULL),
692 GNUNET_MQ_hd_var_size (add_address,
693 GNUNET_MESSAGE_TYPE_TRANSPORT_ADD_ADDRESS,
694 struct GNUNET_TRANSPORT_AddAddressMessage,
695 NULL),
696 GNUNET_MQ_hd_fixed_size (del_address,
697 GNUNET_MESSAGE_TYPE_TRANSPORT_DEL_ADDRESS,
698 struct GNUNET_TRANSPORT_DelAddressMessage,
699 NULL),
700 GNUNET_MQ_hd_var_size (incoming_msg,
701 GNUNET_MESSAGE_TYPE_TRANSPORT_INCOMING_MSG,
702 struct GNUNET_TRANSPORT_IncomingMessage,
703 NULL),
704 GNUNET_MQ_hd_var_size (add_queue_message,
705 GNUNET_MESSAGE_TYPE_TRANSPORT_QUEUE_SETUP,
706 struct GNUNET_TRANSPORT_AddQueueMessage,
707 NULL),
708 GNUNET_MQ_hd_fixed_size (del_queue_message,
709 GNUNET_MESSAGE_TYPE_TRANSPORT_QUEUE_TEARDOWN,
710 struct GNUNET_TRANSPORT_DelQueueMessage,
711 NULL),
712 GNUNET_MQ_hd_fixed_size (send_message_ack,
713 GNUNET_MESSAGE_TYPE_TRANSPORT_SEND_MSG_ACK,
714 struct GNUNET_TRANSPORT_SendMessageToAck,
715 NULL),
716 GNUNET_MQ_handler_end ());
717
718
719/* end of file gnunet-service-transport.c */