GNUnet 0.21.2
gnunet-service-core_sessions.c File Reference

code for managing of 'encrypted' sessions (key exchange done) More...

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

Go to the source code of this file.

Data Structures

struct  SessionMessageEntry
 Message ready for encryption. More...
 
struct  Session
 Data kept per session. More...
 
struct  TypeMapConfirmationMessage
 Message sent to confirm that a typemap was received. More...
 

Macros

#define MAX_ENCRYPTED_MESSAGE_QUEUE_SIZE   4
 How many encrypted messages do we queue at most? Needed to bound memory consumption. More...
 

Functions

static struct Sessionfind_session (const struct GNUNET_PeerIdentity *peer)
 Find the session for the given peer. More...
 
void GSC_SESSIONS_end (const struct GNUNET_PeerIdentity *pid)
 End the session with the given peer (we are no longer connected). More...
 
static void transmit_typemap_task (void *cls)
 Transmit our current typemap message to the other peer. More...
 
static void start_typemap_task (struct Session *session)
 Restart the typemap task for the given session. More...
 
void GSC_SESSIONS_create (const struct GNUNET_PeerIdentity *peer, struct GSC_KeyExchangeInfo *kx)
 Create a session, a key exchange was just completed. More...
 
void GSC_SESSIONS_reinit (const struct GNUNET_PeerIdentity *peer)
 The other peer has indicated that it 'lost' the session (KX down), reinitialize the session on our end, in particular this means to restart the typemap transmission. More...
 
void GSC_SESSIONS_confirm_typemap (const struct GNUNET_PeerIdentity *peer, const struct GNUNET_MessageHeader *msg)
 The other peer has confirmed receiving our type map, check if it is current and if so, stop retransmitting it. More...
 
static int notify_client_about_session (void *cls, const struct GNUNET_PeerIdentity *key, void *value)
 Notify the given client about the session (client is new). More...
 
void GSC_SESSIONS_notify_client_about_sessions (struct GSC_Client *client)
 We have a new client, notify it about all current sessions. More...
 
static void try_transmission (struct Session *session)
 Try to perform a transmission on the given session. More...
 
void GSC_SESSIONS_queue_request (struct GSC_ClientActiveRequest *car)
 Queue a request from a client for transmission to a particular peer. More...
 
void GSC_SESSIONS_dequeue_request (struct GSC_ClientActiveRequest *car)
 Dequeue a request from a client from transmission to a particular peer. More...
 
static void solicit_messages (struct Session *session, size_t msize)
 Solicit messages for transmission, starting with those of the highest priority. More...
 
static void pop_cork_task (void *cls)
 Some messages were delayed (corked), but the timeout has now expired. More...
 
static int do_restart_typemap_message (void *cls, const struct GNUNET_PeerIdentity *key, void *value)
 Send an updated typemap message to the neighbour now, and restart typemap transmissions. More...
 
void GSC_SESSIONS_broadcast_typemap (const struct GNUNET_MessageHeader *msg)
 Broadcast an updated typemap message to all neighbours. More...
 
void GSC_SESSIONS_solicit (const struct GNUNET_PeerIdentity *pid)
 Traffic is being solicited for the given peer. More...
 
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. More...
 
void GSC_SESSIONS_set_typemap (const struct GNUNET_PeerIdentity *peer, const struct GNUNET_MessageHeader *msg)
 We've received a typemap message from a peer, update ours. More...
 
void GSC_SESSIONS_add_to_typemap (const struct GNUNET_PeerIdentity *peer, uint16_t type)
 The given peer send a message of the specified type. More...
 
void GSC_SESSIONS_init ()
 Initialize sessions subsystem. More...
 
static int free_session_helper (void *cls, const struct GNUNET_PeerIdentity *key, void *value)
 Helper function for GSC_SESSIONS_done() to free all active sessions. More...
 
void GSC_SESSIONS_done ()
 Shutdown sessions subsystem. More...
 

Variables

static GNUNET_NETWORK_STRUCT_END struct GNUNET_CONTAINER_MultiPeerMapsessions
 Map of peer identities to struct Session. More...
 

Detailed Description

code for managing of 'encrypted' sessions (key exchange done)

Author
Christian Grothoff

Definition in file gnunet-service-core_sessions.c.

Macro Definition Documentation

◆ MAX_ENCRYPTED_MESSAGE_QUEUE_SIZE

#define MAX_ENCRYPTED_MESSAGE_QUEUE_SIZE   4

How many encrypted messages do we queue at most? Needed to bound memory consumption.

Definition at line 39 of file gnunet-service-core_sessions.c.

Function Documentation

◆ find_session()

static struct Session * find_session ( const struct GNUNET_PeerIdentity peer)
static

Find the session for the given peer.

Parameters
peeridentity of the peer
Returns
NULL if we are not connected, otherwise the session handle

Definition at line 196 of file gnunet-service-core_sessions.c.

197{
198 if (NULL == sessions)
199 return NULL;
201}
static GNUNET_NETWORK_STRUCT_END struct GNUNET_CONTAINER_MultiPeerMap * sessions
Map of peer identities to struct Session.
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.

References GNUNET_CONTAINER_multipeermap_get(), Session::peer, and sessions.

Referenced by GSC_SESSIONS_add_to_typemap(), GSC_SESSIONS_confirm_typemap(), GSC_SESSIONS_dequeue_request(), GSC_SESSIONS_end(), GSC_SESSIONS_queue_request(), GSC_SESSIONS_reinit(), GSC_SESSIONS_set_typemap(), GSC_SESSIONS_solicit(), and GSC_SESSIONS_transmit().

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

◆ GSC_SESSIONS_end()

void GSC_SESSIONS_end ( const struct GNUNET_PeerIdentity pid)

End the session with the given peer (we are no longer connected).

Parameters
pididentity of peer to kill session with

Definition at line 211 of file gnunet-service-core_sessions.c.

