GNUnet 0.28.0-dev.3-20-gf1136b0b8
 
Loading...
Searching...
No Matches
gnunet-service-core.c File Reference

high-level P2P messaging More...

Include dependency graph for gnunet-service-core.c:

Go to the source code of this file.

Data Structures

struct  GSC_Client
 Data structure for each client connected to the CORE service. More...
 
struct  GSC_ServicesInfo_Entry
 
struct  GSC_ServicesInfo
 
struct  TokenizerContext
 Closure for the #client_tokenizer_callback(). More...
 

Macros

#define SOFT_MAX_QUEUE   128
 How many messages do we queue up at most for any client? This can cause messages to be dropped if clients do not process them fast enough! Note that this is a soft limit; we try to keep a few larger messages above the limit.
 
#define HARD_MAX_QUEUE   256
 How many messages do we queue up at most for any client? This can cause messages to be dropped if clients do not process them fast enough! Note that this is the hard limit.
 

Functions

static struct GSC_ServicesInfoGSC_SVCI_init ()
 
static void GSC_SVCI_destroy (struct GSC_ServicesInfo *services_info)
 
static void GSC_SVCI_add (struct GSC_ServicesInfo *services, char *name, uint32_t name_len, char *version, uint32_t version_len)
 
static void GSC_SVCI_remove (struct GSC_ServicesInfo *services, char *name, uint32_t name_len)
 
static int type_match (uint16_t type, struct GSC_Client *c)
 Test if the client is interested in messages of the given type.
 
static int check_client_init (void *cls, const struct InitMessage *im)
 Check GNUNET_MESSAGE_TYPE_CORE_INIT request.
 
static void handle_client_init (void *cls, const struct InitMessage *im)
 Handle GNUNET_MESSAGE_TYPE_CORE_INIT 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).
 
void GSC_CLIENTS_solicit_request (struct GSC_ClientActiveRequest *car)
 Tell a client that we are ready to receive the message.
 
static void handle_client_send_request (void *cls, const struct SendMessageRequest *req)
 Handle GNUNET_MESSAGE_TYPE_CORE_SEND_REQUEST message.
 
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.
 
static int check_client_send (void *cls, const struct SendMessage *sm)
 Check GNUNET_MESSAGE_TYPE_CORE_SEND request.
 
static void handle_client_send (void *cls, const struct SendMessage *sm)
 Handle GNUNET_MESSAGE_TYPE_CORE_SEND request.
 
static int destroy_active_client_request (void *cls, const struct GNUNET_PeerIdentity *key, void *value)
 Free client request records.
 
static void * client_connect_cb (void *cls, struct GNUNET_SERVICE_Client *client, struct GNUNET_MQ_Handle *mq)
 A client connected, set up.
 
static void client_disconnect_cb (void *cls, struct GNUNET_SERVICE_Client *client, void *app_ctx)
 A client disconnected, clean up.
 
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 the client is interested).
 
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_notify_clients_about_neighbour (const struct GNUNET_PeerIdentity *neighbour, enum GNUNET_CORE_PeerClass class)
 Notify all clients about a change to existing session.
 
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 shutdown_task (void *cls)
 Last task run during shutdown.
 
static void handle_client_monitor_peers (void *cls, const struct GNUNET_MessageHeader *message)
 Handle GNUNET_MESSAGE_TYPE_CORE_MONITOR_PEERS request.
 
static void run (void *cls, const struct GNUNET_CONFIGURATION_Handle *c, struct GNUNET_SERVICE_Handle *service)
 Initiate core service.
 
 GNUNET_SERVICE_MAIN (GNUNET_OS_project_data_gnunet(), "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.
 

Variables

const struct GNUNET_CONFIGURATION_HandleGSC_cfg
 Our configuration.
 
struct GNUNET_SERVICE_Handleservice_h
 Handle to the running service.
 
struct GNUNET_STATISTICS_HandleGSC_stats
 For creating statistics.
 
struct GNUNET_PILS_HandleGSC_pils
 For peer identity access.
 
static enum GNUNET_CORE_PeerClass GSC_peer_class
 Our peer class.
 
static uint32_t all_client_options
 Big "or" of all client options.
 
static struct GSC_Clientclient_head
 Head of linked list of our clients.
 
static struct GSC_Clientclient_tail
 Tail of linked list of our clients.
 
static struct GSC_ServicesInfoown_services
 

Detailed Description

high-level P2P messaging

Author
Christian Grothoff

Definition in file gnunet-service-core.c.

Macro Definition Documentation

◆ SOFT_MAX_QUEUE

#define SOFT_MAX_QUEUE   128

How many messages do we queue up at most for any client? This can cause messages to be dropped if clients do not process them fast enough! Note that this is a soft limit; we try to keep a few larger messages above the limit.

Definition at line 41 of file gnunet-service-core.c.

◆ HARD_MAX_QUEUE

#define HARD_MAX_QUEUE   256

How many messages do we queue up at most for any client? This can cause messages to be dropped if clients do not process them fast enough! Note that this is the hard limit.

Definition at line 48 of file gnunet-service-core.c.

Function Documentation

◆ GSC_SVCI_init()

static struct GSC_ServicesInfo * GSC_SVCI_init ( )
static

Definition at line 199 of file gnunet-service-core.c.

200{
201 struct GSC_ServicesInfo *services_info = GNUNET_new (struct GSC_ServicesInfo);
202 services_info->num_entries = 0;
203 services_info->entries = NULL;
204 return services_info;
205}
#define GNUNET_new(type)
Allocate a struct or union of the given type.
struct GSC_ServicesInfo_Entry * entries

References GSC_ServicesInfo::entries, GNUNET_new, and GSC_ServicesInfo::num_entries.

Referenced by run().

Here is the caller graph for this function:

◆ GSC_SVCI_destroy()

static void GSC_SVCI_destroy ( struct GSC_ServicesInfo services_info)
static

Definition at line 210 of file gnunet-service-core.c.

211{
212 GNUNET_assert (NULL != services_info);
213 GNUNET_free (services_info);
214}
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_free(ptr)
Wrapper around free.

References GNUNET_assert, and GNUNET_free.

Referenced by shutdown_task().

Here is the caller graph for this function:

◆ GSC_SVCI_add()

static void GSC_SVCI_add ( struct GSC_ServicesInfo services,
char *  name,
uint32_t  name_len,
char *  version,
uint32_t  version_len 
)
static

Definition at line 220 of file gnunet-service-core.c.

223{
224 struct GSC_ServicesInfo_Entry *entry;
225
226 GNUNET_array_grow (services->entries, services->num_entries, 1);
227 entry = &services->entries[services->num_entries - 1];
228 entry->name = GNUNET_strdup (name);
229 entry->name_len = name_len;
230 entry->version = GNUNET_strdup (version);
231 entry->version_len = version_len;
232}
static struct GNUNET_CONTAINER_MultiHashMap * services
This hashmaps saves interesting things about the configured services.
static char * name
Name (label) of the records to list.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define GNUNET_array_grow(arr, size, tsize)
Grow a well-typed (!) array.
char * name
uint32_t name_len
uint32_t version_len
char * version

References GNUNET_array_grow, GNUNET_strdup, name, GSC_ServicesInfo_Entry::name, GSC_ServicesInfo_Entry::name_len, services, GSC_ServicesInfo_Entry::version, and GSC_ServicesInfo_Entry::version_len.

Referenced by handle_client_init().

Here is the caller graph for this function:

◆ GSC_SVCI_remove()

static void GSC_SVCI_remove ( struct GSC_ServicesInfo services,
char *  name,
uint32_t  name_len 
)
static

Definition at line 237 of file gnunet-service-core.c.

239{
240 struct GSC_ServicesInfo_Entry *entry;
241 uint64_t i_entry;
242
243 /* Find element */
244 entry = NULL;
245 for (uint64_t i = 0; i < services->num_entries; i++)
246 {
247 if (services->entries[i].name_len != name_len)
248 continue;
249 if (0 == memcmp (services->entries[i].name, name, name_len))
250 {
251 entry = &services->entries[i];
252 i_entry = i;
253 break;
254 }
255 }
256 if (NULL == entry)
257 {
258 /* No matching entry was found!*/
260 "No matching service entry `%s' was found in services info.\n",
261 name);
262 return;
263 }
264
265 /* Remove element */
266 GNUNET_free (entry->name);
267 GNUNET_free (entry->version);
268 for (uint64_t i = i_entry; i < services->num_entries - 1; i++)
269 {
270 GNUNET_memcpy (&services->entries[i],
271 &services->entries[i + 1],
272 sizeof (services->entries[i + 1]));
273 }
274 GNUNET_array_grow (services->entries,
275 services->num_entries,
276 services->num_entries - 1);
277}
#define GNUNET_log(kind,...)
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
@ GNUNET_ERROR_TYPE_WARNING

