GNUnet  0.10.x
Data Structures | Macros | Functions | Variables
gnunet-service-core_sessions.c File Reference

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

#include "platform.h"
#include "gnunet-service-core.h"
#include "gnunet-service-core_kx.h"
#include "gnunet-service-core_typemap.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...
 
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 have 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.

Referenced by try_transmission().

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

References GNUNET_CONTAINER_multipeermap_get().

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().

194 {
195  if (NULL == sessions)
196  return NULL;
198 }
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.
static GNUNET_NETWORK_STRUCT_END struct GNUNET_CONTAINER_MultiPeerMap * sessions
Map of peer identities to struct Session.
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 208 of file gnunet-service-core_sessions.c.

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

209 {
210  struct Session *session;
211  struct GSC_ClientActiveRequest *car;
212  struct SessionMessageEntry *sme;
213 
214  session = find_session(pid);
215  if (NULL == session)
216  return;
218  "Destroying session for peer `%s'\n",
219  GNUNET_i2s(session->peer));
220  if (NULL != session->cork_task)
221  {
223  session->cork_task = NULL;
224  }
225  while (NULL != (car = session->active_client_request_head))
226  {
229  car);
231  }
232  while (NULL != (sme = session->sme_head))
233  {
234  GNUNET_CONTAINER_DLL_remove(session->sme_head, session->sme_tail, sme);
235  GNUNET_free(sme);
236  }
237  if (NULL != session->typemap_task)
238  {
240  session->typemap_task = NULL;
241  }
243  session->tmap,
244  NULL);
246  GNUNET_YES ==
249  gettext_noop("# peers connected"),
251  GNUNET_NO);
252  GSC_TYPEMAP_destroy(session->tmap);
253  session->tmap = NULL;
254  GNUNET_free(session);
255 }
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
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.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
struct SessionMessageEntry * sme_tail
Tail of list of messages ready for encryption.
int 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_NO
Definition: gnunet_common.h:78
struct GNUNET_STATISTICS_Handle * GSC_stats
For creating statistics.
Message ready for encryption.
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 SessionMessageEntry * sme_head
Head of list of messages ready for encryption.
Record kept for each request for transmission issued by a client that is still pending.
void GSC_TYPEMAP_destroy(struct GSC_TypeMap *tmap)
Free the given type map.
void GNUNET_STATISTICS_set(struct GNUNET_STATISTICS_Handle *handle, const char *name, uint64_t value, int make_persistent)
Set statistic value for the peer.
struct GSC_TypeMap * tmap
Current type map for this peer.
struct GSC_ClientActiveRequest * active_client_request_head
Head of list of requests from clients for transmission to this peer.
static struct Session * find_session(const struct GNUNET_PeerIdentity *peer)
Find the session for the given peer.
Data kept per session.
const struct GNUNET_PeerIdentity * peer
Identity of the other peer.
struct GNUNET_SCHEDULER_Task * typemap_task
Task to transmit our type map.
#define GNUNET_log(kind,...)
#define GNUNET_YES
Definition: gnunet_common.h:77
unsigned int GNUNET_CONTAINER_multipeermap_size(const struct GNUNET_CONTAINER_MultiPeerMap *map)
Get the number of key-value pairs in the map.
static GNUNET_NETWORK_STRUCT_END struct GNUNET_CONTAINER_MultiPeerMap * sessions
Map of peer identities to struct Session.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
void GSC_CLIENTS_notify_clients_about_neighbour(const struct GNUNET_PeerIdentity *neighbour, const struct GSC_TypeMap *tmap_old, const struct GSC_TypeMap *tmap_new)
Notify all clients about a change to existing session.
#define GNUNET_free(ptr)
Wrapper around free.
#define gettext_noop(String)
Definition: gettext.h:69
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:956
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 265 of file gnunet-service-core_sessions.c.

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, Session::typemap_delay, and Session::typemap_task.

Referenced by start_typemap_task().

266 {
267  struct Session *session = cls;
268  struct GNUNET_MessageHeader *hdr;
270 
272  "Sending TYPEMAP to %s\n",
273  GNUNET_i2s(session->peer));
275  delay = session->typemap_delay;
276  /* randomize a bit to avoid spont. sync */
279  session->typemap_task =
282  gettext_noop("# type map refreshes sent"),
283  1,
284  GNUNET_NO);
286  GSC_KX_encrypt_and_transmit(session->kx, hdr, ntohs(hdr->size));
287  GNUNET_free(hdr);
288 }
struct GNUNET_MessageHeader * GSC_TYPEMAP_compute_type_map_message()
Compute a type map message for this peer.
uint64_t rel_value_us
The actual value.
uint32_t GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i)
Produce a random value.
#define GNUNET_NO
Definition: gnunet_common.h:78
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
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_STATISTICS_Handle * GSC_stats
For creating statistics.
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:1237
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.
Data kept per session.
struct GNUNET_TIME_Relative typemap_delay
Retransmission delay we currently use for the typemap transmissions (if not confirmed).
const struct GNUNET_PeerIdentity * peer
Identity of the other peer.
static void transmit_typemap_task(void *cls)
Transmit our current typemap message to the other peer.
static struct GNUNET_TIME_Relative delay
When should dkg communication start?
#define GNUNET_TIME_STD_BACKOFF(r)
Perform our standard exponential back-off calculation, starting at 1 ms and then going by a factor of...
struct GNUNET_SCHEDULER_Task * typemap_task
Task to transmit our type map.
#define GNUNET_log(kind,...)
struct GSC_KeyExchangeInfo * kx
Key exchange state for this peer.
Header for all communications.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
No good quality of the operation is needed (i.e., random numbers can be pseudo-random).
#define GNUNET_free(ptr)
Wrapper around free.
Time for relative time used by GNUnet, in microseconds.
#define gettext_noop(String)
Definition: gettext.h:69
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 297 of file gnunet-service-core_sessions.c.

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().