212{
213 struct Session *session;
214 struct GSC_ClientActiveRequest *car;
215 struct SessionMessageEntry *sme;
216
217 session = find_session (pid);
218 if (NULL == session)
219 return;
221 "Destroying session for peer `%s'\n",
222 GNUNET_i2s (session->peer));
223 if (NULL != session->cork_task)
224 {
226 session->cork_task = NULL;
227 }
228 while (NULL != (car = session->active_client_request_head))
229 {
232 car);
234 }
235 while (NULL != (sme = session->sme_head))
236 {
237 GNUNET_CONTAINER_DLL_remove (session->sme_head, session->sme_tail, sme);
238 GNUNET_free (sme);
239 }
240 if (NULL != session->typemap_task)
241 {
243 session->typemap_task = NULL;
244 }
246 session->tmap,
247 NULL);
249 GNUNET_YES ==
252 gettext_noop ("# peers connected"),
254 GNUNET_NO);
255 GSC_TYPEMAP_destroy (session->tmap);
256 session->tmap = NULL;
257 GNUNET_free (session);
258}
#define gettext_noop(String)
Definition: gettext.h:70
void GSC_CLIENTS_reject_request(struct GSC_ClientActiveRequest *car, int drop_client)
We will never be ready to transmit the given message in (disconnect or invalid request).
struct GNUNET_STATISTICS_Handle * GSC_stats
For creating statistics.
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.
static struct Session * find_session(const struct GNUNET_PeerIdentity *peer)
Find the session for the given peer.
void GSC_TYPEMAP_destroy(struct GSC_TypeMap *tmap)
Free the given type map.
static struct GNUNET_PeerIdentity pid
Identity of the peer we transmit to / connect to.
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
unsigned int GNUNET_CONTAINER_multipeermap_size(const struct GNUNET_CONTAINER_MultiPeerMap *map)
Get the number of key-value pairs 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.
#define GNUNET_log(kind,...)
@ GNUNET_YES
@ GNUNET_NO
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
@ GNUNET_ERROR_TYPE_DEBUG
#define GNUNET_free(ptr)
Wrapper around free.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:981
void GNUNET_STATISTICS_set(struct GNUNET_STATISTICS_Handle *handle, const char *name, uint64_t value, int make_persistent)
Set statistic value for the peer.
Record kept for each request for transmission issued by a client that is still pending.
Message ready for encryption.
Data kept per session.
struct SessionMessageEntry * sme_head
Head of list of messages ready for encryption.
struct SessionMessageEntry * sme_tail
Tail of list of messages ready for encryption.
struct GSC_TypeMap * tmap
Current type map for this peer.
const struct GNUNET_PeerIdentity * peer
Identity of the other peer.
struct GSC_ClientActiveRequest * active_client_request_head
Head of list of requests from clients for transmission to this peer.
struct GNUNET_SCHEDULER_Task * typemap_task
Task to transmit our type map.
struct GNUNET_SCHEDULER_Task * cork_task
Task to transmit corked messages with a delay.
struct GSC_ClientActiveRequest * active_client_request_tail
Tail of list of requests from clients for transmission to this peer.

References Session::active_client_request_head, Session::active_client_request_tail, Session::cork_task, find_session(), gettext_noop, GNUNET_assert, GNUNET_CONTAINER_DLL_remove, GNUNET_CONTAINER_multipeermap_remove(), GNUNET_CONTAINER_multipeermap_size(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_i2s(), GNUNET_log, GNUNET_NO, GNUNET_SCHEDULER_cancel(), GNUNET_STATISTICS_set(), GNUNET_YES, GSC_CLIENTS_notify_clients_about_neighbour(), GSC_CLIENTS_reject_request(), GSC_stats, GSC_TYPEMAP_destroy(), Session::peer, pid, sessions, Session::sme_head, Session::sme_tail, Session::tmap, and Session::typemap_task.

Referenced by free_session_helper(), handle_encrypted(), handle_transport_notify_disconnect(), and send_keep_alive().

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

◆ transmit_typemap_task()

static void transmit_typemap_task ( void *  cls)
static

Transmit our current typemap message to the other peer.

(Done periodically until the typemap is confirmed).

Parameters
clsthe struct Session *

Definition at line 268 of file gnunet-service-core_sessions.c.

269{
270 struct Session *session = cls;
271 struct GNUNET_MessageHeader *hdr;
272 struct GNUNET_TIME_Relative delay;
273
275 "Sending TYPEMAP to %s\n",
276 GNUNET_i2s (session->peer));
278 delay = session->typemap_delay;
279 /* randomize a bit to avoid spont. sync */
280 delay.rel_value_us +=
282 session->typemap_task =
285 gettext_noop ("# type map refreshes sent"),
286 1,
287 GNUNET_NO);
289 GSC_KX_encrypt_and_transmit (session->kx, hdr, ntohs (hdr->size));
290 GNUNET_free (hdr);
291}
void GSC_KX_encrypt_and_transmit(struct GSC_KeyExchangeInfo *kx, const void *payload, size_t payload_size)
Encrypt and transmit a message with the given payload.
static void transmit_typemap_task(void *cls)
Transmit our current typemap message to the other peer.
struct GNUNET_MessageHeader * GSC_TYPEMAP_compute_type_map_message()
Compute a type map message for this peer.
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).
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1278
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
#define GNUNET_TIME_STD_BACKOFF(r)
Perform our standard exponential back-off calculation, starting at 1 ms and then going by a factor of...
Header for all communications.
Time for relative time used by GNUnet, in microseconds.
uint64_t rel_value_us
The actual value.
struct GNUNET_TIME_Relative typemap_delay
Retransmission delay we currently use for the typemap transmissions (if not confirmed).
struct GSC_KeyExchangeInfo * kx
Key exchange state for this peer.

