GNUnet 0.28.1-dev.2-13-g57ceb9dfb
 
Loading...
Searching...
No Matches
gnunet-service-core_sessions.c File Reference

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

#include "gnunet_common.h"
#include "platform.h"
#include "gnunet-service-core.h"
#include "gnunet-service-core_kx.h"
#include "gnunet-service-core_sessions.h"
#include "gnunet_constants.h"
#include "core.h"
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...
 

Macros

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

Functions

static struct Sessionfind_session (const struct GNUNET_PeerIdentity *peer)
 Find the session for the given peer.
 
void GSC_SESSIONS_end (const struct GNUNET_PeerIdentity *pid)
 End the session with the given peer (we are no longer connected).
 
void GSC_SESSIONS_create (const struct GNUNET_PeerIdentity *peer, struct GSC_KeyExchangeInfo *kx, enum GNUNET_CORE_PeerClass class)
 Create a session, a key exchange was just completed.
 
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.
 
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).
 
void GSC_SESSIONS_notify_client_about_sessions (struct GSC_Client *client)
 We have a new client, notify it about all current sessions.
 
static void try_transmission (struct Session *session)
 Try to perform a transmission on the given session.
 
void GSC_SESSIONS_queue_request (struct GSC_ClientActiveRequest *car)
 Queue a request from a client for transmission to a particular peer.
 
void GSC_SESSIONS_dequeue_request (struct GSC_ClientActiveRequest *car)
 Dequeue a request from a client from transmission to a particular peer.
 
static void solicit_messages (struct Session *session, size_t msize)
 Solicit messages for transmission, starting with those of the highest priority.
 
static void pop_cork_task (void *cls)
 Some messages were delayed (corked), but the timeout has now expired.
 
void GSC_SESSIONS_solicit (const struct GNUNET_PeerIdentity *pid)
 Traffic is being solicited for the given peer.
 
void GSC_SESSIONS_transmit (struct GSC_ClientActiveRequest *car, const struct GNUNET_MessageHeader *msg, enum GNUNET_MQ_PriorityPreferences priority)
 Transmit a message to a particular peer.
 
void GSC_SESSIONS_init ()
 Initialize sessions subsystem.
 
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 GSC_SESSIONS_done ()
 Shutdown sessions subsystem.
 

Variables

static struct GNUNET_CONTAINER_MultiPeerMapsessions
 Map of peer identities to struct Session.
 

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 145 of file gnunet-service-core_sessions.c.

146{
147 if (NULL == sessions)
148 return NULL;
150}
static 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_dequeue_request(), GSC_SESSIONS_end(), GSC_SESSIONS_queue_request(), GSC_SESSIONS_reinit(), 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 160 of file gnunet-service-core_sessions.c.

161{
162 struct Session *session;
163 struct GSC_ClientActiveRequest *car;
164 struct SessionMessageEntry *sme;
165
166 if (NULL == pid)
167 {
168 /* We might not know the peer_id yet. */
169 return;
170 }
171 session = find_session (pid);
172 if (NULL == session)
173 return;
175 "Destroying session for peer `%s'\n",
176 GNUNET_i2s (session->peer));
177 if (NULL != session->cork_task)
178 {
180 session->cork_task = NULL;
181 }
182 while (NULL != (car = session->active_client_request_head))
183 {
186 car);
188 }
189 while (NULL != (sme = session->sme_head))
190 {
191 GNUNET_CONTAINER_DLL_remove (session->sme_head, session->sme_tail, sme);
192 GNUNET_free (sme);
193 }
194 // TODO
196 session->class,
197 GNUNET_NO);
199 GNUNET_YES ==
202 gettext_noop ("# peers connected"),
204 GNUNET_NO);
205 // TODO
206 // GSC_SVCI_destroy (session->services);
207 GNUNET_free (session);
208}
#define gettext_noop(String)
Definition gettext.h:74
void GSC_CLIENTS_notify_clients_about_neighbour(const struct GNUNET_PeerIdentity *neighbour, enum GNUNET_CORE_PeerClass class, enum GNUNET_GenericReturnValue is_connect)
Notify all clients about a change to existing session.
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.
static struct Session * find_session(const struct GNUNET_PeerIdentity *peer)
Find the session for the given peer.
#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:986
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.
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.
enum GNUNET_CORE_PeerClass class
Class of the peer.
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::class, 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, Session::peer, sessions, Session::sme_head, and Session::sme_tail.