298 {
299  if (NULL != session->typemap_task)
304  session);
305 }
#define GNUNET_TIME_UNIT_SECONDS
One second.
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:1237
struct GNUNET_TIME_Relative typemap_delay
Retransmission delay we currently use for the typemap transmissions (if not confirmed).
static void transmit_typemap_task(void *cls)
Transmit our current typemap message to the other peer.
struct GNUNET_SCHEDULER_Task * typemap_task
Task to transmit our type map.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:956
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 315 of file gnunet-service-core_sessions.c.

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, peer, start_typemap_task(), and Session::tmap.

Referenced by handle_pong().

317 {
318  struct Session *session;
319 
321  "Creating session for peer `%s'\n",
322  GNUNET_i2s(peer));
323  session = GNUNET_new(struct Session);
324  session->tmap = GSC_TYPEMAP_create();
325  session->peer = peer;
326  session->kx = kx;
329  sessions,
330  session->peer,
331  session,
334  gettext_noop("# peers connected"),
336  GNUNET_NO);
337  GSC_CLIENTS_notify_clients_about_neighbour(peer, NULL, session->tmap);
338  start_typemap_task(session);
339 }
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
#define GNUNET_new(type)
Allocate a struct or union of the given type.
struct GNUNET_STATISTICS_Handle * GSC_stats
For creating statistics.
void GNUNET_STATISTICS_set(struct GNUNET_STATISTICS_Handle *handle, const char *name, uint64_t value, int make_persistent)
Set statistic value for the peer.
struct GSC_TypeMap * tmap
Current type map for this peer.
There must only be one value per key; storing a value should fail if a value under the same key alrea...
Data kept per session.
struct GNUNET_TESTBED_Peer * peer
The peer associated with this model.
struct GSC_TypeMap * GSC_TYPEMAP_create()
Create an empty type map.
const struct GNUNET_PeerIdentity * peer
Identity of the other peer.
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.
#define GNUNET_log(kind,...)
struct GSC_KeyExchangeInfo * kx
Key exchange state for this peer.
unsigned int GNUNET_CONTAINER_multipeermap_size(const struct GNUNET_CONTAINER_MultiPeerMap *map)
Get the number of key-value pairs in the map.
static void start_typemap_task(struct Session *session)
Restart the typemap task for the given session.
static GNUNET_NETWORK_STRUCT_END struct GNUNET_CONTAINER_MultiPeerMap * sessions
Map of peer identities to struct Session.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
void GSC_CLIENTS_notify_clients_about_neighbour(const struct GNUNET_PeerIdentity *neighbour, const struct GSC_TypeMap *tmap_old, const struct GSC_TypeMap *tmap_new)
Notify all clients about a change to existing session.
#define gettext_noop(String)
Definition: gettext.h:69
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 350 of file gnunet-service-core_sessions.c.

References find_session(), and start_typemap_task().

Referenced by handle_ephemeral_key().

351 {
352  struct Session *session;
353 
354  session = find_session(peer);
355  if (NULL == session)
356  {
357  /* KX/session is new for both sides; thus no need to restart what
358  has not yet begun */
359  return;
360  }
361  start_typemap_task(session);
362 }
static struct Session * find_session(const struct GNUNET_PeerIdentity *peer)
Find the session for the given peer.
Data kept per session.
static void start_typemap_task(struct Session *session)
Restart the typemap task for the given session.
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 373 of file gnunet-service-core_sessions.c.

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(), Session::peer, GNUNET_MessageHeader::size, TypeMapConfirmationMessage::tm_hash, and Session::typemap_task.

Referenced by deliver_message().