References gettext_noop, GNUNET_CRYPTO_QUALITY_WEAK, GNUNET_CRYPTO_random_u32(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_i2s(), GNUNET_log, GNUNET_NO, GNUNET_SCHEDULER_add_delayed(), GNUNET_STATISTICS_update(), GNUNET_TIME_STD_BACKOFF, GSC_KX_encrypt_and_transmit(), GSC_stats, GSC_TYPEMAP_compute_type_map_message(), Session::kx, Session::peer, GNUNET_TIME_Relative::rel_value_us, GNUNET_MessageHeader::size, transmit_typemap_task(), Session::typemap_delay, and Session::typemap_task.

Referenced by start_typemap_task(), and transmit_typemap_task().

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

◆ start_typemap_task()

static void start_typemap_task ( struct Session session)
static

Restart the typemap task for the given session.

Parameters
sessionsession to restart typemap transmission for

Definition at line 300 of file gnunet-service-core_sessions.c.

301{
302 if (NULL != session->typemap_task)
307 session);
308}
#define GNUNET_TIME_UNIT_SECONDS
One second.

References GNUNET_SCHEDULER_add_delayed(), GNUNET_SCHEDULER_cancel(), GNUNET_TIME_UNIT_SECONDS, transmit_typemap_task(), Session::typemap_delay, and Session::typemap_task.

Referenced by do_restart_typemap_message(), GSC_SESSIONS_create(), and GSC_SESSIONS_reinit().

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

◆ GSC_SESSIONS_create()

void GSC_SESSIONS_create ( const struct GNUNET_PeerIdentity peer,
struct GSC_KeyExchangeInfo kx 
)

Create a session, a key exchange was just completed.

Parameters
peerpeer that is now connected
kxkey exchange that completed

Definition at line 318 of file gnunet-service-core_sessions.c.

320{
321 struct Session *session;
322
324 "Creating session for peer `%s'\n",
325 GNUNET_i2s (peer));
326 session = GNUNET_new (struct Session);
327 session->tmap = GSC_TYPEMAP_create ();
328 session->peer = peer;
329 session->kx = kx;
332 sessions,
333 session->peer,
334 session,
337 gettext_noop ("# peers connected"),
339 GNUNET_NO);
341 start_typemap_task (session);
342}
static void start_typemap_task(struct Session *session)
Restart the typemap task for the given session.
struct GSC_TypeMap * GSC_TYPEMAP_create()
Create an empty type map.
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...
@ GNUNET_OK
#define GNUNET_new(type)
Allocate a struct or union of the given type.

References gettext_noop, GNUNET_assert, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY, GNUNET_CONTAINER_multipeermap_put(), GNUNET_CONTAINER_multipeermap_size(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_i2s(), GNUNET_log, GNUNET_new, GNUNET_NO, GNUNET_OK, GNUNET_STATISTICS_set(), GSC_CLIENTS_notify_clients_about_neighbour(), GSC_stats, GSC_TYPEMAP_create(), Session::kx, Session::peer, sessions, start_typemap_task(), and Session::tmap.

Referenced by handle_pong().

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

◆ GSC_SESSIONS_reinit()

void GSC_SESSIONS_reinit ( const struct GNUNET_PeerIdentity peer)

The other peer has indicated that it 'lost' the session (KX down), reinitialize the session on our end, in particular this means to restart the typemap transmission.

Parameters
peerpeer that is now connected

Definition at line 353 of file gnunet-service-core_sessions.c.

354{
355 struct Session *session;
356
357 session = find_session (peer);
358 if (NULL == session)
359 {
360 /* KX/session is new for both sides; thus no need to restart what
361 has not yet begun */
362 return;
363 }
364 start_typemap_task (session);
365}

References find_session(), Session::peer, and start_typemap_task().

Referenced by handle_ephemeral_key().

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

◆ GSC_SESSIONS_confirm_typemap()

void GSC_SESSIONS_confirm_typemap ( const struct GNUNET_PeerIdentity peer,
const struct GNUNET_MessageHeader msg 
)

The other peer has confirmed receiving our type map, check if it is current and if so, stop retransmitting it.

Parameters
peerpeer that confirmed the type map
msgconfirmation message we received

Definition at line 376 of file gnunet-service-core_sessions.c.

378{
379 const struct TypeMapConfirmationMessage *cmsg;
380 struct Session *session;
381
382 session = find_session (peer);
383 if (NULL == session)
384 {
385 GNUNET_break (0);
386 return;
387 }
388 if (ntohs (msg->size) != sizeof(struct TypeMapConfirmationMessage))
389 {
390 GNUNET_break_op (0);
391 return;
392 }
393 cmsg = (const struct TypeMapConfirmationMessage *) msg;
395 {
396 /* our typemap has changed in the meantime, do not
397 accept confirmation */
400 "# outdated typemap confirmations received"),
401 1,
402 GNUNET_NO);
404 "Got outdated typemap confirmated from peer `%s'\n",
405 GNUNET_i2s (session->peer));
406 return;
407 }
409 "Got typemap confirmation from peer `%s'\n",
410 GNUNET_i2s (session->peer));
411 if (NULL != session->typemap_task)
412 {
414 session->typemap_task = NULL;
415 }
418 "# valid typemap confirmations received"),
419 1,
420 GNUNET_NO);
421}
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
int GSC_TYPEMAP_check_hash(const struct GNUNET_HashCode *hc)
Check if the given hash matches our current type map.
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
Message sent to confirm that a typemap was received.
struct GNUNET_HashCode tm_hash
Hash of the (decompressed) type map that was received.

References find_session(), gettext_noop, GNUNET_break, GNUNET_break_op, GNUNET_ERROR_TYPE_DEBUG, GNUNET_i2s(), GNUNET_log, GNUNET_NO, GNUNET_SCHEDULER_cancel(), GNUNET_STATISTICS_update(), GNUNET_YES, GSC_stats, GSC_TYPEMAP_check_hash(), msg, Session::peer, GNUNET_MessageHeader::size, TypeMapConfirmationMessage::tm_hash, and Session::typemap_task.

Referenced by deliver_message().

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

◆ notify_client_about_session()

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

Notify the given client about the session (client is new).

Parameters
clsthe struct GSC_Client
keypeer identity
valuethe struct Session
Returns
GNUNET_OK (continue to iterate)

Definition at line 433 of file gnunet-service-core_sessions.c.