References GNUNET_array_grow, GNUNET_ERROR_TYPE_WARNING, GNUNET_free, GNUNET_log, GNUNET_memcpy, name, GSC_ServicesInfo_Entry::name, GSC_ServicesInfo_Entry::name_len, services, and GSC_ServicesInfo_Entry::version.

Referenced by client_disconnect_cb().

Here is the caller graph for this function:

◆ type_match()

static int type_match ( uint16_t  type,
struct GSC_Client c 
)
static

Test if the client is interested in messages of the given type.

Parameters
typemessage type
cclient to test
Returns
GNUNET_YES if c is interested, GNUNET_NO if not.

Definition at line 293 of file gnunet-service-core.c.

294{
295 if ((0 == c->tcnt) && (0 != c->options))
296 return GNUNET_YES; /* peer without handlers and inbound/outbond
297 callbacks matches ALL */
298 if (NULL == c->types)
299 return GNUNET_NO;
300 for (unsigned int i = 0; i < c->tcnt; i++)
301 if (type == c->types[i])
302 return GNUNET_YES;
303 return GNUNET_NO;
304}
static uint32_t type
Type string converted to DNS type value.
@ GNUNET_YES
@ GNUNET_NO
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.
uint16_t * types
Array of the types of messages this peer cares about (with tcnt entries).

References GNUNET_NO, GNUNET_YES, GSC_Client::options, GSC_Client::tcnt, type, and GSC_Client::types.

Referenced by GSC_CLIENTS_deliver_message().

Here is the caller graph for this function:

◆ check_client_init()

static int check_client_init ( void *  cls,
const struct InitMessage im 
)
static

Check GNUNET_MESSAGE_TYPE_CORE_INIT request.

Parameters
clsclient that sent GNUNET_MESSAGE_TYPE_CORE_INIT
imthe struct InitMessage
Returns
GNUNET_OK if im is well-formed

Definition at line 315 of file gnunet-service-core.c.

316{
317 return GNUNET_OK;
318}
@ GNUNET_OK

References GNUNET_OK.

◆ handle_client_init()

static void handle_client_init ( void *  cls,
const struct InitMessage im 
)
static

Handle GNUNET_MESSAGE_TYPE_CORE_INIT request.

Parameters
clsclient that sent GNUNET_MESSAGE_TYPE_CORE_INIT
imthe struct InitMessage

Definition at line 328 of file gnunet-service-core.c.

329{
330 const struct GNUNET_PeerIdentity *my_identity;
331 struct GSC_Client *c = cls;
332 struct GNUNET_MQ_Envelope *env;
333 struct InitReplyMessage *irm;
334 uint16_t msize;
335 const uint16_t *types;
336
338 GNUNET_assert (NULL != my_identity);
339
340 /* check that we don't have an entry already */
341 msize = ntohs (im->header.size) - sizeof(struct InitMessage);
342 types = (const uint16_t *) &im[1];
343 c->tcnt = msize / sizeof(uint16_t);
344 c->options = ntohl (im->options);
345 c->got_init = GNUNET_YES;
347 c->types = GNUNET_malloc (msize);
350 c->connectmap,
352 NULL,
354 for (unsigned int i = 0; i < c->tcnt; i++)
355 c->types[i] = ntohs (types[i]);
356 // TODO
357 GSC_SVCI_add (own_services, "example", 7, "0.1", 3);
358 GNUNET_log (
360 "Client connecting to core service is interested in %u message types\n",
361 (unsigned int) c->tcnt);
362 for (unsigned int i = 0; i < c->tcnt; i++)
364 " type[%u]: %u\n",
365 i,
366 c->types[i]);
367 /* send init reply message */
369 irm->reserved = htonl (0);
370 irm->my_identity = *my_identity;
371 irm->class = GSC_peer_class;
372 GNUNET_MQ_send (c->mq, env);
375}
struct GNUNET_MQ_Envelope * env
Definition 005.c:1
static struct GNUNET_PeerIdentity my_identity
Identity of this peer.
static struct GSC_ServicesInfo * own_services
static uint32_t all_client_options
Big "or" of all client options.
static void GSC_SVCI_add(struct GSC_ServicesInfo *services, char *name, uint32_t name_len, char *version, uint32_t version_len)
static enum GNUNET_CORE_PeerClass GSC_peer_class
Our peer class.
struct GNUNET_PILS_Handle * GSC_pils
For peer identity access.
void GSC_SESSIONS_notify_client_about_sessions(struct GSC_Client *client)
We have a new client, notify it about all current sessions.
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
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.
@ 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 size
The length of the struct (in bytes, including the length field itself), in big-endian format.
@ GNUNET_ERROR_TYPE_DEBUG
#define GNUNET_malloc(size)
Wrapper around malloc.
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_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
#define GNUNET_MESSAGE_TYPE_CORE_INIT_REPLY
Response from core to core client to INIT message.
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition service.c:2434
The identity of the host (wraps the signing key of the peer).
Data structure for each client connected to the CORE service.
struct GNUNET_SERVICE_Client * client
Handle for the client with the server API.
struct GNUNET_MQ_Handle * mq
Message queue to talk to client.
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?
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

