GNUnet  0.10.x
gnunet-service-core_sessions.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2009-2014, 2016 GNUnet e.V.
4 
5  GNUnet is free software: you can redistribute it and/or modify it
6  under the terms of the GNU Affero General Public License as published
7  by the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  GNUnet is distributed in the hope that it will be useful, but
11  WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Affero General Public License for more details.
14 
15  You should have received a copy of the GNU Affero General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 
18  SPDX-License-Identifier: AGPL3.0-or-later
19 */
20 
26 #include "platform.h"
27 #include "gnunet-service-core.h"
28 #include "gnunet-service-core_kx.h"
31 #include "gnunet_constants.h"
32 #include "core.h"
33 
34 
39 #define MAX_ENCRYPTED_MESSAGE_QUEUE_SIZE 4
40 
41 
47 {
48 
53 
58 
63 
68 
73 
80 
86  size_t size;
87 };
88 
89 
93 struct Session
94 {
98  const struct GNUNET_PeerIdentity *peer;
99 
104 
110 
116 
121 
126 
130  struct GSC_TypeMap *tmap;
131 
136 
141 
146  struct GNUNET_TIME_Relative typemap_delay;
147 
154 };
155 
156 
158 
163 {
164 
168  struct GNUNET_MessageHeader header;
169 
174 
178  struct GNUNET_HashCode tm_hash;
179 };
180 
182 
183 
188 
189 
197 static struct Session *
199 {
200  if (NULL == sessions)
201  return NULL;
202  return GNUNET_CONTAINER_multipeermap_get (sessions, peer);
203 }
204 
205 
212 void
214 {
215  struct Session *session;
216  struct GSC_ClientActiveRequest *car;
217  struct SessionMessageEntry *sme;
218 
219  session = find_session (pid);
220  if (NULL == session)
221  return;
223  "Destroying session for peer `%s'\n",
224  GNUNET_i2s (session->peer));
225  if (NULL != session->cork_task)
226  {
228  session->cork_task = NULL;
229  }
230  while (NULL != (car = session->active_client_request_head))
231  {
234  car);
236  }
237  while (NULL != (sme = session->sme_head))
238  {
239  GNUNET_CONTAINER_DLL_remove (session->sme_head, session->sme_tail, sme);
240  GNUNET_free (sme);
241  }
242  if (NULL != session->typemap_task)
243  {
245  session->typemap_task = NULL;
246  }
248  session->tmap,
249  NULL);
250  GNUNET_assert (
251  GNUNET_YES ==
252  GNUNET_CONTAINER_multipeermap_remove (sessions, session->peer, session));
254  gettext_noop ("# peers connected"),
256  GNUNET_NO);
257  GSC_TYPEMAP_destroy (session->tmap);
258  session->tmap = NULL;
259  GNUNET_free (session);
260 }
261 
262 
269 static void
271 {
272  struct Session *session = cls;
273  struct GNUNET_MessageHeader *hdr;
274  struct GNUNET_TIME_Relative delay;
275 
277  "Sending TYPEMAP to %s\n",
278  GNUNET_i2s (session->peer));
280  delay = session->typemap_delay;
281  /* randomize a bit to avoid spont. sync */
282  delay.rel_value_us +=
284  session->typemap_task =
287  gettext_noop ("# type map refreshes sent"),
288  1,
289  GNUNET_NO);
291  GSC_KX_encrypt_and_transmit (session->kx, hdr, ntohs (hdr->size));
292  GNUNET_free (hdr);
293 }
294 
295 
301 static void
302 start_typemap_task (struct Session *session)
303 {
304  if (NULL != session->typemap_task)
309  session);
310 }
311 
312 
319 void
321  struct GSC_KeyExchangeInfo *kx)
322 {
323  struct Session *session;
324 
326  "Creating session for peer `%s'\n",
327  GNUNET_i2s (peer));
328  session = GNUNET_new (struct Session);
329  session->tmap = GSC_TYPEMAP_create ();
330  session->peer = peer;
331  session->kx = kx;
334  sessions,
335  session->peer,
336  session,
339  gettext_noop ("# peers connected"),
341  GNUNET_NO);
342  GSC_CLIENTS_notify_clients_about_neighbour (peer, NULL, session->tmap);
343  start_typemap_task (session);
344 }
345 
346 
354 void
356 {
357  struct Session *session;
358 
359  session = find_session (peer);
360  if (NULL == session)
361  {
362  /* KX/session is new for both sides; thus no need to restart what
363  has not yet begun */
364  return;
365  }
366  start_typemap_task (session);
367 }
368 
369 
377 void
379  const struct GNUNET_MessageHeader *msg)
380 {
381  const struct TypeMapConfirmationMessage *cmsg;
382  struct Session *session;
383 
384  session = find_session (peer);
385  if (NULL == session)
386  {
387  GNUNET_break (0);
388  return;
389  }
390  if (ntohs (msg->size) != sizeof (struct TypeMapConfirmationMessage))
391  {
392  GNUNET_break_op (0);
393  return;
394  }
395  cmsg = (const struct TypeMapConfirmationMessage *) msg;
396  if (GNUNET_YES != GSC_TYPEMAP_check_hash (&cmsg->tm_hash))
397  {
398  /* our typemap has changed in the meantime, do not
399  accept confirmation */
401  gettext_noop (
402  "# outdated typemap confirmations received"),
403  1,
404  GNUNET_NO);
406  "Got outdated typemap confirmated from peer `%s'\n",
407  GNUNET_i2s (session->peer));
408  return;
409  }
411  "Got typemap confirmation from peer `%s'\n",
412  GNUNET_i2s (session->peer));
413  if (NULL != session->typemap_task)
414  {
416  session->typemap_task = NULL;
417  }
419  gettext_noop (
420  "# valid typemap confirmations received"),
421  1,
422  GNUNET_NO);
423 }
424 
425 
434 static int
436  const struct GNUNET_PeerIdentity *key,
437  void *value)
438 {
439  struct GSC_Client *client = cls;
440  struct Session *session = value;
441 
443  session->peer,
444  NULL, /* old TMAP: none */
445  session->tmap);
446  return GNUNET_OK;
447 }
448 
449 
455 void
457 {
458  /* notify new client about existing sessions */
461  client);
462 }
463 
464 
471 static void
472 try_transmission (struct Session *session);
473 
474 
484 void
486 {
487  struct Session *session;
488 
489  session = find_session (&car->target);
490  if (NULL == session)
491  {
493  "Dropped client request for transmission (am disconnected)\n");
494  GNUNET_break (0); /* should have been rejected earlier */
496  return;
497  }
499  {
500  GNUNET_break (0);
502  return;
503  }
505  "Received client transmission request. queueing\n");
508  car);
509  try_transmission (session);
510 }
511 
512 
519 void
521 {
522  struct Session *session;
523 
524  if (0 == memcmp (&car->target,
526  sizeof (struct GNUNET_PeerIdentity)))
527  return;
528  session = find_session (&car->target);
529  GNUNET_assert (NULL != session);
532  car);
533  /* dequeueing of 'high' priority messages may unblock
534  transmission for lower-priority messages, so we also
535  need to try in this case. */
536  try_transmission (session);
537 }
538 
539 
547 static void
548 solicit_messages (struct Session *session, size_t msize)
549 {
550  struct GSC_ClientActiveRequest *car;
551  struct GSC_ClientActiveRequest *nxt;
552  size_t so_size;
554 
555  so_size = msize;
557  for (car = session->active_client_request_head; NULL != car; car = car->next)
558  {
559  if (GNUNET_YES == car->was_solicited)
560  continue;
561  pmax = GNUNET_MAX (pmax, car->priority & GNUNET_MQ_PRIORITY_MASK);
562  }
563  nxt = session->active_client_request_head;
564  while (NULL != (car = nxt))
565  {
566  nxt = car->next;
567  if (car->priority < pmax)
568  continue;
570  break;
571  so_size += car->msize;
572  if (GNUNET_YES == car->was_solicited)
573  continue;
574  car->was_solicited = GNUNET_YES;
576  "Soliciting message with priority %u\n",
577  car->priority);
579  /* The above call may *dequeue* requests and thereby
580  clobber 'nxt'. Hence we need to restart from the
581  head of the list. */
582  nxt = session->active_client_request_head;
583  so_size = msize;
584  }
585 }
586 
587 
594 static void
595 pop_cork_task (void *cls)
596 {
597  struct Session *session = cls;
598 
599  session->cork_task = NULL;
600  try_transmission (session);
601 }
602 
603 
611 static void
612 try_transmission (struct Session *session)
613 {
614  struct SessionMessageEntry *pos;
615  size_t msize;
616  struct GNUNET_TIME_Absolute now;
617  struct GNUNET_TIME_Absolute min_deadline;
620  struct GSC_ClientActiveRequest *car;
621  int excess;
622 
623  msize = 0;
624  min_deadline = GNUNET_TIME_UNIT_FOREVER_ABS;
625  /* if the peer has excess bandwidth, background traffic is allowed,
626  otherwise not */
629  {
631  "Transmission queue already very long, waiting...\n");
632  return; /* queue already too long */
633  }
634  excess = GSC_NEIGHBOURS_check_excess_bandwidth (session->kx);
635  if (GNUNET_YES == excess)
637  else
639  /* determine highest priority of 'ready' messages we already solicited from clients */
640  pos = session->sme_head;
641  while ((NULL != pos) &&
643  {
645  msize += pos->size;
646  maxp = GNUNET_MAX (maxp, pos->priority & GNUNET_MQ_PRIORITY_MASK);
647  min_deadline = GNUNET_TIME_absolute_min (min_deadline, pos->deadline);
648  pos = pos->next;
649  }
650  GNUNET_log (
652  "Calculating transmission set with %u priority (%s) and %s earliest deadline\n",
653  maxp,
654  (GNUNET_YES == excess) ? "excess bandwidth" : "limited bandwidth",
656  min_deadline),
657  GNUNET_YES));
658 
660  {
661  /* if highest already solicited priority from clients is not critical,
662  check if there are higher-priority messages to be solicited from clients */
663  if (GNUNET_YES == excess)
665  else
667  for (car = session->active_client_request_head; NULL != car;
668  car = car->next)
669  {
670  if (GNUNET_YES == car->was_solicited)
671  continue;
672  maxpc = GNUNET_MAX (maxpc, car->priority & GNUNET_MQ_PRIORITY_MASK);
673  }
674  if (maxpc > maxp)
675  {
676  /* we have messages waiting for solicitation that have a higher
677  priority than those that we already accepted; solicit the
678  high-priority messages first */
680  "Soliciting messages based on priority (%u > %u)\n",
681  maxpc,
682  maxp);
683  solicit_messages (session, 0);
684  return;
685  }
686  }
687  else
688  {
689  /* never solicit more, we have critical messages to process */
690  excess = GNUNET_NO;
692  }
693  now = GNUNET_TIME_absolute_get ();
694  if (((GNUNET_YES == excess) || (maxpc >= GNUNET_MQ_PRIO_BEST_EFFORT)) &&
695  ((0 == msize) ||
697  (min_deadline.abs_value_us > now.abs_value_us))))
698  {
699  /* not enough ready yet (tiny message & cork possible), or no messages at all,
700  and either excess bandwidth or best-effort or higher message waiting at
701  client; in this case, we try to solicit more */
702  GNUNET_log (
704  "Soliciting messages (excess %d, maxpc %d, message size %u, deadline %s)\n",
705  excess,
706  maxpc,
707  (unsigned int) msize,
709  min_deadline),
710  GNUNET_YES));
711  solicit_messages (session, msize);
712  if (msize > 0)
713  {
714  /* if there is data to send, just not yet, make sure we do transmit
715  * it once the deadline is reached */
717  "Corking until %s\n",
719  GNUNET_TIME_absolute_get_remaining (min_deadline),
720  GNUNET_YES));
721  if (NULL != session->cork_task)
723  session->cork_task =
724  GNUNET_SCHEDULER_add_at (min_deadline, &pop_cork_task, session);
725  }
726  else
727  {
729  "Queue empty, waiting for solicitations\n");
730  }
731  return;
732  }
734  "Building combined plaintext buffer to transmit message!\n");
735  /* create plaintext buffer of all messages (that fit), encrypt and
736  transmit */
737  {
738  static unsigned long long total_bytes;
739  static unsigned int total_msgs;
740  char pbuf[msize]; /* plaintext */
741  size_t used;
742 
743  used = 0;
744  while ((NULL != (pos = session->sme_head)) && (used + pos->size <= msize))
745  {
747  "Adding message of type %d (%d/%d) to payload for %s\n",
748  ntohs (((const struct GNUNET_MessageHeader *) &pos[1])->type),
749  pos->is_typemap,
750  pos->is_typemap_confirm,
751  GNUNET_i2s (session->peer));
752  GNUNET_memcpy (&pbuf[used], &pos[1], pos->size);
753  used += pos->size;
754  GNUNET_CONTAINER_DLL_remove (session->sme_head, session->sme_tail, pos);
755  GNUNET_free (pos);
756  }
757  /* compute average payload size */
758  total_bytes += used;
759  total_msgs++;
760  if (0 == total_msgs)
761  {
762  /* 2^32 messages, wrap around... */
763  total_msgs = 1;
764  total_bytes = used;
765  }
767  "# avg payload per encrypted message",
768  total_bytes / total_msgs,
769  GNUNET_NO);
770  /* now actually transmit... */
771  GSC_KX_encrypt_and_transmit (session->kx, pbuf, used);
772  }
773 }
774 
775 
785 static int
787  const struct GNUNET_PeerIdentity *key,
788  void *value)
789 {
790  const struct GNUNET_MessageHeader *hdr = cls;
791  struct Session *session = value;
792  struct SessionMessageEntry *sme;
793  uint16_t size;
794 
796  "Restarting sending TYPEMAP to %s\n",
797  GNUNET_i2s (session->peer));
798  size = ntohs (hdr->size);
799  for (sme = session->sme_head; NULL != sme; sme = sme->next)
800  {
801  if (GNUNET_YES == sme->is_typemap)
802  {
803  GNUNET_CONTAINER_DLL_remove (session->sme_head, session->sme_tail, sme);
804  GNUNET_free (sme);
805  break;
806  }
807  }
808  sme = GNUNET_malloc (sizeof (struct SessionMessageEntry) + size);
809  sme->is_typemap = GNUNET_YES;
810  GNUNET_memcpy (&sme[1], hdr, size);
811  sme->size = size;
813  GNUNET_CONTAINER_DLL_insert (session->sme_head, session->sme_tail, sme);
814  try_transmission (session);
815  start_typemap_task (session);
816  return GNUNET_OK;
817 }
818 
819 
826 void
828 {
829  if (NULL == sessions)
830  return;
833  (void *) msg);
834 }
835 
836 
844 void
846 {
847  struct Session *session;
848 
850  "Transport solicits for %s\n",
851  GNUNET_i2s (pid));
852  session = find_session (pid);
853  if (NULL == session)
854  return;
855  try_transmission (session);
856 }
857 
858 
867 void
869  const struct GNUNET_MessageHeader *msg,
871 {
872  struct Session *session;
873  struct SessionMessageEntry *sme;
874  struct SessionMessageEntry *pos;
875  size_t msize;
876 
877  session = find_session (&car->target);
878  if (NULL == session)
879  return;
880  msize = ntohs (msg->size);
881  sme = GNUNET_malloc (sizeof (struct SessionMessageEntry) + msize);
882  GNUNET_memcpy (&sme[1], msg, msize);
883  sme->size = msize;
884  sme->priority = priority;
885  if (0 != (GNUNET_MQ_PREF_CORK_ALLOWED & priority))
886  {
887  sme->deadline =
890  "Mesage corked, delaying transmission\n");
891  }
892  pos = session->sme_head;
893  while ((NULL != pos) && (pos->priority >= sme->priority))
894  pos = pos->next;
895  if (NULL == pos)
897  session->sme_tail,
898  sme);
899  else
901  session->sme_tail,
902  pos->prev,
903  sme);
904  try_transmission (session);
905 }
906 
907 
915 void
917  const struct GNUNET_MessageHeader *msg)
918 {
919  struct Session *session;
920  struct GSC_TypeMap *nmap;
921  struct SessionMessageEntry *sme;
922  struct TypeMapConfirmationMessage *tmc;
923 
924  nmap = GSC_TYPEMAP_get_from_message (msg);
925  if (NULL == nmap)
926  {
927  GNUNET_break_op (0);
928  return; /* malformed */
929  }
930  session = find_session (peer);
931  if (NULL == session)
932  {
933  GSC_TYPEMAP_destroy (nmap);
934  GNUNET_break (0);
935  return;
936  }
938  "Received TYPEMAP from %s\n",
939  GNUNET_i2s (session->peer));
940  for (sme = session->sme_head; NULL != sme; sme = sme->next)
941  {
942  if (GNUNET_YES == sme->is_typemap_confirm)
943  {
944  GNUNET_CONTAINER_DLL_remove (session->sme_head, session->sme_tail, sme);
945  GNUNET_free (sme);
946  break;
947  }
948  }
949  sme = GNUNET_malloc (sizeof (struct SessionMessageEntry) +
950  sizeof (struct TypeMapConfirmationMessage));
952  sme->size = sizeof (struct TypeMapConfirmationMessage);
955  tmc = (struct TypeMapConfirmationMessage *) &sme[1];
956  tmc->header.size = htons (sizeof (struct TypeMapConfirmationMessage));
958  tmc->reserved = htonl (0);
959  GSC_TYPEMAP_hash (nmap, &tmc->tm_hash);
960  GNUNET_CONTAINER_DLL_insert (session->sme_head, session->sme_tail, sme);
961  try_transmission (session);
962  GSC_CLIENTS_notify_clients_about_neighbour (peer, session->tmap, nmap);
963  GSC_TYPEMAP_destroy (session->tmap);
964  session->tmap = nmap;
965 }
966 
967 
976 void
978  uint16_t type)
979 {
980  struct Session *session;
981  struct GSC_TypeMap *nmap;
982 
983  if (0 == memcmp (peer, &GSC_my_identity, sizeof (struct GNUNET_PeerIdentity)))
984  return;
985  session = find_session (peer);
986  GNUNET_assert (NULL != session);
987  if (GNUNET_YES == GSC_TYPEMAP_test_match (session->tmap, &type, 1))
988  return; /* already in it */
989  nmap = GSC_TYPEMAP_extend (session->tmap, &type, 1);
990  GSC_CLIENTS_notify_clients_about_neighbour (peer, session->tmap, nmap);
991  GSC_TYPEMAP_destroy (session->tmap);
992  session->tmap = nmap;
993 }
994 
995 
999 void
1001 {
1003 }
1004 
1005 
1015 static int
1017  const struct GNUNET_PeerIdentity *key,
1018  void *value)
1019 {
1020  /* struct Session *session = value; */
1021 
1022  GSC_SESSIONS_end (key);
1023  return GNUNET_OK;
1024 }
1025 
1026 
1030 void
1032 {
1033  if (NULL != sessions)
1034  {
1037  NULL);
1039  sessions = NULL;
1040  }
1041 }
1042 
1043 /* end of gnunet-service-core_sessions.c */
#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.
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...
void GSC_SESSIONS_init()
Initialize sessions subsystem.
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
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.
#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.
struct GSC_ClientActiveRequest * active_client_request_tail
Tail of list of requests from clients for transmission to this peer.
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:245
uint32_t GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i)
Produce a random value.
#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.
#define GNUNET_TIME_UNIT_SECONDS
One second.
static void try_transmission(struct Session *session)
Try to perform a transmission on the given session.
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.
common internal definitions for core service
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:81
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
GNUNET_MQ_PriorityPreferences
Per envelope preferences and priorities.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
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_TIME_Absolute deadline
Deadline for transmission, 1s after we received it (if we are not corking), otherwise "now"...
void GSC_SESSIONS_queue_request(struct GSC_ClientActiveRequest *car)
Queue a request from a client for transmission to a particular peer.
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).
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...
uint64_t abs_value_us
The actual value.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
#define GNUNET_NETWORK_STRUCT_BEGIN
Define as empty, GNUNET_PACKED should suffice, but this won&#39;t work on W32.
void GNUNET_CONTAINER_multipeermap_destroy(struct GNUNET_CONTAINER_MultiPeerMap *map)
Destroy a hash map.
management of map that specifies which message types this peer supports
#define GNUNET_TIME_UNIT_FOREVER_ABS
Constant used to specify "forever".
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).
Best-effort traffic (i.e.
Data structure for each client connected to the CORE service.
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:1246
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
#define GNUNET_memcpy(dst, src, n)
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 char * value
Value of the record to add/remove.
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_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.
#define GNUNET_MAX(a, b)
Definition: gnunet_common.h:85
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.
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:727
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.
struct SessionMessageEntry * next
We keep messages in a doubly linked list.
Message sent to confirm that a typemap was received.
#define GNUNET_CONTAINER_DLL_insert_after(head, tail, other, element)
Insert an element into a DLL after the given other element.
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.
Internal representation of the hash map.
struct SessionMessageEntry * prev
We keep messages in a doubly linked list.
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_TypeMap * tmap
Current type map for this peer.
Information about the status of a key exchange with another peer.
A 512-bit hashcode.
struct GSC_ClientActiveRequest * active_client_request_head
Head of list of requests from clients for transmission to this peer.
Globals for gnunet-service-core.
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.
struct GNUNET_PeerIdentity GSC_my_identity
Our identity.
#define MAX_ENCRYPTED_MESSAGE_QUEUE_SIZE
How many encrypted messages do we queue at most? Needed to bound memory consumption.
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.
void GSC_SESSIONS_solicit(const struct GNUNET_PeerIdentity *pid)
Traffic is being solicited for the given peer.
struct GNUNET_HashCode key
The key used in the DHT.
struct GSC_TypeMap * GSC_TYPEMAP_create()
Create an empty type map.
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...
Lowest priority, i.e.
void GSC_SESSIONS_create(const struct GNUNET_PeerIdentity *peer, struct GSC_KeyExchangeInfo *kx)
Create a session, a key exchange was just completed.
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.
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
void GSC_SESSIONS_done()
Shutdown sessions subsystem.
#define GNUNET_TIME_STD_BACKOFF(r)
Perform our standard exponential back-off calculation, starting at 1 ms and then going by a factor of...
Bit mask to apply to extract the priority bits.
code for managing the key exchange (SET_KEY, PING, PONG) with other peers
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 is_typemap_confirm
Flag set to GNUNET_YES if this is a typemap confirmation message.
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_NETWORK_STRUCT_END
Define as empty, GNUNET_PACKED should suffice, but this won&#39;t work on W32;.
void GSC_CLIENTS_solicit_request(struct GSC_ClientActiveRequest *car)
Tell a client that we are ready to receive the message.
int GNUNET_CONTAINER_multipeermap_iterate(struct GNUNET_CONTAINER_MultiPeerMap *map, GNUNET_CONTAINER_PeerMapIterator it, void *it_cls)
Iterate over all entries in the map.
int GSC_TYPEMAP_check_hash(const struct GNUNET_HashCode *hc)
Check if the given hash matches our current type map.
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.
#define GNUNET_PACKED
gcc-ism to get packed structs.
void GSC_TYPEMAP_hash(const struct GSC_TypeMap *tm, struct GNUNET_HashCode *hc)
Hash the contents of a type map.
struct GNUNET_SCHEDULER_Task * typemap_task
Task to transmit our type map.
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
void GSC_SESSIONS_notify_client_about_sessions(struct GSC_Client *client)
We have a new client, notify it about all current sessions.
void * GNUNET_CONTAINER_multipeermap_get(const struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key)
Given a key find a value in the map matching the key.
struct GNUNET_SERVICE_Client * client
Handle for the client with the server API.
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.
#define GNUNET_log(kind,...)
Entry in list of pending tasks.
Definition: scheduler.c:134
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.
struct GSC_KeyExchangeInfo * kx
Key exchange state for this peer.
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.
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
void GSC_SESSIONS_dequeue_request(struct GSC_ClientActiveRequest *car)
Dequeue a request from a client from transmission to a particular peer.
Flag to indicate that CORKing is acceptable.
void GSC_SESSIONS_add_to_typemap(const struct GNUNET_PeerIdentity *peer, uint16_t type)
The given peer send a message of the specified type.
enum GNUNET_TESTBED_UnderlayLinkModelType type
the type of this model
Header for all communications.
int is_typemap
Flag set to GNUNET_YES if this is a typemap message.
Time for absolute times used by GNUnet, in microseconds.
#define GNUNET_YES
Definition: gnunet_common.h:80
uint32_t reserved
Reserved, always zero.
unsigned int GNUNET_CONTAINER_multipeermap_size(const struct GNUNET_CONTAINER_MultiPeerMap *map)
Get the number of key-value pairs in the map.
void GSC_SESSIONS_broadcast_typemap(const struct GNUNET_MessageHeader *msg)
Broadcast an updated typemap message to all neighbours.
static unsigned long long reserved
How much space have we currently reserved?
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.
static struct GNUNET_PeerIdentity pid
Identity of the peer we transmit to / connect to.
#define GNUNET_CONSTANTS_MAX_CORK_DELAY
How long do we delay messages to get larger packet sizes (CORKing)?
static void start_typemap_task(struct Session *session)
Restart the typemap task for the given session.
struct GNUNET_PeerIdentity target
Which peer is the message going to be for?
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:1223
static GNUNET_NETWORK_STRUCT_END struct GNUNET_CONTAINER_MultiPeerMap * sessions
Map of peer identities to struct Session.
int first_typemap
Is this the first time we&#39;re sending the typemap? If so, we want to send it a bit faster the second t...
void GSC_SESSIONS_end(const struct GNUNET_PeerIdentity *pid)
End the session with the given peer (we are no longer connected).
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?
struct GNUNET_MessageHeader header
Header with type GNUNET_MESSAGE_TYPE_CORE_CONFIRM_TYPE_MAP.
No good quality of the operation is needed (i.e., random numbers can be pseudo-random).
void GSC_SESSIONS_reinit(const struct GNUNET_PeerIdentity *peer)
The other peer has indicated that it &#39;lost&#39; the session (KX down), reinitialize the session on our en...
struct GSC_TypeMap * GSC_TYPEMAP_get_from_message(const struct GNUNET_MessageHeader *msg)
Extract a type map from a TYPE_MAP message.
#define GNUNET_malloc(size)
Wrapper around malloc.
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.
Time for relative time used by GNUnet, in microseconds.
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).
#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:965