436{
437 struct GSC_Client *client = cls;
438 struct Session *session = value;
439
441 session->peer,
442 NULL, /* old TMAP: none */
443 session->tmap);
444 return GNUNET_OK;
445}
static char * value
Value of the record to add/remove.
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...
Data structure for each client connected to the CORE service.
struct GNUNET_SERVICE_Client * client
Handle for the client with the server API.

References GSC_Client::client, GNUNET_OK, GSC_CLIENTS_notify_client_about_neighbour(), Session::peer, Session::tmap, and value.

Referenced by GSC_SESSIONS_notify_client_about_sessions().

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

◆ GSC_SESSIONS_notify_client_about_sessions()

void GSC_SESSIONS_notify_client_about_sessions ( struct GSC_Client client)

We have a new client, notify it about all current sessions.

Parameters
clientthe new client

Definition at line 454 of file gnunet-service-core_sessions.c.

455{
456 /* notify new client about existing sessions */
459 client);
460}
static int notify_client_about_session(void *cls, const struct GNUNET_PeerIdentity *key, void *value)
Notify the given client about the session (client is new).
int GNUNET_CONTAINER_multipeermap_iterate(struct GNUNET_CONTAINER_MultiPeerMap *map, GNUNET_CONTAINER_PeerMapIterator it, void *it_cls)
Iterate over all entries in the map.

References GNUNET_CONTAINER_multipeermap_iterate(), notify_client_about_session(), and sessions.

Referenced by handle_client_init().

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

◆ try_transmission()

static void try_transmission ( struct Session session)
static

Try to perform a transmission on the given session.

Will solicit additional messages if the 'sme' queue is not full enough.

Parameters
sessionsession to transmit messages from

Will solicit additional messages if the 'sme' queue is not full enough or has only low-priority messages.

Parameters
sessionsession to transmit messages from

Definition at line 610 of file gnunet-service-core_sessions.c.

