GNUnet 0.26.2-106-g126384b46
 
Loading...
Searching...
No Matches
gnunet-service-core.c
Go to the documentation of this file.
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2009, 2010, 2011, 2016, 2026 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
26#include "gnunet_common.h"
27#include "platform.h"
28#include <gcrypt.h>
29#include "gnunet_util_lib.h"
30#include "gnunet-service-core.h"
33#include "gnunet_constants.h"
34#include "gnunet_pils_service.h"
35
42#define SOFT_MAX_QUEUE 128
43
49#define HARD_MAX_QUEUE 256
50
51
52struct GSC_ServicesInfo;
53
58{
63
68
73
78
84 uint16_t *types;
85
91
96
101 uint32_t options;
102
108
113 unsigned int tcnt;
114};
115
116
121
126
131
136
141
145static uint32_t all_client_options;
146
150static struct GSC_Client *client_head;
151
155static struct GSC_Client *client_tail;
156
157// TODO
159
160/*************************************
161 * Services Info Utils *
162 ************************************/
163
164// TODO put into gnunet-service-core_services_info.[h|c]
165// TODO write its own test
166// TODO rewrite: don't keep the big string, have only a known data structure
167// (DLL? array?) have a from_string() and a to_string()
168
169// TODO
171{
172 // TODO
173 // pointer to the beginning of service name
174 char *name; // TODO find syntax to set array size to num_entries
175 // TODO
176 uint32_t name_len;
177 // TODO
178 // pointer to the beginning of service version
179 char *version; // TODO find syntax to set array size to num_entries
180 // TODO
181 uint32_t version_len;
182};
183
184// TODO
186{
187 // TODO
188 uint32_t num_entries;
189
190 // TODO
192};
193
194// TODO
195// (?) _remove()
196// (?) _iter()
197
198// TODO
199static struct GSC_ServicesInfo *
201{
202 struct GSC_ServicesInfo *services_info = GNUNET_new (struct GSC_ServicesInfo);
203 services_info->num_entries = 0;
204 services_info->entries = NULL;
205 return services_info;
206}
207
208
209// TODO
210static void
211GSC_SVCI_destroy (struct GSC_ServicesInfo *services_info)
212{
213 GNUNET_assert (NULL != services_info);
214 GNUNET_free (services_info);
215}
216
217
218// TODO
219// todo check string size while adding!
220static void
222 char *name, uint32_t name_len,
223 char *version, uint32_t version_len)
224{
225 struct GSC_ServicesInfo_Entry *entry;
226
227 GNUNET_array_grow (services->entries, services->num_entries, 1);
228 entry = &services->entries[services->num_entries - 1];
229 entry->name = GNUNET_strdup (name);
230 entry->name_len = name_len;
231 entry->version = GNUNET_strdup (version);
232 entry->version_len = version_len;
233}
234
235
236// TODO
237static void
239 char *name, uint32_t name_len)
240{
241 struct GSC_ServicesInfo_Entry *entry;
242 uint64_t i_entry;
243
244 /* Find element */
245 entry = NULL;
246 for (uint64_t i = 0; i < services->num_entries; i++)
247 {
248 if (services->entries[i].name_len != name_len)
249 continue;
250 if (0 == memcmp (&services->entries[i].name, name, name_len))
251 {
252 entry = &services->entries[i];
253 i_entry = i;
254 break;
255 }
256 }
257 if (NULL == entry)
258 {
259 /* No matching entry was found!*/
261 "No matching service entry `%s' was found in services info.\n",
262 name);
263 return;
264 }
265
266 /* Remove element */
267 GNUNET_free (entry->name);
268 GNUNET_free (entry->version);
269 for (uint64_t i = i_entry; i < services->num_entries - 1; i++)
270 {
271 GNUNET_memcpy (&services->entries[i],
272 &services->entries[i + 1],
273 sizeof (services->entries[i + 1]));
274 }
275 GNUNET_array_grow (services->entries,
276 services->num_entries,
277 services->num_entries - 1);
278}
279
280
281/*************************************
282 * End of Services Info Utils *
283 ************************************/
284
285
293static int
294type_match (uint16_t type, struct GSC_Client *c)
295{
296 if ((0 == c->tcnt) && (0 != c->options))
297 return GNUNET_YES; /* peer without handlers and inbound/outbond
298 callbacks matches ALL */
299 if (NULL == c->types)
300 return GNUNET_NO;
301 for (unsigned int i = 0; i < c->tcnt; i++)
302 if (type == c->types[i])
303 return GNUNET_YES;
304 return GNUNET_NO;
305}
306
307
315static int
316check_client_init (void *cls, const struct InitMessage *im)
317{
318 return GNUNET_OK;
319}
320
321
328static void
329handle_client_init (void *cls, const struct InitMessage *im)
330{
331 const struct GNUNET_PeerIdentity *my_identity;
332 struct GSC_Client *c = cls;
333 struct GNUNET_MQ_Envelope *env;
334 struct InitReplyMessage *irm;
335 uint16_t msize;
336 const uint16_t *types;
337
339 GNUNET_assert (NULL != my_identity);
340
341 /* check that we don't have an entry already */
342 msize = ntohs (im->header.size) - sizeof(struct InitMessage);
343 types = (const uint16_t *) &im[1];
344 c->tcnt = msize / sizeof(uint16_t);
345 c->options = ntohl (im->options);
346 c->got_init = GNUNET_YES;
348 c->types = GNUNET_malloc (msize);
351 c->connectmap,
353 NULL,
355 for (unsigned int i = 0; i < c->tcnt; i++)
356 c->types[i] = ntohs (types[i]);
357 // TODO
358 GSC_SVCI_add (own_services, "example", 7, "0.1", 3);
359 GNUNET_log (
361 "Client connecting to core service is interested in %u message types\n",
362 (unsigned int) c->tcnt);
363 for (unsigned int i = 0; i < c->tcnt; i++)
365 " type[%u]: %u\n",
366 i,
367 c->types[i]);
368 /* send init reply message */
370 irm->reserved = htonl (0);
371 irm->my_identity = *my_identity;
372 irm->class = GSC_peer_class;
373 GNUNET_MQ_send (c->mq, env);
376}
377
378
391void
393 int drop_client)
394{
396 GNUNET_YES ==
398 &car->target,
399 car));
400 if (GNUNET_YES == drop_client)
402 GNUNET_free (car);
403}
404
405
413void
415{
416 struct GSC_Client *c;
417 struct GNUNET_MQ_Envelope *env;
418 struct SendMessageReady *smr;
419 struct GNUNET_TIME_Relative delay;
420 struct GNUNET_TIME_Relative left;
421
422 c = car->client_handle;
423 if (GNUNET_YES !=
425 {
426 const struct GNUNET_PeerIdentity *my_identity;
428 GNUNET_assert (NULL != my_identity);
429 /* connection has gone down since, drop request */
430 GNUNET_assert (0 !=
431 GNUNET_memcmp (&car->target,
432 my_identity));
435 return;
436 }
439 if (delay.rel_value_us > GNUNET_CONSTANTS_LATENCY_WARN.rel_value_us)
440 GNUNET_log (
442 "Client waited %s for permission to transmit to `%s'%s (priority %u)\n",
444 GNUNET_i2s (&car->target),
445 (0 == left.rel_value_us) ? " (past deadline)" : "",
446 car->priority);
448 smr->size = htons (car->msize);
449 smr->smr_id = car->smr_id;
450 smr->peer = car->target;
451 GNUNET_MQ_send (c->mq, env);
452}
453
454
461static void
462handle_client_send_request (void *cls, const struct SendMessageRequest *req)
463{
464 const struct GNUNET_PeerIdentity *my_identity;
465 struct GSC_Client *c = cls;
466 struct GSC_ClientActiveRequest *car;
467 int is_loopback;
468
470 GNUNET_assert (NULL != my_identity);
471
472 if (NULL == c->requests)
475 "Client asked for transmission to `%s'\n",
476 GNUNET_i2s (&req->peer));
477 is_loopback = (0 == GNUNET_memcmp (&req->peer, my_identity));
478 if ((! is_loopback) &&
479 (GNUNET_YES !=
481 {
482 /* neighbour must have disconnected since request was issued,
483 * ignore (client will realize it once it processes the
484 * disconnect notification) */
487 "# send requests dropped (disconnected)"),
488 1,
489 GNUNET_NO);
491 return;
492 }
493
495 if (NULL == car)
496 {
497 /* create new entry */
498 car = GNUNET_new (struct GSC_ClientActiveRequest);
501 c->requests,
502 &req->peer,
503 car,
505 car->client_handle = c;
506 }
507 else
508 {
509 /* dequeue and recycle memory from pending request, there can only
510 be at most one per client and peer */
513 "# dequeuing CAR (duplicate request)"),
514 1,
515 GNUNET_NO);
518 "Transmission request to `%s' was a duplicate!\n",
519 GNUNET_i2s (&req->peer));
520 }
521 car->target = req->peer;
524 car->priority = ntohl (req->priority);
525 car->msize = ntohs (req->size);
526 car->smr_id = req->smr_id;
529 if (is_loopback)
530 {
531 /* loopback, satisfy immediately */
533 return;
534 }
536}
537
538
554
555
568static int
569tokenized_cb (void *cls, const struct GNUNET_MessageHeader *message)
570{
571 const struct GNUNET_PeerIdentity *my_identity;
572 struct TokenizerContext *tc = cls;
573 struct GSC_ClientActiveRequest *car = tc->car;
574 char buf[92];
575
577 GNUNET_assert (NULL != my_identity);
578
579 GNUNET_snprintf (buf,
580 sizeof(buf),
581 gettext_noop ("# bytes of messages of type %u received"),
582 (unsigned int) ntohs (message->type));
583 GNUNET_STATISTICS_update (GSC_stats, buf, ntohs (message->size), GNUNET_NO);
584 if (0 == GNUNET_memcmp (&car->target, my_identity))
585 {
587 "Delivering message of type %u to myself\n",
588 ntohs (message->type));
590 message,
591 ntohs (message->size),
594 message,
595 sizeof(struct GNUNET_MessageHeader),
598 message,
599 ntohs (message->size),
602 message,
603 sizeof(struct GNUNET_MessageHeader),
605 }
606 else
607 {
609 "Delivering message of type %u and size %u to %s\n",
610 ntohs (message->type),
611 ntohs (message->size),
612 GNUNET_i2s (&car->target));
614 message,
615 ntohs (message->size),
618 message,
619 sizeof(struct GNUNET_MessageHeader),
621 GSC_SESSIONS_transmit (car, message, tc->priority);
622 }
623 return GNUNET_OK;
624}
625
626
634static int
635check_client_send (void *cls, const struct SendMessage *sm)
636{
637 return GNUNET_OK;
638}
639
640
647static void
648handle_client_send (void *cls, const struct SendMessage *sm)
649{
650 struct GSC_Client *c = cls;
651 struct TokenizerContext tc;
652 uint16_t msize;
653 struct GNUNET_TIME_Relative delay;
655
656 msize = ntohs (sm->header.size) - sizeof(struct SendMessage);
658 if (NULL == tc.car)
659 {
660 /* Must have been that we first approved the request, then got disconnected
661 * (which triggered removal of the 'car') and now the client gives us a message
662 * just *before* the client learns about the disconnect. Theoretically, we
663 * might also now be *again* connected. So this can happen (but should be
664 * rare). If it does happen, the message is discarded. */
667 "# messages discarded (session disconnected)"),
668 1,
669 GNUNET_NO);
671 return;
672 }
673 delay = GNUNET_TIME_absolute_get_duration (tc.car->received_time);
674 tc.priority = ntohl (sm->priority);
675 if (delay.rel_value_us > GNUNET_CONSTANTS_LATENCY_WARN.rel_value_us)
677 "Client waited %s for transmission of %u bytes to `%s'\n",
679 msize,
680 GNUNET_i2s (&sm->peer));
681 else
683 "Client waited %s for transmission of %u bytes to `%s'\n",
685 msize,
686 GNUNET_i2s (&sm->peer));
687
689 GNUNET_YES ==
693 (const char *) &sm[1],
694 msize,
696 GNUNET_NO);
697 GNUNET_MST_destroy (mst);
699 GNUNET_free (tc.car);
701}
702
703
712static int
714 const struct GNUNET_PeerIdentity *key,
715 void *value)
716{
717 struct GSC_ClientActiveRequest *car = value;
718
720 GNUNET_YES ==
722 &car->target,
723 car));
725 GNUNET_free (car);
726 return GNUNET_YES;
727}
728
729
738static void *
740 struct GNUNET_SERVICE_Client *client,
741 struct GNUNET_MQ_Handle *mq)
742{
743 struct GSC_Client *c;
744
745 c = GNUNET_new (struct GSC_Client);
746 c->client = client;
747 c->mq = mq;
750 return c;
751}
752
753
761static void
764 void *app_ctx)
765{
766 struct GSC_Client *c = app_ctx;
767
769 "Client %p has disconnected from core service.\n",
770 client);
772 if (NULL != c->requests)
773 {
776 NULL);
778 }
780 c->connectmap = NULL;
781 // TODO
782 GSC_SVCI_remove (own_services, "example", 7);
783
784 /* recalculate 'all_client_options' */
786 for (c = client_head; NULL != c; c = c->next)
788}
789
790
802void
804 struct GSC_Client *client,
805 const struct GNUNET_PeerIdentity *neighbour,
806 enum GNUNET_CORE_PeerClass class)
807{
808 struct GNUNET_MQ_Envelope *env;
809 struct ConnectNotifyMessage *cnm;
810
811 if (GNUNET_YES != client->got_init)
812 return;
813 // TODO
814 // GSC_SVCI_contains (own_services, "example", 7);
816 "Notifying client about neighbour %s\n",
817 GNUNET_i2s (neighbour));
818
819 /* send connect */
820 // TODO this used to be an assert. evaluate what handling makes sense here.
822 neighbour))
823 {
824 return;
825 }
828 client->connectmap,
829 neighbour,
830 NULL,
833 cnm->reserved = htonl (0);
835 "Sending NOTIFY_CONNECT message about peer %s to client.\n",
836 GNUNET_i2s (neighbour));
837 cnm->peer = *neighbour;
838 cnm->peer_class = class;
839 GNUNET_MQ_send (client->mq, env);
840}
841
842
848void
860
861
872void
874 const struct GNUNET_PeerIdentity *neighbour,
875 enum GNUNET_CORE_PeerClass class)
876{
877 struct GSC_Client *c;
878
879 for (c = client_head; NULL != c; c = c->next)
881 neighbour,
882 class);
883}
884
885
897void
899 const struct GNUNET_MessageHeader *msg,
900 uint16_t msize,
901 uint32_t options)
902{
903 size_t size = msize + sizeof(struct NotifyTrafficMessage);
904
906 {
907 GNUNET_break (0);
908 return;
909 }
910 if (! ((0 != (all_client_options & options)) ||
912 {
913 return; /* no client cares about this message notification */
914 }
916 "Core service passes message from `%s' of type %u to client.\n",
917 GNUNET_i2s (sender),
918 (unsigned int) ntohs (msg->type));
919 // TODO
920 // GSC_SVCI_add (sender->services, "example", 7, "0.1", 3);
921
922 for (struct GSC_Client *c = client_head; NULL != c; c = c->next)
923 {
924 struct GNUNET_MQ_Envelope *env;
925 struct NotifyTrafficMessage *ntm;
926 uint16_t mtype;
927 unsigned int qlen;
928 int tm;
929
930 tm = type_match (ntohs (msg->type), c);
931 if (! ((0 != (c->options & options)) ||
933 (GNUNET_YES == tm))))
934 continue; /* neither options nor type match permit the message */
936 ((0 != (c->options & GNUNET_CORE_OPTION_SEND_FULL_INBOUND)) ||
937 (GNUNET_YES == tm)))
938 continue;
940 (0 != (c->options & GNUNET_CORE_OPTION_SEND_FULL_OUTBOUND)))
941 continue;
942
943 /* Drop messages if:
944 1) We are above the hard limit, or
945 2) We are above the soft limit, and a coin toss limited
946 to the message size (giving larger messages a
947 proportionally higher chance of being queued) falls
948 below the threshold. The threshold is based on where
949 we are between the soft and the hard limit, scaled
950 to match the range of message sizes we usually encounter
951 (i.e. up to 32k); so a 64k message has a 50% chance of
952 being kept if we are just barely below the hard max,
953 and a 99% chance of being kept if we are at the soft max.
954 The reason is to make it more likely to drop control traffic
955 (ACK, queries) which may be cumulative or highly redundant,
956 and cheap to drop than data traffic. */qlen = GNUNET_MQ_get_length (c->mq);
957 if ((qlen >= HARD_MAX_QUEUE) ||
958 ((qlen > SOFT_MAX_QUEUE) &&
960 ntohs (msg->size))) <
961 (qlen - SOFT_MAX_QUEUE) * 0x8000
963 {
964 char buf[1024];
965
966 GNUNET_log (
968 "Dropping decrypted message of type %u as client is too busy (queue full)\n",
969 (unsigned int) ntohs (msg->type));
970 GNUNET_snprintf (buf,
971 sizeof(buf),
973 "# messages of type %u discarded (client busy)"),
974 (unsigned int) ntohs (msg->type));
976 continue;
977 }
978
979 GNUNET_log (
981 "Sending %u message with %u bytes to client interested in messages of type %u.\n",
982 options,
983 ntohs (msg->size),
984 (unsigned int) ntohs (msg->type));
985
989 else
991 env = GNUNET_MQ_msg_extra (ntm, msize, mtype);
992 ntm->peer = *sender;
993 GNUNET_memcpy (&ntm[1], msg, msize);
994
996 (0 == (c->options & GNUNET_CORE_OPTION_SEND_FULL_INBOUND)) ||
997 (GNUNET_YES != tm) ||
998 (GNUNET_YES ==
999 GNUNET_CONTAINER_multipeermap_contains (c->connectmap, sender)));
1000 GNUNET_MQ_send (c->mq, env);
1001 }
1002}
1003
1004
1011static void
1012shutdown_task (void *cls)
1013{
1014 struct GSC_Client *c;
1015
1016 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Core service shutting down.\n");
1017 while (NULL != (c = client_head))
1020 GSC_KX_done ();
1022 if (NULL != GSC_stats)
1023 {
1025 GSC_stats = NULL;
1026 }
1027 GSC_cfg = NULL;
1028}
1029
1030
1040static void
1042 const struct GNUNET_MessageHeader *message)
1043{
1044 struct GSC_Client *c = cls;
1045
1048}
1049
1050
1058static void
1059run (void *cls,
1060 const struct GNUNET_CONFIGURATION_Handle *c,
1062{
1063 GSC_cfg = c;
1066 {
1067 /* Read the peer class from the configuration */
1068 const char *peer_class_str = "UNKNOWN";
1069 const char *choices[] = {
1070 "UNKNOWN",
1071 "UNWILLING",
1072 "MOBILE",
1073 "DESKTOP",
1074 "ROUTER",
1075 "SERVER",
1076 NULL
1077 };
1079 "Starting CORE service\n");
1080 if (GNUNET_OK !=
1082 "core",
1083 "CLASS",
1084 choices,
1085 &peer_class_str))
1086 {
1088 "No class found in configuration! (Continuing with unknown class)");
1090 }
1091 if (0 == strcasecmp (peer_class_str, "UNKNOWN"))
1093 else if (0 == strcasecmp (peer_class_str, "UNWILLING"))
1095 else if (0 == strcasecmp (peer_class_str, "MOBILE"))
1097 else if (0 == strcasecmp (peer_class_str, "DESKTOP"))
1099 else if (0 == strcasecmp (peer_class_str, "ROUTER"))
1101 else if (0 == strcasecmp (peer_class_str, "SERVER"))
1103 else
1104 GNUNET_assert (0);
1105 }
1109 if (GNUNET_OK != GSC_KX_init ())
1110 {
1112 return;
1113 }
1114}
1115
1116
1122 "core",
1124 &run,
1127 NULL,
1128 GNUNET_MQ_hd_var_size (client_init,
1130 struct InitMessage,
1131 NULL),
1132 GNUNET_MQ_hd_fixed_size (client_monitor_peers,
1134 struct GNUNET_MessageHeader,
1135 NULL),
1136 GNUNET_MQ_hd_fixed_size (client_send_request,
1138 struct SendMessageRequest,
1139 NULL),
1140 GNUNET_MQ_hd_var_size (client_send,
1142 struct SendMessage,
1143 NULL),
1145
1146
1147/* end of gnunet-service-core.c */
struct GNUNET_GETOPT_CommandLineOption options[]
Definition 002.c:5
struct GNUNET_MessageHeader * msg
Definition 005.c:2
struct GNUNET_MQ_Envelope * env
Definition 005.c:1
#define GNUNET_CORE_OPTION_SEND_FULL_INBOUND
Client wants all inbound messages in full.
Definition core.h:53
#define GNUNET_CORE_OPTION_SEND_HDR_OUTBOUND
Client just wants the 4-byte message headers of all outbound messages.
Definition core.h:70
#define GNUNET_CORE_OPTION_SEND_FULL_OUTBOUND
Client wants all outbound messages in full.
Definition core.h:64
#define GNUNET_CORE_OPTION_SEND_HDR_INBOUND
Client just wants the 4-byte message headers of all inbound messages.
Definition core.h:59
#define gettext_noop(String)
Definition gettext.h:74
static struct GNUNET_CONTAINER_MultiHashMap * services
This hashmaps saves interesting things about the configured services.
struct GNUNET_HashCode key
The key used in the DHT.
struct GNUNET_SCHEDULER_Task * shutdown_task
static char * name
Name (label) of the records to list.
static char * value
Value of the record to add/remove.
static uint32_t type
Type string converted to DNS type value.
static struct GNUNET_SERVICE_Handle * service
Handle to our service instance.
static struct GNUNET_PeerIdentity my_identity
Identity of this peer.
const struct GNUNET_CONFIGURATION_Handle * GSC_cfg
Our configuration.
static struct GSC_ServicesInfo * own_services
static struct GSC_Client * client_head
Head of linked list of our clients.
static struct GSC_ServicesInfo * GSC_SVCI_init()
static void handle_client_monitor_peers(void *cls, const struct GNUNET_MessageHeader *message)
Handle GNUNET_MESSAGE_TYPE_CORE_MONITOR_PEERS request.
static void handle_client_init(void *cls, const struct InitMessage *im)
Handle GNUNET_MESSAGE_TYPE_CORE_INIT request.
static int type_match(uint16_t type, struct GSC_Client *c)
Test if the client is interested in messages of the given type.
static void GSC_SVCI_destroy(struct GSC_ServicesInfo *services_info)
struct GNUNET_SERVICE_Handle * service_h
Handle to the running service.
static uint32_t all_client_options
Big "or" of all client options.
void GSC_complete_initialization_cb(void)
This function is called from GSC_KX_init() once it got its peer id from pils.
void GSC_CLIENTS_deliver_message(const struct GNUNET_PeerIdentity *sender, const struct GNUNET_MessageHeader *msg, uint16_t msize, uint32_t options)
Deliver P2P message to interested clients.
static void * client_connect_cb(void *cls, struct GNUNET_SERVICE_Client *client, struct GNUNET_MQ_Handle *mq)
A client connected, set up.
static int destroy_active_client_request(void *cls, const struct GNUNET_PeerIdentity *key, void *value)
Free client request records.
static void GSC_SVCI_add(struct GSC_ServicesInfo *services, char *name, uint32_t name_len, char *version, uint32_t version_len)
static void run(void *cls, const struct GNUNET_CONFIGURATION_Handle *c, struct GNUNET_SERVICE_Handle *service)
Initiate core service.
static void handle_client_send_request(void *cls, const struct SendMessageRequest *req)
Handle GNUNET_MESSAGE_TYPE_CORE_SEND_REQUEST message.
#define SOFT_MAX_QUEUE
How many messages do we queue up at most for any client? This can cause messages to be dropped if cli...
static void handle_client_send(void *cls, const struct SendMessage *sm)
Handle GNUNET_MESSAGE_TYPE_CORE_SEND request.
static enum GNUNET_CORE_PeerClass GSC_peer_class
Our peer class.
static int check_client_init(void *cls, const struct InitMessage *im)
Check GNUNET_MESSAGE_TYPE_CORE_INIT request.
void GSC_CLIENTS_notify_client_about_neighbour(struct GSC_Client *client, const struct GNUNET_PeerIdentity *neighbour, enum GNUNET_CORE_PeerClass class)
Notify a particular client about a change to existing connection to one of our neighbours (check if t...
static int check_client_send(void *cls, const struct SendMessage *sm)
Check GNUNET_MESSAGE_TYPE_CORE_SEND request.
void GSC_CLIENTS_reject_request(struct GSC_ClientActiveRequest *car, int drop_client)
We will never be ready to transmit the given message in (disconnect or invalid request).
struct GNUNET_PILS_Handle * GSC_pils
For peer identity access.
static struct GSC_Client * client_tail
Tail of linked list of our clients.
static void client_disconnect_cb(void *cls, struct GNUNET_SERVICE_Client *client, void *app_ctx)
A client disconnected, clean up.
void GSC_CLIENTS_notify_clients_about_neighbour(const struct GNUNET_PeerIdentity *neighbour, enum GNUNET_CORE_PeerClass class)
Notify all clients about a change to existing session.
struct GNUNET_STATISTICS_Handle * GSC_stats
For creating statistics.
static int tokenized_cb(void *cls, const struct GNUNET_MessageHeader *message)
Functions with this signature are called whenever a complete message is received by the tokenizer.
void GSC_CLIENTS_solicit_request(struct GSC_ClientActiveRequest *car)
Tell a client that we are ready to receive the message.
#define HARD_MAX_QUEUE
How many messages do we queue up at most for any client? This can cause messages to be dropped if cli...
static void GSC_SVCI_remove(struct GSC_ServicesInfo *services, char *name, uint32_t name_len)
Globals for gnunet-service-core.
void GSC_KX_handle_client_monitor_peers(struct GNUNET_MQ_Handle *mq)
Handle GNUNET_MESSAGE_TYPE_CORE_MONITOR_PEERS request.
void GSC_KX_done()
Shutdown KX subsystem.
int GSC_KX_init(void)
Initialize KX subsystem.
code for managing the key exchange (SET_KEY, PING, PONG) with other peers
void GSC_SESSIONS_dequeue_request(struct GSC_ClientActiveRequest *car)
Dequeue a request from a client from transmission to a particular peer.
void GSC_SESSIONS_transmit(struct GSC_ClientActiveRequest *car, const struct GNUNET_MessageHeader *msg, enum GNUNET_MQ_PriorityPreferences priority)
Transmit a message to a particular peer.
void GSC_SESSIONS_notify_client_about_sessions(struct GSC_Client *client)
We have a new client, notify it about all current sessions.
void GSC_SESSIONS_init()
Initialize sessions subsystem.
void GSC_SESSIONS_queue_request(struct GSC_ClientActiveRequest *car)
Queue a request from a client for transmission to a particular peer.
void GSC_SESSIONS_done()
Shutdown sessions subsystem.
commonly used definitions; globals in this file are exempt from the rule that the module name ("commo...
const struct GNUNET_PeerIdentity * GNUNET_PILS_get_identity(const struct GNUNET_PILS_Handle *handle)
Return the current peer identity of a given handle.
Definition pils_api.c:727
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message,...
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_choice(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, const char *const *choices, const char **value)
Get a configuration value that should be in a set of predefined strings.
#define GNUNET_CONSTANTS_LATENCY_WARN
After what amount of latency for a message do we print a warning?
GNUNET_CORE_PeerClass
The peer class gives a hint about the capabilities of a peer.
@ GNUNET_CORE_CLASS_SERVER
This is something like a server.
@ GNUNET_CORE_CLASS_UNKNOWN
The device's capabilities are currently unknown.
@ GNUNET_CORE_CLASS_ROUTER
This is a piece of network infrastructure.
@ GNUNET_CORE_CLASS_MOBILE
This is a mobile device.
@ GNUNET_CORE_CLASS_DESKTOP
This is a desktop computer.
@ GNUNET_CORE_CLASS_UNWILLING
This device is currently unwilling to spend more then the absolutely necessary resources.
uint32_t GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i)
Produce a random value.
@ GNUNET_CRYPTO_QUALITY_WEAK
No good quality of the operation is needed (i.e., random numbers can be pseudo-random).
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
void * GNUNET_CONTAINER_multipeermap_get(const struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key)
Given a key find a value in the map matching the key.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multipeermap_contains(const struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key)
Check if the map contains any value under the given key (including values that are NULL).
void GNUNET_CONTAINER_multipeermap_destroy(struct GNUNET_CONTAINER_MultiPeerMap *map)
Destroy a hash map.
int GNUNET_CONTAINER_multipeermap_iterate(struct GNUNET_CONTAINER_MultiPeerMap *map, GNUNET_CONTAINER_PeerMapIterator it, void *it_cls)
Iterate over all entries in the map.
struct GNUNET_CONTAINER_MultiPeerMap * GNUNET_CONTAINER_multipeermap_create(unsigned int len, int do_not_copy_keys)
Create a multi peer map (hash map for public keys of peers).
int GNUNET_CONTAINER_multipeermap_put(struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multipeermap_remove(struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key, const void *value)
Remove the given key-value pair from the map.
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST
, ' bother checking if a value already exists (faster than GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE...
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY
There must only be one value per key; storing a value should fail if a value under the same key alrea...
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
#define GNUNET_log(kind,...)
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_BULK
@ GNUNET_ERROR_TYPE_DEBUG
@ GNUNET_ERROR_TYPE_INFO
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define GNUNET_array_grow(arr, size, tsize)
Grow a well-typed (!) array.
int GNUNET_snprintf(char *buf, size_t size, const char *format,...) __attribute__((format(printf
Like snprintf, just aborts if the buffer is of insufficient size.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
unsigned int GNUNET_MQ_get_length(struct GNUNET_MQ_Handle *mq)
Obtain the current length of the message queue.
Definition mq.c:293
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition mq.c:305
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct.
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
GNUNET_MQ_PriorityPreferences
Per envelope preferences and priorities.
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
#define GNUNET_MQ_hd_fixed_size(name, code, str, ctx)
const struct GNUNET_OS_ProjectData * GNUNET_OS_project_data_gnunet(void)
Return default project data used by 'libgnunetutil' for GNUnet.
#define GNUNET_MESSAGE_TYPE_CORE_SEND_REQUEST
Request from client to transmit message.
#define GNUNET_MESSAGE_TYPE_CORE_NOTIFY_OUTBOUND
Notify clients about outgoing P2P transmissions.
#define GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT
Notify clients about new peer-to-peer connections (triggered after key exchange).
#define GNUNET_MESSAGE_TYPE_CORE_MONITOR_PEERS
Request for connection monitoring from CORE service.
#define GNUNET_MESSAGE_TYPE_CORE_INIT
Initial setup message from core client to core.
#define GNUNET_MESSAGE_TYPE_CORE_SEND
Client with message to transmit (after SEND_READY confirmation was received).
#define GNUNET_MESSAGE_TYPE_CORE_NOTIFY_INBOUND
Notify clients about incoming P2P messages.
#define GNUNET_MESSAGE_TYPE_CORE_INIT_REPLY
Response from core to core client to INIT message.
#define GNUNET_MESSAGE_TYPE_CORE_SEND_READY
Confirmation from core that message can now be sent.
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition scheduler.c:572
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_shutdown(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run on shutdown, that is when a CTRL-C signal is received,...
Definition scheduler.c:1345
enum GNUNET_GenericReturnValue GNUNET_MST_from_buffer(struct GNUNET_MessageStreamTokenizer *mst, const char *buf, size_t size, int purge, int one_shot)
Add incoming data to the receive buffer and call the callback for all complete messages.
Definition mst.c:101
struct GNUNET_MessageStreamTokenizer * GNUNET_MST_create(GNUNET_MessageTokenizerCallback cb, void *cb_cls)
Create a message stream tokenizer.
Definition mst.c:86
void GNUNET_MST_destroy(struct GNUNET_MessageStreamTokenizer *mst)
Destroys a tokenizer.
Definition mst.c:404
#define GNUNET_SERVICE_MAIN(pd, service_name, service_options, init_cb, connect_cb, disconnect_cb, cls,...)
Creates the "main" function for a GNUnet service.
void GNUNET_SERVICE_suspend(struct GNUNET_SERVICE_Handle *sh)
Suspend accepting connections from the listen socket temporarily.
Definition service.c:2381
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition service.c:2463
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition service.c:2434
void GNUNET_SERVICE_resume(struct GNUNET_SERVICE_Handle *sh)
Resume accepting connections from the listen socket.
Definition service.c:2389
@ GNUNET_SERVICE_OPTION_NONE
Use defaults.
struct GNUNET_STATISTICS_Handle * GNUNET_STATISTICS_create(const char *subsystem, const struct GNUNET_CONFIGURATION_Handle *cfg)
Get handle for the statistics service.
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
void GNUNET_STATISTICS_destroy(struct GNUNET_STATISTICS_Handle *h, int sync_first)
Destroy a handle (free all state associated with it).
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_duration(struct GNUNET_TIME_Absolute whence)
Get the duration of an operation as the difference of the current time and the given start time "henc...
Definition time.c:438
const char * GNUNET_STRINGS_relative_time_to_string(struct GNUNET_TIME_Relative delta, int do_round)
Give relative time in human-readable fancy format.
Definition strings.c:604
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition time.c:111
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_ntoh(struct GNUNET_TIME_AbsoluteNBO a)
Convert absolute time from network byte order.
Definition time.c:737
static unsigned int size
Size of the "table".
Definition peer.c:68
#define _(String)
GNU gettext support macro.
Definition platform.h:179
static struct GNUNET_MQ_Handle * mq
Our connection to the resolver service, created on-demand, but then persists until error or shutdown.
static struct GNUNET_SCHEDULER_TaskContext tc
Task context of the current task.
Definition scheduler.c:436
Message sent by the service to clients to notify them about a peer connecting.
Definition core.h:129
struct GNUNET_PeerIdentity peer
Identity of the connecting peer.
Definition core.h:143
uint32_t reserved
Always zero.
Definition core.h:138
enum GNUNET_CORE_PeerClass peer_class
Class of the connecting peer TODO is it correct to send an enum like this?
Definition core.h:149
Internal representation of the hash map.
Handle to a message queue.
Definition mq.c:87
Header for all communications.
Handle to a message stream tokenizer.
Definition mst.c:45
size_t off
How many bytes in buffer have we already processed?
Definition mst.c:64
A handle for the PILS service.
Definition pils_api.c:82
The identity of the host (wraps the signing key of the peer).
Handle to a client that is connected to a service.
Definition service.c:249
Handle to a service.
Definition service.c:116
Handle for the service.
Time for relative time used by GNUnet, in microseconds.
uint64_t rel_value_us
The actual value.
Record kept for each request for transmission issued by a client that is still pending.
uint16_t smr_id
Unique request ID (in big endian).
struct GNUNET_TIME_Absolute deadline
By what time would the client want to see this message out?
struct GNUNET_TIME_Absolute received_time
At what time did we first see this request?
struct GNUNET_PeerIdentity target
Which peer is the message going to be for?
int was_solicited
Has this request been solicited yet?
uint16_t msize
How many bytes does the client intend to send?
struct GSC_Client * client_handle
Handle to the client.
enum GNUNET_MQ_PriorityPreferences priority
How important is this request.
Data structure for each client connected to the CORE service.
uint32_t options
Options for messages this client cares about, see GNUNET_CORE_OPTION_ values.
unsigned int tcnt
Number of types of incoming messages this client specifically cares about.
struct GNUNET_SERVICE_Client * client
Handle for the client with the server API.
struct GSC_Client * next
Clients are kept in a linked list.
struct GNUNET_MQ_Handle * mq
Message queue to talk to client.
struct GNUNET_CONTAINER_MultiPeerMap * requests
Map of peer identities to active transmission requests of this client to the peer (of type struct GSC...
struct GSC_Client * prev
Clients are kept in a linked list.
struct GNUNET_CONTAINER_MultiPeerMap * connectmap
Map containing all peers that this client knows we're connected to.
int got_init
Have we gotten the GNUNET_MESSAGE_TYPE_CORE_INIT message from this client already?
uint16_t * types
Array of the types of messages this peer cares about (with tcnt entries).
char * name
uint32_t name_len
uint32_t version_len
char * version
struct GSC_ServicesInfo_Entry * entries
Message transmitted core clients to gnunet-service-core to start the interaction.
Definition core.h:82
struct GNUNET_MessageHeader header
Header with type GNUNET_MESSAGE_TYPE_CORE_INIT.
Definition core.h:86
uint32_t options
Options, see GNUNET_CORE_OPTION_ values.
Definition core.h:91
Message transmitted by the gnunet-service-core process to its clients in response to an INIT message.
Definition core.h:100
enum GNUNET_CORE_PeerClass class
Class of the peer TODO is it correct to send an enum like this?
Definition core.h:120
struct GNUNET_PeerIdentity my_identity
Public key of the local peer.
Definition core.h:114
uint32_t reserved
Always zero.
Definition core.h:109
Message sent by the service to clients to notify them about messages being received or transmitted.
Definition core.h:186
struct GNUNET_PeerIdentity peer
Identity of the receiver or sender.
Definition core.h:196
Core notifying client that it is allowed to now transmit a message to the given target (response to G...
Definition core.h:252
uint16_t smr_id
smr_id from the request.
Definition core.h:269
struct GNUNET_PeerIdentity peer
Identity of the intended target.
Definition core.h:274
uint16_t size
How many bytes are allowed for transmission? Guaranteed to be at least as big as the requested size,...
Definition core.h:264
Client notifying core about the maximum-priority message it has in the queue for a particular target.
Definition core.h:207
uint32_t priority
How important is this message?
Definition core.h:216
struct GNUNET_PeerIdentity peer
Identity of the intended target.
Definition core.h:227
uint16_t size
How large is the message?
Definition core.h:237
uint16_t smr_id
Counter for this peer to match SMRs to replies.
Definition core.h:242
struct GNUNET_TIME_AbsoluteNBO deadline
By what time would the sender really like to see this message transmitted?
Definition core.h:222
Client asking core to transmit a particular message to a particular target (response to GNUNET_MESSAG...
Definition core.h:283
uint32_t priority
How important is this message? Contains a enum GNUNET_MQ_PriorityPreferences in NBO.
Definition core.h:293
struct GNUNET_PeerIdentity peer
Identity of the intended receiver.
Definition core.h:304
Closure for the #client_tokenizer_callback().
struct GSC_ClientActiveRequest * car
Active request handle for the message.
enum GNUNET_MQ_PriorityPreferences priority
How important is this message.