References all_client_options, InitReplyMessage::class, GSC_Client::client, GSC_Client::connectmap, env, GNUNET_assert, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY, GNUNET_CONTAINER_multipeermap_put(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_malloc, GNUNET_MESSAGE_TYPE_CORE_INIT_REPLY, GNUNET_MQ_msg, GNUNET_MQ_send(), GNUNET_PILS_get_identity(), GNUNET_SERVICE_client_continue(), GNUNET_YES, GSC_Client::got_init, GSC_peer_class, GSC_pils, GSC_SESSIONS_notify_client_about_sessions(), GSC_SVCI_add(), InitMessage::header, GSC_Client::mq, my_identity, InitReplyMessage::my_identity, InitMessage::options, GSC_Client::options, own_services, InitReplyMessage::reserved, GNUNET_MessageHeader::size, GSC_Client::tcnt, and GSC_Client::types.

Here is the call graph for this function:

◆ GSC_CLIENTS_reject_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).

Frees resources associated with car. We don't explicitly tell the client, it'll learn with the disconnect (or violated the protocol).

Parameters
carrequest that now permanently failed; the responsibility for the handle is now returned to CLIENTS (SESSIONS is done with it).
drop_clientGNUNET_YES if the client violated the protocol and we should thus drop the connection

Definition at line 391 of file gnunet-service-core.c.

393{
395 GNUNET_YES ==
397 &car->target,
398 car));
399 if (GNUNET_YES == drop_client)
401 GNUNET_free (car);
402}
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.
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition service.c:2463
struct GNUNET_PeerIdentity target
Which peer is the message going to be for?
struct GSC_Client * client_handle
Handle to the client.
struct GNUNET_CONTAINER_MultiPeerMap * requests
Map of peer identities to active transmission requests of this client to the peer (of type struct GSC...

References GSC_Client::client, GSC_ClientActiveRequest::client_handle, GNUNET_assert, GNUNET_CONTAINER_multipeermap_remove(), GNUNET_free, GNUNET_SERVICE_client_drop(), GNUNET_YES, GSC_Client::requests, and GSC_ClientActiveRequest::target.

Referenced by GSC_CLIENTS_solicit_request(), GSC_SESSIONS_end(), GSC_SESSIONS_queue_request(), and GSC_SESSIONS_transmit().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GSC_CLIENTS_solicit_request()

void GSC_CLIENTS_solicit_request ( struct GSC_ClientActiveRequest car)

Tell a client that we are ready to receive the message.

Parameters
carrequest that is now ready; the responsibility for the handle remains shared between CLIENTS and SESSIONS after this call.

Definition at line 413 of file gnunet-service-core.c.

414{
415 struct GSC_Client *c;
416 struct GNUNET_MQ_Envelope *env;
417 struct SendMessageReady *smr;
418 struct GNUNET_TIME_Relative delay;
419 struct GNUNET_TIME_Relative left;
420
421 c = car->client_handle;
422 if (GNUNET_YES !=
424 {
425 const struct GNUNET_PeerIdentity *my_identity;
427 GNUNET_assert (NULL != my_identity);
428 /* connection has gone down since, drop request */
429 GNUNET_assert (0 !=
430 GNUNET_memcmp (&car->target,
431 my_identity));
434 return;
435 }
438 if (delay.rel_value_us > GNUNET_CONSTANTS_LATENCY_WARN.rel_value_us)
439 GNUNET_log (
441 "Client waited %s for permission to transmit to `%s'%s (priority %u)\n",
443 GNUNET_i2s (&car->target),
444 (0 == left.rel_value_us) ? " (past deadline)" : "",
445 car->priority);
447 smr->size = htons (car->msize);
448 smr->smr_id = car->smr_id;
449 smr->peer = car->target;
450 GNUNET_MQ_send (c->mq, env);
451}
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).
void GSC_SESSIONS_dequeue_request(struct GSC_ClientActiveRequest *car)
Dequeue a request from a client from transmission to a particular peer.
#define GNUNET_CONSTANTS_LATENCY_WARN
After what amount of latency for a message do we print a warning?
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).
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#define GNUNET_MESSAGE_TYPE_CORE_SEND_READY
Confirmation from core that message can now be sent.
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:610
Time for relative time used by GNUnet, in microseconds.
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?
uint16_t msize
How many bytes does the client intend to send?
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

References GSC_ClientActiveRequest::client_handle, GSC_Client::connectmap, GSC_ClientActiveRequest::deadline, env, GNUNET_assert, GNUNET_CONSTANTS_LATENCY_WARN, GNUNET_CONTAINER_multipeermap_contains(), GNUNET_ERROR_TYPE_WARNING, GNUNET_i2s(), GNUNET_log, GNUNET_memcmp, GNUNET_MESSAGE_TYPE_CORE_SEND_READY, GNUNET_MQ_msg, GNUNET_MQ_send(), GNUNET_NO, GNUNET_PILS_get_identity(), GNUNET_STRINGS_relative_time_to_string(), GNUNET_TIME_absolute_get_duration(), GNUNET_YES, GSC_CLIENTS_reject_request(), GSC_pils, GSC_SESSIONS_dequeue_request(), GSC_Client::mq, GSC_ClientActiveRequest::msize, my_identity, SendMessageReady::peer, GSC_ClientActiveRequest::priority, GSC_ClientActiveRequest::received_time, GNUNET_TIME_Relative::rel_value_us, SendMessageReady::size, SendMessageReady::smr_id, GSC_ClientActiveRequest::smr_id, and GSC_ClientActiveRequest::target.