611{
612 struct SessionMessageEntry *pos;
613 size_t msize;
614 struct GNUNET_TIME_Absolute now;
615 struct GNUNET_TIME_Absolute min_deadline;
618 struct GSC_ClientActiveRequest *car;
619 int excess;
620
621 msize = 0;
622 min_deadline = GNUNET_TIME_UNIT_FOREVER_ABS;
623 /* if the peer has excess bandwidth, background traffic is allowed,
624 otherwise not */
627 {
629 "Transmission queue already very long, waiting...\n");
630 return; /* queue already too long */
631 }
632 excess = GSC_NEIGHBOURS_check_excess_bandwidth (session->kx);
633 if (GNUNET_YES == excess)
635 else
637 /* determine highest priority of 'ready' messages we already solicited from clients */
638 pos = session->sme_head;
639 while ((NULL != pos) &&
641 {
643 msize += pos->size;
644 maxp = GNUNET_MAX (maxp, pos->priority & GNUNET_MQ_PRIORITY_MASK);
645 min_deadline = GNUNET_TIME_absolute_min (min_deadline, pos->deadline);
646 pos = pos->next;
647 }
648 GNUNET_log (
650 "Calculating transmission set with %u priority (%s) and %s earliest deadline\n",
651 maxp,
652 (GNUNET_YES == excess) ? "excess bandwidth" : "limited bandwidth",
654 min_deadline),
655 GNUNET_YES));
656
658 {
659 /* if highest already solicited priority from clients is not critical,
660 check if there are higher-priority messages to be solicited from clients */
661 if (GNUNET_YES == excess)
663 else
665 for (car = session->active_client_request_head; NULL != car;
666 car = car->next)
667 {
668 if (GNUNET_YES == car->was_solicited)
669 continue;
670 maxpc = GNUNET_MAX (maxpc, car->priority & GNUNET_MQ_PRIORITY_MASK);
671 }
672 if (maxpc > maxp)
673 {
674 /* we have messages waiting for solicitation that have a higher
675 priority than those that we already accepted; solicit the
676 high-priority messages first */
678 "Soliciting messages based on priority (%u > %u)\n",
679 maxpc,
680 maxp);
681 solicit_messages (session, 0);
682 return;
683 }
684 }
685 else
686 {
687 /* never solicit more, we have critical messages to process */
688 excess = GNUNET_NO;
690 }
692 if (((GNUNET_YES == excess) || (maxpc >= GNUNET_MQ_PRIO_BEST_EFFORT)) &&
693 ((0 == msize) ||
695 (min_deadline.abs_value_us > now.abs_value_us))))
696 {
697 /* not enough ready yet (tiny message & cork possible), or no messages at all,
698 and either excess bandwidth or best-effort or higher message waiting at
699 client; in this case, we try to solicit more */
700 GNUNET_log (
702 "Soliciting messages (excess %d, maxpc %d, message size %u, deadline %s)\n",
703 excess,
704 maxpc,
705 (unsigned int) msize,
708 min_deadline),
709 GNUNET_YES));
710 solicit_messages (session, msize);
711 if (msize > 0)
712 {
713 /* if there is data to send, just not yet, make sure we do transmit
714 * it once the deadline is reached */
716 "Corking until %s\n",
719 GNUNET_YES));
720 if (NULL != session->cork_task)
722 session->cork_task =
723 GNUNET_SCHEDULER_add_at (min_deadline, &pop_cork_task, session);
724 }
725 else
726 {
728 "Queue empty, waiting for solicitations\n");
729 }
730 return;
731 }
733 "Building combined plaintext buffer to transmit message!\n");
734 /* create plaintext buffer of all messages (that fit), encrypt and
735 transmit */
736 {
737 static unsigned long long total_bytes;
738 static unsigned int total_msgs;
739 char pbuf[msize]; /* plaintext */
740 size_t used;
741
742 used = 0;
743 while ((NULL != (pos = session->sme_head)) && (used + pos->size <= msize))
744 {
746 "Adding message of type %d (%d/%d) to payload for %s\n",
747 ntohs (((const struct GNUNET_MessageHeader *) &pos[1])->type),
748 pos->is_typemap,
749 pos->is_typemap_confirm,
750 GNUNET_i2s (session->peer));
751 GNUNET_memcpy (&pbuf[used], &pos[1], pos->size);
752 used += pos->size;
753 GNUNET_CONTAINER_DLL_remove (session->sme_head, session->sme_tail, pos);
754 GNUNET_free (pos);
755 }
756 /* compute average payload size */
757 total_bytes += used;
758 total_msgs++;
759 if (0 == total_msgs)
760 {
761 /* 2^32 messages, wrap around... */
762 total_msgs = 1;
763 total_bytes = used;
764 }
766 "# avg payload per encrypted message",
767 total_bytes / total_msgs,
768 GNUNET_NO);
769 /* now actually transmit... */
770 GSC_KX_encrypt_and_transmit (session->kx, pbuf, used);
771 }
772}
static uint32_t type
Type string converted to DNS type value.
unsigned int GSC_NEIGHBOURS_get_queue_length(const struct GSC_KeyExchangeInfo *kxinfo)
Check how many messages are queued for the given neighbour.
int GSC_NEIGHBOURS_check_excess_bandwidth(const struct GSC_KeyExchangeInfo *kxinfo)
Check if the given neighbour has excess bandwidth available.
static void pop_cork_task(void *cls)
Some messages were delayed (corked), but the timeout has now expired.
static void solicit_messages(struct Session *session, size_t msize)
Solicit messages for transmission, starting with those of the highest priority.
#define MAX_ENCRYPTED_MESSAGE_QUEUE_SIZE
How many encrypted messages do we queue at most? Needed to bound memory consumption.
#define GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE
What is the maximum size for encrypted messages? Note that this number imposes a clear limit on the m...
#define GNUNET_MAX(a, b)
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
GNUNET_MQ_PriorityPreferences
Per envelope preferences and priorities.
@ GNUNET_MQ_PRIO_CRITICAL_CONTROL
Highest priority, control traffic (e.g.
@ GNUNET_MQ_PRIORITY_MASK
Bit mask to apply to extract the priority bits.
@ GNUNET_MQ_PRIO_BACKGROUND
Lowest priority, i.e.
@ GNUNET_MQ_PRIO_BEST_EFFORT
Best-effort traffic (e.g.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_at(struct GNUNET_TIME_Absolute at, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run at the specified time.
Definition: scheduler.c:1255
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_remaining(struct GNUNET_TIME_Absolute future)
Given a timestamp in the future, how much time remains until then?
Definition: time.c:405
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_min(struct GNUNET_TIME_Absolute t1, struct GNUNET_TIME_Absolute t2)
Return the minimum of two absolute time values.
Definition: time.c:359
#define GNUNET_TIME_UNIT_FOREVER_ABS
Constant used to specify "forever".
Time for absolute times used by GNUnet, in microseconds.
struct GSC_ClientActiveRequest * next
Active requests are kept in a doubly-linked list of the respective target peer.
int was_solicited
Has this request been solicited yet?
uint16_t msize
How many bytes does the client intend to send?
enum GNUNET_MQ_PriorityPreferences priority
How important is this request.
struct GNUNET_TIME_Absolute deadline
Deadline for transmission, 1s after we received it (if we are not corking), otherwise "now".
size_t size
How long is the message? (number of bytes following the struct MessageEntry, but not including the si...
struct SessionMessageEntry * next
We keep messages in a doubly linked list.
enum GNUNET_MQ_PriorityPreferences priority
How important is this message.

References GNUNET_TIME_Absolute::abs_value_us, Session::active_client_request_head, Session::cork_task, SessionMessageEntry::deadline, GNUNET_assert, GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE, GNUNET_CONTAINER_DLL_remove, GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_i2s(), GNUNET_log, GNUNET_MAX, GNUNET_memcpy, GNUNET_MQ_PRIO_BACKGROUND, GNUNET_MQ_PRIO_BEST_EFFORT, GNUNET_MQ_PRIO_CRITICAL_CONTROL, GNUNET_MQ_PRIORITY_MASK, GNUNET_NO, GNUNET_SCHEDULER_add_at(), GNUNET_SCHEDULER_cancel(), GNUNET_STATISTICS_set(), GNUNET_STRINGS_relative_time_to_string(), GNUNET_TIME_absolute_get(), GNUNET_TIME_absolute_get_remaining(), GNUNET_TIME_absolute_min(), GNUNET_TIME_UNIT_FOREVER_ABS, GNUNET_YES, GSC_KX_encrypt_and_transmit(), GSC_NEIGHBOURS_check_excess_bandwidth(), GSC_NEIGHBOURS_get_queue_length(), GSC_stats, Session::kx, MAX_ENCRYPTED_MESSAGE_QUEUE_SIZE, GSC_ClientActiveRequest::msize, GSC_ClientActiveRequest::next, SessionMessageEntry::next, Session::peer, pop_cork_task(), GSC_ClientActiveRequest::priority, SessionMessageEntry::priority, GNUNET_MessageHeader::size, SessionMessageEntry::size, Session::sme_head, Session::sme_tail, solicit_messages(), type, and GSC_ClientActiveRequest::was_solicited.

Referenced by do_restart_typemap_message(), GSC_SESSIONS_dequeue_request(), GSC_SESSIONS_queue_request(), GSC_SESSIONS_set_typemap(), GSC_SESSIONS_solicit(), GSC_SESSIONS_transmit(), and pop_cork_task().

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

◆ GSC_SESSIONS_queue_request()

void GSC_SESSIONS_queue_request ( struct GSC_ClientActiveRequest car)

Queue a request from a client for transmission to a particular peer.

Parameters
carrequest to queue; this handle is then shared between the caller (CLIENTS subsystem) and SESSIONS and must not be released by either until either #GSC_SESSIONS_dequeue(), GSC_SESSIONS_transmit() or #GSC_CLIENTS_failed() have been invoked on it

Definition at line 483 of file gnunet-service-core_sessions.c.

484{
485 struct Session *session;
486
487 session = find_session (&car->target);
488 if (NULL == session)
489 {
491 "Dropped client request for transmission (am disconnected)\n");
492 GNUNET_break (0); /* should have been rejected earlier */
494 return;
495 }
497 {
498 GNUNET_break (0);
500 return;
501 }
503 "Received client transmission request. queueing\n");
506 car);
507 try_transmission (session);
508}
static void try_transmission(struct Session *session)
Try to perform a transmission on the given session.
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
struct GNUNET_PeerIdentity target
Which peer is the message going to be for?

References Session::active_client_request_head, Session::active_client_request_tail, find_session(), GNUNET_break, GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE, GNUNET_CONTAINER_DLL_insert_tail, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_NO, GNUNET_YES, GSC_CLIENTS_reject_request(), GSC_ClientActiveRequest::msize, GSC_ClientActiveRequest::target, and try_transmission().

Referenced by handle_client_send_request().

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

◆ GSC_SESSIONS_dequeue_request()

void GSC_SESSIONS_dequeue_request ( struct GSC_ClientActiveRequest car)

Dequeue a request from a client from transmission to a particular peer.

Parameters
carrequest to dequeue; this handle will then be 'owned' by the caller (CLIENTS sysbsystem)

Definition at line 518 of file gnunet-service-core_sessions.c.

519{
520 struct Session *session;
521
522 if (0 == memcmp (&car->target,
524 sizeof(struct GNUNET_PeerIdentity)))
525 return;
526 session = find_session (&car->target);
527 GNUNET_assert (NULL != session);
530 car);
531 /* dequeueing of 'high' priority messages may unblock
532 transmission for lower-priority messages, so we also
533 need to try in this case. */
534 try_transmission (session);
535}
struct GNUNET_PeerIdentity GSC_my_identity
Our identity.
The identity of the host (wraps the signing key of the peer).