375 {
376  const struct TypeMapConfirmationMessage *cmsg;
377  struct Session *session;
378 
379  session = find_session(peer);
380  if (NULL == session)
381  {
382  GNUNET_break(0);
383  return;
384  }
385  if (ntohs(msg->size) != sizeof(struct TypeMapConfirmationMessage))
386  {
387  GNUNET_break_op(0);
388  return;
389  }
390  cmsg = (const struct TypeMapConfirmationMessage *)msg;
392  {
393  /* our typemap has changed in the meantime, do not
394  accept confirmation */
396  gettext_noop(
397  "# outdated typemap confirmations received"),
398  1,
399  GNUNET_NO);
401  "Got outdated typemap confirmated from peer `%s'\n",
402  GNUNET_i2s(session->peer));
403  return;
404  }
406  "Got typemap confirmation from peer `%s'\n",
407  GNUNET_i2s(session->peer));
408  if (NULL != session->typemap_task)
409  {
411  session->typemap_task = NULL;
412  }
414  gettext_noop(
415  "# valid typemap confirmations received"),
416  1,
417  GNUNET_NO);
418 }
#define GNUNET_NO
Definition: gnunet_common.h:78
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
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_STATISTICS_Handle * GSC_stats
For creating statistics.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
Message sent to confirm that a typemap was received.
static struct Session * find_session(const struct GNUNET_PeerIdentity *peer)
Find the session for the given peer.
Data kept per session.
const struct GNUNET_PeerIdentity * peer
Identity of the other peer.
int GSC_TYPEMAP_check_hash(const struct GNUNET_HashCode *hc)
Check if the given hash matches our current type map.
struct GNUNET_SCHEDULER_Task * typemap_task
Task to transmit our type map.
#define GNUNET_log(kind,...)
struct GNUNET_HashCode tm_hash
Hash of the (decompressed) type map that was received.
#define GNUNET_YES
Definition: gnunet_common.h:77
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#define gettext_noop(String)
Definition: gettext.h:69
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:956
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 430 of file gnunet-service-core_sessions.c.

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().

433 {
434  struct GSC_Client *client = cls;
435  struct Session *session = value;
436 
438  session->peer,
439  NULL, /* old TMAP: none */
440  session->tmap);
441  return GNUNET_OK;
442 }
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
Data structure for each client connected to the CORE service.
static char * value
Value of the record to add/remove.
struct GSC_TypeMap * tmap
Current type map for this peer.
Data kept per session.
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...
const struct GNUNET_PeerIdentity * peer
Identity of the other peer.
struct GNUNET_SERVICE_Client * client
Handle for the client with the server API.
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 451 of file gnunet-service-core_sessions.c.

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

Referenced by handle_client_init().

452 {
453  /* notify new client about existing sessions */
456  client);
457 }
int GNUNET_CONTAINER_multipeermap_iterate(struct GNUNET_CONTAINER_MultiPeerMap *map, GNUNET_CONTAINER_PeerMapIterator it, void *it_cls)
Iterate over all entries in the map.
static GNUNET_NETWORK_STRUCT_END struct GNUNET_CONTAINER_MultiPeerMap * sessions
Map of peer identities to struct Session.
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).
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 607 of file gnunet-service-core_sessions.c.

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, SessionMessageEntry::next, GSC_ClientActiveRequest::next, Session::peer, pop_cork_task(), SessionMessageEntry::priority, GSC_ClientActiveRequest::priority, SessionMessageEntry::size, GNUNET_MessageHeader::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_notify_client_about_sessions(), GSC_SESSIONS_queue_request(), GSC_SESSIONS_set_typemap(), GSC_SESSIONS_solicit(), GSC_SESSIONS_transmit(), and pop_cork_task().