Referenced by handle_client_send_request(), and solicit_messages().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ handle_client_send_request()

static void handle_client_send_request ( void *  cls,
const struct SendMessageRequest req 
)
static

Handle GNUNET_MESSAGE_TYPE_CORE_SEND_REQUEST message.

Parameters
clsclient that sent a GNUNET_MESSAGE_TYPE_CORE_SEND_REQUEST
reqthe struct SendMessageRequest

Definition at line 461 of file gnunet-service-core.c.

462{
463 const struct GNUNET_PeerIdentity *my_identity;
464 struct GSC_Client *c = cls;
465 struct GSC_ClientActiveRequest *car;
466 int is_loopback;
467
469 GNUNET_assert (NULL != my_identity);
470
471 if (NULL == c->requests)
474 "Client asked for transmission to `%s'\n",
475 GNUNET_i2s (&req->peer));
476 is_loopback = (0 == GNUNET_memcmp (&req->peer, my_identity));
477 if ((! is_loopback) &&
478 (GNUNET_YES !=
480 {
481 /* neighbour must have disconnected since request was issued,
482 * ignore (client will realize it once it processes the
483 * disconnect notification) */
486 "# send requests dropped (disconnected)"),
487 1,
488 GNUNET_NO);
490 return;
491 }
492
494 if (NULL == car)
495 {
496 /* create new entry */
497 car = GNUNET_new (struct GSC_ClientActiveRequest);
500 c->requests,
501 &req->peer,
502 car,
504 car->client_handle = c;
505 }
506 else
507 {
508 /* dequeue and recycle memory from pending request, there can only
509 be at most one per client and peer */
512 "# dequeuing CAR (duplicate request)"),
513 1,
514 GNUNET_NO);
517 "Transmission request to `%s' was a duplicate!\n",
518 GNUNET_i2s (&req->peer));
519 }
520 car->target = req->peer;
523 car->priority = ntohl (req->priority);
524 car->msize = ntohs (req->size);
525 car->smr_id = req->smr_id;
528 if (is_loopback)
529 {
530 /* loopback, satisfy immediately */
532 return;
533 }
535}
#define gettext_noop(String)
Definition gettext.h:74
struct GNUNET_STATISTICS_Handle * GSC_stats
For creating statistics.
void GSC_CLIENTS_solicit_request(struct GSC_ClientActiveRequest *car)
Tell a client that we are ready to receive the message.
void GSC_SESSIONS_queue_request(struct GSC_ClientActiveRequest *car)
Queue a request from a client for transmission to a particular peer.
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.
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).
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST
, ' bother checking if a value already exists (faster than GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE...
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
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
Record kept for each request for transmission issued by a client that is still pending.
int was_solicited
Has this request been solicited yet?
enum GNUNET_MQ_PriorityPreferences priority
How important is this request.
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

References GSC_Client::client, GSC_ClientActiveRequest::client_handle, GSC_Client::connectmap, SendMessageRequest::deadline, GSC_ClientActiveRequest::deadline, gettext_noop, GNUNET_assert, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST, GNUNET_CONTAINER_multipeermap_contains(), GNUNET_CONTAINER_multipeermap_create(), GNUNET_CONTAINER_multipeermap_get(), GNUNET_CONTAINER_multipeermap_put(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_i2s(), GNUNET_log, GNUNET_memcmp, GNUNET_new, GNUNET_NO, GNUNET_OK, GNUNET_PILS_get_identity(), GNUNET_SERVICE_client_continue(), GNUNET_STATISTICS_update(), GNUNET_TIME_absolute_get(), GNUNET_TIME_absolute_ntoh(), GNUNET_YES, GSC_CLIENTS_solicit_request(), GSC_pils, GSC_SESSIONS_dequeue_request(), GSC_SESSIONS_queue_request(), GSC_stats, GSC_ClientActiveRequest::msize, my_identity, SendMessageRequest::peer, SendMessageRequest::priority, GSC_ClientActiveRequest::priority, GSC_ClientActiveRequest::received_time, GSC_Client::requests, SendMessageRequest::size, SendMessageRequest::smr_id, GSC_ClientActiveRequest::smr_id, GSC_ClientActiveRequest::target, and GSC_ClientActiveRequest::was_solicited.

Here is the call graph for this function:

◆ tokenized_cb()

static int tokenized_cb ( void *  cls,
const struct GNUNET_MessageHeader message 
)
static

Functions with this signature are called whenever a complete message is received by the tokenizer.

Used by handle_client_send() for dispatching messages from clients to either the SESSION subsystem or other CLIENT (for loopback).

Parameters
clsreservation request (struct TokenizerContext)
messagethe actual message
Returns
GNUNET_OK on success, GNUNET_NO to stop further processing (no error) GNUNET_SYSERR to stop further processing with error

Definition at line 568 of file gnunet-service-core.c.

569{
570 const struct GNUNET_PeerIdentity *my_identity;
571 struct TokenizerContext *tc = cls;
572 struct GSC_ClientActiveRequest *car = tc->car;
573 char buf[92];
574
576 GNUNET_assert (NULL != my_identity);
577
578 GNUNET_snprintf (buf,
579 sizeof(buf),
580 gettext_noop ("# bytes of messages of type %u received"),
581 (unsigned int) ntohs (message->type));
582 GNUNET_STATISTICS_update (GSC_stats, buf, ntohs (message->size), GNUNET_NO);
583 if (0 == GNUNET_memcmp (&car->target, my_identity))
584 {
586 "Delivering message of type %u to myself\n",
587 ntohs (message->type));
589 message,
590 ntohs (message->size),
593 message,
594 sizeof(struct GNUNET_MessageHeader),
597 message,
598 ntohs (message->size),
601 message,
602 sizeof(struct GNUNET_MessageHeader),
604 }
605 else
606 {
608 "Delivering message of type %u and size %u to %s\n",
609 ntohs (message->type),
610 ntohs (message->size),
611 GNUNET_i2s (&car->target));
613 message,
614 ntohs (message->size),
617 message,
618 sizeof(struct GNUNET_MessageHeader),
620 GSC_SESSIONS_transmit (car, message, tc->priority);
621 }
622 return GNUNET_OK;
623}
#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
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.
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.
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
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.
static struct GNUNET_SCHEDULER_TaskContext tc
Task context of the current task.
Definition scheduler.c:436
Header for all communications.
Closure for the #client_tokenizer_callback().

