GNUnet  0.11.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 {
52 
57 
62 
67 
72 
79 
85  size_t size;
86 };
87 
88 
92 struct Session
93 {
97  const struct GNUNET_PeerIdentity *peer;
98 
103 
109 
115 
120 
125 
129  struct GSC_TypeMap *tmap;
130 
135 
140 
145  struct GNUNET_TIME_Relative typemap_delay;
146 
153 };
154 
155 
157 
162 {
166  struct GNUNET_MessageHeader header;
167 
172 
176  struct GNUNET_HashCode tm_hash;
177 };
178 
180 
181 
186 
187 
195 static struct Session *
197 {
198  if (NULL == sessions)
199  return NULL;
200  return GNUNET_CONTAINER_multipeermap_get (sessions, peer);
201 }
202 
203 
210 void
212 {
213  struct Session *session;
214  struct GSC_ClientActiveRequest *car;
215  struct SessionMessageEntry *sme;
216 
217  session = find_session (pid);
218  if (NULL == session)
219  return;
221  "Destroying session for peer `%s'\n",
222  GNUNET_i2s (session->peer));
223  if (NULL != session->cork_task)
224  {
226  session->cork_task = NULL;
227  }
228  while (NULL != (car = session->active_client_request_head))
229  {
232  car);
234  }
235  while (NULL != (sme = session->sme_head))
236  {
237  GNUNET_CONTAINER_DLL_remove (session->sme_head, session->sme_tail, sme);
238  GNUNET_free (sme);
239  }
240  if (NULL != session->typemap_task)
241  {
243  session->typemap_task = NULL;
244  }
246  session->tmap,
247  NULL);
248  GNUNET_assert (
249  GNUNET_YES ==
250  GNUNET_CONTAINER_multipeermap_remove (sessions, session->peer, session));
252  gettext_noop ("# peers connected"),
254  GNUNET_NO);
255  GSC_TYPEMAP_destroy (session->tmap);
256  session->tmap = NULL;
257  GNUNET_free (session);
258 }
259 
260 
267 static void
269 {
270  struct Session *session = cls;
271  struct GNUNET_MessageHeader *hdr;
272  struct GNUNET_TIME_Relative delay;
273 
275  "Sending TYPEMAP to %s\n",
276  GNUNET_i2s (session->peer));
278  delay = session->typemap_delay;
279  /* randomize a bit to avoid spont. sync */
280  delay.rel_value_us +=
282  session->typemap_task =
285  gettext_noop ("# type map refreshes sent"),
286  1,
287  GNUNET_NO);
289  GSC_KX_encrypt_and_transmit (session->kx, hdr, ntohs (hdr->size));
290  GNUNET_free (hdr);
291 }
292 
293 
299 static void
300 start_typemap_task (struct Session *session)
301 {
302  if (NULL != session->typemap_task)
307  session);
308 }
309 
310 
317 void
319  struct GSC_KeyExchangeInfo *kx)
320 {
321  struct Session *session;
322 
324  "Creating session for peer `%s'\n",
325  GNUNET_i2s (peer));
326  session = GNUNET_new (struct Session);
327  session->tmap = GSC_TYPEMAP_create ();
328  session->peer = peer;
329  session->kx = kx;
332  sessions,
333  session->peer,
334  session,
337  gettext_noop ("# peers connected"),
339  GNUNET_NO);
340  GSC_CLIENTS_notify_clients_about_neighbour (peer, NULL, session->tmap);
341  start_typemap_task (session);
342 }
343 
344 
352 void
354 {
355  struct Session *session;
356 
357  session = find_session (peer);
358  if (NULL == session)
359  {
360  /* KX/session is new for both sides; thus no need to restart what
361  has not yet begun */
362  return;
363  }
364  start_typemap_task (session);
365 }
366 
367 
375 void
377  const struct GNUNET_MessageHeader *msg)
378 {
379  const struct TypeMapConfirmationMessage *cmsg;
380  struct Session *session;
381 
382  session = find_session (peer);
383  if (NULL == session)
384  {
385  GNUNET_break (0);
386  return;
387  }
388  if (ntohs (msg->size) != sizeof(struct TypeMapConfirmationMessage))
389  {
390  GNUNET_break_op (0);
391  return;
392  }
393  cmsg = (const struct TypeMapConfirmationMessage *) msg;
394  if (GNUNET_YES != GSC_TYPEMAP_check_hash (&cmsg->tm_hash))
395  {
396  /* our typemap has changed in the meantime, do not
397  accept confirmation */
399  gettext_noop (
400  "# outdated typemap confirmations received"),
401  1,
402  GNUNET_NO);
404  "Got outdated typemap confirmated from peer `%s'\n",
405  GNUNET_i2s (session->peer));
406  return;
407  }
409  "Got typemap confirmation from peer `%s'\n",
410  GNUNET_i2s (session->peer));
411  if (NULL != session->typemap_task)
412  {
414  session->typemap_task = NULL;
415  }
417  gettext_noop (
418  "# valid typemap confirmations received"),
419  1,
420  GNUNET_NO);
421 }
422 
423 
432 static int
434  const struct GNUNET_PeerIdentity *key,
435  void *value)
436 {
437  struct GSC_Client *client = cls;
438  struct Session *session = value;
439 
441  session->peer,
442  NULL, /* old TMAP: none */
443  session->tmap);
444  return GNUNET_OK;
445 }
446 
447 
453 void
455 {
456  /* notify new client about existing sessions */
459  client);
460 }
461 
462 
469 static void
470 try_transmission (struct Session *session);
471 
472 
482 void
484 {
485  struct Session *session;
486 
487  session = find_session (&car->target);
488  if (NULL == session)
489  {
491  "Dropped client request for transmission (am disconnected)\n");
492  GNUNET_break (0); /* should have been rejected earlier */
494  return;
495  }
497  {
498  GNUNET_break (0);
500  return;
501  }
503  "Received client transmission request. queueing\n");
506  car);
507  try_transmission (session);
508 }
509 
510 
517 void
519 {
520  struct Session *session;
521 
522  if (0 == memcmp (&car->target,
524  sizeof(struct GNUNET_PeerIdentity)))
525  return;
526  session = find_session (&car->target);
527  GNUNET_assert (NULL != session);
530  car);
531  /* dequeueing of 'high' priority messages may unblock
532  transmission for lower-priority messages, so we also
533  need to try in this case. */
534  try_transmission (session);
535 }
536 
537 
545 static void
546 solicit_messages (struct Session *session, size_t msize)
547 {
548  struct GSC_ClientActiveRequest *car;
549  struct GSC_ClientActiveRequest *nxt;
550  size_t so_size;
552 
553  so_size = msize;
555  for (car = session->active_client_request_head; NULL != car; car = car->next)
556  {
557  if (GNUNET_YES == car->was_solicited)
558  continue;
559  pmax = GNUNET_MAX (pmax, car->priority & GNUNET_MQ_PRIORITY_MASK);
560  }
561  nxt = session->active_client_request_head;
562  while (NULL != (car = nxt))
563  {
564  nxt = car->next;
565  if (car->priority < pmax)
566  continue;
568  break;
569  so_size += car->msize;
570  if (GNUNET_YES == car->was_solicited)
571  continue;
572  car->was_solicited = GNUNET_YES;
574  "Soliciting message with priority %u\n",
575  car->priority);
577  /* The above call may *dequeue* requests and thereby
578  clobber 'nxt'. Hence we need to restart from the
579  head of the list. */
580  nxt = session->active_client_request_head;
581  so_size = msize;
582  }
583 }
584 
585 
592 static void
593 pop_cork_task (void *cls)
594 {
595  struct Session *session = cls;
596 
597  session->cork_task = NULL;
598  try_transmission (session);
599 }
600 
601 
609 static void
610 try_transmission (struct Session *session)
611 {
612  struct SessionMessageEntry *pos;
613  size_t msize;
614  struct GNUNET_TIME_Absolute now;
615  struct GNUNET_TIME_Absolute min_deadline;
618  struct GSC_ClientActiveRequest *car;
619  int excess;
620 
621  msize = 0;
622  min_deadline = GNUNET_TIME_UNIT_FOREVER_ABS;
623  /* if the peer has excess bandwidth, background traffic is allowed,
624  otherwise not */
627  {
629  "Transmission queue already very long, waiting...\n");
630  return; /* queue already too long */
631  }
632  excess = GSC_NEIGHBOURS_check_excess_bandwidth (session->kx);
633  if (GNUNET_YES == excess)
635  else
637  /* determine highest priority of 'ready' messages we already solicited from clients */
638  pos = session->sme_head;
639  while ((NULL != pos) &&
641  {
643  msize += pos->size;
644  maxp = GNUNET_MAX (maxp, pos->priority & GNUNET_MQ_PRIORITY_MASK);
645  min_deadline = GNUNET_TIME_absolute_min (min_deadline, pos->deadline);
646  pos = pos->next;
647  }
648  GNUNET_log (
650  "Calculating transmission set with %u priority (%s) and %s earliest deadline\n",
651  maxp,
652  (GNUNET_YES == excess) ? "excess bandwidth" : "limited bandwidth",
654  min_deadline),
655  GNUNET_YES));
656 
658  {
659  /* if highest already solicited priority from clients is not critical,
660  check if there are higher-priority messages to be solicited from clients */
661  if (GNUNET_YES == excess)
663  else
665  for (car = session->active_client_request_head; NULL != car;
666  car = car->next)
667  {
668  if (GNUNET_YES == car->was_solicited)
669  continue;
670  maxpc = GNUNET_MAX (maxpc, car->priority & GNUNET_MQ_PRIORITY_MASK);
671  }
672  if (maxpc > maxp)
673  {
674  /* we have messages waiting for solicitation that have a higher
675  priority than those that we already accepted; solicit the
676  high-priority messages first */
678  "Soliciting messages based on priority (%u > %u)\n",
679  maxpc,
680  maxp);
681  solicit_messages (session, 0);
682  return;
683  }
684  }
685  else
686  {
687  /* never solicit more, we have critical messages to process */
688  excess = GNUNET_NO;
690  }
691  now = GNUNET_TIME_absolute_get ();
692  if (((GNUNET_YES == excess) || (maxpc >= GNUNET_MQ_PRIO_BEST_EFFORT)) &&
693  ((0 == msize) ||
695  (min_deadline.abs_value_us > now.abs_value_us))))
696  {
697  /* not enough ready yet (tiny message & cork possible), or no messages at all,
698  and either excess bandwidth or best-effort or higher message waiting at
699  client; in this case, we try to solicit more */
700  GNUNET_log (
702  "Soliciting messages (excess %d, maxpc %d, message size %u, deadline %s)\n",
703  excess,
704  maxpc,
705  (unsigned int) msize,
708  min_deadline),
709  GNUNET_YES));
710  solicit_messages (session, msize);
711  if (msize > 0)
712  {
713  /* if there is data to send, just not yet, make sure we do transmit
714  * it once the deadline is reached */
716  "Corking until %s\n",
718  GNUNET_TIME_absolute_get_remaining (min_deadline),
719  GNUNET_YES));
720  if (NULL != session->cork_task)
722  session->cork_task =
723  GNUNET_SCHEDULER_add_at (min_deadline, &pop_cork_task, session);
724  }
725  else
726  {
728  "Queue empty, waiting for solicitations\n");
729  }
730  return;
731  }
733  "Building combined plaintext buffer to transmit message!\n");
734  /* create plaintext buffer of all messages (that fit), encrypt and
735  transmit */
736  {
737  static unsigned long long total_bytes;
738  static unsigned int total_msgs;
739  char pbuf[msize]; /* plaintext */
740  size_t used;
741 
742  used = 0;
743  while ((NULL != (pos = session->sme_head)) && (used + pos->size <= msize))
744  {
746  "Adding message of type %d (%d/%d) to payload for %s\n",
747  ntohs (((const struct GNUNET_MessageHeader *) &pos[1])->type),
748  pos->is_typemap,
749  pos->is_typemap_confirm,
750  GNUNET_i2s (session->peer));
751  GNUNET_memcpy (&pbuf[used], &pos[1], pos->size);
752  used += pos->size;
753  GNUNET_CONTAINER_DLL_remove (session->sme_head, session->sme_tail, pos);
754  GNUNET_free (pos);
755  }
756  /* compute average payload size */
757  total_bytes += used;
758  total_msgs++;
759  if (0 == total_msgs)
760  {
761  /* 2^32 messages, wrap around... */
762  total_msgs = 1;
763  total_bytes = used;
764  }
766  "# avg payload per encrypted message",
767  total_bytes / total_msgs,
768  GNUNET_NO);
769  /* now actually transmit... */
770  GSC_KX_encrypt_and_transmit (session->kx, pbuf, used);
771  }
772 }
773 
774 
784 static int
786  const struct GNUNET_PeerIdentity *key,
787  void *value)
788 {
789  const struct GNUNET_MessageHeader *hdr = cls;
790  struct Session *session = value;
791  struct SessionMessageEntry *sme;
792  uint16_t size;
793 
795  "Restarting sending TYPEMAP to %s\n",
796  GNUNET_i2s (session->peer));
797  size = ntohs (hdr->size);
798  for (sme = session->sme_head; NULL != sme; sme = sme->next)
799  {
800  if (GNUNET_YES == sme->is_typemap)
801  {
802  GNUNET_CONTAINER_DLL_remove (session->sme_head, session->sme_tail, sme);
803  GNUNET_free (sme);
804  break;
805  }
806  }
807  sme = GNUNET_malloc (sizeof(struct SessionMessageEntry) + size);
808  sme->is_typemap = GNUNET_YES;
809  GNUNET_memcpy (&sme[1], hdr, size);
810  sme->size = size;
812  GNUNET_CONTAINER_DLL_insert (session->sme_head, session->sme_tail, sme);
813  try_transmission (session);
814  start_typemap_task (session);
815  return GNUNET_OK;
816 }
817 
818 
825 void
827 {
828  if (NULL == sessions)
829  return;
832  (void *) msg);
833 }
834 
835 
843 void
845 {
846  struct Session *session;
847 
849  "Transport solicits for %s\n",
850  GNUNET_i2s (pid));
851  session = find_session (pid);
852  if (NULL == session)
853  return;
854  try_transmission (session);
855 }
856 
857 
866 void
868  const struct GNUNET_MessageHeader *msg,
870 {
871  struct Session *session;
872  struct SessionMessageEntry *sme;
873  struct SessionMessageEntry *pos;
874  size_t msize;
875 
876  session = find_session (&car->target);
877  if (NULL == session)
878  return;
879  msize = ntohs (msg->size);
880  sme = GNUNET_malloc (sizeof(struct SessionMessageEntry) + msize);
881  GNUNET_memcpy (&sme[1], msg, msize);
882  sme->size = msize;
883  sme->priority = priority;
884  if (0 != (GNUNET_MQ_PREF_CORK_ALLOWED & priority))
885  {
886  sme->deadline =
889  "Mesage corked, delaying transmission\n");
890  }
891  pos = session->sme_head;
892  while ((NULL != pos) && (pos->priority >= sme->priority))
893  pos = pos->next;
894  if (NULL == pos)
896  session->sme_tail,
897  sme);
898  else
900  session->sme_tail,
901  pos->prev,
902  sme);
903  try_transmission (session);
904 }
905 
906 
914 void
916  const struct GNUNET_MessageHeader *msg)
917 {
918  struct Session *session;
919  struct GSC_TypeMap *nmap;
920  struct SessionMessageEntry *sme;
921  struct TypeMapConfirmationMessage *tmc;
922 
923  nmap = GSC_TYPEMAP_get_from_message (msg);
924  if (NULL == nmap)
925  {
926  GNUNET_break_op (0);
927  return; /* malformed */
928  }
929  session = find_session (peer);
930  if (NULL == session)
931  {
932  GSC_TYPEMAP_destroy (nmap);
933  GNUNET_break (0);
934  return;
935  }
937  "Received TYPEMAP from %s\n",
938  GNUNET_i2s (session->peer));
939  for (sme = session->sme_head; NULL != sme; sme = sme->next)
940  {
941  if (GNUNET_YES == sme->is_typemap_confirm)
942  {
943  GNUNET_CONTAINER_DLL_remove (session->sme_head, session->sme_tail, sme);
944  GNUNET_free (sme);
945  break;
946  }
947  }
948  sme = GNUNET_malloc (sizeof(struct SessionMessageEntry)
949  + sizeof(struct TypeMapConfirmationMessage));
951  sme->size = sizeof(struct TypeMapConfirmationMessage);
954  tmc = (struct TypeMapConfirmationMessage *) &sme[1];
955  tmc->header.size = htons (sizeof(struct TypeMapConfirmationMessage));
957  tmc->reserved = htonl (0);
958  GSC_TYPEMAP_hash (nmap, &tmc->tm_hash);
959  GNUNET_CONTAINER_DLL_insert (session->sme_head, session->sme_tail, sme);
960  try_transmission (session);
961  GSC_CLIENTS_notify_clients_about_neighbour (peer, session->tmap, nmap);
962  GSC_TYPEMAP_destroy (session->tmap);
963  session->tmap = nmap;
964 }
965 
966 
975 void
977  uint16_t type)
978 {
979  struct Session *session;
980  struct GSC_TypeMap *nmap;
981 
982  if (0 == memcmp (peer, &GSC_my_identity, sizeof(struct GNUNET_PeerIdentity)))
983  return;
984  session = find_session (peer);
985  GNUNET_assert (NULL != session);
986  if (GNUNET_YES == GSC_TYPEMAP_test_match (session->tmap, &type, 1))
987  return; /* already in it */
988  nmap = GSC_TYPEMAP_extend (session->tmap, &type, 1);
989  GSC_CLIENTS_notify_clients_about_neighbour (peer, session->tmap, nmap);
990  GSC_TYPEMAP_destroy (session->tmap);
991  session->tmap = nmap;
992 }
993 
994 
998 void
1000 {
1002 }
1003 
1004 
1014 static int
1016  const struct GNUNET_PeerIdentity *key,
1017  void *value)
1018 {
1019  /* struct Session *session = value; */
1020 
1021  GSC_SESSIONS_end (key);
1022  return GNUNET_OK;
1023 }
1024 
1025 
1029 void
1031 {
1032  if (NULL != sessions)
1033  {
1036  NULL);
1038  sessions = NULL;
1039  }
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:246
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
#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.
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
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
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:1253
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
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:82
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:687
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:77
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:1230
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:966