608 {
609  struct SessionMessageEntry *pos;
610  size_t msize;
611  struct GNUNET_TIME_Absolute now;
612  struct GNUNET_TIME_Absolute min_deadline;
615  struct GSC_ClientActiveRequest *car;
616  int excess;
617 
618  msize = 0;
619  min_deadline = GNUNET_TIME_UNIT_FOREVER_ABS;
620  /* if the peer has excess bandwidth, background traffic is allowed,
621  otherwise not */
624  {
626  "Transmission queue already very long, waiting...\n");
627  return; /* queue already too long */
628  }
629  excess = GSC_NEIGHBOURS_check_excess_bandwidth(session->kx);
630  if (GNUNET_YES == excess)
632  else
634  /* determine highest priority of 'ready' messages we already solicited from clients */
635  pos = session->sme_head;
636  while ((NULL != pos) &&
638  {
640  msize += pos->size;
641  maxp = GNUNET_MAX(maxp, pos->priority & GNUNET_MQ_PRIORITY_MASK);
642  min_deadline = GNUNET_TIME_absolute_min(min_deadline, pos->deadline);
643  pos = pos->next;
644  }
645  GNUNET_log(
647  "Calculating transmission set with %u priority (%s) and %s earliest deadline\n",
648  maxp,
649  (GNUNET_YES == excess) ? "excess bandwidth" : "limited bandwidth",
651  min_deadline),
652  GNUNET_YES));
653 
655  {
656  /* if highest already solicited priority from clients is not critical,
657  check if there are higher-priority messages to be solicited from clients */
658  if (GNUNET_YES == excess)
660  else
662  for (car = session->active_client_request_head; NULL != car;
663  car = car->next)
664  {
665  if (GNUNET_YES == car->was_solicited)
666  continue;
667  maxpc = GNUNET_MAX(maxpc, car->priority & GNUNET_MQ_PRIORITY_MASK);
668  }
669  if (maxpc > maxp)
670  {
671  /* we have messages waiting for solicitation that have a higher
672  priority than those that we already accepted; solicit the
673  high-priority messages first */
675  "Soliciting messages based on priority (%u > %u)\n",
676  maxpc,
677  maxp);
678  solicit_messages(session, 0);
679  return;
680  }
681  }
682  else
683  {
684  /* never solicit more, we have critical messages to process */
685  excess = GNUNET_NO;
687  }
688  now = GNUNET_TIME_absolute_get();
689  if (((GNUNET_YES == excess) || (maxpc >= GNUNET_MQ_PRIO_BEST_EFFORT)) &&
690  ((0 == msize) ||
692  (min_deadline.abs_value_us > now.abs_value_us))))
693  {
694  /* not enough ready yet (tiny message & cork possible), or no messages at all,
695  and either excess bandwidth or best-effort or higher message waiting at
696  client; in this case, we try to solicit more */
697  GNUNET_log(
699  "Soliciting messages (excess %d, maxpc %d, message size %u, deadline %s)\n",
700  excess,
701  maxpc,
702  (unsigned int)msize,
704  min_deadline),
705  GNUNET_YES));
706  solicit_messages(session, msize);
707  if (msize > 0)
708  {
709  /* if there is data to send, just not yet, make sure we do transmit
710  * it once the deadline is reached */
712  "Corking until %s\n",
715  GNUNET_YES));
716  if (NULL != session->cork_task)
718  session->cork_task =
719  GNUNET_SCHEDULER_add_at(min_deadline, &pop_cork_task, session);
720  }
721  else
722  {
724  "Queue empty, waiting for solicitations\n");
725  }
726  return;
727  }
729  "Building combined plaintext buffer to transmit message!\n");
730  /* create plaintext buffer of all messages (that fit), encrypt and
731  transmit */
732  {
733  static unsigned long long total_bytes;
734  static unsigned int total_msgs;
735  char pbuf[msize]; /* plaintext */
736  size_t used;
737 
738  used = 0;
739  while ((NULL != (pos = session->sme_head)) && (used + pos->size <= msize))
740  {
742  "Adding message of type %d (%d/%d) to payload for %s\n",
743  ntohs(((const struct GNUNET_MessageHeader *)&pos[1])->type),
744  pos->is_typemap,
745  pos->is_typemap_confirm,
746  GNUNET_i2s(session->peer));
747  GNUNET_memcpy(&pbuf[used], &pos[1], pos->size);
748  used += pos->size;
749  GNUNET_CONTAINER_DLL_remove(session->sme_head, session->sme_tail, pos);
750  GNUNET_free(pos);
751  }
752  /* compute average payload size */
753  total_bytes += used;
754  total_msgs++;
755  if (0 == total_msgs)
756  {
757  /* 2^32 messages, wrap around... */
758  total_msgs = 1;
759  total_bytes = used;
760  }
762  "# avg payload per encrypted message",
763  total_bytes / total_msgs,
764  GNUNET_NO);
765  /* now actually transmit... */
766  GSC_KX_encrypt_and_transmit(session->kx, pbuf, used);
767  }
768 }
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
struct GNUNET_SCHEDULER_Task * cork_task
Task to transmit corked messages with a delay.
size_t size
How long is the message? (number of bytes following the struct MessageEntry, but not including the si...
enum GNUNET_MQ_PriorityPreferences priority
How important is this message.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
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?
unsigned int GSC_NEIGHBOURS_get_queue_length(const struct GSC_KeyExchangeInfo *kxinfo)
Check how many messages are queued for the given neighbour.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
struct SessionMessageEntry * sme_tail
Tail of list of messages ready for encryption.
#define GNUNET_NO
Definition: gnunet_common.h:78
GNUNET_MQ_PriorityPreferences
Per envelope preferences and priorities.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
struct GNUNET_TIME_Absolute deadline
Deadline for transmission, 1s after we received it (if we are not corking), otherwise "now"...
struct GNUNET_STATISTICS_Handle * GSC_stats
For creating statistics.
#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_TIME_UNIT_FOREVER_ABS
Constant used to specify "forever".
Message ready for encryption.
Best-effort traffic (i.e.
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 solicit_messages(struct Session *session, size_t msize)
Solicit messages for transmission, starting with those of the highest priority.
enum GNUNET_MQ_PriorityPreferences priority
How important is this request.
#define GNUNET_MAX(a, b)
Definition: gnunet_common.h:82
struct SessionMessageEntry * sme_head
Head of list of messages ready for encryption.
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:686
struct SessionMessageEntry * next
We keep messages in a doubly linked list.
Record kept for each request for transmission issued by a client that is still pending.
static void pop_cork_task(void *cls)
Some messages were delayed (corked), but the timeout has now expired.
void GNUNET_STATISTICS_set(struct GNUNET_STATISTICS_Handle *handle, const char *name, uint64_t value, int make_persistent)
Set statistic value for the peer.
struct GSC_ClientActiveRequest * active_client_request_head
Head of list of requests from clients for transmission to this peer.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:118
#define MAX_ENCRYPTED_MESSAGE_QUEUE_SIZE
How many encrypted messages do we queue at most? Needed to bound memory consumption.
Lowest priority, i.e.
const struct GNUNET_PeerIdentity * peer
Identity of the other peer.
Bit mask to apply to extract the priority bits.
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:302
#define GNUNET_log(kind,...)
struct GSC_KeyExchangeInfo * kx
Key exchange state for this peer.
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:331
enum GNUNET_TESTBED_UnderlayLinkModelType type
the type of this model
Header for all communications.
Time for absolute times used by GNUnet, in microseconds.
#define GNUNET_YES
Definition: gnunet_common.h:77
int GSC_NEIGHBOURS_check_excess_bandwidth(const struct GSC_KeyExchangeInfo *kxinfo)
Check if the given neighbour has excess bandwidth available.
Highest priority, control traffic (i.e.
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:1214
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
uint16_t msize
How many bytes does the client intend to send?
#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:956
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 480 of file gnunet-service-core_sessions.c.

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().

481 {
482  struct Session *session;
483 
484  session = find_session(&car->target);
485  if (NULL == session)
486  {
488  "Dropped client request for transmission (am disconnected)\n");
489  GNUNET_break(0); /* should have been rejected earlier */
491  return;
492  }
494  {
495  GNUNET_break(0);
497  return;
498  }
500  "Received client transmission request. queueing\n");
503  car);
504  try_transmission(session);
505 }
struct GSC_ClientActiveRequest * active_client_request_tail
Tail of list of requests from clients for transmission to this peer.
static void try_transmission(struct Session *session)
Try to perform a transmission on the given session.
#define GNUNET_NO
Definition: gnunet_common.h:78
#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_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
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 GSC_ClientActiveRequest * active_client_request_head
Head of list of requests from clients for transmission to this peer.
static struct Session * find_session(const struct GNUNET_PeerIdentity *peer)
Find the session for the given peer.
Data kept per session.
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
#define GNUNET_log(kind,...)
#define GNUNET_YES
Definition: gnunet_common.h:77
struct GNUNET_PeerIdentity target
Which peer is the message going to be for?
uint16_t msize
How many bytes does the client intend to send?
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 515 of file gnunet-service-core_sessions.c.

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().