References gettext_noop, GNUNET_assert, GNUNET_CORE_OPTION_SEND_FULL_INBOUND, GNUNET_CORE_OPTION_SEND_FULL_OUTBOUND, GNUNET_CORE_OPTION_SEND_HDR_INBOUND, GNUNET_CORE_OPTION_SEND_HDR_OUTBOUND, GNUNET_ERROR_TYPE_DEBUG, GNUNET_i2s(), GNUNET_log, GNUNET_memcmp, GNUNET_NO, GNUNET_OK, GNUNET_PILS_get_identity(), GNUNET_snprintf(), GNUNET_STATISTICS_update(), GSC_CLIENTS_deliver_message(), GSC_pils, GSC_SESSIONS_transmit(), GSC_stats, my_identity, GNUNET_MessageHeader::size, GSC_ClientActiveRequest::target, tc, and GNUNET_MessageHeader::type.

Referenced by handle_client_send().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_client_send()

static int check_client_send ( void *  cls,
const struct SendMessage sm 
)
static

Check GNUNET_MESSAGE_TYPE_CORE_SEND request.

Parameters
clsthe struct GSC_Client
smthe struct SendMessage
Returns
GNUNET_OK if sm is well-formed

Definition at line 634 of file gnunet-service-core.c.

635{
636 return GNUNET_OK;
637}

References GNUNET_OK.

◆ handle_client_send()

static void handle_client_send ( void *  cls,
const struct SendMessage sm 
)
static

Handle GNUNET_MESSAGE_TYPE_CORE_SEND request.

Parameters
clsthe struct GSC_Client
smthe struct SendMessage

Definition at line 647 of file gnunet-service-core.c.

648{
649 struct GSC_Client *c = cls;
650 struct TokenizerContext tc;
651 uint16_t msize;
652 struct GNUNET_TIME_Relative delay;
654
655 msize = ntohs (sm->header.size) - sizeof(struct SendMessage);
657 if (NULL == tc.car)
658 {
659 /* Must have been that we first approved the request, then got disconnected
660 * (which triggered removal of the 'car') and now the client gives us a message
661 * just *before* the client learns about the disconnect. Theoretically, we
662 * might also now be *again* connected. So this can happen (but should be
663 * rare). If it does happen, the message is discarded. */
666 "# messages discarded (session disconnected)"),
667 1,
668 GNUNET_NO);
670 return;
671 }
672 delay = GNUNET_TIME_absolute_get_duration (tc.car->received_time);
673 tc.priority = ntohl (sm->priority);
674 if (delay.rel_value_us > GNUNET_CONSTANTS_LATENCY_WARN.rel_value_us)
676 "Client waited %s for transmission of %u bytes to `%s'\n",
678 msize,
679 GNUNET_i2s (&sm->peer));
680 else
682 "Client waited %s for transmission of %u bytes to `%s'\n",
684 msize,
685 GNUNET_i2s (&sm->peer));
686
688 GNUNET_YES ==
692 (const char *) &sm[1],
693 msize,
695 GNUNET_NO);
696 GNUNET_MST_destroy (mst);
698 GNUNET_free (tc.car);
700}
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.
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
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
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

References GSC_Client::client, gettext_noop, GNUNET_assert, GNUNET_CONSTANTS_LATENCY_WARN, GNUNET_CONTAINER_multipeermap_get(), GNUNET_CONTAINER_multipeermap_remove(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_WARNING, GNUNET_free, GNUNET_i2s(), GNUNET_log, GNUNET_MST_create(), GNUNET_MST_destroy(), GNUNET_MST_from_buffer(), GNUNET_NO, GNUNET_SERVICE_client_continue(), GNUNET_STATISTICS_update(), GNUNET_STRINGS_relative_time_to_string(), GNUNET_TIME_absolute_get_duration(), GNUNET_YES, GSC_SESSIONS_dequeue_request(), GSC_stats, GNUNET_MessageStreamTokenizer::off, SendMessage::peer, SendMessage::priority, GNUNET_TIME_Relative::rel_value_us, GSC_Client::requests, tc, and tokenized_cb().

Here is the call graph for this function:

◆ destroy_active_client_request()

static int destroy_active_client_request ( void *  cls,
const struct GNUNET_PeerIdentity key,
void *  value 
)
static

Free client request records.

Parameters
clsNULL
keyidentity of peer for which this is an active request
valuethe struct GSC_ClientActiveRequest to free
Returns
GNUNET_YES (continue iteration)

Definition at line 712 of file gnunet-service-core.c.

715{
716 struct GSC_ClientActiveRequest *car = value;
717
719 GNUNET_YES ==
721 &car->target,
722 car));
724 GNUNET_free (car);
725 return GNUNET_YES;
726}
static char * value
Value of the record to add/remove.

References GSC_ClientActiveRequest::client_handle, GNUNET_assert, GNUNET_CONTAINER_multipeermap_remove(), GNUNET_free, GNUNET_YES, GSC_SESSIONS_dequeue_request(), GSC_Client::requests, GSC_ClientActiveRequest::target, and value.

Referenced by client_disconnect_cb().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ client_connect_cb()

static void * client_connect_cb ( void *  cls,
struct GNUNET_SERVICE_Client client,
struct GNUNET_MQ_Handle mq 
)
static

A client connected, set up.

Parameters
clsclosure
clientidentification of the client
mqmessage queue to talk to client
Returns
our client handle

Definition at line 738 of file gnunet-service-core.c.

741{
742 struct GSC_Client *c;
743
744 c = GNUNET_new (struct GSC_Client);
745 c->client = client;
746 c->mq = mq;
749 return c;
750}
static struct GSC_Client * client_head
Head of linked list of our clients.
static struct GSC_Client * client_tail
Tail of linked list of our clients.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
static struct GNUNET_MQ_Handle * mq
Our connection to the resolver service, created on-demand, but then persists until error or shutdown.