Referenced by abandon_exchange(), free_session_helper(), handle_initiator_done(), handle_transport_notify_disconnect(), and send_heartbeat().

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,
enum GNUNET_CORE_PeerClass  class 
)

Create a session, a key exchange was just completed.

Parameters
peerpeer that is now connected
kxkey exchange that completed
classthe class of the now connected peer

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

222{
223 struct Session *session;
224
226 "Creating session for peer `%s'\n",
227 GNUNET_i2s (peer));
228 session = GNUNET_new (struct Session);
229 // TODO
230 // session->services = GSC_SVCI_init ();
231 session->peer = peer;
232 session->kx = kx;
233 session->class = class;
236 sessions,
237 session->peer,
238 session,
241 gettext_noop ("# peers connected"),
243 GNUNET_NO);
244 // TODO
246 session->class,
247 GNUNET_YES);
248}
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.
struct GSC_KeyExchangeInfo * kx
Key exchange state for this peer.

References Session::class, 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(), GNUNET_YES, GSC_CLIENTS_notify_clients_about_neighbour(), GSC_stats, Session::kx, Session::peer, and sessions.

Referenced by check_if_ack_or_heartbeat(), and handle_initiator_done().

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.

XXX typemap does not exist anymore

Parameters
peerpeer that is now connected

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

261{
262 struct Session *session;
263
264 session = find_session (peer);
265 if (NULL == session)
266 {
267 /* KX/session is new for both sides; thus no need to restart what
268 has not yet begun */
269 return;
270 }
271}

References find_session(), and Session::peer.

Here is the call 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 283 of file gnunet-service-core_sessions.c.

286{
287 struct GSC_Client *client = cls;
288 struct Session *session = value;
289
290 // TODO
292 session->peer,
293 session->class,
294 GNUNET_YES);
295 return GNUNET_OK;
296}
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, enum GNUNET_CORE_PeerClass class, enum GNUNET_GenericReturnValue is_connect)
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 Session::class, GSC_Client::client, GNUNET_OK, GNUNET_YES, GSC_CLIENTS_notify_client_about_neighbour(), Session::peer, 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 305 of file gnunet-service-core_sessions.c.

306{
307 /* notify new client about existing sessions */
310 client);
311}
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 465 of file gnunet-service-core_sessions.c.

