GNUnet 0.21.1
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 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 "platform.h"
27#include <gcrypt.h>
28#include "gnunet_util_lib.h"
29#include "gnunet-service-core.h"
33#include "gnunet_constants.h"
34
41#define SOFT_MAX_QUEUE 128
42
48#define HARD_MAX_QUEUE 256
49
50
55{
60
65
70
75
81 uint16_t *types;
82
88
93
98 uint32_t options;
99
105
110 unsigned int tcnt;
111};
112
113
118
123
128
132static uint32_t all_client_options;
133
137static struct GSC_Client *client_head;
138
142static struct GSC_Client *client_tail;
143
144
152static int
153type_match (uint16_t type, struct GSC_Client *c)
154{
155 if ((0 == c->tcnt) && (0 != c->options))
156 return GNUNET_YES; /* peer without handlers and inbound/outbond
157 callbacks matches ALL */
158 if (NULL == c->types)
159 return GNUNET_NO;
160 for (unsigned int i = 0; i < c->tcnt; i++)
161 if (type == c->types[i])
162 return GNUNET_YES;
163 return GNUNET_NO;
164}
165
166
174static int
175check_client_init (void *cls, const struct InitMessage *im)
176{
177 return GNUNET_OK;
178}
179
180
187static void
188handle_client_init (void *cls, const struct InitMessage *im)
189{
190 struct GSC_Client *c = cls;
191 struct GNUNET_MQ_Envelope *env;
192 struct InitReplyMessage *irm;
193 uint16_t msize;
194 const uint16_t *types;
195
196 /* check that we don't have an entry already */
197 msize = ntohs (im->header.size) - sizeof(struct InitMessage);
198 types = (const uint16_t *) &im[1];
199 c->tcnt = msize / sizeof(uint16_t);
200 c->options = ntohl (im->options);
201 c->got_init = GNUNET_YES;
203 c->types = GNUNET_malloc (msize);
206 c->connectmap,
208 NULL,
210 for (unsigned int i = 0; i < c->tcnt; i++)
211 c->types[i] = ntohs (types[i]);
212 GSC_TYPEMAP_add (c->types, c->tcnt);
213 GNUNET_log (
215 "Client connecting to core service is interested in %u message types\n",
216 (unsigned int) c->tcnt);
217 /* send init reply message */
219 irm->reserved = htonl (0);
221 GNUNET_MQ_send (c->mq, env);
224}
225
226
239void
241 int drop_client)
242{
244 GNUNET_YES ==
246 &car->target,
247 car));
248 if (GNUNET_YES == drop_client)
250 GNUNET_free (car);
251}
252
253
261void
263{
264 struct GSC_Client *c;
265 struct GNUNET_MQ_Envelope *env;
266 struct SendMessageReady *smr;
267 struct GNUNET_TIME_Relative delay;
268 struct GNUNET_TIME_Relative left;
269
270 c = car->client_handle;
271 if (GNUNET_YES !=
273 {
274 /* connection has gone down since, drop request */
275 GNUNET_assert (0 !=
276 GNUNET_memcmp (&car->target,
280 return;
281 }
284 if (delay.rel_value_us > GNUNET_CONSTANTS_LATENCY_WARN.rel_value_us)
285 GNUNET_log (
287 "Client waited %s for permission to transmit to `%s'%s (priority %u)\n",
289 GNUNET_i2s (&car->target),
290 (0 == left.rel_value_us) ? " (past deadline)" : "",
291 car->priority);
293 smr->size = htons (car->msize);
294 smr->smr_id = car->smr_id;
295 smr->peer = car->target;
296 GNUNET_MQ_send (c->mq, env);
297}
298
299
306static void
307handle_client_send_request (void *cls, const struct SendMessageRequest *req)
308{
309 struct GSC_Client *c = cls;
310 struct GSC_ClientActiveRequest *car;
311 int is_loopback;
312
313 if (NULL == c->requests)
316 "Client asked for transmission to `%s'\n",
317 GNUNET_i2s (&req->peer));
318 is_loopback = (0 == GNUNET_memcmp (&req->peer,
320 if ((! is_loopback) &&
321 (GNUNET_YES !=
323 {
324 /* neighbour must have disconnected since request was issued,
325 * ignore (client will realize it once it processes the
326 * disconnect notification) */
329 "# send requests dropped (disconnected)"),
330 1,
331 GNUNET_NO);
333 return;
334 }
335
337 if (NULL == car)
338 {
339 /* create new entry */
340 car = GNUNET_new (struct GSC_ClientActiveRequest);
343 c->requests,
344 &req->peer,
345 car,
347 car->client_handle = c;
348 }
349 else
350 {
351 /* dequeue and recycle memory from pending request, there can only
352 be at most one per client and peer */
355 "# dequeuing CAR (duplicate request)"),
356 1,
357 GNUNET_NO);
360 "Transmission request to `%s' was a duplicate!\n",
361 GNUNET_i2s (&req->peer));
362 }
363 car->target = req->peer;
366 car->priority = (enum GNUNET_MQ_PriorityPreferences) ntohl (req->priority);
367 car->msize = ntohs (req->size);
368 car->smr_id = req->smr_id;
371 if (is_loopback)
372 {
373 /* loopback, satisfy immediately */
375 return;
376 }
378}
379
380
385{
390
395};
396
397
410static int
411tokenized_cb (void *cls, const struct GNUNET_MessageHeader *message)
412{
413 struct TokenizerContext *tc = cls;
414 struct GSC_ClientActiveRequest *car = tc->car;
415 char buf[92];
416
417 GNUNET_snprintf (buf,
418 sizeof(buf),
419 gettext_noop ("# bytes of messages of type %u received"),
420 (unsigned int) ntohs (message->type));
421 GNUNET_STATISTICS_update (GSC_stats, buf, ntohs (message->size), GNUNET_NO);
422 if (0 == GNUNET_memcmp (&car->target,
424 {
426 "Delivering message of type %u to myself\n",
427 ntohs (message->type));
429 message,
430 ntohs (message->size),
433 message,
434 sizeof(struct GNUNET_MessageHeader),
437 message,
438 ntohs (message->size),
441 message,
442 sizeof(struct GNUNET_MessageHeader),
444 }
445 else
446 {
448 "Delivering message of type %u and size %u to %s\n",
449 ntohs (message->type),
450 ntohs (message->size),
451 GNUNET_i2s (&car->target));
453 message,
454 ntohs (message->size),
457 message,
458 sizeof(struct GNUNET_MessageHeader),
460 GSC_SESSIONS_transmit (car, message, tc->priority);
461 }
462 return GNUNET_OK;
463}
464
465
473static int
474check_client_send (void *cls, const struct SendMessage *sm)
475{
476 return GNUNET_OK;
477}
478
479
486static void
487handle_client_send (void *cls, const struct SendMessage *sm)
488{
489 struct GSC_Client *c = cls;
490 struct TokenizerContext tc;
491 uint16_t msize;
492 struct GNUNET_TIME_Relative delay;
494
495 msize = ntohs (sm->header.size) - sizeof(struct SendMessage);
497 if (NULL == tc.car)
498 {
499 /* Must have been that we first approved the request, then got disconnected
500 * (which triggered removal of the 'car') and now the client gives us a message
501 * just *before* the client learns about the disconnect. Theoretically, we
502 * might also now be *again* connected. So this can happen (but should be
503 * rare). If it does happen, the message is discarded. */GNUNET_STATISTICS_update (GSC_stats,
505 "# messages discarded (session disconnected)"),
506 1,
507 GNUNET_NO);
509 return;
510 }
511 delay = GNUNET_TIME_absolute_get_duration (tc.car->received_time);
512 tc.priority = (enum GNUNET_MQ_PriorityPreferences) ntohl (sm->priority);
513 if (delay.rel_value_us > GNUNET_CONSTANTS_LATENCY_WARN.rel_value_us)
515 "Client waited %s for transmission of %u bytes to `%s'\n",
517 msize,
518 GNUNET_i2s (&sm->peer));
519 else
521 "Client waited %s for transmission of %u bytes to `%s'\n",
523 msize,
524 GNUNET_i2s (&sm->peer));
525
527 GNUNET_YES ==
531 (const char *) &sm[1],
532 msize,
534 GNUNET_NO);
535 GNUNET_MST_destroy (mst);
537 GNUNET_free (tc.car);
539}
540
541
550static int
552 const struct GNUNET_PeerIdentity *key,
553 void *value)
554{
555 struct GSC_ClientActiveRequest *car = value;
556
558 GNUNET_YES ==
560 &car->target,
561 car));
563 GNUNET_free (car);
564 return GNUNET_YES;
565}
566
567
576static void *
578 struct GNUNET_SERVICE_Client *client,
579 struct GNUNET_MQ_Handle *mq)
580{
581 struct GSC_Client *c;
582
583 c = GNUNET_new (struct GSC_Client);
584 c->client = client;
585 c->mq = mq;
588 return c;
589}
590
591
599static void
602 void *app_ctx)
603{
604 struct GSC_Client *c = app_ctx;
605
607 "Client %p has disconnected from core service.\n",
608 client);
610 if (NULL != c->requests)
611 {
614 NULL);
616 }
618 c->connectmap = NULL;
619 if (NULL != c->types)
620 {
622 GNUNET_free (c->types);
623 }
624 GNUNET_free (c);
625
626 /* recalculate 'all_client_options' */
628 for (c = client_head; NULL != c; c = c->next)
630}
631
632
643void
645 struct GSC_Client *client,
646 const struct GNUNET_PeerIdentity *neighbour,
647 const struct GSC_TypeMap *tmap_old,
648 const struct GSC_TypeMap *tmap_new)
649{
650 struct GNUNET_MQ_Envelope *env;
651 int old_match;
652 int new_match;
653
654 if (GNUNET_YES != client->got_init)
655 return;
656 old_match = GSC_TYPEMAP_test_match (tmap_old, client->types, client->tcnt);
657 new_match = GSC_TYPEMAP_test_match (tmap_new, client->types, client->tcnt);
659 "Notifying client about neighbour %s (%d/%d)\n",
660 GNUNET_i2s (neighbour),
661 old_match,
662 new_match);
663 if (old_match == new_match)
664 {
666 old_match ==
668 return; /* no change */
669 }
670 if (GNUNET_NO == old_match)
671 {
672 struct ConnectNotifyMessage *cnm;
673
674 /* send connect */
676 GNUNET_NO ==
680 client->connectmap,
681 neighbour,
682 NULL,
685 cnm->reserved = htonl (0);
687 "Sending NOTIFY_CONNECT message about peer %s to client.\n",
688 GNUNET_i2s (neighbour));
689 cnm->peer = *neighbour;
690 GNUNET_MQ_send (client->mq, env);
691 }
692 else
693 {
694 struct DisconnectNotifyMessage *dcm;
695
696 /* send disconnect */
698 GNUNET_YES ==
702 neighbour,
703 NULL));
705 dcm->reserved = htonl (0);
707 "Sending NOTIFY_DISCONNECT message about peer %s to client.\n",
708 GNUNET_i2s (neighbour));
709 dcm->peer = *neighbour;
710 GNUNET_MQ_send (client->mq, env);
711 }
712}
713
714
724void
726 const struct GNUNET_PeerIdentity *neighbour,
727 const struct GSC_TypeMap *tmap_old,
728 const struct GSC_TypeMap *tmap_new)
729{
730 struct GSC_Client *c;
731
732 for (c = client_head; NULL != c; c = c->next)
734 neighbour,
735 tmap_old,
736 tmap_new);
737}
738
739
751void
753 const struct GNUNET_MessageHeader *msg,
754 uint16_t msize,
755 uint32_t options)
756{
757 size_t size = msize + sizeof(struct NotifyTrafficMessage);
758
760 {
761 GNUNET_break (0);
762 return;
763 }
764 if (! ((0 != (all_client_options & options)) ||
766 return; /* no client cares about this message notification */
768 "Core service passes message from `%s' of type %u to client.\n",
769 GNUNET_i2s (sender),
770 (unsigned int) ntohs (msg->type));
771 GSC_SESSIONS_add_to_typemap (sender, ntohs (msg->type));
772
773 for (struct GSC_Client *c = client_head; NULL != c; c = c->next)
774 {
775 struct GNUNET_MQ_Envelope *env;
776 struct NotifyTrafficMessage *ntm;
777 uint16_t mtype;
778 unsigned int qlen;
779 int tm;
780
781 tm = type_match (ntohs (msg->type), c);
782 if (! ((0 != (c->options & options)) ||
784 (GNUNET_YES == tm))))
785 continue; /* neither options nor type match permit the message */
787 ((0 != (c->options & GNUNET_CORE_OPTION_SEND_FULL_INBOUND)) ||
788 (GNUNET_YES == tm)))
789 continue;
791 (0 != (c->options & GNUNET_CORE_OPTION_SEND_FULL_OUTBOUND)))
792 continue;
793
794 /* Drop messages if:
795 1) We are above the hard limit, or
796 2) We are above the soft limit, and a coin toss limited
797 to the message size (giving larger messages a
798 proportionally higher chance of being queued) falls
799 below the threshold. The threshold is based on where
800 we are between the soft and the hard limit, scaled
801 to match the range of message sizes we usually encounter
802 (i.e. up to 32k); so a 64k message has a 50% chance of
803 being kept if we are just barely below the hard max,
804 and a 99% chance of being kept if we are at the soft max.
805 The reason is to make it more likely to drop control traffic
806 (ACK, queries) which may be cumulative or highly redundant,
807 and cheap to drop than data traffic. */qlen = GNUNET_MQ_get_length (c->mq);
808 if ((qlen >= HARD_MAX_QUEUE) ||
809 ((qlen > SOFT_MAX_QUEUE) &&
811 ntohs (msg->size))) <
812 (qlen - SOFT_MAX_QUEUE) * 0x8000
814 {
815 char buf[1024];
816
817 GNUNET_log (
819 "Dropping decrypted message of type %u as client is too busy (queue full)\n",
820 (unsigned int) ntohs (msg->type));
821 GNUNET_snprintf (buf,
822 sizeof(buf),
824 "# messages of type %u discarded (client busy)"),
825 (unsigned int) ntohs (msg->type));
827 continue;
828 }
829
830 GNUNET_log (
832 "Sending %u message with %u bytes to client interested in messages of type %u.\n",
833 options,
834 ntohs (msg->size),
835 (unsigned int) ntohs (msg->type));
836
840 else
842 env = GNUNET_MQ_msg_extra (ntm, msize, mtype);
843 ntm->peer = *sender;
844 GNUNET_memcpy (&ntm[1], msg, msize);
845
847 (0 == (c->options & GNUNET_CORE_OPTION_SEND_FULL_INBOUND)) ||
848 (GNUNET_YES != tm) ||
849 (GNUNET_YES ==
850 GNUNET_CONTAINER_multipeermap_contains (c->connectmap, sender)));
851 GNUNET_MQ_send (c->mq, env);
852 }
853}
854
855
862static void
863shutdown_task (void *cls)
864{
865 struct GSC_Client *c;
866
867 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Core service shutting down.\n");
868 while (NULL != (c = client_head))
871 GSC_KX_done ();
873 if (NULL != GSC_stats)
874 {
876 GSC_stats = NULL;
877 }
878 GSC_cfg = NULL;
879}
880
881
891static void
893 const struct GNUNET_MessageHeader *message)
894{
895 struct GSC_Client *c = cls;
896
899}
900
901
909static void
910run (void *cls,
911 const struct GNUNET_CONFIGURATION_Handle *c,
913{
915 char *keyfile;
916
917 GSC_cfg = c;
918 if (GNUNET_OK !=
920 "PEER",
921 "PRIVATE_KEY",
922 &keyfile))
923 {
924 GNUNET_log (
926 _ ("Core service is lacking HOSTKEY configuration setting. Exiting.\n"));
928 return;
929 }
934 if (GNUNET_SYSERR ==
937 &pk))
938 {
940 "Failed to setup peer's private key\n");
942 GNUNET_free (keyfile);
943 return;
944 }
945 GNUNET_free (keyfile);
946 if (GNUNET_OK != GSC_KX_init (&pk))
947 {
949 return;
950 }
954 _ ("Core service of `%s' ready.\n"),
956}
957
958
963 "core",
965 &run,
968 NULL,
969 GNUNET_MQ_hd_var_size (client_init,
971 struct InitMessage,
972 NULL),
973 GNUNET_MQ_hd_fixed_size (client_monitor_peers,
976 NULL),
977 GNUNET_MQ_hd_fixed_size (client_send_request,
979 struct SendMessageRequest,
980 NULL),
981 GNUNET_MQ_hd_var_size (client_send,
983 struct SendMessage,
984 NULL),
986
987
988/* end of gnunet-service-core.c */
struct GNUNET_GETOPT_CommandLineOption options[]
Definition: 002.c:5
struct GNUNET_MQ_Handle * mq
Definition: 003.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:70
struct GNUNET_HashCode key
The key used in the DHT.
struct GNUNET_CRYPTO_PrivateKey pk
Private key from command line option, or NULL.
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.
const struct GNUNET_CONFIGURATION_Handle * GSC_cfg
Our configuration.
static struct GSC_Client * client_head
Head of linked list of our clients.
void GSC_CLIENTS_notify_client_about_neighbour(struct GSC_Client *client, const struct GNUNET_PeerIdentity *neighbour, const struct GSC_TypeMap *tmap_old, const struct GSC_TypeMap *tmap_new)
Notify a particular client about a change to existing connection to one of our neighbours (check if t...
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 uint32_t all_client_options
Big "or" of all client options.
struct GNUNET_PeerIdentity GSC_my_identity
Our identity.
GNUNET_SERVICE_MAIN("core", GNUNET_SERVICE_OPTION_NONE, &run, &client_connect_cb, &client_disconnect_cb, NULL, GNUNET_MQ_hd_var_size(client_init, GNUNET_MESSAGE_TYPE_CORE_INIT, struct InitMessage, NULL), GNUNET_MQ_hd_fixed_size(client_monitor_peers, GNUNET_MESSAGE_TYPE_CORE_MONITOR_PEERS, struct GNUNET_MessageHeader, NULL), GNUNET_MQ_hd_fixed_size(client_send_request, GNUNET_MESSAGE_TYPE_CORE_SEND_REQUEST, struct SendMessageRequest, NULL), GNUNET_MQ_hd_var_size(client_send, GNUNET_MESSAGE_TYPE_CORE_SEND, struct SendMessage, NULL), GNUNET_MQ_handler_end())
Define "main" method using service macro.
static void shutdown_task(void *cls)
Last task run during shutdown.
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 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 int check_client_init(void *cls, const struct InitMessage *im)
Check GNUNET_MESSAGE_TYPE_CORE_INIT request.
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).
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.
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.
void GSC_CLIENTS_notify_clients_about_neighbour(const struct GNUNET_PeerIdentity *neighbour, const struct GSC_TypeMap *tmap_old, const struct GSC_TypeMap *tmap_new)
Notify all clients about a change to existing session.
#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...
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.
int GSC_KX_init(struct GNUNET_CRYPTO_EddsaPrivateKey *pk)
Initialize KX subsystem.
void GSC_KX_done()
Shutdown 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_add_to_typemap(const struct GNUNET_PeerIdentity *peer, uint16_t type)
The given peer send a message of the specified type.
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.
void GSC_TYPEMAP_done()
Shutdown typemap subsystem.
int GSC_TYPEMAP_test_match(const struct GSC_TypeMap *tmap, const uint16_t *types, unsigned int tcnt)
Test if any of the types from the types array is in the given type map.
void GSC_TYPEMAP_add(const uint16_t *types, unsigned int tlen)
Add a set of types to our type map.
void GSC_TYPEMAP_init()
Initialize typemap subsystem.
void GSC_TYPEMAP_remove(const uint16_t *types, unsigned int tlen)
Remove a set of message types from our type map.
management of map that specifies which message types this peer supports
#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_filename(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be the name of a file or directory.
#define GNUNET_CONSTANTS_LATENCY_WARN
After what amount of latency for a message do we print a warning?
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_key_from_file(const char *filename, int do_create, struct GNUNET_CRYPTO_EddsaPrivateKey *pkey)
Create a new private key by reading it from a file.
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
@ GNUNET_SYSERR
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_ERROR
@ GNUNET_ERROR_TYPE_BULK
@ GNUNET_ERROR_TYPE_DEBUG
@ GNUNET_ERROR_TYPE_INFO
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:304
#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.
Definition: gnunet_mq_lib.h:63
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:78
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)
#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_NOTIFY_DISCONNECT
Notify clients about peer disconnecting.
#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:567
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:1340
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
void GNUNET_SERVICE_suspend(struct GNUNET_SERVICE_Handle *sh)
Suspend accepting connections from the listen socket temporarily.
Definition: service.c:2402
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition: service.c:2484
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2455
void GNUNET_SERVICE_resume(struct GNUNET_SERVICE_Handle *sh)
Resume accepting connections from the listen socket.
Definition: service.c:2410
@ 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:436
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:570
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:178
static struct GNUNET_SCHEDULER_TaskContext tc
Task context of the current task.
Definition: scheduler.c:431
Message sent by the service to clients to notify them about a peer connecting.
Definition: core.h:123
struct GNUNET_PeerIdentity peer
Identity of the connecting peer.
Definition: core.h:137
uint32_t reserved
Always zero.
Definition: core.h:132
Message sent by the service to clients to notify them about a peer disconnecting.
Definition: core.h:146
uint32_t reserved
Always zero.
Definition: core.h:155
struct GNUNET_PeerIdentity peer
Identity of the connecting peer.
Definition: core.h:160
Internal representation of the hash map.
Private ECC key encoded for transmission.
Handle to a message queue.
Definition: mq.c:87
Header for all communications.
Handle to a message stream tokenizer.
Definition: mst.c:45
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:246
Handle to a service.
Definition: service.c:117
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).
A type map describing which messages a given neighbour is able to process.
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
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:174
struct GNUNET_PeerIdentity peer
Identity of the receiver or sender.
Definition: core.h:184
Core notifying client that it is allowed to now transmit a message to the given target (response to G...
Definition: core.h:240
uint16_t smr_id
smr_id from the request.
Definition: core.h:257
struct GNUNET_PeerIdentity peer
Identity of the intended target.
Definition: core.h:262
uint16_t size
How many bytes are allowed for transmission? Guaranteed to be at least as big as the requested size,...
Definition: core.h:252
Client notifying core about the maximum-priority message it has in the queue for a particular target.
Definition: core.h:195
uint32_t priority
How important is this message?
Definition: core.h:204
struct GNUNET_PeerIdentity peer
Identity of the intended target.
Definition: core.h:215
uint16_t size
How large is the message?
Definition: core.h:225
uint16_t smr_id
Counter for this peer to match SMRs to replies.
Definition: core.h:230
struct GNUNET_TIME_AbsoluteNBO deadline
By what time would the sender really like to see this message transmitted?
Definition: core.h:210
Client asking core to transmit a particular message to a particular target (response to GNUNET_MESSAG...
Definition: core.h:271
struct GNUNET_MessageHeader header
Header with type GNUNET_MESSAGE_TYPE_CORE_SEND.
Definition: core.h:275
uint32_t priority
How important is this message? Contains a enum GNUNET_MQ_PriorityPreferences in NBO.
Definition: core.h:281
struct GNUNET_PeerIdentity peer
Identity of the intended receiver.
Definition: core.h:292
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.