References GSC_Client::client, client_head, client_tail, GSC_Client::connectmap, GNUNET_CONTAINER_DLL_insert, GNUNET_CONTAINER_multipeermap_create(), GNUNET_new, GNUNET_NO, mq, and GSC_Client::mq.

Here is the call graph for this function:

◆ client_disconnect_cb()

static void client_disconnect_cb ( void *  cls,
struct GNUNET_SERVICE_Client client,
void *  app_ctx 
)
static

A client disconnected, clean up.

Parameters
clsclosure
clientidentification of the client
app_ctxour struct GST_Client for client

Definition at line 761 of file gnunet-service-core.c.

764{
765 struct GSC_Client *c = app_ctx;
766
768 "Client %p has disconnected from core service.\n",
769 client);
771 if (NULL != c->requests)
772 {
775 NULL);
777 }
779 c->connectmap = NULL;
780 // TODO
781 GSC_SVCI_remove (own_services, "example", 7);
782
783 /* recalculate 'all_client_options' */
785 for (c = client_head; NULL != c; c = c->next)
787}
static int destroy_active_client_request(void *cls, const struct GNUNET_PeerIdentity *key, void *value)
Free client request records.
static void GSC_SVCI_remove(struct GSC_ServicesInfo *services, char *name, uint32_t name_len)
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
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 GSC_Client * next
Clients are kept in a linked list.

References all_client_options, GSC_Client::client, client_head, client_tail, GSC_Client::connectmap, destroy_active_client_request(), GNUNET_CONTAINER_DLL_remove, GNUNET_CONTAINER_multipeermap_destroy(), GNUNET_CONTAINER_multipeermap_iterate(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GSC_SVCI_remove(), GSC_Client::next, GSC_Client::options, own_services, and GSC_Client::requests.

Here is the call graph for this function:

◆ GSC_CLIENTS_notify_client_about_neighbour()

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 the client is interested).

Called from GSC_SESSIONS_notify_client_about_sessions().

Parameters
clientclient to notify
neighbouridentity of the neighbour that changed status
tmap_oldprevious type map for the neighbour, NULL for connect
tmap_newupdated type map for the neighbour, NULL for disconnect
classthe class of the neighbour that changed status

Definition at line 802 of file gnunet-service-core.c.

806{
807 struct GNUNET_MQ_Envelope *env;
808 struct ConnectNotifyMessage *cnm;
809
810 if (GNUNET_YES != client->got_init)
811 return;
812 // TODO
813 // GSC_SVCI_contains (own_services, "example", 7);
815 "Notifying client about neighbour %s\n",
816 GNUNET_i2s (neighbour));
817
818 /* send connect */
819 // TODO this used to be an assert. evaluate what handling makes sense here.
821 neighbour))
822 {
823 return;
824 }
827 client->connectmap,
828 neighbour,
829 NULL,
832 cnm->reserved = htonl (0);
834 "Sending NOTIFY_CONNECT message about peer %s to client.\n",
835 GNUNET_i2s (neighbour));
836 cnm->peer = *neighbour;
837 cnm->peer_class = class;
838 GNUNET_MQ_send (client->mq, env);
839}
#define GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT
Notify clients about new peer-to-peer connections (triggered after key exchange).
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

References GSC_Client::connectmap, env, GNUNET_assert, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY, GNUNET_CONTAINER_multipeermap_contains(), GNUNET_CONTAINER_multipeermap_put(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_i2s(), GNUNET_log, GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT, GNUNET_MQ_msg, GNUNET_MQ_send(), GNUNET_YES, GSC_Client::got_init, GSC_Client::mq, ConnectNotifyMessage::peer, ConnectNotifyMessage::peer_class, and ConnectNotifyMessage::reserved.

Referenced by GSC_CLIENTS_notify_clients_about_neighbour(), and notify_client_about_session().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GSC_complete_initialization_cb()

void GSC_complete_initialization_cb ( void  )

This function is called from GSC_KX_init() once it got its peer id from pils.

Parameters
clsclosure to the callback

Definition at line 848 of file gnunet-service-core.c.

849{
850 const struct GNUNET_PeerIdentity *my_identity;
854 GNUNET_assert (NULL != my_identity);
856 _ ("Core service of `%s' ready.\n"),
858}
struct GNUNET_SERVICE_Handle * service_h
Handle to the running service.
void GSC_SESSIONS_init()
Initialize sessions subsystem.
@ GNUNET_ERROR_TYPE_INFO
void GNUNET_SERVICE_resume(struct GNUNET_SERVICE_Handle *sh)
Resume accepting connections from the listen socket.
Definition service.c:2389
#define _(String)
GNU gettext support macro.
Definition platform.h:179

References _, GNUNET_assert, GNUNET_ERROR_TYPE_INFO, GNUNET_i2s(), GNUNET_log, GNUNET_PILS_get_identity(), GNUNET_SERVICE_resume(), GSC_pils, GSC_SESSIONS_init(), my_identity, and service_h.

Referenced by GSC_KX_start().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GSC_CLIENTS_notify_clients_about_neighbour()

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.

Called from SESSIONS whenever there is a change in sessions or types processed by the respective peer.

Parameters
neighbouridentity of the neighbour that changed status
tmap_oldprevious type map for the neighbour, NULL for connect
tmap_newupdated type map for the neighbour, NULL for disconnect
classthe class of the neighbour that changed status

Definition at line 872 of file gnunet-service-core.c.

875{
876 struct GSC_Client *c;
877
878 for (c = client_head; NULL != c; c = c->next)
880 neighbour,
881 class);
882}
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...

References client_head, GSC_CLIENTS_notify_client_about_neighbour(), and GSC_Client::next.

Referenced by GSC_SESSIONS_create(), and GSC_SESSIONS_end().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GSC_CLIENTS_deliver_message()

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.

Caller must have checked that the sending peer actually lists the given message type as one of its types.

Parameters
senderpeer who sent us the message
msgthe message
msizenumber of bytes to transmit
optionsoptions for checking which clients should receive the message

Definition at line 897 of file gnunet-service-core.c.