516 {
517  struct Session *session;
518 
519  if (0 == memcmp(&car->target,
521  sizeof(struct GNUNET_PeerIdentity)))
522  return;
523  session = find_session(&car->target);
524  GNUNET_assert(NULL != session);
527  car);
528  /* dequeueing of 'high' priority messages may unblock
529  transmission for lower-priority messages, so we also
530  need to try in this case. */
531  try_transmission(session);
532 }
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
struct GSC_ClientActiveRequest * active_client_request_tail
Tail of list of requests from clients for transmission to this peer.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static void try_transmission(struct Session *session)
Try to perform a transmission on the given session.
struct GSC_ClientActiveRequest * active_client_request_head
Head of list of requests from clients for transmission to this peer.
static struct Session * find_session(const struct GNUNET_PeerIdentity *peer)
Find the session for the given peer.
struct GNUNET_PeerIdentity GSC_my_identity
Our identity.
Data kept per session.
The identity of the host (wraps the signing key of the peer).
struct GNUNET_PeerIdentity target
Which peer is the message going to be for?
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 543 of file gnunet-service-core_sessions.c.

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().

544 {
545  struct GSC_ClientActiveRequest *car;
546  struct GSC_ClientActiveRequest *nxt;
547  size_t so_size;
549 
550  so_size = msize;
552  for (car = session->active_client_request_head; NULL != car; car = car->next)
553  {
554  if (GNUNET_YES == car->was_solicited)
555  continue;
556  pmax = GNUNET_MAX(pmax, car->priority & GNUNET_MQ_PRIORITY_MASK);
557  }
558  nxt = session->active_client_request_head;
559  while (NULL != (car = nxt))
560  {
561  nxt = car->next;
562  if (car->priority < pmax)
563  continue;
565  break;
566  so_size += car->msize;
567  if (GNUNET_YES == car->was_solicited)
568  continue;
569  car->was_solicited = GNUNET_YES;
571  "Soliciting message with priority %u\n",
572  car->priority);
574  /* The above call may *dequeue* requests and thereby
575  clobber 'nxt'. Hence we need to restart from the
576  head of the list. */
577  nxt = session->active_client_request_head;
578  so_size = msize;
579  }
580 }
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?
GNUNET_MQ_PriorityPreferences
Per envelope preferences and priorities.
#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...
enum GNUNET_MQ_PriorityPreferences priority
How important is this request.
#define GNUNET_MAX(a, b)
Definition: gnunet_common.h:82
Record kept for each request for transmission issued by a client that is still pending.
struct GSC_ClientActiveRequest * active_client_request_head
Head of list of requests from clients for transmission to this peer.
Lowest priority, i.e.
Bit mask to apply to extract the priority bits.
void GSC_CLIENTS_solicit_request(struct GSC_ClientActiveRequest *car)
Tell a client that we are ready to receive the message.
#define GNUNET_log(kind,...)
#define GNUNET_YES
Definition: gnunet_common.h:77
uint16_t msize
How many bytes does the client intend to send?
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 590 of file gnunet-service-core_sessions.c.