References Session::active_client_request_head, Session::active_client_request_tail, find_session(), GNUNET_assert, GNUNET_CONTAINER_DLL_remove, GSC_my_identity, GSC_ClientActiveRequest::target, and try_transmission().

Referenced by destroy_active_client_request(), GSC_CLIENTS_solicit_request(), handle_client_send(), and handle_client_send_request().

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

◆ solicit_messages()

static void solicit_messages ( struct Session session,
size_t  msize 
)
static

Solicit messages for transmission, starting with those of the highest priority.

Parameters
sessionsession to solict messages for
msizehow many bytes do we have already

Definition at line 546 of file gnunet-service-core_sessions.c.

547{
548 struct GSC_ClientActiveRequest *car;
549 struct GSC_ClientActiveRequest *nxt;
550 size_t so_size;
552
553 so_size = msize;
555 for (car = session->active_client_request_head; NULL != car; car = car->next)
556 {
557 if (GNUNET_YES == car->was_solicited)
558 continue;
559 pmax = GNUNET_MAX (pmax, car->priority & GNUNET_MQ_PRIORITY_MASK);
560 }
561 nxt = session->active_client_request_head;
562 while (NULL != (car = nxt))
563 {
564 nxt = car->next;
565 if (car->priority < pmax)
566 continue;
568 break;
569 so_size += car->msize;
570 if (GNUNET_YES == car->was_solicited)
571 continue;
574 "Soliciting message with priority %u\n",
575 car->priority);
577 /* The above call may *dequeue* requests and thereby
578 clobber 'nxt'. Hence we need to restart from the
579 head of the list. */
580 nxt = session->active_client_request_head;
581 so_size = msize;
582 }
583}
void GSC_CLIENTS_solicit_request(struct GSC_ClientActiveRequest *car)
Tell a client that we are ready to receive the message.

References Session::active_client_request_head, GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_MAX, GNUNET_MQ_PRIO_BACKGROUND, GNUNET_MQ_PRIORITY_MASK, GNUNET_YES, GSC_CLIENTS_solicit_request(), GSC_ClientActiveRequest::msize, GSC_ClientActiveRequest::next, GSC_ClientActiveRequest::priority, and GSC_ClientActiveRequest::was_solicited.

Referenced by try_transmission().

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

◆ pop_cork_task()

static void pop_cork_task ( void *  cls)
static

Some messages were delayed (corked), but the timeout has now expired.

Send them now.

Parameters
clsstruct Session with the messages to transmit now

Definition at line 593 of file gnunet-service-core_sessions.c.

594{
595 struct Session *session = cls;
596
597 session->cork_task = NULL;
598 try_transmission (session);
599}

References Session::cork_task, and try_transmission().

Referenced by try_transmission().

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

◆ do_restart_typemap_message()

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

Send an updated typemap message to the neighbour now, and restart typemap transmissions.

Parameters
clsthe message
keyneighbour's identity
valuestruct Neighbour of the target
Returns
always GNUNET_OK

Definition at line 785 of file gnunet-service-core_sessions.c.

788{
789 const struct GNUNET_MessageHeader *hdr = cls;
790 struct Session *session = value;
791 struct SessionMessageEntry *sme;
792 uint16_t size;
793
795 "Restarting sending TYPEMAP to %s\n",
796 GNUNET_i2s (session->peer));
797 size = ntohs (hdr->size);
798 for (sme = session->sme_head; NULL != sme; sme = sme->next)
799 {
800 if (GNUNET_YES == sme->is_typemap)
801 {
802 GNUNET_CONTAINER_DLL_remove (session->sme_head, session->sme_tail, sme);
803 GNUNET_free (sme);
804 break;
805 }
806 }
807 sme = GNUNET_malloc (sizeof(struct SessionMessageEntry) + size);
808 sme->is_typemap = GNUNET_YES;
809 GNUNET_memcpy (&sme[1], hdr, size);
810 sme->size = size;
812 GNUNET_CONTAINER_DLL_insert (session->sme_head, session->sme_tail, sme);
813 try_transmission (session);
814 start_typemap_task (session);
815 return GNUNET_OK;
816}
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
#define GNUNET_malloc(size)
Wrapper around malloc.
static unsigned int size
Size of the "table".
Definition: peer.c:68
int is_typemap
Flag set to GNUNET_YES if this is a typemap message.