901{
902 size_t size = msize + sizeof(struct NotifyTrafficMessage);
903
905 {
906 GNUNET_break (0);
907 return;
908 }
909 if (! ((0 != (all_client_options & options)) ||
911 {
912 return; /* no client cares about this message notification */
913 }
915 "Core service passes message from `%s' of type %u to client.\n",
916 GNUNET_i2s (sender),
917 (unsigned int) ntohs (msg->type));
918 // TODO
919 // GSC_SVCI_add (sender->services, "example", 7, "0.1", 3);
920
921 for (struct GSC_Client *c = client_head; NULL != c; c = c->next)
922 {
923 struct GNUNET_MQ_Envelope *env;
924 struct NotifyTrafficMessage *ntm;
925 uint16_t mtype;
926 unsigned int qlen;
927 int tm;
928
929 tm = type_match (ntohs (msg->type), c);
930 if (! ((0 != (c->options & options)) ||
932 (GNUNET_YES == tm))))
933 continue; /* neither options nor type match permit the message */
935 ((0 != (c->options & GNUNET_CORE_OPTION_SEND_FULL_INBOUND)) ||
936 (GNUNET_YES == tm)))
937 continue;
939 (0 != (c->options & GNUNET_CORE_OPTION_SEND_FULL_OUTBOUND)))
940 continue;
941
942 /* Drop messages if:
943 1) We are above the hard limit, or
944 2) We are above the soft limit, and a coin toss limited
945 to the message size (giving larger messages a
946 proportionally higher chance of being queued) falls
947 below the threshold. The threshold is based on where
948 we are between the soft and the hard limit, scaled
949 to match the range of message sizes we usually encounter
950 (i.e. up to 32k); so a 64k message has a 50% chance of
951 being kept if we are just barely below the hard max,
952 and a 99% chance of being kept if we are at the soft max.
953 The reason is to make it more likely to drop control traffic
954 (ACK, queries) which may be cumulative or highly redundant,
955 and cheap to drop than data traffic. */qlen = GNUNET_MQ_get_length (c->mq);
956 if ((qlen >= HARD_MAX_QUEUE) ||
957 ((qlen > SOFT_MAX_QUEUE) &&
958 ((GNUNET_CRYPTO_random_u32 (ntohs (msg->size))) <
959 (qlen - SOFT_MAX_QUEUE) * 0x8000
961 {
962 char buf[1024];
963
964 GNUNET_log (
966 "Dropping decrypted message of type %u as client is too busy (queue full)\n",
967 (unsigned int) ntohs (msg->type));
968 GNUNET_snprintf (buf,
969 sizeof(buf),
971 "# messages of type %u discarded (client busy)"),
972 (unsigned int) ntohs (msg->type));
974 continue;
975 }
976
977 GNUNET_log (
979 "Sending %u message with %u bytes to client interested in messages of type %u.\n",
980 options,
981 ntohs (msg->size),
982 (unsigned int) ntohs (msg->type));
983
987 else
989 env = GNUNET_MQ_msg_extra (ntm, msize, mtype);
990 ntm->peer = *sender;
991 GNUNET_memcpy (&ntm[1], msg, msize);
992
994 (0 == (c->options & GNUNET_CORE_OPTION_SEND_FULL_INBOUND)) ||
995 (GNUNET_YES != tm) ||
996 (GNUNET_YES ==
997 GNUNET_CONTAINER_multipeermap_contains (c->connectmap, sender)));
998 GNUNET_MQ_send (c->mq, env);
999 }
1000}
struct GNUNET_GETOPT_CommandLineOption options[]
Definition 002.c:5
struct GNUNET_MessageHeader * msg
Definition 005.c:2
static int type_match(uint16_t type, struct GSC_Client *c)
Test if the client is interested in messages of the given type.
#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...
#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...
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message,...
uint32_t GNUNET_CRYPTO_random_u32(uint32_t i)
Produce a random value.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
@ GNUNET_ERROR_TYPE_BULK
unsigned int GNUNET_MQ_get_length(struct GNUNET_MQ_Handle *mq)
Obtain the current length of the message queue.
Definition mq.c:293
#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_MESSAGE_TYPE_CORE_NOTIFY_OUTBOUND
Notify clients about outgoing P2P transmissions.
#define GNUNET_MESSAGE_TYPE_CORE_NOTIFY_INBOUND
Notify clients about incoming P2P messages.
static unsigned int size
Size of the "table".
Definition peer.c:68
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

References all_client_options, client_head, env, gettext_noop, GNUNET_assert, GNUNET_break, GNUNET_CONTAINER_multipeermap_contains(), GNUNET_CORE_OPTION_SEND_FULL_INBOUND, GNUNET_CORE_OPTION_SEND_FULL_OUTBOUND, GNUNET_CORE_OPTION_SEND_HDR_INBOUND, GNUNET_CORE_OPTION_SEND_HDR_OUTBOUND, GNUNET_CRYPTO_random_u32(), GNUNET_ERROR_TYPE_BULK, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_INFO, GNUNET_i2s(), GNUNET_log, GNUNET_MAX_MESSAGE_SIZE, GNUNET_memcpy, GNUNET_MESSAGE_TYPE_CORE_NOTIFY_INBOUND, GNUNET_MESSAGE_TYPE_CORE_NOTIFY_OUTBOUND, GNUNET_MQ_get_length(), GNUNET_MQ_msg_extra, GNUNET_MQ_send(), GNUNET_NO, GNUNET_snprintf(), GNUNET_STATISTICS_update(), GNUNET_YES, GSC_stats, HARD_MAX_QUEUE, msg, GSC_Client::next, options, NotifyTrafficMessage::peer, GNUNET_MessageHeader::size, size, SOFT_MAX_QUEUE, GNUNET_MessageHeader::type, and type_match().

Referenced by deliver_message(), and tokenized_cb().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ shutdown_task()

static void shutdown_task ( void *  cls)
static

Last task run during shutdown.

Disconnects us from the transport.

Parameters
clsNULL, unused

Definition at line 1010 of file gnunet-service-core.c.

1011{
1012 struct GSC_Client *c;
1013
1014 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Core service shutting down.\n");
1015 while (NULL != (c = client_head))
1018 GSC_KX_done ();
1020 if (NULL != GSC_stats)
1021 {
1023 GSC_stats = NULL;
1024 }
1025 GSC_cfg = NULL;
1026}
const struct GNUNET_CONFIGURATION_Handle * GSC_cfg
Our configuration.
static void GSC_SVCI_destroy(struct GSC_ServicesInfo *services_info)
void GSC_KX_done()
Shutdown KX subsystem.
void GSC_SESSIONS_done()
Shutdown sessions subsystem.
void GNUNET_STATISTICS_destroy(struct GNUNET_STATISTICS_Handle *h, int sync_first)
Destroy a handle (free all state associated with it).