References Session::cork_task, and try_transmission().

Referenced by try_transmission().

591 {
592  struct Session *session = cls;
593 
594  session->cork_task = NULL;
595  try_transmission(session);
596 }
struct GNUNET_SCHEDULER_Task * cork_task
Task to transmit corked messages with a delay.
static void try_transmission(struct Session *session)
Try to perform a transmission on the given session.
Data kept per session.
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 781 of file gnunet-service-core_sessions.c.

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, SessionMessageEntry::size, GNUNET_MessageHeader::size, Session::sme_head, Session::sme_tail, start_typemap_task(), try_transmission(), and value.

Referenced by GSC_SESSIONS_broadcast_typemap().

784 {
785  const struct GNUNET_MessageHeader *hdr = cls;
786  struct Session *session = value;
787  struct SessionMessageEntry *sme;
788  uint16_t size;
789 
791  "Restarting sending TYPEMAP to %s\n",
792  GNUNET_i2s(session->peer));
793  size = ntohs(hdr->size);
794  for (sme = session->sme_head; NULL != sme; sme = sme->next)
795  {
796  if (GNUNET_YES == sme->is_typemap)
797  {
798  GNUNET_CONTAINER_DLL_remove(session->sme_head, session->sme_tail, sme);
799  GNUNET_free(sme);
800  break;
801  }
802  }
803  sme = GNUNET_malloc(sizeof(struct SessionMessageEntry) + size);
804  sme->is_typemap = GNUNET_YES;
805  GNUNET_memcpy(&sme[1], hdr, size);
806  sme->size = size;
808  GNUNET_CONTAINER_DLL_insert(session->sme_head, session->sme_tail, sme);
809  try_transmission(session);
810  start_typemap_task(session);
811  return GNUNET_OK;
812 }
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
size_t size
How long is the message? (number of bytes following the struct MessageEntry, but not including the si...
enum GNUNET_MQ_PriorityPreferences priority
How important is this message.
static void try_transmission(struct Session *session)
Try to perform a transmission on the given session.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
struct SessionMessageEntry * sme_tail
Tail of list of messages ready for encryption.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
Message ready for encryption.
static char * value
Value of the record to add/remove.
struct SessionMessageEntry * sme_head
Head of list of messages ready for encryption.
struct SessionMessageEntry * next
We keep messages in a doubly linked list.
Data kept per session.
static unsigned int size
Size of the "table".
Definition: peer.c:66
const struct GNUNET_PeerIdentity * peer
Identity of the other peer.
#define GNUNET_log(kind,...)
Header for all communications.
int is_typemap
Flag set to GNUNET_YES if this is a typemap message.
#define GNUNET_YES
Definition: gnunet_common.h:77
Highest priority, control traffic (i.e.
static void start_typemap_task(struct Session *session)
Restart the typemap task for the given session.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
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 822 of file gnunet-service-core_sessions.c.

References do_restart_typemap_message(), and GNUNET_CONTAINER_multipeermap_iterate().

Referenced by broadcast_my_type_map().

823 {
824  if (NULL == sessions)
825  return;
828  (void *)msg);
829 }
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.
int GNUNET_CONTAINER_multipeermap_iterate(struct GNUNET_CONTAINER_MultiPeerMap *map, GNUNET_CONTAINER_PeerMapIterator it, void *it_cls)
Iterate over all entries in the map.
static GNUNET_NETWORK_STRUCT_END struct GNUNET_CONTAINER_MultiPeerMap * sessions
Map of peer identities to struct Session.
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 840 of file gnunet-service-core_sessions.c.

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

Referenced by handle_transport_notify_excess_bw().

841 {
842  struct Session *session;
843 
845  "Transport solicits for %s\n",
846  GNUNET_i2s(pid));
847  session = find_session(pid);
848  if (NULL == session)
849  return;
850  try_transmission(session);
851 }
static void try_transmission(struct Session *session)
Try to perform a transmission on the given session.
static struct Session * find_session(const struct GNUNET_PeerIdentity *peer)
Find the session for the given peer.
Data kept per session.
#define GNUNET_log(kind,...)
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
Here is the call graph for this function:
Here is the caller 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; this handle will now be 'owned' by the SESSIONS subsystem
msgmessage to transmit
priorityhow important is this message

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

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(), SessionMessageEntry::next, SessionMessageEntry::prev, SessionMessageEntry::priority, SessionMessageEntry::size, GNUNET_MessageHeader::size, Session::sme_head, Session::sme_tail, GSC_ClientActiveRequest::target, and try_transmission().

Referenced by tokenized_cb().