References GNUNET_CONTAINER_DLL_insert, GNUNET_CONTAINER_DLL_remove, GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_i2s(), GNUNET_log, GNUNET_malloc, GNUNET_memcpy, GNUNET_MQ_PRIO_CRITICAL_CONTROL, GNUNET_OK, GNUNET_YES, SessionMessageEntry::is_typemap, SessionMessageEntry::next, Session::peer, SessionMessageEntry::priority, GNUNET_MessageHeader::size, size, SessionMessageEntry::size, Session::sme_head, Session::sme_tail, start_typemap_task(), try_transmission(), and value.

Referenced by GSC_SESSIONS_broadcast_typemap().

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

◆ GSC_SESSIONS_broadcast_typemap()

void GSC_SESSIONS_broadcast_typemap ( const struct GNUNET_MessageHeader msg)

Broadcast an updated typemap message to all neighbours.

Restarts the retransmissions until the typemaps are confirmed.

Parameters
msgmessage to transmit

Definition at line 826 of file gnunet-service-core_sessions.c.

827{
828 if (NULL == sessions)
829 return;
832 (void *) msg);
833}
static int do_restart_typemap_message(void *cls, const struct GNUNET_PeerIdentity *key, void *value)
Send an updated typemap message to the neighbour now, and restart typemap transmissions.

References do_restart_typemap_message(), GNUNET_CONTAINER_multipeermap_iterate(), msg, and sessions.

Referenced by broadcast_my_type_map().

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

◆ GSC_SESSIONS_solicit()

void GSC_SESSIONS_solicit ( const struct GNUNET_PeerIdentity pid)

Traffic is being solicited for the given peer.

This means that the message queue on the transport-level (NEIGHBOURS subsystem) is now empty and it is now OK to transmit another (non-control) message.

Parameters
pididentity of peer ready to receive data

Definition at line 844 of file gnunet-service-core_sessions.c.

845{
846 struct Session *session;
847
849 "Transport solicits for %s\n",
850 GNUNET_i2s (pid));
851 session = find_session (pid);
852 if (NULL == session)
853 return;
854 try_transmission (session);
855}

References find_session(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_i2s(), GNUNET_log, pid, and try_transmission().

Here is the call graph for this function:

◆ GSC_SESSIONS_transmit()

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.

Parameters
caroriginal request that was queued and then solicited, ownership does not change (dequeue will be called soon).
msgmessage to transmit
priorityhow important is this message

Definition at line 859 of file gnunet-service-core_sessions.c.

862{
863 struct Session *session;
864 struct SessionMessageEntry *sme;
865 struct SessionMessageEntry *pos;
866 size_t msize;
867
868 session = find_session (&car->target);
869 if (NULL == session)
870 return;
871 msize = ntohs (msg->size);
872 sme = GNUNET_malloc (sizeof(struct SessionMessageEntry) + msize);
873 GNUNET_memcpy (&sme[1], msg, msize);
874 sme->size = msize;
875 sme->priority = priority;
877 {
878 sme->deadline =
881 "Message corked, delaying transmission\n");
882 }
883 pos = session->sme_head;
884 while ((NULL != pos) && (pos->priority >= sme->priority))
885 pos = pos->next;
886 if (NULL == pos)
888 session->sme_tail,
889 sme);
890 else
892 session->sme_tail,
893 pos->prev,
894 sme);
895 try_transmission (session);
896}
#define GNUNET_CONSTANTS_MAX_CORK_DELAY
How long do we delay messages to get larger packet sizes (CORKing)?
#define GNUNET_CONTAINER_DLL_insert_after(head, tail, other, element)
Insert an element into a DLL after the given other element.
@ GNUNET_MQ_PREF_CORK_ALLOWED
Flag to indicate that CORKing is acceptable.
struct GNUNET_TIME_Absolute GNUNET_TIME_relative_to_absolute(struct GNUNET_TIME_Relative rel)
Convert relative time to an absolute time in the future.
Definition: time.c:316
struct SessionMessageEntry * prev
We keep messages in a doubly linked list.

References SessionMessageEntry::deadline, find_session(), GNUNET_CONSTANTS_MAX_CORK_DELAY, GNUNET_CONTAINER_DLL_insert_after, GNUNET_CONTAINER_DLL_insert_tail, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_malloc, GNUNET_memcpy, GNUNET_MQ_PREF_CORK_ALLOWED, GNUNET_TIME_relative_to_absolute(), msg, SessionMessageEntry::next, SessionMessageEntry::prev, SessionMessageEntry::priority, GNUNET_MessageHeader::size, SessionMessageEntry::size, Session::sme_head, Session::sme_tail, GSC_ClientActiveRequest::target, and try_transmission().

Referenced by tokenized_cb().

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

◆ GSC_SESSIONS_set_typemap()

void GSC_SESSIONS_set_typemap ( const struct GNUNET_PeerIdentity peer,
const struct GNUNET_MessageHeader msg 
)

We've received a typemap message from a peer, update ours.

Notifies clients about the session.

Parameters
peerpeer this is about
msgtypemap update message

Definition at line 900 of file gnunet-service-core_sessions.c.