References GSC_Client::client, client_head, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_NO, GNUNET_SERVICE_client_drop(), GNUNET_STATISTICS_destroy(), GSC_cfg, GSC_KX_done(), GSC_SESSIONS_done(), GSC_stats, GSC_SVCI_destroy(), and own_services.

Here is the call graph for this function:

◆ handle_client_monitor_peers()

static void handle_client_monitor_peers ( void *  cls,
const struct GNUNET_MessageHeader message 
)
static

Handle GNUNET_MESSAGE_TYPE_CORE_MONITOR_PEERS request.

For this request type, the client does not have to have transmitted an INIT request. All current peers are returned, regardless of which message types they accept.

Parameters
clsclient sending the iteration request
messageiteration request message

Definition at line 1039 of file gnunet-service-core.c.

1041{
1042 struct GSC_Client *c = cls;
1043
1046}
void GSC_KX_handle_client_monitor_peers(struct GNUNET_MQ_Handle *mq)
Handle GNUNET_MESSAGE_TYPE_CORE_MONITOR_PEERS request.

References GSC_Client::client, GNUNET_SERVICE_client_continue(), GSC_KX_handle_client_monitor_peers(), and GSC_Client::mq.

Here is the call graph for this function:

◆ run()

static void run ( void *  cls,
const struct GNUNET_CONFIGURATION_Handle c,
struct GNUNET_SERVICE_Handle service 
)
static

Initiate core service.

Parameters
clsclosure
cconfiguration to use
servicethe initialized service

Definition at line 1057 of file gnunet-service-core.c.

1060{
1061 GSC_cfg = c;
1064 {
1065 /* Read the peer class from the configuration */
1066 const char *peer_class_str = "UNKNOWN";
1067 const char *choices[] = {
1068 "UNKNOWN",
1069 "UNWILLING",
1070 "MOBILE",
1071 "DESKTOP",
1072 "ROUTER",
1073 "SERVER",
1074 NULL
1075 };
1077 "Starting CORE service\n");
1078 if (GNUNET_OK !=
1080 "core",
1081 "CLASS",
1082 choices,
1083 &peer_class_str))
1084 {
1086 "No class found in configuration! (Continuing with unknown class)");
1088 }
1089 if (0 == strcasecmp (peer_class_str, "UNKNOWN"))
1091 else if (0 == strcasecmp (peer_class_str, "UNWILLING"))
1093 else if (0 == strcasecmp (peer_class_str, "MOBILE"))
1095 else if (0 == strcasecmp (peer_class_str, "DESKTOP"))
1097 else if (0 == strcasecmp (peer_class_str, "ROUTER"))
1099 else if (0 == strcasecmp (peer_class_str, "SERVER"))
1101 else
1102 GNUNET_assert (0);
1103 }
1107 if (GNUNET_OK != GSC_KX_init ())
1108 {
1110 return;
1111 }
1112}
struct GNUNET_SCHEDULER_Task * shutdown_task
static struct GNUNET_SERVICE_Handle * service
Handle to our service instance.
static struct GSC_ServicesInfo * GSC_SVCI_init()
int GSC_KX_init(void)
Initialize KX subsystem.
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.
@ 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.
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
void GNUNET_SERVICE_suspend(struct GNUNET_SERVICE_Handle *sh)
Suspend accepting connections from the listen socket temporarily.
Definition service.c:2381
struct GNUNET_STATISTICS_Handle * GNUNET_STATISTICS_create(const char *subsystem, const struct GNUNET_CONFIGURATION_Handle *cfg)
Get handle for the statistics service.

References GNUNET_assert, GNUNET_CONFIGURATION_get_value_choice(), GNUNET_CORE_CLASS_DESKTOP, GNUNET_CORE_CLASS_MOBILE, GNUNET_CORE_CLASS_ROUTER, GNUNET_CORE_CLASS_SERVER, GNUNET_CORE_CLASS_UNKNOWN, GNUNET_CORE_CLASS_UNWILLING, GNUNET_ERROR_TYPE_INFO, GNUNET_ERROR_TYPE_WARNING, GNUNET_log, GNUNET_OK, GNUNET_SCHEDULER_add_shutdown(), GNUNET_SCHEDULER_shutdown(), GNUNET_SERVICE_suspend(), GNUNET_STATISTICS_create(), GSC_cfg, GSC_KX_init(), GSC_peer_class, GSC_stats, GSC_SVCI_init(), own_services, service, service_h, and shutdown_task.

Here is the call graph for this function:

◆ GNUNET_SERVICE_MAIN()

GNUNET_SERVICE_MAIN ( GNUNET_OS_project_data_gnunet()  ,
"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.

Variable Documentation

◆ GSC_cfg

const struct GNUNET_CONFIGURATION_Handle* GSC_cfg

Our configuration.

Definition at line 119 of file gnunet-service-core.c.

Referenced by GSC_KX_init(), GSC_KX_start(), run(), and shutdown_task().

◆ service_h

struct GNUNET_SERVICE_Handle* service_h

Handle to the running service.

Definition at line 124 of file gnunet-service-core.c.

Referenced by GSC_complete_initialization_cb(), and run().

◆ GSC_stats

◆ GSC_pils

◆ GSC_peer_class

enum GNUNET_CORE_PeerClass GSC_peer_class
static

Our peer class.

Definition at line 139 of file gnunet-service-core.c.

Referenced by handle_client_init(), and run().

◆ all_client_options

uint32_t all_client_options
static

Big "or" of all client options.

Definition at line 144 of file gnunet-service-core.c.

Referenced by client_disconnect_cb(), GSC_CLIENTS_deliver_message(), and handle_client_init().

◆ client_head

struct GSC_Client* client_head
static

◆ client_tail

struct GSC_Client* client_tail
static

Tail of linked list of our clients.

Definition at line 154 of file gnunet-service-core.c.

Referenced by client_connect_cb(), and client_disconnect_cb().

◆ own_services

struct GSC_ServicesInfo* own_services
static