466{
467 struct SessionMessageEntry *pos;
468 size_t msize;
469 struct GNUNET_TIME_Absolute now;
470 struct GNUNET_TIME_Absolute min_deadline;
473 struct GSC_ClientActiveRequest *car;
474 int excess;
475
476 msize = 0;
477 min_deadline = GNUNET_TIME_UNIT_FOREVER_ABS;
478 /* if the peer has excess bandwidth, background traffic is allowed,
479 otherwise not */
482 {
484 "Transmission queue already very long, waiting...\n");
485 return; /* queue already too long */
486 }
487 excess = GSC_NEIGHBOURS_check_excess_bandwidth (session->kx);
488 if (GNUNET_YES == excess)
490 else
492 /* determine highest priority of 'ready' messages we already solicited from clients */
493 pos = session->sme_head;
494 while ((NULL != pos) &&
496 {
498 msize += pos->size;
499 maxp = GNUNET_MAX (maxp, pos->priority & GNUNET_MQ_PRIORITY_MASK);
500 min_deadline = GNUNET_TIME_absolute_min (min_deadline, pos->deadline);
501 pos = pos->next;
502 }
503 GNUNET_log (
505 "Calculating transmission set with %u priority (%s) and %s earliest deadline\n",
506 maxp,
507 (GNUNET_YES == excess) ? "excess bandwidth" : "limited bandwidth",
509 min_deadline),
510 GNUNET_YES));
511
513 {
514 /* if highest already solicited priority from clients is not critical,
515 check if there are higher-priority messages to be solicited from clients */
516 if (GNUNET_YES == excess)
518 else
520 for (car = session->active_client_request_head; NULL != car;
521 car = car->next)
522 {
523 if (GNUNET_YES == car->was_solicited)
524 continue;
525 maxpc = GNUNET_MAX (maxpc, car->priority & GNUNET_MQ_PRIORITY_MASK);
526 }
527 if (maxpc > maxp)
528 {
529 /* we have messages waiting for solicitation that have a higher
530 priority than those that we already accepted; solicit the
531 high-priority messages first */
533 "Soliciting messages based on priority (%u > %u)\n",
534 maxpc,
535 maxp);
536 solicit_messages (session, 0);
537 return;
538 }
539 }
540 else
541 {
542 /* never solicit more, we have critical messages to process */
543 excess = GNUNET_NO;
545 }
547 if (((GNUNET_YES == excess) || (maxpc >= GNUNET_MQ_PRIO_BEST_EFFORT)) &&
548 ((0 == msize) ||
550 (min_deadline.abs_value_us > now.abs_value_us))))
551 {
552 /* not enough ready yet (tiny message & cork possible), or no messages at all,
553 and either excess bandwidth or best-effort or higher message waiting at
554 client; in this case, we try to solicit more */
555 GNUNET_log (
557 "Soliciting messages (excess %d, maxpc %d, message size %u, deadline %s)\n",
558 excess,
559 maxpc,
560 (unsigned int) msize,
563 min_deadline),
564 GNUNET_YES));
565 solicit_messages (session, msize);
566 if (msize > 0)
567 {
568 /* if there is data to send, just not yet, make sure we do transmit
569 * it once the deadline is reached */
571 "Corking until %s\n",
574 GNUNET_YES));
575 if (NULL != session->cork_task)
577 session->cork_task =
578 GNUNET_SCHEDULER_add_at (min_deadline, &pop_cork_task, session);
579 }
580 else
581 {
583 "Queue empty, waiting for solicitations\n");
584 }
585 return;
586 }
588 "Building combined plaintext buffer to transmit message!\n");
589 /* create plaintext buffer of all messages (that fit), encrypt and
590 transmit */
591 {
592 static unsigned long long total_bytes;
593 static unsigned int total_msgs;
594 char pbuf[msize]; /* plaintext */
595 size_t used;
596
597 used = 0;
598 while ((NULL != (pos = session->sme_head)) && (used + pos->size <= msize))
599 {
601 "Adding message of type %d to payload for %s\n",
602 ntohs (((const struct GNUNET_MessageHeader *) &pos[1])->type),
603 GNUNET_i2s (session->peer));
604 GNUNET_memcpy (&pbuf[used], &pos[1], pos->size);
605 used += pos->size;
606 GNUNET_CONTAINER_DLL_remove (session->sme_head, session->sme_tail, pos);
607 GNUNET_free (pos);
608 }
609 /* compute average payload size */
610 total_bytes += used;
611 total_msgs++;
612 if (0 == total_msgs)
613 {
614 /* 2^32 messages, wrap around... */
615 total_msgs = 1;
616 total_bytes = used;
617 }
619 "# avg payload per encrypted message",
620 total_bytes / total_msgs,
621 GNUNET_NO);
622 /* now actually transmit... */
623 GSC_KX_encrypt_and_transmit (session->kx, pbuf, used);
624 }
625}
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.
void GSC_KX_encrypt_and_transmit(struct GSC_KeyExchangeInfo *kx, const void *payload, size_t payload_size)
Encrypt and transmit payload.
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.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
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:1260
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:406
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
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:360
#define GNUNET_TIME_UNIT_FOREVER_ABS
Constant used to specify "forever".
Header for all communications.
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 GSC_SESSIONS_dequeue_request(), GSC_SESSIONS_queue_request(), 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 334 of file gnunet-service-core_sessions.c.

335{
336 struct Session *session;
337
338 session = find_session (&car->target);
339 if (NULL == session)
340 {
342 "Dropped client request for transmission (am disconnected)\n");
343 GNUNET_break (0); /* should have been rejected earlier */
345 return;
346 }
348 {
349 GNUNET_break (0);
351 return;
352 }
354 "Received client transmission request. queueing\n");
357 car);
358 try_transmission (session);
359}
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.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
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 369 of file gnunet-service-core_sessions.c.