866 {
867  struct Session *session;
868  struct SessionMessageEntry *sme;
869  struct SessionMessageEntry *pos;
870  size_t msize;
871 
872  session = find_session(&car->target);
873  if (NULL == session)
874  return;
875  msize = ntohs(msg->size);
876  sme = GNUNET_malloc(sizeof(struct SessionMessageEntry) + msize);
877  GNUNET_memcpy(&sme[1], msg, msize);
878  sme->size = msize;
879  sme->priority = priority;
881  {
882  sme->deadline =
885  "Mesage corked, delaying transmission\n");
886  }
887  pos = session->sme_head;
888  while ((NULL != pos) && (pos->priority >= sme->priority))
889  pos = pos->next;
890  if (NULL == pos)
892  session->sme_tail,
893  sme);
894  else
896  session->sme_tail,
897  pos->prev,
898  sme);
899  try_transmission(session);
900 }
size_t size
How long is the message? (number of bytes following the struct MessageEntry, but not including the si...
enum GNUNET_MQ_PriorityPreferences priority
How important is this message.
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:246
static void try_transmission(struct Session *session)
Try to perform a transmission on the given session.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
struct SessionMessageEntry * sme_tail
Tail of list of messages ready for encryption.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
struct GNUNET_TIME_Absolute deadline
Deadline for transmission, 1s after we received it (if we are not corking), otherwise "now"...
Message ready for encryption.
struct SessionMessageEntry * sme_head
Head of list of messages ready for encryption.
struct SessionMessageEntry * next
We keep messages in a doubly linked list.
#define GNUNET_CONTAINER_DLL_insert_after(head, tail, other, element)
Insert an element into a DLL after the given other element.
struct SessionMessageEntry * prev
We keep messages in a doubly linked list.
static struct Session * find_session(const struct GNUNET_PeerIdentity *peer)
Find the session for the given peer.
Data kept per session.
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
#define GNUNET_log(kind,...)
Flag to indicate that CORKing is acceptable.
#define GNUNET_CONSTANTS_MAX_CORK_DELAY
How long do we delay messages to get larger packet sizes (CORKing)?
struct GNUNET_PeerIdentity target
Which peer is the message going to be for?
#define GNUNET_malloc(size)
Wrapper around malloc.
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 have received a typemap message from a peer, update ours.

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

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, SessionMessageEntry::next, Session::peer, SessionMessageEntry::priority, TypeMapConfirmationMessage::reserved, SessionMessageEntry::size, GNUNET_MessageHeader::size, Session::sme_head, Session::sme_tail, TypeMapConfirmationMessage::tm_hash, Session::tmap, try_transmission(), and GNUNET_MessageHeader::type.

Referenced by deliver_message().

913 {
914  struct Session *session;
915  struct GSC_TypeMap *nmap;
916  struct SessionMessageEntry *sme;
917  struct TypeMapConfirmationMessage *tmc;
918 
919  nmap = GSC_TYPEMAP_get_from_message(msg);
920  if (NULL == nmap)
921  {
922  GNUNET_break_op(0);
923  return; /* malformed */
924  }
925  session = find_session(peer);
926  if (NULL == session)
927  {
928  GSC_TYPEMAP_destroy(nmap);
929  GNUNET_break(0);
930  return;
931  }
933  "Received TYPEMAP from %s\n",
934  GNUNET_i2s(session->peer));
935  for (sme = session->sme_head; NULL != sme; sme = sme->next)
936  {
937  if (GNUNET_YES == sme->is_typemap_confirm)
938  {
939  GNUNET_CONTAINER_DLL_remove(session->sme_head, session->sme_tail, sme);
940  GNUNET_free(sme);
941  break;
942  }
943  }
944  sme = GNUNET_malloc(sizeof(struct SessionMessageEntry) +
945  sizeof(struct TypeMapConfirmationMessage));
947  sme->size = sizeof(struct TypeMapConfirmationMessage);
950  tmc = (struct TypeMapConfirmationMessage *)&sme[1];
951  tmc->header.size = htons(sizeof(struct TypeMapConfirmationMessage));
953  tmc->reserved = htonl(0);
954  GSC_TYPEMAP_hash(nmap, &tmc->tm_hash);
955  GNUNET_CONTAINER_DLL_insert(session->sme_head, session->sme_tail, sme);
956  try_transmission(session);
957  GSC_CLIENTS_notify_clients_about_neighbour(peer, session->tmap, nmap);
958  GSC_TYPEMAP_destroy(session->tmap);
959  session->tmap = nmap;
960 }
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
size_t size
How long is the message? (number of bytes following the struct MessageEntry, but not including the si...
enum GNUNET_MQ_PriorityPreferences priority
How important is this message.
static void try_transmission(struct Session *session)
Try to perform a transmission on the given session.
struct SessionMessageEntry * sme_tail
Tail of list of messages ready for encryption.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
struct GNUNET_TIME_Absolute deadline
Deadline for transmission, 1s after we received it (if we are not corking), otherwise "now"...
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
Message ready for encryption.
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
#define GNUNET_MESSAGE_TYPE_CORE_CONFIRM_TYPE_MAP
Other peer confirms having received the type map.
struct SessionMessageEntry * sme_head
Head of list of messages ready for encryption.
struct SessionMessageEntry * next
We keep messages in a doubly linked list.
Message sent to confirm that a typemap was received.
void GSC_TYPEMAP_destroy(struct GSC_TypeMap *tmap)
Free the given type map.
struct GSC_TypeMap * tmap
Current type map for this peer.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:118
static struct Session * find_session(const struct GNUNET_PeerIdentity *peer)
Find the session for the given peer.
Data kept per session.
const struct GNUNET_PeerIdentity * peer
Identity of the other peer.
int is_typemap_confirm
Flag set to GNUNET_YES if this is a typemap confirmation message.
void GSC_TYPEMAP_hash(const struct GSC_TypeMap *tm, struct GNUNET_HashCode *hc)
Hash the contents of a type map.
#define GNUNET_log(kind,...)
A type map describing which messages a given neighbour is able to process.
struct GNUNET_HashCode tm_hash
Hash of the (decompressed) type map that was received.
#define GNUNET_YES
Definition: gnunet_common.h:77
uint32_t reserved
Reserved, always zero.
Highest priority, control traffic (i.e.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
struct GNUNET_MessageHeader header
Header with type GNUNET_MESSAGE_TYPE_CORE_CONFIRM_TYPE_MAP.
#define GNUNET_malloc(size)
Wrapper around malloc.
struct GSC_TypeMap * GSC_TYPEMAP_get_from_message(const struct GNUNET_MessageHeader *msg)
Extract a type map from a TYPE_MAP message.
void GSC_CLIENTS_notify_clients_about_neighbour(const struct GNUNET_PeerIdentity *neighbour, const struct GSC_TypeMap *tmap_old, const struct GSC_TypeMap *tmap_new)
Notify all clients about a change to existing session.
#define GNUNET_free(ptr)
Wrapper around free.
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 972 of file gnunet-service-core_sessions.c.

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(), and Session::tmap.

Referenced by GSC_CLIENTS_deliver_message().

974 {
975  struct Session *session;
976  struct GSC_TypeMap *nmap;
977 
978  if (0 == memcmp(peer, &GSC_my_identity, sizeof(struct GNUNET_PeerIdentity)))
979  return;
980  session = find_session(peer);
981  GNUNET_assert(NULL != session);
982  if (GNUNET_YES == GSC_TYPEMAP_test_match(session->tmap, &type, 1))
983  return; /* already in it */
984  nmap = GSC_TYPEMAP_extend(session->tmap, &type, 1);
985  GSC_CLIENTS_notify_clients_about_neighbour(peer, session->tmap, nmap);
986  GSC_TYPEMAP_destroy(session->tmap);
987  session->tmap = nmap;
988 }
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
void GSC_TYPEMAP_destroy(struct GSC_TypeMap *tmap)
Free the given type map.
struct GSC_TypeMap * tmap
Current type map for this peer.
static struct Session * find_session(const struct GNUNET_PeerIdentity *peer)
Find the session for the given peer.
struct GNUNET_PeerIdentity GSC_my_identity
Our identity.
Data kept per session.
The identity of the host (wraps the signing key of the peer).
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.
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.
A type map describing which messages a given neighbour is able to process.
enum GNUNET_TESTBED_UnderlayLinkModelType type
the type of this model
#define GNUNET_YES
Definition: gnunet_common.h:77
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.
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 995 of file gnunet-service-core_sessions.c.

References GNUNET_CONTAINER_multipeermap_create(), and GNUNET_YES.

Referenced by run().

996 {
998 }
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).
#define GNUNET_YES
Definition: gnunet_common.h:77
static GNUNET_NETWORK_STRUCT_END struct GNUNET_CONTAINER_MultiPeerMap * sessions
Map of peer identities to struct Session.
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 1011 of file gnunet-service-core_sessions.c.

References GNUNET_OK, and GSC_SESSIONS_end().

Referenced by GSC_SESSIONS_done().

1014 {
1015  /* struct Session *session = value; */
1016 
1017  GSC_SESSIONS_end(key);
1018  return GNUNET_OK;
1019 }
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
void GSC_SESSIONS_end(const struct GNUNET_PeerIdentity *pid)
End the session with the given peer (we are no longer connected).
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 1026 of file gnunet-service-core_sessions.c.

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

Referenced by shutdown_task().

1027 {
1028  if (NULL != sessions)
1029  {
1032  NULL);
1034  sessions = NULL;
1035  }
1036 }
void GNUNET_CONTAINER_multipeermap_destroy(struct GNUNET_CONTAINER_MultiPeerMap *map)
Destroy a hash map.
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.
int GNUNET_CONTAINER_multipeermap_iterate(struct GNUNET_CONTAINER_MultiPeerMap *map, GNUNET_CONTAINER_PeerMapIterator it, void *it_cls)
Iterate over all entries in the map.
static GNUNET_NETWORK_STRUCT_END struct GNUNET_CONTAINER_MultiPeerMap * sessions
Map of peer identities to struct Session.
Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ sessions

Map of peer identities to struct Session.

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