902{
903 struct Session *session;
904 struct GSC_TypeMap *nmap;
905 struct SessionMessageEntry *sme;
906 struct TypeMapConfirmationMessage *tmc;
907
909 if (NULL == nmap)
910 {
911 GNUNET_break_op (0);
912 return; /* malformed */
913 }
914 session = find_session (peer);
915 if (NULL == session)
916 {
917 GSC_TYPEMAP_destroy (nmap);
918 GNUNET_break (0);
919 return;
920 }
922 "Received TYPEMAP from %s\n",
923 GNUNET_i2s (session->peer));
924 for (sme = session->sme_head; NULL != sme; sme = sme->next)
925 {
926 if (GNUNET_YES == sme->is_typemap_confirm)
927 {
928 GNUNET_CONTAINER_DLL_remove (session->sme_head, session->sme_tail, sme);
929 GNUNET_free (sme);
930 break;
931 }
932 }
933 sme = GNUNET_malloc (sizeof(struct SessionMessageEntry)
934 + sizeof(struct TypeMapConfirmationMessage));
936 sme->size = sizeof(struct TypeMapConfirmationMessage);
939 tmc = (struct TypeMapConfirmationMessage *) &sme[1];
940 tmc->header.size = htons (sizeof(struct TypeMapConfirmationMessage));
942 tmc->reserved = htonl (0);
943 GSC_TYPEMAP_hash (nmap, &tmc->tm_hash);
944 GNUNET_CONTAINER_DLL_insert (session->sme_head, session->sme_tail, sme);
945 try_transmission (session);
947 GSC_TYPEMAP_destroy (session->tmap);
948 session->tmap = nmap;
949}
struct GSC_TypeMap * GSC_TYPEMAP_get_from_message(const struct GNUNET_MessageHeader *msg)
Extract a type map from a TYPE_MAP message.
void GSC_TYPEMAP_hash(const struct GSC_TypeMap *tm, struct GNUNET_HashCode *hc)
Hash the contents of a type map.
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
#define GNUNET_MESSAGE_TYPE_CORE_CONFIRM_TYPE_MAP
Other peer confirms having received the type map.
A type map describing which messages a given neighbour is able to process.
int is_typemap_confirm
Flag set to GNUNET_YES if this is a typemap confirmation message.
uint32_t reserved
Reserved, always zero.
struct GNUNET_MessageHeader header
Header with type GNUNET_MESSAGE_TYPE_CORE_CONFIRM_TYPE_MAP.

References SessionMessageEntry::deadline, find_session(), GNUNET_break, GNUNET_break_op, GNUNET_CONTAINER_DLL_insert, GNUNET_CONTAINER_DLL_remove, GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_i2s(), GNUNET_log, GNUNET_malloc, GNUNET_MESSAGE_TYPE_CORE_CONFIRM_TYPE_MAP, GNUNET_MQ_PRIO_CRITICAL_CONTROL, GNUNET_TIME_absolute_get(), GNUNET_YES, GSC_CLIENTS_notify_clients_about_neighbour(), GSC_TYPEMAP_destroy(), GSC_TYPEMAP_get_from_message(), GSC_TYPEMAP_hash(), TypeMapConfirmationMessage::header, SessionMessageEntry::is_typemap_confirm, msg, SessionMessageEntry::next, Session::peer, SessionMessageEntry::priority, TypeMapConfirmationMessage::reserved, GNUNET_MessageHeader::size, SessionMessageEntry::size, Session::sme_head, Session::sme_tail, TypeMapConfirmationMessage::tm_hash, Session::tmap, try_transmission(), and GNUNET_MessageHeader::type.

Referenced by deliver_message().

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

◆ GSC_SESSIONS_add_to_typemap()

void GSC_SESSIONS_add_to_typemap ( const struct GNUNET_PeerIdentity peer,
uint16_t  type 
)

The given peer send a message of the specified type.

Make sure the respective bit is set in its type-map and that clients are notified about the session.

Parameters
peerpeer this is about
typetype of the message

Definition at line 961 of file gnunet-service-core_sessions.c.

963{
964 struct Session *session;
965 struct GSC_TypeMap *nmap;
966
967 if (0 == memcmp (peer, &GSC_my_identity, sizeof(struct GNUNET_PeerIdentity)))
968 return;
969 session = find_session (peer);
970 GNUNET_assert (NULL != session);
971 if (GNUNET_YES == GSC_TYPEMAP_test_match (session->tmap, &type, 1))
972 return; /* already in it */
973 nmap = GSC_TYPEMAP_extend (session->tmap, &type, 1);
975 GSC_TYPEMAP_destroy (session->tmap);
976 session->tmap = nmap;
977}
struct GSC_TypeMap * GSC_TYPEMAP_extend(const struct GSC_TypeMap *tmap, const uint16_t *types, unsigned int tcnt)
Add additional types to a given typemap.
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.

References find_session(), GNUNET_assert, GNUNET_YES, GSC_CLIENTS_notify_clients_about_neighbour(), GSC_my_identity, GSC_TYPEMAP_destroy(), GSC_TYPEMAP_extend(), GSC_TYPEMAP_test_match(), Session::tmap, and type.

Referenced by GSC_CLIENTS_deliver_message().

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

◆ GSC_SESSIONS_init()

void GSC_SESSIONS_init ( void  )

Initialize sessions subsystem.

Definition at line 984 of file gnunet-service-core_sessions.c.

985{
987}
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).

References GNUNET_CONTAINER_multipeermap_create(), GNUNET_YES, and sessions.

Referenced by run().

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

◆ free_session_helper()

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

Helper function for GSC_SESSIONS_done() to free all active sessions.

Parameters
clsNULL
keyidentity of the connected peer
valuethe struct Session for the peer
Returns
GNUNET_OK (continue to iterate)

Definition at line 1000 of file gnunet-service-core_sessions.c.

1003{
1004 /* struct Session *session = value; */
1005
1007 return GNUNET_OK;
1008}
struct GNUNET_HashCode key
The key used in the DHT.
void GSC_SESSIONS_end(const struct GNUNET_PeerIdentity *pid)
End the session with the given peer (we are no longer connected).

References GNUNET_OK, GSC_SESSIONS_end(), and key.

Referenced by GSC_SESSIONS_done().

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

◆ GSC_SESSIONS_done()

void GSC_SESSIONS_done ( void  )

Shutdown sessions subsystem.

Definition at line 1015 of file gnunet-service-core_sessions.c.

1016{
1017 if (NULL != sessions)
1018 {
1021 NULL);
1023 sessions = NULL;
1024 }
1025}
static int free_session_helper(void *cls, const struct GNUNET_PeerIdentity *key, void *value)
Helper function for GSC_SESSIONS_done() to free all active sessions.
void GNUNET_CONTAINER_multipeermap_destroy(struct GNUNET_CONTAINER_MultiPeerMap *map)
Destroy a hash map.

References free_session_helper(), GNUNET_CONTAINER_multipeermap_destroy(), GNUNET_CONTAINER_multipeermap_iterate(), and sessions.

Referenced by shutdown_task().

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

Variable Documentation

◆ sessions