370{
371 const struct GNUNET_PeerIdentity *my_identity;
372 struct Session *session;
374 if (NULL == my_identity)
375 return;
376
377 if (0 == memcmp (&car->target,
379 sizeof(struct GNUNET_PeerIdentity)))
380 return;
381 session = find_session (&car->target);
382 GNUNET_assert (NULL != session);
385 car);
386 /* dequeueing of 'high' priority messages may unblock
387 transmission for lower-priority messages, so we also
388 need to try in this case. */
389 try_transmission (session);
390}
static struct GNUNET_PeerIdentity my_identity
Identity of this peer.
struct GNUNET_PILS_Handle * GSC_pils
For peer identity access.
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:875
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, GNUNET_PILS_get_identity(), GSC_pils, 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 401 of file gnunet-service-core_sessions.c.

402{
403 struct GSC_ClientActiveRequest *car;
404 struct GSC_ClientActiveRequest *nxt;
405 size_t so_size;
407
408 so_size = msize;
410 for (car = session->active_client_request_head; NULL != car; car = car->next)
411 {
412 if (GNUNET_YES == car->was_solicited)
413 continue;
414 pmax = GNUNET_MAX (pmax, car->priority & GNUNET_MQ_PRIORITY_MASK);
415 }
416 nxt = session->active_client_request_head;
417 while (NULL != (car = nxt))
418 {
419 nxt = car->next;
420 if (car->priority < pmax)
421 continue;
423 break;
424 so_size += car->msize;
425 if (GNUNET_YES == car->was_solicited)
426 continue;
429 "Soliciting message with priority %u\n",
430 car->priority);
432 /* The above call may *dequeue* requests and thereby
433 clobber 'nxt'. Hence we need to restart from the
434 head of the list. */
435 nxt = session->active_client_request_head;
436 so_size = msize;
437 }
438}
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 448 of file gnunet-service-core_sessions.c.

449{
450 struct Session *session = cls;
451
452 session->cork_task = NULL;
453 try_transmission (session);
454}

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:

◆ 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 636 of file gnunet-service-core_sessions.c.

637{
638 struct Session *session;
639
641 "Transport solicits for %s\n",
642 GNUNET_i2s (pid));
643 session = find_session (pid);
644 if (NULL == session)
645 return;
646 try_transmission (session);
647}

References find_session(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_i2s(), GNUNET_log, 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 651 of file gnunet-service-core_sessions.c.

654{
655 struct Session *session;
656 struct SessionMessageEntry *sme;
657 struct SessionMessageEntry *pos;
658 size_t msize;
659
660 session = find_session (&car->target);
661 if (NULL == session)
662 {
664 return;
665 }
666 msize = ntohs (msg->size);
667 sme = GNUNET_malloc (sizeof(struct SessionMessageEntry) + msize);
668 GNUNET_memcpy (&sme[1], msg, msize);
669 sme->size = msize;
670 sme->priority = priority;
672 {
673 sme->deadline =
676 "Message corked, delaying transmission\n");
677 }
678 pos = session->sme_head;
679 while ((NULL != pos) && (pos->priority >= sme->priority))
680 pos = pos->next;
681 if (NULL == pos)
683 session->sme_tail,
684 sme);
685 else
687 session->sme_tail,
688 pos->prev,
689 sme);
690 try_transmission (session);
691}
struct GNUNET_MessageHeader * msg
Definition 005.c:2
#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.
#define GNUNET_malloc(size)
Wrapper around malloc.
@ 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(), GNUNET_YES, GSC_CLIENTS_reject_request(), 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_init()

void GSC_SESSIONS_init ( void  )

Initialize sessions subsystem.

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

699{
701}
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 GSC_complete_initialization_cb().

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 714 of file gnunet-service-core_sessions.c.

717{
718 /* struct Session *session = value; */
719
721 return GNUNET_OK;
722}
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 729 of file gnunet-service-core_sessions.c.

730{
731 if (NULL != sessions)
732 {
735 NULL);
737 sessions = NULL;
738 }
739}
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