GNUnet 0.22.2
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"
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
92struct Session
93{
98
103
109
115
120
125
130
135
140
146
153};
154
155
157
162{
167
172
177};
178
180
181
186
187
195static struct Session *
197{
198 if (NULL == sessions)
199 return NULL;
201}
202
203
210void
212{
213 struct Session *session;
214 struct GSC_ClientActiveRequest *car;
215 struct SessionMessageEntry *sme;
216
217 session = find_session (pid);
218 if (NULL == session)
219 return;
221 "Destroying session for peer `%s'\n",
222 GNUNET_i2s (session->peer));
223 if (NULL != session->cork_task)
224 {
226 session->cork_task = NULL;
227 }
228 while (NULL != (car = session->active_client_request_head))
229 {
232 car);
234 }
235 while (NULL != (sme = session->sme_head))
236 {
237 GNUNET_CONTAINER_DLL_remove (session->sme_head, session->sme_tail, sme);
238 GNUNET_free (sme);
239 }
240 if (NULL != session->typemap_task)
241 {
243 session->typemap_task = NULL;
244 }
246 session->tmap,
247 NULL);
249 GNUNET_YES ==
252 gettext_noop ("# peers connected"),
254 GNUNET_NO);
255 GSC_TYPEMAP_destroy (session->tmap);
256 session->tmap = NULL;
257 GNUNET_free (session);
258}
259
260
267static 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
299static void
301{
302 if (NULL != session->typemap_task)
307 session);
308}
309
310
317void
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);
341 start_typemap_task (session);
342}
343
344
352void
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
375void
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;
395 {
396 /* our typemap has changed in the meantime, do not
397 accept confirmation */
400 "# outdated typemap confirmations received"),
401 1,
402 GNUNET_NO);
404 "Got outdated typemap confirmated from peer `%s'\n",
405 GNUNET_i2s (session->peer));
406 return;
407 }
409 "Got typemap confirmation from peer `%s'\n",
410 GNUNET_i2s (session->peer));
411 if (NULL != session->typemap_task)
412 {
414 session->typemap_task = NULL;
415 }
418 "# valid typemap confirmations received"),
419 1,
420 GNUNET_NO);
421}
422
423
432static 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
453void
455{
456 /* notify new client about existing sessions */
459 client);
460}
461
462
469static void
470try_transmission (struct Session *session);
471
472
482void
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
517void
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
545static void
546solicit_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;
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
592static void
593pop_cork_task (void *cls)
594{
595 struct Session *session = cls;
596
597 session->cork_task = NULL;
598 try_transmission (session);
599}
600
601
609static void
610try_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 }
692 if (((GNUNET_YES == excess) || (maxpc >= GNUNET_MQ_PRIO_BEST_EFFORT)) &&
693 ((0 == msize) ||
695 (min_deadline.abs_value_us > now.abs_value_us))))
696 {
697 /* not enough ready yet (tiny message & cork possible), or no messages at all,
698 and either excess bandwidth or best-effort or higher message waiting at
699 client; in this case, we try to solicit more */
700 GNUNET_log (
702 "Soliciting messages (excess %d, maxpc %d, message size %u, deadline %s)\n",
703 excess,
704 maxpc,
705 (unsigned int) msize,
708 min_deadline),
709 GNUNET_YES));
710 solicit_messages (session, msize);
711 if (msize > 0)
712 {
713 /* if there is data to send, just not yet, make sure we do transmit
714 * it once the deadline is reached */
716 "Corking until %s\n",
719 GNUNET_YES));
720 if (NULL != session->cork_task)
722 session->cork_task =
723 GNUNET_SCHEDULER_add_at (min_deadline, &pop_cork_task, session);
724 }
725 else
726 {
728 "Queue empty, waiting for solicitations\n");
729 }
730 return;
731 }
733 "Building combined plaintext buffer to transmit message!\n");
734 /* create plaintext buffer of all messages (that fit), encrypt and
735 transmit */
736 {
737 static unsigned long long total_bytes;
738 static unsigned int total_msgs;
739 char pbuf[msize]; /* plaintext */
740 size_t used;
741
742 used = 0;
743 while ((NULL != (pos = session->sme_head)) && (used + pos->size <= msize))
744 {
746 "Adding message of type %d (%d/%d) to payload for %s\n",
747 ntohs (((const struct GNUNET_MessageHeader *) &pos[1])->type),
748 pos->is_typemap,
749 pos->is_typemap_confirm,
750 GNUNET_i2s (session->peer));
751 GNUNET_memcpy (&pbuf[used], &pos[1], pos->size);
752 used += pos->size;
753 GNUNET_CONTAINER_DLL_remove (session->sme_head, session->sme_tail, pos);
754 GNUNET_free (pos);
755 }
756 /* compute average payload size */
757 total_bytes += used;
758 total_msgs++;
759 if (0 == total_msgs)
760 {
761 /* 2^32 messages, wrap around... */
762 total_msgs = 1;
763 total_bytes = used;
764 }
766 "# avg payload per encrypted message",
767 total_bytes / total_msgs,
768 GNUNET_NO);
769 /* now actually transmit... */
770 GSC_KX_encrypt_and_transmit (session->kx, pbuf, used);
771 }
772}
773
774
784static 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
825void
827{
828 if (NULL == sessions)
829 return;
832 (void *) msg);
833}
834
835
843void
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
858void
860 const struct GNUNET_MessageHeader *msg,
861 enum GNUNET_MQ_PriorityPreferences priority)
862{
863 struct Session *session;
864 struct SessionMessageEntry *sme;
865 struct SessionMessageEntry *pos;
866 size_t msize;
867
868 session = find_session (&car->target);
869 if (NULL == session)
870 return;
871 msize = ntohs (msg->size);
872 sme = GNUNET_malloc (sizeof(struct SessionMessageEntry) + msize);
873 GNUNET_memcpy (&sme[1], msg, msize);
874 sme->size = msize;
875 sme->priority = priority;
877 {
878 sme->deadline =
881 "Message corked, delaying transmission\n");
882 }
883 pos = session->sme_head;
884 while ((NULL != pos) && (pos->priority >= sme->priority))
885 pos = pos->next;
886 if (NULL == pos)
888 session->sme_tail,
889 sme);
890 else
892 session->sme_tail,
893 pos->prev,
894 sme);
895 try_transmission (session);
896}
897
898
899void
901 const struct GNUNET_MessageHeader *msg)
902{
903 struct Session *session;
904 struct GSC_TypeMap *nmap;
905 struct SessionMessageEntry *sme;
906 struct TypeMapConfirmationMessage *tmc;
907
909 if (NULL == nmap)
910 {
911 GNUNET_break_op (0);
912 return; /* malformed */
913 }
914 session = find_session (peer);
915 if (NULL == session)
916 {
917 GSC_TYPEMAP_destroy (nmap);
918 GNUNET_break (0);
919 return;
920 }
922 "Received TYPEMAP from %s\n",
923 GNUNET_i2s (session->peer));
924 for (sme = session->sme_head; NULL != sme; sme = sme->next)
925 {
926 if (GNUNET_YES == sme->is_typemap_confirm)
927 {
928 GNUNET_CONTAINER_DLL_remove (session->sme_head, session->sme_tail, sme);
929 GNUNET_free (sme);
930 break;
931 }
932 }
933 sme = GNUNET_malloc (sizeof(struct SessionMessageEntry)
934 + sizeof(struct TypeMapConfirmationMessage));
936 sme->size = sizeof(struct TypeMapConfirmationMessage);
939 tmc = (struct TypeMapConfirmationMessage *) &sme[1];
940 tmc->header.size = htons (sizeof(struct TypeMapConfirmationMessage));
942 tmc->reserved = htonl (0);
943 GSC_TYPEMAP_hash (nmap, &tmc->tm_hash);
944 GNUNET_CONTAINER_DLL_insert (session->sme_head, session->sme_tail, sme);
945 try_transmission (session);
947 GSC_TYPEMAP_destroy (session->tmap);
948 session->tmap = nmap;
949}
950
951
960void
962 uint16_t type)
963{
964 struct Session *session;
965 struct GSC_TypeMap *nmap;
966
967 if (0 == memcmp (peer, &GSC_my_identity, sizeof(struct GNUNET_PeerIdentity)))
968 return;
969 session = find_session (peer);
970 GNUNET_assert (NULL != session);
971 if (GNUNET_YES == GSC_TYPEMAP_test_match (session->tmap, &type, 1))
972 return; /* already in it */
973 nmap = GSC_TYPEMAP_extend (session->tmap, &type, 1);
975 GSC_TYPEMAP_destroy (session->tmap);
976 session->tmap = nmap;
977}
978
979
983void
985{
987}
988
989
999static int
1001 const struct GNUNET_PeerIdentity *key,
1002 void *value)
1003{
1004 /* struct Session *session = value; */
1005
1007 return GNUNET_OK;
1008}
1009
1010
1014void
1016{
1017 if (NULL != sessions)
1018 {
1021 NULL);
1023 sessions = NULL;
1024 }
1025}
1026
1027
1028/* end of gnunet-service-core_sessions.c */
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
common internal definitions for core service
#define gettext_noop(String)
Definition: gettext.h:74
struct GNUNET_HashCode key
The key used in the DHT.
static char * value
Value of the record to add/remove.
static uint32_t type
Type string converted to DNS type value.
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...
struct GNUNET_PeerIdentity GSC_my_identity
Our identity.
void GSC_CLIENTS_reject_request(struct GSC_ClientActiveRequest *car, int drop_client)
We will never be ready to transmit the given message in (disconnect or invalid request).
struct GNUNET_STATISTICS_Handle * GSC_stats
For creating statistics.
void GSC_CLIENTS_solicit_request(struct GSC_ClientActiveRequest *car)
Tell a client that we are ready to receive the 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.
Globals for gnunet-service-core.
unsigned int GSC_NEIGHBOURS_get_queue_length(const struct GSC_KeyExchangeInfo *kxinfo)
Check how many messages are queued for the given neighbour.
int GSC_NEIGHBOURS_check_excess_bandwidth(const struct GSC_KeyExchangeInfo *kxinfo)
Check if the given neighbour has excess bandwidth available.
void GSC_KX_encrypt_and_transmit(struct GSC_KeyExchangeInfo *kx, const void *payload, size_t payload_size)
Encrypt and transmit a message with the given payload.
code for managing the key exchange (SET_KEY, PING, PONG) with other peers
void GSC_SESSIONS_dequeue_request(struct GSC_ClientActiveRequest *car)
Dequeue a request from a client from transmission to a particular peer.
static void transmit_typemap_task(void *cls)
Transmit our current typemap message to the other peer.
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 en...
static struct Session * find_session(const struct GNUNET_PeerIdentity *peer)
Find the session for the given peer.
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.
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).
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.
void GSC_SESSIONS_transmit(struct GSC_ClientActiveRequest *car, const struct GNUNET_MessageHeader *msg, enum GNUNET_MQ_PriorityPreferences priority)
Transmit a message to a particular peer.
void GSC_SESSIONS_add_to_typemap(const struct GNUNET_PeerIdentity *peer, uint16_t type)
The given peer send a message of the specified type.
void GSC_SESSIONS_end(const struct GNUNET_PeerIdentity *pid)
End the session with the given peer (we are no longer connected).
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_solicit(const struct GNUNET_PeerIdentity *pid)
Traffic is being solicited for the given peer.
void GSC_SESSIONS_notify_client_about_sessions(struct GSC_Client *client)
We have a new client, notify it about all current sessions.
static void pop_cork_task(void *cls)
Some messages were delayed (corked), but the timeout has now expired.
static void try_transmission(struct Session *session)
Try to perform a transmission on the given session.
static GNUNET_NETWORK_STRUCT_END struct GNUNET_CONTAINER_MultiPeerMap * sessions
Map of peer identities to struct Session.
static void solicit_messages(struct Session *session, size_t msize)
Solicit messages for transmission, starting with those of the highest priority.
void GSC_SESSIONS_init()
Initialize sessions subsystem.
#define MAX_ENCRYPTED_MESSAGE_QUEUE_SIZE
How many encrypted messages do we queue at most? Needed to bound memory consumption.
void GSC_SESSIONS_broadcast_typemap(const struct GNUNET_MessageHeader *msg)
Broadcast an updated typemap message to all neighbours.
void GSC_SESSIONS_create(const struct GNUNET_PeerIdentity *peer, struct GSC_KeyExchangeInfo *kx)
Create a session, a key exchange was just completed.
void GSC_SESSIONS_set_typemap(const struct GNUNET_PeerIdentity *peer, const struct GNUNET_MessageHeader *msg)
We've received a typemap message from a peer, update ours.
static void start_typemap_task(struct Session *session)
Restart the typemap task for the given session.
void GSC_SESSIONS_queue_request(struct GSC_ClientActiveRequest *car)
Queue a request from a client for transmission to a particular peer.
void GSC_SESSIONS_done()
Shutdown sessions subsystem.
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.
void GSC_TYPEMAP_destroy(struct GSC_TypeMap *tmap)
Free the given type map.
int GSC_TYPEMAP_check_hash(const struct GNUNET_HashCode *hc)
Check if the given hash matches our current type map.
struct GSC_TypeMap * GSC_TYPEMAP_create()
Create an empty type map.
struct GSC_TypeMap * GSC_TYPEMAP_get_from_message(const struct GNUNET_MessageHeader *msg)
Extract a type map from a TYPE_MAP message.
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 GNUNET_MessageHeader * GSC_TYPEMAP_compute_type_map_message()
Compute a type map message for this peer.
void GSC_TYPEMAP_hash(const struct GSC_TypeMap *tm, struct GNUNET_HashCode *hc)
Hash the contents of a type map.
management of map that specifies which message types this peer supports
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)?
#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...
uint32_t GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i)
Produce a random value.
@ GNUNET_CRYPTO_QUALITY_WEAK
No good quality of the operation is needed (i.e., random numbers can be pseudo-random).
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_CONTAINER_DLL_insert_after(head, tail, other, element)
Insert an element into a DLL after the given other element.
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
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.
void GNUNET_CONTAINER_multipeermap_destroy(struct GNUNET_CONTAINER_MultiPeerMap *map)
Destroy a hash map.
int GNUNET_CONTAINER_multipeermap_iterate(struct GNUNET_CONTAINER_MultiPeerMap *map, GNUNET_CONTAINER_PeerMapIterator it, void *it_cls)
Iterate over all entries in the map.
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).
unsigned int GNUNET_CONTAINER_multipeermap_size(const struct GNUNET_CONTAINER_MultiPeerMap *map)
Get the number of key-value pairs in the map.
int GNUNET_CONTAINER_multipeermap_put(struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multipeermap_remove(struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key, const void *value)
Remove the given key-value pair from the map.
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY
There must only be one value per key; storing a value should fail if a value under the same key alrea...
#define GNUNET_NETWORK_STRUCT_BEGIN
Define as empty, GNUNET_PACKED should suffice, but this won't work on W32.
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
#define GNUNET_log(kind,...)
#define GNUNET_MAX(a, b)
#define GNUNET_NETWORK_STRUCT_END
Define as empty, GNUNET_PACKED should suffice, but this won't work on W32;.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
#define GNUNET_PACKED
gcc-ism to get packed structs.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
@ GNUNET_ERROR_TYPE_DEBUG
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
GNUNET_MQ_PriorityPreferences
Per envelope preferences and priorities.
@ GNUNET_MQ_PRIO_CRITICAL_CONTROL
Highest priority, control traffic (e.g.
@ GNUNET_MQ_PRIORITY_MASK
Bit mask to apply to extract the priority bits.
@ GNUNET_MQ_PRIO_BACKGROUND
Lowest priority, i.e.
@ GNUNET_MQ_PREF_CORK_ALLOWED
Flag to indicate that CORKing is acceptable.
@ GNUNET_MQ_PRIO_BEST_EFFORT
Best-effort traffic (e.g.
#define GNUNET_MESSAGE_TYPE_CORE_CONFIRM_TYPE_MAP
Other peer confirms having received the type map.
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:1254
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:980
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:1277
void GNUNET_STATISTICS_set(struct GNUNET_STATISTICS_Handle *handle, const char *name, uint64_t value, int make_persistent)
Set statistic value for the peer.
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
#define GNUNET_TIME_UNIT_SECONDS
One second.
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_remaining(struct GNUNET_TIME_Absolute future)
Given a timestamp in the future, how much time remains until then?
Definition: time.c:406
const char * GNUNET_STRINGS_relative_time_to_string(struct GNUNET_TIME_Relative delta, int do_round)
Give relative time in human-readable fancy format.
Definition: strings.c:579
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:111
struct GNUNET_TIME_Absolute GNUNET_TIME_relative_to_absolute(struct GNUNET_TIME_Relative rel)
Convert relative time to an absolute time in the future.
Definition: time.c:316
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_min(struct GNUNET_TIME_Absolute t1, struct GNUNET_TIME_Absolute t2)
Return the minimum of two absolute time values.
Definition: time.c:360
#define GNUNET_TIME_UNIT_FOREVER_ABS
Constant used to specify "forever".
#define GNUNET_TIME_STD_BACKOFF(r)
Perform our standard exponential back-off calculation, starting at 1 ms and then going by a factor of...
static unsigned int size
Size of the "table".
Definition: peer.c:68
Internal representation of the hash map.
A 512-bit hashcode.
Header for all communications.
The identity of the host (wraps the signing key of the peer).
Entry in list of pending tasks.
Definition: scheduler.c:136
Time for absolute times used by GNUnet, in microseconds.
uint64_t abs_value_us
The actual value.
Time for relative time used by GNUnet, in microseconds.
uint64_t rel_value_us
The actual value.
Record kept for each request for transmission issued by a client that is still pending.
struct GSC_ClientActiveRequest * next
Active requests are kept in a doubly-linked list of the respective target peer.
struct GNUNET_PeerIdentity target
Which peer is the message going to be for?
int was_solicited
Has this request been solicited yet?
uint16_t msize
How many bytes does the client intend to send?
enum GNUNET_MQ_PriorityPreferences priority
How important is this request.
Data structure for each client connected to the CORE service.
struct GNUNET_SERVICE_Client * client
Handle for the client with the server API.
Information about the status of a key exchange with another peer.
A type map describing which messages a given neighbour is able to process.
Message ready for encryption.
struct GNUNET_TIME_Absolute deadline
Deadline for transmission, 1s after we received it (if we are not corking), otherwise "now".
int is_typemap_confirm
Flag set to GNUNET_YES if this is a typemap confirmation message.
size_t size
How long is the message? (number of bytes following the struct MessageEntry, but not including the si...
struct SessionMessageEntry * next
We keep messages in a doubly linked list.
struct SessionMessageEntry * prev
We keep messages in a doubly linked list.
int is_typemap
Flag set to GNUNET_YES if this is a typemap message.
enum GNUNET_MQ_PriorityPreferences priority
How important is this message.
Data kept per session.
struct SessionMessageEntry * sme_head
Head of list of messages ready for encryption.
struct SessionMessageEntry * sme_tail
Tail of list of messages ready for encryption.
struct GSC_TypeMap * tmap
Current type map for this peer.
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.
struct GSC_ClientActiveRequest * active_client_request_head
Head of list of requests from clients for transmission to this peer.
struct GNUNET_SCHEDULER_Task * typemap_task
Task to transmit our type map.
struct GNUNET_SCHEDULER_Task * cork_task
Task to transmit corked messages with a delay.
int first_typemap
Is this the first time we're sending the typemap? If so, we want to send it a bit faster the second t...
struct GSC_KeyExchangeInfo * kx
Key exchange state for this peer.
struct GSC_ClientActiveRequest * active_client_request_tail
Tail of list of requests from clients for transmission to this peer.
Message sent to confirm that a typemap was received.
struct GNUNET_HashCode tm_hash
Hash of the (decompressed) type map that was received.
uint32_t reserved
Reserved, always zero.
struct GNUNET_MessageHeader header
Header with type GNUNET_MESSAGE_TYPE_CORE_CONFIRM_TYPE_MAP.