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

API to handle 'connected peers'. More...

Include dependency graph for gnunet-service-fs_cp.c:

Go to the source code of this file.

Data Structures

struct  GSF_PeerTransmitHandle
 Handle to cancel a transmission request. More...
 
struct  GSF_DelayedHandle
 Handle for an entry in our delay list. More...
 
struct  PeerRequest
 Information per peer and request. More...
 
struct  GSF_ConnectedPeer
 A connected peer. More...
 
struct  TestExistClosure
 Closure for test_exist_cb(). More...
 
struct  IterationContext
 Closure for call_iterator(). More...
 

Macros

#define RUNAVG_DELAY_N   16
 Ratio for moving average delay calculation.
 
#define RESPECT_FLUSH_FREQ
 How often do we flush respect values to disk?
 
#define REPLY_TIMEOUT
 After how long do we discard a reply?
 
#define INSANE_STATISTICS   GNUNET_NO
 Collect an instance number of statistics? May cause excessive IPC.
 
#define N   ((double) 128.0)
 

Functions

void GSF_update_peer_latency_ (const struct GNUNET_PeerIdentity *id, struct GNUNET_TIME_Relative latency)
 Update the latency information kept for the given peer.
 
struct GSF_PeerPerformanceDataGSF_get_peer_performance_data_ (struct GSF_ConnectedPeer *cp)
 Return the performance data record for the given peer.
 
static void peer_transmit (struct GSF_ConnectedPeer *cp)
 Core is ready to transmit to a peer, get the message.
 
static void schedule_transmission (struct GSF_PeerTransmitHandle *pth)
 If ready (bandwidth reserved), try to schedule transmission via core for the given handle.
 
static void peer_respect_cb (void *cls, const struct GNUNET_PEERSTORE_Record *record, const char *emsg)
 Function called by PEERSTORE with peer respect record.
 
static int consider_peer_for_forwarding (void *cls, const struct GNUNET_HashCode *key, struct GSF_PendingRequest *pr)
 Function called for each pending request whenever a new peer connects, giving us a chance to decide about submitting the existing request to the new peer.
 
void * GSF_peer_connect_handler (void *cls, const struct GNUNET_PeerIdentity *peer, struct GNUNET_MQ_Handle *mq, enum GNUNET_CORE_PeerClass class)
 A peer connected to us.
 
static void revive_migration (void *cls)
 It may be time to re-start migrating content to this peer.
 
struct GSF_ConnectedPeerGSF_peer_get_ (const struct GNUNET_PeerIdentity *peer)
 Get a handle for a connected peer.
 
void handle_p2p_migration_stop (void *cls, const struct MigrationStopMessage *msm)
 Handle P2P GNUNET_MESSAGE_TYPE_FS_MIGRATION_STOP message.
 
static void free_pending_request (struct PeerRequest *peerreq)
 Free resources associated with the given peer request.
 
static int cancel_pending_request (void *cls, const struct GNUNET_HashCode *query, void *value)
 Cancel all requests associated with the peer.
 
static void peer_request_destroy (void *cls)
 Free the given request.
 
static void transmit_delayed_now (void *cls)
 The artificial delay is over, transmit the message now.
 
static struct GNUNET_TIME_Relative get_randomized_delay ()
 Get the randomized delay a response should be subjected to.
 
static void handle_p2p_reply (void *cls, enum GNUNET_BLOCK_ReplyEvaluationResult eval, struct GSF_PendingRequest *pr, uint32_t reply_anonymity_level, struct GNUNET_TIME_Absolute expiration, struct GNUNET_TIME_Absolute last_transmission, enum GNUNET_BLOCK_Type type, const void *data, size_t data_len)
 Handle a reply to a pending request.
 
static int change_peer_respect (struct GSF_ConnectedPeer *cp, int value)
 Increase the peer's respect by a value.
 
static int32_t bound_priority (uint32_t prio_in, struct GSF_ConnectedPeer *cp)
 We've received a request with the specified priority.
 
static int32_t bound_ttl (int32_t ttl_in, uint32_t prio)
 The priority level imposes a bound on the maximum value for the ttl that can be requested.
 
static int test_exist_cb (void *cls, const struct GNUNET_HashCode *hc, void *value)
 Test if the query already exists.
 
void handle_p2p_get (void *cls, const struct GetMessage *gm)
 Handle P2P "QUERY" message.
 
void GSF_peer_transmit_ (struct GSF_ConnectedPeer *cp, int is_query, uint32_t priority, struct GNUNET_MQ_Envelope *env)
 Transmit a message to the given peer as soon as possible.
 
void GSF_peer_update_performance_ (struct GSF_ConnectedPeer *cp, struct GNUNET_TIME_Absolute request_time, uint32_t request_priority)
 Report on receiving a reply; update the performance record of the given peer.
 
void GSF_peer_update_responder_client_ (struct GSF_ConnectedPeer *cp, struct GSF_LocalClient *initiator_client)
 Report on receiving a reply in response to an initiating client.
 
void GSF_peer_update_responder_peer_ (struct GSF_ConnectedPeer *cp, const struct GSF_ConnectedPeer *initiator_peer)
 Report on receiving a reply in response to an initiating peer.
 
static int flush_respect (void *cls, const struct GNUNET_PeerIdentity *key, void *value)
 Write peer-respect information to a file - flush the buffer entry!
 
void GSF_peer_disconnect_handler (void *cls, const struct GNUNET_PeerIdentity *peer, void *internal_cls)
 A peer disconnected from us.
 
static int call_iterator (void *cls, const struct GNUNET_PeerIdentity *key, void *value)
 Function that calls the callback for each peer.
 
void GSF_iterate_connected_peers_ (GSF_ConnectedPeerIterator it, void *it_cls)
 Iterate over all connected peers.
 
void GSF_connected_peer_get_identity_ (const struct GSF_ConnectedPeer *cp, struct GNUNET_PeerIdentity *id)
 Obtain the identity of a connected peer.
 
const struct GNUNET_PeerIdentityGSF_connected_peer_get_identity2_ (const struct GSF_ConnectedPeer *cp)
 Obtain the identity of a connected peer.
 
void GSF_block_peer_migration_ (struct GSF_ConnectedPeer *cp, struct GNUNET_TIME_Absolute block_time)
 Ask a peer to stop migrating data to us until the given point in time.
 
void GSF_connected_peer_change_preference_ (struct GSF_ConnectedPeer *cp, uint64_t pref)
 Notify core about a preference we have for the given peer (to allocate more resources towards it).
 
static void cron_flush_respect (void *cls)
 Call this method periodically to flush respect information to disk.
 
void GSF_connected_peer_init_ ()
 Initialize peer management subsystem.
 
void GSF_connected_peer_done_ ()
 Shutdown peer management subsystem.
 
static int clean_local_client (void *cls, const struct GNUNET_PeerIdentity *key, void *value)
 Iterator to remove references to LC entry.
 
void GSF_handle_local_client_disconnect_ (const struct GSF_LocalClient *lc)
 Notification that a local client disconnected.
 

Variables

static struct GNUNET_CONTAINER_MultiPeerMapcp_map
 Map from peer identities to struct GSF_ConnectPeer entries.
 
static struct GNUNET_PEERSTORE_Handlepeerstore
 Handle to peerstore service.
 
static struct GNUNET_SCHEDULER_Taskfr_task
 Task used to flush respect values to disk.
 

Detailed Description

API to handle 'connected peers'.

Author
Christian Grothoff

Definition in file gnunet-service-fs_cp.c.

Macro Definition Documentation

◆ RUNAVG_DELAY_N

#define RUNAVG_DELAY_N   16

Ratio for moving average delay calculation.

The previous average goes in with a factor of (n-1) into the calculation. Must be > 0.

Definition at line 43 of file gnunet-service-fs_cp.c.

◆ RESPECT_FLUSH_FREQ

#define RESPECT_FLUSH_FREQ
Value:
#define GNUNET_TIME_UNIT_MINUTES
One minute.
struct GNUNET_TIME_Relative GNUNET_TIME_relative_multiply(struct GNUNET_TIME_Relative rel, unsigned long long factor)
Multiply relative time by a given factor.
Definition time.c:486

How often do we flush respect values to disk?

Definition at line 48 of file gnunet-service-fs_cp.c.

66{
71
76
80 struct GNUNET_TIME_Absolute transmission_request_start_time;
81
85 struct GNUNET_MQ_Envelope *env;
86
90 struct GSF_ConnectedPeer *cp;
91
95 int is_query;
96
100 uint32_t priority;
101};
102
103
108{
112 struct GSF_DelayedHandle *next;
113
117 struct GSF_DelayedHandle *prev;
118
122 struct GSF_ConnectedPeer *cp;
123
127 struct GNUNET_MQ_Envelope *env;
128
133
137 size_t msize;
138};
139
140
144struct PeerRequest
145{
149 struct GSF_PendingRequest *pr;
150
154 struct GSF_ConnectedPeer *cp;
155
160};
161
162
167{
172
178
183
189
195
201
207
212
217
222 struct GNUNET_MQ_Handle *mq;
223
228 uint64_t inc_preference;
229
233 unsigned int delay_queue_size;
234
238 uint32_t disk_respect;
239
244 unsigned int last_p2p_replies_woff;
245
250 unsigned int last_client_replies_woff;
251
255 unsigned int last_request_times_off;
256
261};
262
263
268
273
277static struct GNUNET_SCHEDULER_Task *fr_task;
278
279
286void
288 struct GNUNET_TIME_Relative latency)
289{
290 struct GSF_ConnectedPeer *cp;
291
292 cp = GSF_peer_get_ (id);
293 if (NULL == cp)
294 return; /* we're not yet connected at the core level, ignore */
296 latency);
297}
298
299
308{
309 return &cp->ppd;
310}
311
312
318static void
320
321
328static void
330{
331 struct GSF_ConnectedPeer *cp;
332 struct GNUNET_PeerIdentity target;
333
334 cp = pth->cp;
335 GNUNET_assert (0 != cp->ppd.pid);
336 GNUNET_PEER_resolve (cp->ppd.pid, &target);
337
338 peer_transmit (cp);
339}
340
341
347static void
349{
350 struct GSF_PeerTransmitHandle *pth = cp->pth_head;
351 struct GSF_PeerTransmitHandle *pos;
352
353 if (NULL == pth)
354 return;
356 cp->pth_tail,
357 pth);
358 if (GNUNET_YES == pth->is_query)
359 {
364 }
365 else if (GNUNET_NO == pth->is_query)
366 {
368 }
373 pth->env);
374 GNUNET_free (pth);
375 if (NULL != (pos = cp->pth_head))
376 {
377 GNUNET_assert (pos != pth);
379 }
380}
381
382
390static void
391peer_respect_cb (void *cls,
392 const struct GNUNET_PEERSTORE_Record *record,
393 const char *emsg)
394{
395 struct GSF_ConnectedPeer *cp = cls;
396
398 if (NULL == record)
399 {
400 /* A NULL record ends the iteration and releases the context, with or
401 without an @a emsg. Testing for `NULL == emsg' as well meant the
402 error case fell through to the GNUNET_PEERSTORE_iteration_next()
403 below and left @e respect_iterate_req dangling. */
404 if (NULL != emsg)
406 "Failed to read respect value from PEERSTORE: %s\n",
407 emsg);
408 cp->respect_iterate_req = NULL;
409 return;
410 }
411 if ((NULL != record) &&
412 (sizeof(cp->disk_respect) == record->value_size))
413 {
414 cp->disk_respect = *((uint32_t *) record->value);
415 cp->ppd.respect += *((uint32_t *) record->value);
416 }
417 GSF_push_start_ (cp);
418 if (NULL != record)
419 {
421 cp->respect_iterate_req = NULL;
422 return;
423 }
425}
426
427
438static int
440 const struct GNUNET_HashCode *key,
441 struct GSF_PendingRequest *pr)
442{
443 struct GSF_ConnectedPeer *cp = cls;
444 struct GNUNET_PeerIdentity pid;
445
446 if (GNUNET_YES !=
448 return GNUNET_YES; /* request is not actually active, skip! */
450 if (GNUNET_YES !=
452 {
454 gettext_noop ("# Loopback routes suppressed"),
455 1,
456 GNUNET_NO);
457 return GNUNET_YES;
458 }
459 GSF_plan_add_ (cp, pr);
460 return GNUNET_YES;
461}
462
463
464void *
465GSF_peer_connect_handler (void *cls,
466 const struct GNUNET_PeerIdentity *peer,
467 struct GNUNET_MQ_Handle *mq,
468 enum GNUNET_CORE_PeerClass class)
469{
470 const struct GNUNET_PeerIdentity *my_identity;
471 struct GSF_ConnectedPeer *cp;
472
475
476 if (0 == GNUNET_memcmp (my_identity, peer))
477 return NULL;
479 "Connected to peer %s\n",
480 GNUNET_i2s (peer));
481 cp = GNUNET_new (struct GSF_ConnectedPeer);
482 cp->ppd.pid = GNUNET_PEER_intern (peer);
483 cp->ppd.peer = peer;
484 cp->mq = mq;
486
488 GNUNET_YES);
492 (
493 cp),
494 cp,
497 gettext_noop ("# peers connected"),
499 GNUNET_NO);
502 "fs",
503 peer,
504 "respect",
506 cp);
508 cp);
509 return cp;
510}
511
512
519static void
520revive_migration (void *cls)
521{
522 struct GSF_ConnectedPeer *cp = cls;
523 struct GNUNET_TIME_Relative bt;
524
525 cp->mig_revive_task = NULL;
527 if (0 != bt.rel_value_us)
528 {
529 /* still time left... */
530 cp->mig_revive_task =
532 return;
533 }
534 GSF_push_start_ (cp);
535}
536
537
538struct GSF_ConnectedPeer *
539GSF_peer_get_ (const struct GNUNET_PeerIdentity *peer)
540{
541 if (NULL == cp_map)
542 return NULL;
544}
545
546
553void
555 const struct MigrationStopMessage *msm)
556{
557 struct GSF_ConnectedPeer *cp = cls;
558 struct GNUNET_TIME_Relative bt;
559
561 gettext_noop ("# migration stop messages received"),
562 1, GNUNET_NO);
565 _ ("Migration of content to peer `%s' blocked for %s\n"),
566 GNUNET_i2s (cp->ppd.peer),
569 if ((NULL == cp->mig_revive_task) &&
570 (NULL == cp->respect_iterate_req))
571 {
572 GSF_push_stop_ (cp);
573 cp->mig_revive_task =
575 &revive_migration, cp);
576 }
577}
578
579
585static void
586free_pending_request (struct PeerRequest *peerreq)
587{
588 struct GSF_ConnectedPeer *cp = peerreq->cp;
589 struct GSF_PendingRequestData *prd;
590
591 prd = GSF_pending_request_get_data_ (peerreq->pr);
592 if (NULL != peerreq->kill_task)
593 {
595 peerreq->kill_task = NULL;
596 }
598 gettext_noop ("# P2P searches active"),
599 -1,
600 GNUNET_NO);
603 &prd->query,
604 peerreq));
605 GNUNET_free (peerreq);
606}
607
608
617static int
618cancel_pending_request (void *cls,
619 const struct GNUNET_HashCode *query,
620 void *value)
621{
622 struct PeerRequest *peerreq = value;
623 struct GSF_PendingRequest *pr = peerreq->pr;
624
625 free_pending_request (peerreq);
627 GNUNET_NO);
628 return GNUNET_OK;
629}
630
631
637static void
638peer_request_destroy (void *cls)
639{
640 struct PeerRequest *peerreq = cls;
641 struct GSF_PendingRequest *pr = peerreq->pr;
642 struct GSF_PendingRequestData *prd;
643
644 peerreq->kill_task = NULL;
647 &prd->query,
648 peerreq);
649}
650
651
657static void
658transmit_delayed_now (void *cls)
659{
660 struct GSF_DelayedHandle *dh = cls;
661 struct GSF_ConnectedPeer *cp = dh->cp;
662
664 cp->delayed_tail,
665 dh);
666 cp->delay_queue_size--;
668 GNUNET_NO,
669 UINT32_MAX,
670 dh->env);
671 GNUNET_free (dh);
672}
673
674
680static struct GNUNET_TIME_Relative
682{
684
685 ret =
688 (2 * GSF_avg_latency.rel_value_us + 1));
689#if INSANE_STATISTICS
692 ("# artificial delays introduced (ms)"),
693 ret.rel_value_us / 1000LL, GNUNET_NO);
694#endif
695 return ret;
696}
697
698
717static void
718handle_p2p_reply (void *cls,
720 struct GSF_PendingRequest *pr,
721 uint32_t reply_anonymity_level,
723 struct GNUNET_TIME_Absolute last_transmission,
725 const void *data,
726 size_t data_len)
727{
728 struct PeerRequest *peerreq = cls;
729 struct GSF_ConnectedPeer *cp = peerreq->cp;
730 struct GSF_PendingRequestData *prd;
731 struct GNUNET_MQ_Envelope *env;
732 struct PutMessage *pm;
733 size_t msize;
734
735 GNUNET_assert (data_len + sizeof(struct PutMessage) <
737 GNUNET_assert (peerreq->pr == pr);
739 if (NULL == data)
740 {
741 free_pending_request (peerreq);
742 return;
743 }
745 if ( (prd->type != type) &&
746 (GNUNET_BLOCK_TYPE_ANY != prd->type) )
747 {
749 "# replies dropped due to type mismatch",
750 1, GNUNET_NO);
751 return;
752 }
754 "Transmitting result for query `%s' to peer\n",
755 GNUNET_h2s (&prd->query));
757 "# replies received for other peers",
758 1,
759 GNUNET_NO);
760 msize = sizeof(struct PutMessage) + data_len;
761 if (msize >= GNUNET_MAX_MESSAGE_SIZE)
762 {
763 GNUNET_break (0);
764 return;
765 }
766 if ( (UINT32_MAX != reply_anonymity_level) &&
767 (reply_anonymity_level > 1) )
768 {
769 if (reply_anonymity_level - 1 > GSF_cover_content_count)
770 {
772 "# replies dropped due to insufficient cover traffic",
773 1, GNUNET_NO);
774 return;
775 }
776 GSF_cover_content_count -= (reply_anonymity_level - 1);
777 }
778
780 data_len,
782 pm->type = htonl (type);
784 GNUNET_memcpy (&pm[1],
785 data,
786 data_len);
787 if ((UINT32_MAX != reply_anonymity_level) &&
788 (0 != reply_anonymity_level) &&
790 {
791 struct GSF_DelayedHandle *dh;
792
793 dh = GNUNET_new (struct GSF_DelayedHandle);
794 dh->cp = cp;
795 dh->env = env;
796 dh->msize = msize;
799 dh);
801 dh->delay_task =
804 dh);
805 }
806 else
807 {
809 GNUNET_NO,
810 UINT32_MAX,
811 env);
812 }
813 if (GNUNET_BLOCK_REPLY_OK_LAST != eval)
814 return;
815 if (NULL == peerreq->kill_task)
816 {
818 "# P2P searches destroyed due to ultimate reply",
819 1,
820 GNUNET_NO);
821 peerreq->kill_task =
823 peerreq);
824 }
825}
826
827
836static int
838{
839 if (0 == value)
840 return 0;
841 GNUNET_assert (NULL != cp);
842 if (value > 0)
843 {
844 if (cp->ppd.respect + value < cp->ppd.respect)
845 {
846 value = UINT32_MAX - cp->ppd.respect;
847 cp->ppd.respect = UINT32_MAX;
848 }
849 else
850 cp->ppd.respect += value;
851 }
852 else
853 {
854 if (cp->ppd.respect < -value)
855 {
856 value = -cp->ppd.respect;
857 cp->ppd.respect = 0;
858 }
859 else
860 cp->ppd.respect += value;
861 }
862 return value;
863}
864
865
874static int32_t
875bound_priority (uint32_t prio_in,
876 struct GSF_ConnectedPeer *cp)
877{
878#define N ((double) 128.0)
879 uint32_t ret;
880 double rret;
881 int ld;
882
884 if (GNUNET_SYSERR == ld)
885 {
886#if INSANE_STATISTICS
889 ("# requests done for free (low load)"), 1,
890 GNUNET_NO);
891#endif
892 return 0; /* excess resources */
893 }
894 if (prio_in > INT32_MAX)
895 prio_in = INT32_MAX;
896 ret = -change_peer_respect (cp, -(int) prio_in);
897 if (ret > 0)
898 {
900 rret = GSF_current_priorities + N;
901 else
902 rret = ret;
904 }
905 if ((GNUNET_YES == ld) && (ret > 0))
906 {
907 /* try with charging */
909 }
910 if (GNUNET_YES == ld)
911 {
914 ("# request dropped, priority insufficient"), 1,
915 GNUNET_NO);
916 /* undo charge */
917 change_peer_respect (cp, (int) ret);
918 return -1; /* not enough resources */
919 }
920 else
921 {
924 ("# requests done for a price (normal load)"),
925 1,
926 GNUNET_NO);
927 }
928#undef N
929 return ret;
930}
931
932
942static int32_t
943bound_ttl (int32_t ttl_in,
944 uint32_t prio)
945{
946 unsigned long long allowed;
947
948 if (ttl_in <= 0)
949 return ttl_in;
950 allowed = ((unsigned long long) prio) * TTL_DECREMENT / 1000;
951 if (ttl_in > allowed)
952 {
953 if (allowed >= (1 << 30))
954 return 1 << 30;
955 return allowed;
956 }
957 return ttl_in;
958}
959
960
964struct TestExistClosure
965{
969 int32_t priority;
970
974 int32_t ttl;
975
980
984 int finished;
985};
986
987
998static int
999test_exist_cb (void *cls,
1000 const struct GNUNET_HashCode *hc,
1001 void *value)
1002{
1003 struct TestExistClosure *tec = cls;
1004 struct PeerRequest *peerreq = value;
1005 struct GSF_PendingRequest *pr;
1006 struct GSF_PendingRequestData *prd;
1007
1008 pr = peerreq->pr;
1010 if (prd->type != tec->type)
1011 return GNUNET_YES;
1012 if (prd->ttl.abs_value_us >=
1013 GNUNET_TIME_absolute_get ().abs_value_us + tec->ttl * 1000LL)
1014 {
1015 /* existing request has higher TTL, drop new one! */
1016 prd->priority += tec->priority;
1018 "Have existing request with higher TTL, dropping new request.\n");
1021 ("# requests dropped due to higher-TTL request")
1022 ,
1023 1, GNUNET_NO);
1024 tec->finished = GNUNET_YES;
1025 return GNUNET_NO;
1026 }
1027 /* existing request has lower TTL, drop old one! */
1028 tec->priority += prd->priority;
1029 free_pending_request (peerreq);
1031 GNUNET_YES);
1032 return GNUNET_NO;
1033}
1034
1035
1045void
1046handle_p2p_get (void *cls,
1047 const struct GetMessage *gm)
1048{
1049 struct GSF_ConnectedPeer *cps = cls;
1050 struct PeerRequest *peerreq;
1051 struct GSF_PendingRequest *pr;
1052 struct GSF_ConnectedPeer *cp;
1053 const struct GNUNET_PeerIdentity *target;
1055 uint16_t msize;
1056 unsigned int bits;
1057 const struct GNUNET_PeerIdentity *opt;
1058 uint32_t bm;
1059 size_t bfsize;
1060 uint32_t ttl_decrement;
1061 struct TestExistClosure tec;
1062 GNUNET_PEER_Id spid;
1063 const struct GSF_PendingRequestData *prd;
1064
1065 msize = ntohs (gm->header.size);
1066 tec.type = ntohl (gm->type);
1067 bm = ntohl (gm->hash_bitmap);
1068 bits = 0;
1069 while (bm > 0)
1070 {
1071 if (1 == (bm & 1))
1072 bits++;
1073 bm >>= 1;
1074 }
1075 opt = (const struct GNUNET_PeerIdentity *) &gm[1];
1076 bfsize = msize - sizeof(struct GetMessage) - bits * sizeof(struct
1080 ("# GET requests received (from other peers)"),
1081 1,
1082 GNUNET_NO);
1084 bm = ntohl (gm->hash_bitmap);
1085 bits = 0;
1086 if (0 != (bm & GET_MESSAGE_BIT_RETURN_TO))
1087 cp = GSF_peer_get_ (&opt[bits++]);
1088 else
1089 cp = cps;
1090 if (NULL == cp)
1091 {
1092 if (0 != (bm & GET_MESSAGE_BIT_RETURN_TO))
1094 "Failed to find RETURN-TO peer `%s' in connection set. Dropping query.\n",
1095 GNUNET_i2s (&opt[bits - 1]));
1096
1097 else
1099 "Failed to find peer `%s' in connection set. Dropping query.\n",
1100 GNUNET_i2s (cps->ppd.peer));
1103 (
1104 "# requests dropped due to missing reverse route"),
1105 1,
1106 GNUNET_NO);
1107 return;
1108 }
1109 unsigned int queue_size = GNUNET_MQ_get_length (cp->mq);
1110 queue_size += cp->ppd.pending_replies + cp->delay_queue_size;
1111 if (queue_size > MAX_QUEUE_PER_PEER)
1112 {
1114 "Peer `%s' has too many replies queued already. Dropping query.\n",
1115 GNUNET_i2s (cps->ppd.peer));
1117 gettext_noop (
1118 "# requests dropped due to full reply queue"),
1119 1,
1120 GNUNET_NO);
1121 return;
1122 }
1123 /* note that we can really only check load here since otherwise
1124 * peers could find out that we are overloaded by not being
1125 * disconnected after sending us a malformed query... */
1126 tec.priority = bound_priority (ntohl (gm->priority),
1127 cps);
1128 if (tec.priority < 0)
1129 {
1131 "Dropping query from `%s', this peer is too busy.\n",
1132 GNUNET_i2s (cps->ppd.peer));
1133 return;
1134 }
1136 "Received request for `%s' of type %u from peer `%s' with flags %u\n",
1137 GNUNET_h2s (&gm->query),
1138 (unsigned int) tec.type,
1139 GNUNET_i2s (cps->ppd.peer),
1140 (unsigned int) bm);
1141 target =
1142 (0 !=
1143 (bm & GET_MESSAGE_BIT_TRANSMIT_TO)) ? (&opt[bits++]) : NULL;
1145 spid = 0;
1146 if ((GNUNET_LOAD_get_load (cp->ppd.transmission_delay) > 3 * (1
1147 + tec.priority))
1149 GNUNET_CONSTANTS_MAX_CORK_DELAY.rel_value_us * 2
1151 {
1152 /* don't have BW to send to peer, or would likely take longer than we have for it,
1153 * so at best indirect the query */
1154 tec.priority = 0;
1156 spid = GNUNET_PEER_intern (cps->ppd.peer);
1157 GNUNET_assert (0 != spid);
1158 }
1159 tec.ttl = bound_ttl (ntohl (gm->ttl),
1160 tec.priority);
1161 /* decrement ttl (always) */
1162 ttl_decrement =
1164 if ((tec.ttl < 0) &&
1165 (((int32_t) (tec.ttl - ttl_decrement)) > 0))
1166 {
1168 "Dropping query from `%s' due to TTL underflow (%d - %u).\n",
1169 GNUNET_i2s (cps->ppd.peer),
1170 tec.ttl,
1171 ttl_decrement);
1174 ("# requests dropped due TTL underflow"), 1,
1175 GNUNET_NO);
1176 /* integer underflow => drop (should be very rare)! */
1177 return;
1178 }
1179 tec.ttl -= ttl_decrement;
1180
1181 /* test if the request already exists */
1182 tec.finished = GNUNET_NO;
1184 &gm->query,
1186 &tec);
1187 if (GNUNET_YES == tec.finished)
1188 return; /* merged into existing request, we're done */
1189
1190 peerreq = GNUNET_new (struct PeerRequest);
1191 peerreq->cp = cp;
1193 tec.type,
1194 &gm->query,
1195 target,
1196 (bfsize > 0)
1197 ? (const char *) &opt[bits]
1198 : NULL,
1199 bfsize,
1200 1 /* anonymity */,
1201 (uint32_t) tec.priority,
1202 tec.ttl,
1203 spid,
1204 GNUNET_PEER_intern (cps->ppd.peer),
1205 NULL, 0, /* replies_seen */
1207 peerreq);
1208 GNUNET_assert (NULL != pr);
1210 peerreq->pr = pr;
1213 &prd->query,
1214 peerreq,
1217 gettext_noop (
1218 "# P2P query messages received and processed"),
1219 1,
1220 GNUNET_NO);
1222 gettext_noop ("# P2P searches active"),
1223 1,
1224 GNUNET_NO);
1228 NULL);
1229}
1230
1231
1242void
1244 int is_query,
1245 uint32_t priority,
1246 struct GNUNET_MQ_Envelope *env)
1247{
1248 struct GSF_PeerTransmitHandle *pth;
1249 struct GSF_PeerTransmitHandle *pos;
1251
1252 pth = GNUNET_new (struct GSF_PeerTransmitHandle);
1254 pth->env = env;
1255 pth->is_query = is_query;
1256 pth->priority = priority;
1257 pth->cp = cp;
1258 /* insertion sort (by priority, descending) */
1259 prev = NULL;
1260 pos = cp->pth_head;
1261 while ((NULL != pos) && (pos->priority > priority))
1262 {
1263 prev = pos;
1264 pos = pos->next;
1265 }
1267 cp->pth_tail,
1268 prev,
1269 pth);
1270 if (GNUNET_YES == is_query)
1272 else if (GNUNET_NO == is_query)
1275}
1276
1277
1285void
1287 struct GNUNET_TIME_Absolute request_time,
1288 uint32_t request_priority)
1289{
1290 struct GNUNET_TIME_Relative delay;
1291
1292 delay = GNUNET_TIME_absolute_get_duration (request_time);
1295 + delay.rel_value_us) / RUNAVG_DELAY_N;
1296 cp->ppd.avg_priority =
1297 (cp->ppd.avg_priority * (RUNAVG_DELAY_N - 1)
1298 + request_priority) / RUNAVG_DELAY_N;
1299}
1300
1301
1309void
1311 struct GSF_LocalClient *initiator_client)
1312{
1314 % CS2P_SUCCESS_LIST_SIZE] = initiator_client;
1315}
1316
1317
1325void
1327 const struct GSF_ConnectedPeer *initiator_peer)
1328{
1329 unsigned int woff;
1330
1333 cp->ppd.last_p2p_replies[woff] = initiator_peer->ppd.pid;
1334 GNUNET_PEER_change_rc (initiator_peer->ppd.pid, 1);
1336}
1337
1338
1347static int
1348flush_respect (void *cls,
1349 const struct GNUNET_PeerIdentity *key,
1350 void *value)
1351{
1352 struct GSF_ConnectedPeer *cp = value;
1353 struct GNUNET_PeerIdentity pid;
1354
1355 if (cp->ppd.respect == cp->disk_respect)
1356 return GNUNET_OK; /* unchanged */
1357 GNUNET_assert (0 != cp->ppd.pid);
1358 GNUNET_PEER_resolve (cp->ppd.pid, &pid);
1359 GNUNET_PEERSTORE_store (peerstore, "fs", &pid, "respect", &cp->ppd.respect,
1360 sizeof(cp->ppd.respect),
1363 NULL,
1364 NULL);
1365 return GNUNET_OK;
1366}
1367
1368
1369void
1371 const struct GNUNET_PeerIdentity *peer,
1372 void *internal_cls)
1373{
1374 struct GSF_ConnectedPeer *cp = internal_cls;
1375 struct GSF_PeerTransmitHandle *pth;
1376 struct GSF_DelayedHandle *dh;
1377
1378 if (NULL == cp)
1379 return; /* must have been disconnect from core with
1380 * 'peer' == my_id, ignore */
1381 flush_respect (NULL,
1382 peer,
1383 cp);
1386 peer,
1387 cp));
1389 gettext_noop ("# peers connected"),
1391 GNUNET_NO);
1392 if (NULL != cp->respect_iterate_req)
1393 {
1395 cp->respect_iterate_req = NULL;
1396 }
1399 cp);
1401 cp->request_map = NULL;
1406 memset (cp->ppd.last_p2p_replies,
1407 0,
1408 sizeof(cp->ppd.last_p2p_replies));
1410 while (NULL != (pth = cp->pth_head))
1411 {
1413 cp->pth_tail,
1414 pth);
1415 if (GNUNET_YES == pth->is_query)
1417 else if (GNUNET_NO == pth->is_query)
1419 GNUNET_free (pth);
1420 }
1421 while (NULL != (dh = cp->delayed_head))
1422 {
1425 dh);
1426 GNUNET_MQ_discard (dh->env);
1429 GNUNET_free (dh);
1430 }
1432 if (NULL != cp->mig_revive_task)
1433 {
1435 cp->mig_revive_task = NULL;
1436 }
1439 GNUNET_free (cp);
1440}
1441
1442
1446struct IterationContext
1447{
1452
1456 void *it_cls;
1457};
1458
1459
1468static int
1469call_iterator (void *cls,
1470 const struct GNUNET_PeerIdentity *key,
1471 void *value)
1472{
1473 struct IterationContext *ic = cls;
1474 struct GSF_ConnectedPeer *cp = value;
1475
1476 ic->it (ic->it_cls,
1477 key, cp,
1478 &cp->ppd);
1479 return GNUNET_YES;
1480}
1481
1482
1483void
1485 void *it_cls)
1486{
1487 struct IterationContext ic;
1488
1489 ic.it = it;
1490 ic.it_cls = it_cls;
1493 &ic);
1494}
1495
1496
1503void
1505 struct GNUNET_PeerIdentity *id)
1506{
1507 GNUNET_assert (0 != cp->ppd.pid);
1508 GNUNET_PEER_resolve (cp->ppd.pid, id);
1509}
1510
1511
1518const struct GNUNET_PeerIdentity *
1520{
1521 GNUNET_assert (0 != cp->ppd.pid);
1522 return GNUNET_PEER_resolve2 (cp->ppd.pid);
1523}
1524
1525
1533void
1535 struct GNUNET_TIME_Absolute block_time)
1536{
1537 struct GNUNET_MQ_Envelope *env;
1538 struct MigrationStopMessage *msm;
1539
1540 if (cp->last_migration_block.abs_value_us > block_time.abs_value_us)
1541 {
1543 "Migration already blocked for another %s\n",
1546 (cp->
1547 last_migration_block), GNUNET_YES));
1548 return; /* already blocked */
1549 }
1550 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Asking to stop migration for %s\n",
1553 GNUNET_YES));
1554 cp->last_migration_block = block_time;
1555 env = GNUNET_MQ_msg (msm,
1557 msm->reserved = htonl (0);
1558 msm->duration
1560 (cp->last_migration_block));
1562 gettext_noop ("# migration stop messages sent"),
1563 1,
1564 GNUNET_NO);
1567 UINT32_MAX,
1568 env);
1569}
1570
1571
1581void
1583 uint64_t pref)
1584{
1585 cp->inc_preference += pref;
1586}
1587
1588
1594static void
1595cron_flush_respect (void *cls)
1596{
1597 fr_task = NULL;
1600 NULL);
1604 NULL);
1605}
1606
1607
1611void
1613{
1617 &cron_flush_respect, NULL);
1618}
1619
1620
1624void
1626{
1629 NULL);
1631 fr_task = NULL;
1633 cp_map = NULL;
1635}
1636
1637
1646static int
1647clean_local_client (void *cls,
1648 const struct GNUNET_PeerIdentity *key,
1649 void *value)
1650{
1651 const struct GSF_LocalClient *lc = cls;
1652 struct GSF_ConnectedPeer *cp = value;
1653 unsigned int i;
1654
1655 for (i = 0; i < CS2P_SUCCESS_LIST_SIZE; i++)
1656 if (cp->ppd.last_client_replies[i] == lc)
1657 cp->ppd.last_client_replies[i] = NULL;
1658 return GNUNET_YES;
1659}
1660
1661
1668void
1670{
1671 if (NULL == cp_map)
1672 return; /* already cleaned up */
1675 (void *) lc);
1676}
1677
1678
1679/* end of gnunet-service-fs_cp.c */
struct GNUNET_GETOPT_CommandLineOption options[]
Definition 002.c:5
struct GNUNET_MQ_Envelope * env
Definition 005.c:1
#define gettext_noop(String)
Definition gettext.h:74
static int ret
Final status code.
Definition gnunet-arm.c:93
static void record(void *cls, size_t data_size, const void *data)
Process recorded audio data.
static char * data
The data to insert into the dht.
struct GNUNET_HashCode key
The key used in the DHT.
static struct GNUNET_TIME_Relative expiration
User supplied expiration value.
static struct GNUNET_TIME_Relative ttl
Current record $TTL to use.
static char * value
Value of the record to add/remove.
static uint32_t type
Type string converted to DNS type value.
static struct GNUNET_PeerIdentity my_identity
Identity of this peer.
int GSF_enable_randomized_delays
Are we introducing randomized delays for better anonymity?
struct GNUNET_PILS_Handle * GSF_pils
Pointer to handle of the pils service (points to NULL until we've connected to it).
int GSF_test_get_load_too_high_(uint32_t priority)
Test if the DATABASE (GET) load on this peer is too high to even consider processing the query at all...
struct GNUNET_STATISTICS_Handle * GSF_stats
Handle for reporting statistics.
double GSF_current_priorities
Typical priorities we're seeing from other peers right now.
unsigned int GSF_cover_query_count
How many query messages have we received 'recently' that have not yet been claimed as cover traffic?
const struct GNUNET_CONFIGURATION_Handle * GSF_cfg
Our configuration.
void GSF_consider_forwarding(void *cls, struct GSF_PendingRequest *pr, enum GNUNET_BLOCK_ReplyEvaluationResult result)
Function to be called after we're done processing replies from the local lookup.
unsigned int GSF_cover_content_count
How many content messages have we received 'recently' that have not yet been claimed as cover traffic...
struct GNUNET_TIME_Relative GSF_avg_latency
Running average of the observed latency to other peers (round trip).
struct GNUNET_LOAD_Value * GSF_rt_entry_lifetime
How long do requests typically stay in the routing table?
#define GET_MESSAGE_BIT_TRANSMIT_TO
The peer identity of a peer that had claimed to have the content previously is included (can be used ...
#define TTL_DECREMENT
By which amount do we decrement the TTL for simple forwarding / indirection of the query; in milli-se...
#define GET_MESSAGE_BIT_RETURN_TO
The peer identity of a peer waiting for the reply is included (used if the response should be transmi...
static void handle_p2p_reply(void *cls, enum GNUNET_BLOCK_ReplyEvaluationResult eval, struct GSF_PendingRequest *pr, uint32_t reply_anonymity_level, struct GNUNET_TIME_Absolute expiration, struct GNUNET_TIME_Absolute last_transmission, enum GNUNET_BLOCK_Type type, const void *data, size_t data_len)
Handle a reply to a pending request.
void GSF_connected_peer_done_()
Shutdown peer management subsystem.
static int flush_respect(void *cls, const struct GNUNET_PeerIdentity *key, void *value)
Write peer-respect information to a file - flush the buffer entry!
#define N
void GSF_peer_disconnect_handler(void *cls, const struct GNUNET_PeerIdentity *peer, void *internal_cls)
A peer disconnected from us.
void handle_p2p_get(void *cls, const struct GetMessage *gm)
Handle P2P "QUERY" message.
static struct GNUNET_TIME_Relative get_randomized_delay()
Get the randomized delay a response should be subjected to.
static int test_exist_cb(void *cls, const struct GNUNET_HashCode *hc, void *value)
Test if the query already exists.
static void cron_flush_respect(void *cls)
Call this method periodically to flush respect information to disk.
struct GSF_PeerPerformanceData * GSF_get_peer_performance_data_(struct GSF_ConnectedPeer *cp)
Return the performance data record for the given peer.
static void free_pending_request(struct PeerRequest *peerreq)
Free resources associated with the given peer request.
static void transmit_delayed_now(void *cls)
The artificial delay is over, transmit the message now.
void GSF_update_peer_latency_(const struct GNUNET_PeerIdentity *id, struct GNUNET_TIME_Relative latency)
Update the latency information kept for the given peer.
static void revive_migration(void *cls)
It may be time to re-start migrating content to this peer.
static int clean_local_client(void *cls, const struct GNUNET_PeerIdentity *key, void *value)
Iterator to remove references to LC entry.
static void peer_request_destroy(void *cls)
Free the given request.
static struct GNUNET_PEERSTORE_Handle * peerstore
Handle to peerstore service.
static void peer_respect_cb(void *cls, const struct GNUNET_PEERSTORE_Record *record, const char *emsg)
Function called by PEERSTORE with peer respect record.
static void peer_transmit(struct GSF_ConnectedPeer *cp)
Core is ready to transmit to a peer, get the message.
void GSF_iterate_connected_peers_(GSF_ConnectedPeerIterator it, void *it_cls)
Iterate over all connected peers.
void GSF_connected_peer_get_identity_(const struct GSF_ConnectedPeer *cp, struct GNUNET_PeerIdentity *id)
Obtain the identity of a connected peer.
void GSF_handle_local_client_disconnect_(const struct GSF_LocalClient *lc)
Notification that a local client disconnected.
const struct GNUNET_PeerIdentity * GSF_connected_peer_get_identity2_(const struct GSF_ConnectedPeer *cp)
Obtain the identity of a connected peer.
static int consider_peer_for_forwarding(void *cls, const struct GNUNET_HashCode *key, struct GSF_PendingRequest *pr)
Function called for each pending request whenever a new peer connects, giving us a chance to decide a...
static int cancel_pending_request(void *cls, const struct GNUNET_HashCode *query, void *value)
Cancel all requests associated with the peer.
static struct GNUNET_CONTAINER_MultiPeerMap * cp_map
Map from peer identities to struct GSF_ConnectPeer entries.
struct GSF_ConnectedPeer * GSF_peer_get_(const struct GNUNET_PeerIdentity *peer)
Get a handle for a connected peer.
void GSF_connected_peer_init_()
Initialize peer management subsystem.
void * GSF_peer_connect_handler(void *cls, const struct GNUNET_PeerIdentity *peer, struct GNUNET_MQ_Handle *mq, enum GNUNET_CORE_PeerClass class)
A peer connected to us.
void GSF_peer_update_responder_peer_(struct GSF_ConnectedPeer *cp, const struct GSF_ConnectedPeer *initiator_peer)
Report on receiving a reply in response to an initiating peer.
static int call_iterator(void *cls, const struct GNUNET_PeerIdentity *key, void *value)
Function that calls the callback for each peer.
void handle_p2p_migration_stop(void *cls, const struct MigrationStopMessage *msm)
Handle P2P GNUNET_MESSAGE_TYPE_FS_MIGRATION_STOP message.
void GSF_peer_update_responder_client_(struct GSF_ConnectedPeer *cp, struct GSF_LocalClient *initiator_client)
Report on receiving a reply in response to an initiating client.
static void schedule_transmission(struct GSF_PeerTransmitHandle *pth)
If ready (bandwidth reserved), try to schedule transmission via core for the given handle.
#define RESPECT_FLUSH_FREQ
How often do we flush respect values to disk?
void GSF_peer_transmit_(struct GSF_ConnectedPeer *cp, int is_query, uint32_t priority, struct GNUNET_MQ_Envelope *env)
Transmit a message to the given peer as soon as possible.
static struct GNUNET_SCHEDULER_Task * fr_task
Task used to flush respect values to disk.
#define RUNAVG_DELAY_N
Ratio for moving average delay calculation.
static int change_peer_respect(struct GSF_ConnectedPeer *cp, int value)
Increase the peer's respect by a value.
void GSF_block_peer_migration_(struct GSF_ConnectedPeer *cp, struct GNUNET_TIME_Absolute block_time)
Ask a peer to stop migrating data to us until the given point in time.
static int32_t bound_priority(uint32_t prio_in, struct GSF_ConnectedPeer *cp)
We've received a request with the specified priority.
void GSF_peer_update_performance_(struct GSF_ConnectedPeer *cp, struct GNUNET_TIME_Absolute request_time, uint32_t request_priority)
Report on receiving a reply; update the performance record of the given peer.
void GSF_connected_peer_change_preference_(struct GSF_ConnectedPeer *cp, uint64_t pref)
Notify core about a preference we have for the given peer (to allocate more resources towards it).
static int32_t bound_ttl(int32_t ttl_in, uint32_t prio)
The priority level imposes a bound on the maximum value for the ttl that can be requested.
void(* GSF_ConnectedPeerIterator)(void *cls, const struct GNUNET_PeerIdentity *peer, struct GSF_ConnectedPeer *cp, const struct GSF_PeerPerformanceData *ppd)
Signature of function called on a connected peer.
#define P2P_SUCCESS_LIST_SIZE
Length of the P2P success tracker.
#define CS2P_SUCCESS_LIST_SIZE
Length of the CS-2-P success tracker.
#define MAX_QUEUE_PER_PEER
Maximum number of outgoing messages we queue per peer.
void GSF_plan_notify_peer_disconnect_(const struct GSF_ConnectedPeer *cp)
Notify the plan about a peer being no longer available; destroy all entries associated with this peer...
void GSF_plan_add_(struct GSF_ConnectedPeer *cp, struct GSF_PendingRequest *pr)
Create a new query plan entry.
int GSF_pending_request_test_target_(struct GSF_PendingRequest *pr, const struct GNUNET_PeerIdentity *target)
Is the given target a legitimate peer for forwarding the given request?
struct GSF_PendingRequest * GSF_pending_request_create_(enum GSF_PendingRequestOptions options, enum GNUNET_BLOCK_Type type, const struct GNUNET_HashCode *query, const struct GNUNET_PeerIdentity *target, const char *bf_data, size_t bf_size, uint32_t anonymity_level, uint32_t priority, int32_t ttl, GNUNET_PEER_Id sender_pid, GNUNET_PEER_Id origin_pid, const struct GNUNET_HashCode *replies_seen, unsigned int replies_seen_count, GSF_PendingRequestReplyHandler rh, void *rh_cls)
Create a new pending request.
void GSF_iterate_pending_requests_(GSF_PendingRequestIterator it, void *cls)
Iterate over all pending requests.
void GSF_local_lookup_(struct GSF_PendingRequest *pr, GSF_LocalLookupContinuation cont, void *cont_cls)
Look up the request in the local datastore.
struct GSF_PendingRequestData * GSF_pending_request_get_data_(struct GSF_PendingRequest *pr)
Obtain the public data associated with a pending request.
int GSF_pending_request_test_active_(struct GSF_PendingRequest *pr)
Check if the given request is still active.
void GSF_pending_request_cancel_(struct GSF_PendingRequest *pr, int full_cleanup)
Explicitly cancel a pending request.
GSF_PendingRequestOptions
Options for pending requests (bits to be ORed).
@ GSF_PRO_DEFAULTS
No special options (P2P-default).
@ GSF_PRO_FORWARD_ONLY
Request must only be forwarded (no routing)
void GSF_push_stop_(struct GSF_ConnectedPeer *peer)
A peer disconnected from us.
void GSF_push_start_(struct GSF_ConnectedPeer *peer)
A peer connected to us.
GNUNET_BLOCK_Type
WARNING: This header is generated! In order to add DHT block types, you must register them in GANA,...
@ GNUNET_BLOCK_TYPE_ANY
Identifier for any block.
const struct GNUNET_PeerIdentity * GNUNET_PILS_get_identity(const struct GNUNET_PILS_Handle *handle)
Return the current peer identity of a given handle.
Definition pils_api.c:875
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message,...
GNUNET_BLOCK_ReplyEvaluationResult
Possible ways for how a block may relate to a query.
@ GNUNET_BLOCK_REPLY_OK_LAST
Last possible valid result.
#define GNUNET_CONSTANTS_MAX_CORK_DELAY
How long do we delay messages to get larger packet sizes (CORKing)?
GNUNET_CORE_PeerClass
The peer class gives a hint about the capabilities of a peer.
uint32_t GNUNET_CRYPTO_random_u32(uint32_t i)
Produce a random value.
#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(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.
int GNUNET_CONTAINER_multihashmap_iterate(struct GNUNET_CONTAINER_MultiHashMap *map, GNUNET_CONTAINER_MultiHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map.
void GNUNET_CONTAINER_multipeermap_destroy(struct GNUNET_CONTAINER_MultiPeerMap *map)
Destroy a hash map.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap_remove(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, const void *value)
Remove the given key-value pair from the 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.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap_put(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash 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).
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap_get_multiple(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, GNUNET_CONTAINER_MultiHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map that match a particular key.
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_MULTIPLE
Allow multiple values with the same key.
@ 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_log(kind,...)
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
@ GNUNET_SCHEDULER_PRIORITY_HIGH
Run with high priority (important requests).
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
void GNUNET_LOAD_value_set_decline(struct GNUNET_LOAD_Value *load, struct GNUNET_TIME_Relative autodecline)
Change the value by which the load automatically declines.
Definition load.c:142
double GNUNET_LOAD_get_average(struct GNUNET_LOAD_Value *load)
Get the average value given to update so far.
Definition load.c:215
struct GNUNET_LOAD_Value * GNUNET_LOAD_value_init(struct GNUNET_TIME_Relative autodecline)
Create a new load value.
Definition load.c:124
void GNUNET_LOAD_update(struct GNUNET_LOAD_Value *load, uint64_t data)
Update the current load.
Definition load.c:236
double GNUNET_LOAD_get_load(struct GNUNET_LOAD_Value *load)
Get the current load.
Definition load.c:200
#define GNUNET_LOAD_value_free(lv)
Free a load value.
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.
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_DEBUG
@ GNUNET_ERROR_TYPE_INFO
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_free(ptr)
Wrapper around free.
unsigned int GNUNET_MQ_get_length(struct GNUNET_MQ_Handle *mq)
Obtain the current length of the message queue.
Definition mq.c:325
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition mq.c:337
void GNUNET_MQ_discard(struct GNUNET_MQ_Envelope *mqm)
Discard the message queue message, free all allocated resources.
Definition mq.c:317
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct.
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
void GNUNET_PEER_decrement_rcs(const GNUNET_PEER_Id *ids, unsigned int count)
Decrement multiple RCs of peer identities by one.
Definition peer.c:157
unsigned int GNUNET_PEER_Id
A GNUNET_PEER_Id is simply a shorter version of a "struct GNUNET_PeerIdentifier" that can be used ins...
void GNUNET_PEER_change_rc(GNUNET_PEER_Id id, int delta)
Change the reference counter of an interned PID.
Definition peer.c:192
const struct GNUNET_PeerIdentity * GNUNET_PEER_resolve2(GNUNET_PEER_Id id)
Convert an interned PID to a normal peer identity.
Definition peer.c:234
void GNUNET_PEER_resolve(GNUNET_PEER_Id id, struct GNUNET_PeerIdentity *pid)
Convert an interned PID to a normal peer identity.
Definition peer.c:220
GNUNET_PEER_Id GNUNET_PEER_intern(const struct GNUNET_PeerIdentity *pid)
Intern an peer identity.
Definition peer.c:108
struct GNUNET_PEERSTORE_IterateContext * GNUNET_PEERSTORE_iteration_start(struct GNUNET_PEERSTORE_Handle *h, const char *sub_system, const struct GNUNET_PeerIdentity *peer, const char *key, GNUNET_PEERSTORE_Processor callback, void *callback_cls)
Iterate over peerstore entries.
void GNUNET_PEERSTORE_iteration_next(struct GNUNET_PEERSTORE_IterateContext *ic, uint64_t limit)
Continue an iteration.
void GNUNET_PEERSTORE_disconnect(struct GNUNET_PEERSTORE_Handle *h)
Disconnect from the PEERSTORE service.
struct GNUNET_PEERSTORE_Handle * GNUNET_PEERSTORE_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the PEERSTORE service.
struct GNUNET_PEERSTORE_StoreContext * GNUNET_PEERSTORE_store(struct GNUNET_PEERSTORE_Handle *h, const char *sub_system, const struct GNUNET_PeerIdentity *peer, const char *key, const void *value, size_t size, struct GNUNET_TIME_Absolute expiry, enum GNUNET_PEERSTORE_StoreOption options, GNUNET_PEERSTORE_Continuation cont, void *cont_cls)
Store a new entry in the PEERSTORE.
void GNUNET_PEERSTORE_iteration_stop(struct GNUNET_PEERSTORE_IterateContext *ic)
Cancel an iteration.
@ GNUNET_PEERSTORE_STOREOPTION_REPLACE
Delete any previous values for the given key before storing the given value.
#define GNUNET_MESSAGE_TYPE_FS_PUT
P2P response with content or active migration of content.
#define GNUNET_MESSAGE_TYPE_FS_MIGRATION_STOP
Peer asks us to stop migrating content towards it for a while.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition scheduler.c:986
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition scheduler.c:1310
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:1283
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed_with_priority(struct GNUNET_TIME_Relative delay, enum GNUNET_SCHEDULER_Priority priority, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition scheduler.c:1213
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_with_priority(enum GNUNET_SCHEDULER_Priority prio, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified priority.
Definition scheduler.c:1237
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.
struct GNUNET_TIME_Relative GNUNET_TIME_relative_ntoh(struct GNUNET_TIME_RelativeNBO a)
Convert relative time from network byte order.
Definition time.c:626
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_duration(struct GNUNET_TIME_Absolute whence)
Get the duration of an operation as the difference of the current time and the given start time "henc...
Definition time.c:438
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_remaining(struct GNUNET_TIME_Absolute future)
Given a timestamp in the future, how much time remains until then?
Definition time.c:406
const char * GNUNET_STRINGS_relative_time_to_string(struct GNUNET_TIME_Relative delta, int do_round)
Give relative time in human-readable fancy format.
Definition strings.c:610
#define GNUNET_TIME_UNIT_MILLISECONDS
One millisecond.
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
#define GNUNET_TIME_UNIT_ZERO
Relative time zero.
struct GNUNET_TIME_RelativeNBO GNUNET_TIME_relative_hton(struct GNUNET_TIME_Relative a)
Convert relative time to network byte order.
Definition time.c:616
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition time.c:636
#define GNUNET_TIME_UNIT_FOREVER_ABS
Constant used to specify "forever".
#define _(String)
GNU gettext support macro.
Definition platform.h:179
static struct GNUNET_MQ_Handle * mq
Our connection to the resolver service, created on-demand, but then persists until error or shutdown.
Internal representation of the hash map.
Internal representation of the hash map.
A 512-bit hashcode.
Handle to a message queue.
Definition mq.c:87
Handle to the PEERSTORE service.
Context for a iterate request.
The identity of the host (wraps the signing key of the peer).
Entry in list of pending tasks.
Definition scheduler.c:141
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.
unsigned int last_p2p_replies_woff
Which offset in last_p2p_replies will be updated next? (we go round-robin).
struct GNUNET_TIME_Absolute last_migration_block
Time until when we blocked this peer from migrating data to us.
struct GSF_DelayedHandle * delayed_tail
Messages (replies, queries, content migration) we would like to send to this peer in the near future.
unsigned int last_client_replies_woff
Which offset in last_client_replies will be updated next? (we go round-robin).
unsigned int delay_queue_size
Number of entries in delayed_head DLL.
struct GSF_DelayedHandle * delayed_head
Messages (replies, queries, content migration) we would like to send to this peer in the near future.
struct GNUNET_PEERSTORE_IterateContext * respect_iterate_req
Handle to the PEERSTORE iterate request for peer respect value.
struct GSF_PeerTransmitHandle * pth_head
Messages (replies, queries, content migration) we would like to send to this peer in the near future.
struct GSF_PeerPerformanceData ppd
Performance data for this peer.
struct GNUNET_CONTAINER_MultiHashMap * request_map
Active requests from this neighbour, map of query to struct PeerRequest.
struct GNUNET_MQ_Handle * mq
Handle for an active request for transmission to this peer.
unsigned int last_request_times_off
Current offset into last_request_times ring buffer.
struct GNUNET_SCHEDULER_Task * rc_delay_task
Task scheduled if we need to retry bandwidth reservation later.
struct GNUNET_SCHEDULER_Task * mig_revive_task
Task scheduled to revive migration to this peer.
uint32_t disk_respect
Respect rating for this peer on disk.
struct GSF_PeerTransmitHandle * pth_tail
Messages (replies, queries, content migration) we would like to send to this peer in the near future.
uint64_t inc_preference
Increase in traffic preference still to be submitted to the core service for this peer.
Handle for an entry in our delay list.
struct GSF_DelayedHandle * next
Kept in a doubly-linked list.
struct GSF_DelayedHandle * prev
Kept in a doubly-linked list.
struct GNUNET_SCHEDULER_Task * delay_task
Task for the delay.
size_t msize
Size of the message.
struct GSF_ConnectedPeer * cp
Peer this transmission belongs to.
struct GNUNET_MQ_Envelope * env
Envelope of the message that was delayed.
A local client.
Performance data kept for a peer.
double avg_priority
Average priority of successful replies.
struct GNUNET_TIME_Relative avg_reply_delay
Average delay between sending the peer a request and getting a reply (only calculated over the reques...
unsigned int pending_replies
Number of pending replies (queries are not counted)
struct GSF_LocalClient * last_client_replies[8]
List of the last clients for which this peer successfully answered a query.
struct GNUNET_LOAD_Value * transmission_delay
How long does it typically take for us to transmit a message to this peer? (delay between the request...
struct GNUNET_TIME_Absolute migration_blocked_until
Point in time until which this peer does not want us to migrate content to it.
const struct GNUNET_PeerIdentity * peer
The peer's identity (pointer).
unsigned int pending_queries
Number of pending queries (replies are not counted)
GNUNET_PEER_Id pid
The peer's identity (interned version).
uint32_t respect
Respect rating for this peer.
struct GNUNET_TIME_Absolute last_request_times[24]
Transmission times for the last MAX_QUEUE_PER_PEER requests for this peer.
GNUNET_PEER_Id last_p2p_replies[8]
List of the last PIDs for which this peer successfully answered a query; We use 0 to indicate no succ...
Handle to cancel a transmission request.
int is_query
GNUNET_YES if this is a query, GNUNET_NO for content.
struct GSF_PeerTransmitHandle * next
Kept in a doubly-linked list.
uint32_t priority
Priority of this request.
struct GNUNET_TIME_Absolute transmission_request_start_time
Time when this transmission request was issued.
struct GSF_PeerTransmitHandle * prev
Kept in a doubly-linked list.
struct GSF_ConnectedPeer * cp
Peer this request targets.
struct GNUNET_MQ_Envelope * env
Envelope with the actual message.
Public data (in the sense of not encapsulated within 'gnunet-service-fs_pr', not in the sense of netw...
int has_started
Has this request been started yet (local/p2p operations)? Or are we still constructing it?
struct GNUNET_TIME_Absolute ttl
Current TTL for the request.
enum GNUNET_BLOCK_Type type
Type of the requested block.
struct GNUNET_HashCode query
Primary query hash for this request.
uint32_t priority
Priority that this request (still) has for us.
An active request.
Message to the datastore service asking about specific content.
Definition datastore.h:141
uint32_t type
Desired content type.
Definition datastore.h:150
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_DATASTORE_GET.
Definition datastore.h:145
uint32_t priority
How important is this request (network byte order)
struct GNUNET_HashCode query
Hashcodes of the file(s) we're looking for.
int32_t ttl
Relative time to live in MILLISECONDS (network byte order)
uint32_t hash_bitmap
Which of the optional hash codes are present at the end of the message? See GET_MESSAGE_BIT_xx consta...
Closure for call_iterator().
void * it_cls
Closure for it.
GSF_ConnectedPeerIterator it
Function to call on each entry.
Message send by a peer that wants to be excluded from migration for a while.
struct GNUNET_TIME_RelativeNBO duration
How long should the block last?
uint32_t reserved
Always zero.
Information per peer and request.
struct GSF_ConnectedPeer * cp
Which specific peer issued this request?
struct GSF_PendingRequest * pr
Handle to generic request (generic: from peer or local client).
struct GNUNET_SCHEDULER_Task * kill_task
Task for asynchronous stopping of this request.
Response from FS service with a result for a previous FS search.
Definition fs.h:330
uint32_t type
Type of the block (in big endian).
Definition fs.h:339
struct GNUNET_TIME_AbsoluteNBO expiration
When does this result expire?
Definition fs.h:344
Closure for test_exist_cb().
int finished
Set to GNUNET_YES if we are done handling the query.
int32_t ttl
Relative TTL of the incoming request.
int32_t priority
Priority of the incoming request.
enum GNUNET_BLOCK_Type type
Type of the incoming request.

◆ REPLY_TIMEOUT

#define REPLY_TIMEOUT
Value:

After how long do we discard a reply?

Definition at line 54 of file gnunet-service-fs_cp.c.

◆ INSANE_STATISTICS

#define INSANE_STATISTICS   GNUNET_NO

Collect an instance number of statistics? May cause excessive IPC.

Definition at line 60 of file gnunet-service-fs_cp.c.

◆ N

#define N   ((double) 128.0)

Function Documentation

◆ GSF_update_peer_latency_()

void GSF_update_peer_latency_ ( const struct GNUNET_PeerIdentity id,
struct GNUNET_TIME_Relative  latency 
)

Update the latency information kept for the given peer.

Parameters
idpeer record to update
latencycurrent latency value

Definition at line 288 of file gnunet-service-fs_cp.c.

290{
291 struct GSF_ConnectedPeer *cp;
292
293 cp = GSF_peer_get_ (id);
294 if (NULL == cp)
295 return; /* we're not yet connected at the core level, ignore */
297 latency);
298}

References GNUNET_LOAD_value_set_decline(), GSF_peer_get_(), GSF_ConnectedPeer::ppd, and GSF_PeerPerformanceData::transmission_delay.

Here is the call graph for this function:

◆ GSF_get_peer_performance_data_()

struct GSF_PeerPerformanceData * GSF_get_peer_performance_data_ ( struct GSF_ConnectedPeer cp)

Return the performance data record for the given peer.

Parameters
cppeer to query
Returns
performance data record for the peer

Definition at line 308 of file gnunet-service-fs_cp.c.

309{
310 return &cp->ppd;
311}

References GSF_ConnectedPeer::ppd.

Referenced by handle_p2p_put(), put_migration_continuation(), score_content(), and transmit_content().

Here is the caller graph for this function:

◆ peer_transmit()

static void peer_transmit ( struct GSF_ConnectedPeer cp)
static

Core is ready to transmit to a peer, get the message.

Parameters
cpwhich peer to send a message to

Definition at line 349 of file gnunet-service-fs_cp.c.

350{
351 struct GSF_PeerTransmitHandle *pth = cp->pth_head;
352 struct GSF_PeerTransmitHandle *pos;
353
354 if (NULL == pth)
355 return;
357 cp->pth_tail,
358 pth);
359 if (GNUNET_YES == pth->is_query)
360 {
365 }
366 else if (GNUNET_NO == pth->is_query)
367 {
369 }
374 pth->env);
375 GNUNET_free (pth);
376 if (NULL != (pos = cp->pth_head))
377 {
378 GNUNET_assert (pos != pth);
380 }
381}

References GSF_PeerTransmitHandle::cp, GSF_PeerTransmitHandle::env, GNUNET_assert, GNUNET_CONTAINER_DLL_remove, GNUNET_free, GNUNET_LOAD_update(), GNUNET_MQ_send(), GNUNET_NO, GNUNET_TIME_absolute_get(), GNUNET_TIME_absolute_get_duration(), GNUNET_YES, GSF_PeerTransmitHandle::is_query, GSF_PeerPerformanceData::last_request_times, GSF_ConnectedPeer::last_request_times_off, MAX_QUEUE_PER_PEER, GSF_ConnectedPeer::mq, GSF_PeerPerformanceData::pending_queries, GSF_PeerPerformanceData::pending_replies, GSF_ConnectedPeer::ppd, GSF_ConnectedPeer::pth_head, GSF_ConnectedPeer::pth_tail, GNUNET_TIME_Relative::rel_value_us, schedule_transmission(), GSF_PeerPerformanceData::transmission_delay, and GSF_PeerTransmitHandle::transmission_request_start_time.

Referenced by schedule_transmission().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ schedule_transmission()

static void schedule_transmission ( struct GSF_PeerTransmitHandle pth)
static

If ready (bandwidth reserved), try to schedule transmission via core for the given handle.

Parameters
pthtransmission handle to schedule

Definition at line 330 of file gnunet-service-fs_cp.c.

331{
332 struct GSF_ConnectedPeer *cp;
333 struct GNUNET_PeerIdentity target;
334
335 cp = pth->cp;
336 GNUNET_assert (0 != cp->ppd.pid);
337 GNUNET_PEER_resolve (cp->ppd.pid, &target);
338
339 peer_transmit (cp);
340}

References GSF_PeerTransmitHandle::cp, GNUNET_assert, GNUNET_PEER_resolve(), peer_transmit(), GSF_PeerPerformanceData::pid, and GSF_ConnectedPeer::ppd.

Referenced by GSF_peer_transmit_(), and peer_transmit().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ peer_respect_cb()

static void peer_respect_cb ( void *  cls,
const struct GNUNET_PEERSTORE_Record record,
const char *  emsg 
)
static

Function called by PEERSTORE with peer respect record.

Parameters
clshandle to connected peer entry
recordpeerstore record information
emsgerror message, or NULL if no errors

Definition at line 392 of file gnunet-service-fs_cp.c.

395{
396 struct GSF_ConnectedPeer *cp = cls;
397
399 if (NULL == record)
400 {
401 /* A NULL record ends the iteration and releases the context, with or
402 without an @a emsg. Testing for `NULL == emsg' as well meant the
403 error case fell through to the GNUNET_PEERSTORE_iteration_next()
404 below and left @e respect_iterate_req dangling. */
405 if (NULL != emsg)
407 "Failed to read respect value from PEERSTORE: %s\n",
408 emsg);
409 cp->respect_iterate_req = NULL;
410 return;
411 }
412 if ((NULL != record) &&
413 (sizeof(cp->disk_respect) == record->value_size))
414 {
415 cp->disk_respect = *((uint32_t *) record->value);
416 cp->ppd.respect += *((uint32_t *) record->value);
417 }
418 GSF_push_start_ (cp);
419 if (NULL != record)
420 {
422 cp->respect_iterate_req = NULL;
423 return;
424 }
426}

References GSF_ConnectedPeer::disk_respect, GNUNET_assert, GNUNET_ERROR_TYPE_WARNING, GNUNET_log, GNUNET_PEERSTORE_iteration_next(), GNUNET_PEERSTORE_iteration_stop(), GSF_push_start_(), GSF_ConnectedPeer::ppd, record(), GSF_PeerPerformanceData::respect, and GSF_ConnectedPeer::respect_iterate_req.

Referenced by GSF_peer_connect_handler().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ consider_peer_for_forwarding()

static int consider_peer_for_forwarding ( void *  cls,
const struct GNUNET_HashCode key,
struct GSF_PendingRequest pr 
)
static

Function called for each pending request whenever a new peer connects, giving us a chance to decide about submitting the existing request to the new peer.

Parameters
clsthe struct GSF_ConnectedPeer of the new peer
keyquery for the request
prhandle to the pending request
Returns
GNUNET_YES to continue to iterate

Definition at line 440 of file gnunet-service-fs_cp.c.

443{
444 struct GSF_ConnectedPeer *cp = cls;
445 struct GNUNET_PeerIdentity pid;
446
447 if (GNUNET_YES !=
449 return GNUNET_YES; /* request is not actually active, skip! */
451 if (GNUNET_YES !=
453 {
455 gettext_noop ("# Loopback routes suppressed"),
456 1,
457 GNUNET_NO);
458 return GNUNET_YES;
459 }
460 GSF_plan_add_ (cp, pr);
461 return GNUNET_YES;
462}

References gettext_noop, GNUNET_NO, GNUNET_STATISTICS_update(), GNUNET_YES, GSF_connected_peer_get_identity_(), GSF_pending_request_test_active_(), GSF_pending_request_test_target_(), GSF_plan_add_(), and GSF_stats.

Referenced by GSF_peer_connect_handler().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GSF_peer_connect_handler()

void * GSF_peer_connect_handler ( void *  cls,
const struct GNUNET_PeerIdentity peer,
struct GNUNET_MQ_Handle mq,
enum GNUNET_CORE_PeerClass  class 
)

A peer connected to us.

Setup the connected peer records.

Parameters
clsNULL
peeridentity of peer that connected
mqmessage queue for talking to peer
classpeer class of connected peer
Returns
internal handle for the peer

Definition at line 466 of file gnunet-service-fs_cp.c.

470{
471 const struct GNUNET_PeerIdentity *my_identity;
472 struct GSF_ConnectedPeer *cp;
473
476
477 if (0 == GNUNET_memcmp (my_identity, peer))
478 return NULL;
480 "Connected to peer %s\n",
481 GNUNET_i2s (peer));
482 cp = GNUNET_new (struct GSF_ConnectedPeer);
483 cp->ppd.pid = GNUNET_PEER_intern (peer);
484 cp->ppd.peer = peer;
485 cp->mq = mq;
487
489 GNUNET_YES);
493 (
494 cp),
495 cp,
498 gettext_noop ("# peers connected"),
500 GNUNET_NO);
503 "fs",
504 peer,
505 "respect",
507 cp);
509 cp);
510 return cp;
511}

References consider_peer_for_forwarding(), cp_map, gettext_noop, GNUNET_assert, GNUNET_break, GNUNET_CONTAINER_multihashmap_create(), GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY, GNUNET_CONTAINER_multipeermap_put(), GNUNET_CONTAINER_multipeermap_size(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_i2s(), GNUNET_LOAD_value_init(), GNUNET_log, GNUNET_memcmp, GNUNET_new, GNUNET_NO, GNUNET_OK, GNUNET_PEER_intern(), GNUNET_PEERSTORE_iteration_start(), GNUNET_PILS_get_identity(), GNUNET_STATISTICS_set(), GNUNET_TIME_UNIT_ZERO, GNUNET_YES, GSF_connected_peer_get_identity2_(), GSF_iterate_pending_requests_(), GSF_pils, GSF_stats, mq, GSF_ConnectedPeer::mq, my_identity, GSF_PeerPerformanceData::peer, peer_respect_cb(), peerstore, GSF_PeerPerformanceData::pid, GSF_ConnectedPeer::ppd, GSF_ConnectedPeer::request_map, GSF_ConnectedPeer::respect_iterate_req, and GSF_PeerPerformanceData::transmission_delay.

Referenced by main_init().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ revive_migration()

static void revive_migration ( void *  cls)
static

It may be time to re-start migrating content to this peer.

Check, and if so, restart migration.

Parameters
clsthe struct GSF_ConnectedPeer

Definition at line 521 of file gnunet-service-fs_cp.c.

522{
523 struct GSF_ConnectedPeer *cp = cls;
524 struct GNUNET_TIME_Relative bt;
525
526 cp->mig_revive_task = NULL;
528 if (0 != bt.rel_value_us)
529 {
530 /* still time left... */
531 cp->mig_revive_task =
533 return;
534 }
535 GSF_push_start_ (cp);
536}

References GNUNET_SCHEDULER_add_delayed(), GNUNET_TIME_absolute_get_remaining(), GSF_push_start_(), GSF_ConnectedPeer::mig_revive_task, GSF_PeerPerformanceData::migration_blocked_until, GSF_ConnectedPeer::ppd, GNUNET_TIME_Relative::rel_value_us, and revive_migration().

Referenced by handle_p2p_migration_stop(), and revive_migration().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GSF_peer_get_()

struct GSF_ConnectedPeer * GSF_peer_get_ ( const struct GNUNET_PeerIdentity peer)

Get a handle for a connected peer.

Parameters
peerpeer's identity
Returns
NULL if this peer is not currently connected

Definition at line 540 of file gnunet-service-fs_cp.c.

541{
542 if (NULL == cp_map)
543 return NULL;
545}

References cp_map, and GNUNET_CONTAINER_multipeermap_get().

Referenced by GSF_update_peer_latency_(), handle_p2p_get(), and put_migration_continuation().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ handle_p2p_migration_stop()

void handle_p2p_migration_stop ( void *  cls,
const struct MigrationStopMessage msm 
)

Handle P2P GNUNET_MESSAGE_TYPE_FS_MIGRATION_STOP message.

Parameters
clsclosure, the struct GSF_ConnectedPeer
msmthe actual message

Definition at line 555 of file gnunet-service-fs_cp.c.

557{
558 struct GSF_ConnectedPeer *cp = cls;
559 struct GNUNET_TIME_Relative bt;
560
562 gettext_noop ("# migration stop messages received"),
563 1, GNUNET_NO);
566 _ ("Migration of content to peer `%s' blocked for %s\n"),
567 GNUNET_i2s (cp->ppd.peer),
570 if ((NULL == cp->mig_revive_task) &&
571 (NULL == cp->respect_iterate_req))
572 {
573 GSF_push_stop_ (cp);
574 cp->mig_revive_task =
576 &revive_migration, cp);
577 }
578}

References _, MigrationStopMessage::duration, gettext_noop, GNUNET_ERROR_TYPE_INFO, GNUNET_i2s(), GNUNET_log, GNUNET_NO, GNUNET_SCHEDULER_add_delayed(), GNUNET_STATISTICS_update(), GNUNET_STRINGS_relative_time_to_string(), GNUNET_TIME_relative_ntoh(), GNUNET_TIME_relative_to_absolute(), GNUNET_YES, GSF_push_stop_(), GSF_stats, GSF_ConnectedPeer::mig_revive_task, GSF_PeerPerformanceData::migration_blocked_until, GSF_PeerPerformanceData::peer, GSF_ConnectedPeer::ppd, GSF_ConnectedPeer::respect_iterate_req, and revive_migration().

Here is the call graph for this function:

◆ free_pending_request()

static void free_pending_request ( struct PeerRequest peerreq)
static

Free resources associated with the given peer request.

Parameters
peerreqrequest to free

Definition at line 587 of file gnunet-service-fs_cp.c.

588{
589 struct GSF_ConnectedPeer *cp = peerreq->cp;
590 struct GSF_PendingRequestData *prd;
591
592 prd = GSF_pending_request_get_data_ (peerreq->pr);
593 if (NULL != peerreq->kill_task)
594 {
596 peerreq->kill_task = NULL;
597 }
599 gettext_noop ("# P2P searches active"),
600 -1,
601 GNUNET_NO);
604 &prd->query,
605 peerreq));
606 GNUNET_free (peerreq);
607}

References PeerRequest::cp, gettext_noop, GNUNET_break, GNUNET_CONTAINER_multihashmap_remove(), GNUNET_free, GNUNET_NO, GNUNET_SCHEDULER_cancel(), GNUNET_STATISTICS_update(), GNUNET_YES, GSF_pending_request_get_data_(), GSF_stats, PeerRequest::kill_task, PeerRequest::pr, GSF_PendingRequestData::query, and GSF_ConnectedPeer::request_map.

Referenced by cancel_pending_request(), handle_p2p_reply(), and test_exist_cb().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ cancel_pending_request()

static int cancel_pending_request ( void *  cls,
const struct GNUNET_HashCode query,
void *  value 
)
static

Cancel all requests associated with the peer.

Parameters
clsunused
queryhash code of the request
valuethe struct GSF_PendingRequest
Returns
GNUNET_YES (continue to iterate)

Definition at line 619 of file gnunet-service-fs_cp.c.

622{
623 struct PeerRequest *peerreq = value;
624 struct GSF_PendingRequest *pr = peerreq->pr;
625
626 free_pending_request (peerreq);
628 GNUNET_NO);
629 return GNUNET_OK;
630}

References free_pending_request(), GNUNET_NO, GNUNET_OK, GSF_pending_request_cancel_(), PeerRequest::pr, and value.

Referenced by GSF_peer_disconnect_handler(), and peer_request_destroy().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ peer_request_destroy()

static void peer_request_destroy ( void *  cls)
static

Free the given request.

Parameters
clsthe request to free

Definition at line 639 of file gnunet-service-fs_cp.c.

640{
641 struct PeerRequest *peerreq = cls;
642 struct GSF_PendingRequest *pr = peerreq->pr;
643 struct GSF_PendingRequestData *prd;
644
645 peerreq->kill_task = NULL;
648 &prd->query,
649 peerreq);
650}

References cancel_pending_request(), GSF_pending_request_get_data_(), PeerRequest::kill_task, PeerRequest::pr, and GSF_PendingRequestData::query.

Referenced by handle_p2p_reply().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ transmit_delayed_now()

static void transmit_delayed_now ( void *  cls)
static

The artificial delay is over, transmit the message now.

Parameters
clsthe struct GSF_DelayedHandle with the message

Definition at line 659 of file gnunet-service-fs_cp.c.

660{
661 struct GSF_DelayedHandle *dh = cls;
662 struct GSF_ConnectedPeer *cp = dh->cp;
663
665 cp->delayed_tail,
666 dh);
667 cp->delay_queue_size--;
669 GNUNET_NO,
670 UINT32_MAX,
671 dh->env);
672 GNUNET_free (dh);
673}

References GSF_DelayedHandle::cp, GSF_ConnectedPeer::delay_queue_size, GSF_ConnectedPeer::delayed_head, GSF_ConnectedPeer::delayed_tail, GSF_DelayedHandle::env, GNUNET_CONTAINER_DLL_remove, GNUNET_free, GNUNET_NO, and GSF_peer_transmit_().

Referenced by handle_p2p_reply().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_randomized_delay()

static struct GNUNET_TIME_Relative get_randomized_delay ( )
static

Get the randomized delay a response should be subjected to.

Returns
desired delay

Definition at line 682 of file gnunet-service-fs_cp.c.

683{
685
686 ret =
689 (2 * GSF_avg_latency.rel_value_us + 1));
690#if INSANE_STATISTICS
693 ("# artificial delays introduced (ms)"),
694 ret.rel_value_us / 1000LL, GNUNET_NO);
695#endif
696 return ret;
697}

References gettext_noop, GNUNET_CRYPTO_random_u32(), GNUNET_NO, GNUNET_STATISTICS_update(), GNUNET_TIME_relative_multiply(), GNUNET_TIME_UNIT_MILLISECONDS, GSF_avg_latency, GSF_stats, GNUNET_TIME_Relative::rel_value_us, and ret.

Referenced by handle_p2p_reply().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ handle_p2p_reply()

static void handle_p2p_reply ( void *  cls,
enum GNUNET_BLOCK_ReplyEvaluationResult  eval,
struct GSF_PendingRequest pr,
uint32_t  reply_anonymity_level,
struct GNUNET_TIME_Absolute  expiration,
struct GNUNET_TIME_Absolute  last_transmission,
enum GNUNET_BLOCK_Type  type,
const void *  data,
size_t  data_len 
)
static

Handle a reply to a pending request.

Also called if a request expires (then with data == NULL). The handler may be called many times (depending on the request type), but will not be called during or after a call to GSF_pending_request_cancel and will also not be called anymore after a call signalling expiration.

Parameters
clsstruct PeerRequest this is an answer for
evalevaluation of the result
prhandle to the original pending request
reply_anonymity_levelanonymity level for the reply, UINT32_MAX for "unknown"
expirationwhen does data expire?
last_transmissionwhen did we last transmit a request for this block
typetype of the block
dataresponse data, NULL on request expiration
data_lennumber of bytes in data

Definition at line 719 of file gnunet-service-fs_cp.c.

728{
729 struct PeerRequest *peerreq = cls;
730 struct GSF_ConnectedPeer *cp = peerreq->cp;
731 struct GSF_PendingRequestData *prd;
732 struct GNUNET_MQ_Envelope *env;
733 struct PutMessage *pm;
734 size_t msize;
735
736 GNUNET_assert (data_len + sizeof(struct PutMessage) <
738 GNUNET_assert (peerreq->pr == pr);
740 if (NULL == data)
741 {
742 free_pending_request (peerreq);
743 return;
744 }
746 if ( (prd->type != type) &&
747 (GNUNET_BLOCK_TYPE_ANY != prd->type) )
748 {
750 "# replies dropped due to type mismatch",
751 1, GNUNET_NO);
752 return;
753 }
755 "Transmitting result for query `%s' to peer\n",
756 GNUNET_h2s (&prd->query));
758 "# replies received for other peers",
759 1,
760 GNUNET_NO);
761 msize = sizeof(struct PutMessage) + data_len;
762 if (msize >= GNUNET_MAX_MESSAGE_SIZE)
763 {
764 GNUNET_break (0);
765 return;
766 }
767 if ( (UINT32_MAX != reply_anonymity_level) &&
768 (reply_anonymity_level > 1) )
769 {
770 if (reply_anonymity_level - 1 > GSF_cover_content_count)
771 {
773 "# replies dropped due to insufficient cover traffic",
774 1, GNUNET_NO);
775 return;
776 }
777 GSF_cover_content_count -= (reply_anonymity_level - 1);
778 }
779
781 data_len,
783 pm->type = htonl (type);
785 GNUNET_memcpy (&pm[1],
786 data,
787 data_len);
788 if ((UINT32_MAX != reply_anonymity_level) &&
789 (0 != reply_anonymity_level) &&
791 {
792 struct GSF_DelayedHandle *dh;
793
794 dh = GNUNET_new (struct GSF_DelayedHandle);
795 dh->cp = cp;
796 dh->env = env;
797 dh->msize = msize;
800 dh);
802 dh->delay_task =
805 dh);
806 }
807 else
808 {
810 GNUNET_NO,
811 UINT32_MAX,
812 env);
813 }
814 if (GNUNET_BLOCK_REPLY_OK_LAST != eval)
815 return;
816 if (NULL == peerreq->kill_task)
817 {
819 "# P2P searches destroyed due to ultimate reply",
820 1,
821 GNUNET_NO);
822 peerreq->kill_task =
824 peerreq);
825 }
826}

References GSF_DelayedHandle::cp, PeerRequest::cp, data, GSF_ConnectedPeer::delay_queue_size, GSF_DelayedHandle::delay_task, GSF_ConnectedPeer::delayed_head, GSF_ConnectedPeer::delayed_tail, env, GSF_DelayedHandle::env, expiration, PutMessage::expiration, free_pending_request(), get_randomized_delay(), GNUNET_assert, GNUNET_BLOCK_REPLY_OK_LAST, GNUNET_BLOCK_TYPE_ANY, GNUNET_break, GNUNET_CONTAINER_DLL_insert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_log, GNUNET_MAX_MESSAGE_SIZE, GNUNET_memcpy, GNUNET_MESSAGE_TYPE_FS_PUT, GNUNET_MQ_msg_extra, GNUNET_new, GNUNET_NO, GNUNET_SCHEDULER_add_delayed(), GNUNET_SCHEDULER_add_now(), GNUNET_STATISTICS_update(), GNUNET_TIME_absolute_hton(), GNUNET_YES, GSF_cover_content_count, GSF_enable_randomized_delays, GSF_peer_transmit_(), GSF_pending_request_get_data_(), GSF_stats, PeerRequest::kill_task, GSF_DelayedHandle::msize, peer_request_destroy(), PeerRequest::pr, GSF_PendingRequestData::query, transmit_delayed_now(), type, PutMessage::type, and GSF_PendingRequestData::type.

Referenced by handle_p2p_get().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ change_peer_respect()

static int change_peer_respect ( struct GSF_ConnectedPeer cp,
int  value 
)
static

Increase the peer's respect by a value.

Parameters
cpwhich peer to change the respect value on
valueis the int value by which the peer's credit is to be increased or decreased
Returns
the actual change in respect (positive or negative)

Definition at line 838 of file gnunet-service-fs_cp.c.

839{
840 if (0 == value)
841 return 0;
842 GNUNET_assert (NULL != cp);
843 if (value > 0)
844 {
845 if (cp->ppd.respect + value < cp->ppd.respect)
846 {
847 value = UINT32_MAX - cp->ppd.respect;
848 cp->ppd.respect = UINT32_MAX;
849 }
850 else
851 cp->ppd.respect += value;
852 }
853 else
854 {
855 if (cp->ppd.respect < -value)
856 {
857 value = -cp->ppd.respect;
858 cp->ppd.respect = 0;
859 }
860 else
861 cp->ppd.respect += value;
862 }
863 return value;
864}

References GSF_DelayedHandle::cp, GNUNET_assert, GSF_ConnectedPeer::ppd, GSF_PeerPerformanceData::respect, and value.

Referenced by bound_priority().

Here is the caller graph for this function:

◆ bound_priority()

static int32_t bound_priority ( uint32_t  prio_in,
struct GSF_ConnectedPeer cp 
)
static

We've received a request with the specified priority.

Bound it according to how much we respect the given peer.

Parameters
prio_inrequested priority
cpthe peer making the request
Returns
effective priority

Definition at line 876 of file gnunet-service-fs_cp.c.

878{
879#define N ((double) 128.0)
880 uint32_t ret;
881 double rret;
882 int ld;
883
885 if (GNUNET_SYSERR == ld)
886 {
887#if INSANE_STATISTICS
890 ("# requests done for free (low load)"), 1,
891 GNUNET_NO);
892#endif
893 return 0; /* excess resources */
894 }
895 if (prio_in > INT32_MAX)
896 prio_in = INT32_MAX;
897 ret = -change_peer_respect (cp, -(int) prio_in);
898 if (ret > 0)
899 {
901 rret = GSF_current_priorities + N;
902 else
903 rret = ret;
905 }
906 if ((GNUNET_YES == ld) && (ret > 0))
907 {
908 /* try with charging */
910 }
911 if (GNUNET_YES == ld)
912 {
915 ("# request dropped, priority insufficient"), 1,
916 GNUNET_NO);
917 /* undo charge */
918 change_peer_respect (cp, (int) ret);
919 return -1; /* not enough resources */
920 }
921 else
922 {
925 ("# requests done for a price (normal load)"),
926 1,
927 GNUNET_NO);
928 }
929#undef N
930 return ret;
931}

References change_peer_respect(), GSF_DelayedHandle::cp, gettext_noop, GNUNET_NO, GNUNET_STATISTICS_update(), GNUNET_SYSERR, GNUNET_YES, GSF_current_priorities, GSF_stats, GSF_test_get_load_too_high_(), N, and ret.

Referenced by handle_p2p_get().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ bound_ttl()

static int32_t bound_ttl ( int32_t  ttl_in,
uint32_t  prio 
)
static

The priority level imposes a bound on the maximum value for the ttl that can be requested.

Parameters
ttl_inrequested ttl
priogiven priority
Returns
ttl_in if ttl_in is below the limit, otherwise the ttl-limit for the given prio

Definition at line 944 of file gnunet-service-fs_cp.c.

946{
947 unsigned long long allowed;
948
949 if (ttl_in <= 0)
950 return ttl_in;
951 allowed = ((unsigned long long) prio) * TTL_DECREMENT / 1000;
952 if (ttl_in > allowed)
953 {
954 if (allowed >= (1 << 30))
955 return 1 << 30;
956 return allowed;
957 }
958 return ttl_in;
959}

References TTL_DECREMENT.

Referenced by handle_p2p_get().

Here is the caller graph for this function:

◆ test_exist_cb()

static int test_exist_cb ( void *  cls,
const struct GNUNET_HashCode hc,
void *  value 
)
static

Test if the query already exists.

If so, merge it, otherwise keep finished at GNUNET_NO.

Parameters
clsour struct TestExistClosure
hcthe key of the query
valuethe existing struct PeerRequest.
Returns
GNUNET_YES to continue to iterate, GNUNET_NO if we successfully merged

Definition at line 1000 of file gnunet-service-fs_cp.c.

1003{
1004 struct TestExistClosure *tec = cls;
1005 struct PeerRequest *peerreq = value;
1006 struct GSF_PendingRequest *pr;
1007 struct GSF_PendingRequestData *prd;
1008
1009 pr = peerreq->pr;
1011 if (prd->type != tec->type)
1012 return GNUNET_YES;
1013 if (prd->ttl.abs_value_us >=
1014 GNUNET_TIME_absolute_get ().abs_value_us + tec->ttl * 1000LL)
1015 {
1016 /* existing request has higher TTL, drop new one! */
1017 prd->priority += tec->priority;
1019 "Have existing request with higher TTL, dropping new request.\n");
1022 ("# requests dropped due to higher-TTL request")
1023 ,
1024 1, GNUNET_NO);
1025 tec->finished = GNUNET_YES;
1026 return GNUNET_NO;
1027 }
1028 /* existing request has lower TTL, drop old one! */
1029 tec->priority += prd->priority;
1030 free_pending_request (peerreq);
1032 GNUNET_YES);
1033 return GNUNET_NO;
1034}

References GNUNET_TIME_Absolute::abs_value_us, TestExistClosure::finished, free_pending_request(), gettext_noop, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_NO, GNUNET_STATISTICS_update(), GNUNET_TIME_absolute_get(), GNUNET_YES, GSF_pending_request_cancel_(), GSF_pending_request_get_data_(), GSF_stats, PeerRequest::pr, TestExistClosure::priority, GSF_PendingRequestData::priority, TestExistClosure::ttl, GSF_PendingRequestData::ttl, TestExistClosure::type, GSF_PendingRequestData::type, and value.

Referenced by handle_p2p_get().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ handle_p2p_get()

void handle_p2p_get ( void *  cls,
const struct GetMessage gm 
)

Handle P2P "QUERY" message.

Creates the pending request entry and sets up all of the data structures to that we will process replies properly. Does not initiate forwarding or local database lookups.

Parameters
clsthe other peer involved (sender of the message)
gmthe GET message

Definition at line 1047 of file gnunet-service-fs_cp.c.

1049{
1050 struct GSF_ConnectedPeer *cps = cls;
1051 struct PeerRequest *peerreq;
1052 struct GSF_PendingRequest *pr;
1053 struct GSF_ConnectedPeer *cp;
1054 const struct GNUNET_PeerIdentity *target;
1056 uint16_t msize;
1057 unsigned int bits;
1058 const struct GNUNET_PeerIdentity *opt;
1059 uint32_t bm;
1060 size_t bfsize;
1061 uint32_t ttl_decrement;
1062 struct TestExistClosure tec;
1063 GNUNET_PEER_Id spid;
1064 const struct GSF_PendingRequestData *prd;
1065
1066 msize = ntohs (gm->header.size);
1067 tec.type = ntohl (gm->type);
1068 bm = ntohl (gm->hash_bitmap);
1069 bits = 0;
1070 while (bm > 0)
1071 {
1072 if (1 == (bm & 1))
1073 bits++;
1074 bm >>= 1;
1075 }
1076 opt = (const struct GNUNET_PeerIdentity *) &gm[1];
1077 bfsize = msize - sizeof(struct GetMessage) - bits * sizeof(struct
1081 ("# GET requests received (from other peers)"),
1082 1,
1083 GNUNET_NO);
1085 bm = ntohl (gm->hash_bitmap);
1086 bits = 0;
1087 if (0 != (bm & GET_MESSAGE_BIT_RETURN_TO))
1088 cp = GSF_peer_get_ (&opt[bits++]);
1089 else
1090 cp = cps;
1091 if (NULL == cp)
1092 {
1093 if (0 != (bm & GET_MESSAGE_BIT_RETURN_TO))
1095 "Failed to find RETURN-TO peer `%s' in connection set. Dropping query.\n",
1096 GNUNET_i2s (&opt[bits - 1]));
1097
1098 else
1100 "Failed to find peer `%s' in connection set. Dropping query.\n",
1101 GNUNET_i2s (cps->ppd.peer));
1104 (
1105 "# requests dropped due to missing reverse route"),
1106 1,
1107 GNUNET_NO);
1108 return;
1109 }
1110 unsigned int queue_size = GNUNET_MQ_get_length (cp->mq);
1111 queue_size += cp->ppd.pending_replies + cp->delay_queue_size;
1112 if (queue_size > MAX_QUEUE_PER_PEER)
1113 {
1115 "Peer `%s' has too many replies queued already. Dropping query.\n",
1116 GNUNET_i2s (cps->ppd.peer));
1118 gettext_noop (
1119 "# requests dropped due to full reply queue"),
1120 1,
1121 GNUNET_NO);
1122 return;
1123 }
1124 /* note that we can really only check load here since otherwise
1125 * peers could find out that we are overloaded by not being
1126 * disconnected after sending us a malformed query... */
1127 tec.priority = bound_priority (ntohl (gm->priority),
1128 cps);
1129 if (tec.priority < 0)
1130 {
1132 "Dropping query from `%s', this peer is too busy.\n",
1133 GNUNET_i2s (cps->ppd.peer));
1134 return;
1135 }
1137 "Received request for `%s' of type %u from peer `%s' with flags %u\n",
1138 GNUNET_h2s (&gm->query),
1139 (unsigned int) tec.type,
1140 GNUNET_i2s (cps->ppd.peer),
1141 (unsigned int) bm);
1142 target =
1143 (0 !=
1144 (bm & GET_MESSAGE_BIT_TRANSMIT_TO)) ? (&opt[bits++]) : NULL;
1146 spid = 0;
1147 if ((GNUNET_LOAD_get_load (cp->ppd.transmission_delay) > 3 * (1
1148 + tec.priority))
1150 GNUNET_CONSTANTS_MAX_CORK_DELAY.rel_value_us * 2
1152 {
1153 /* don't have BW to send to peer, or would likely take longer than we have for it,
1154 * so at best indirect the query */
1155 tec.priority = 0;
1157 spid = GNUNET_PEER_intern (cps->ppd.peer);
1158 GNUNET_assert (0 != spid);
1159 }
1160 tec.ttl = bound_ttl (ntohl (gm->ttl),
1161 tec.priority);
1162 /* decrement ttl (always) */
1163 ttl_decrement =
1165 if ((tec.ttl < 0) &&
1166 (((int32_t) (tec.ttl - ttl_decrement)) > 0))
1167 {
1169 "Dropping query from `%s' due to TTL underflow (%d - %u).\n",
1170 GNUNET_i2s (cps->ppd.peer),
1171 tec.ttl,
1172 ttl_decrement);
1175 ("# requests dropped due TTL underflow"), 1,
1176 GNUNET_NO);
1177 /* integer underflow => drop (should be very rare)! */
1178 return;
1179 }
1180 tec.ttl -= ttl_decrement;
1181
1182 /* test if the request already exists */
1183 tec.finished = GNUNET_NO;
1185 &gm->query,
1187 &tec);
1188 if (GNUNET_YES == tec.finished)
1189 return; /* merged into existing request, we're done */
1190
1191 peerreq = GNUNET_new (struct PeerRequest);
1192 peerreq->cp = cp;
1194 tec.type,
1195 &gm->query,
1196 target,
1197 (bfsize > 0)
1198 ? (const char *) &opt[bits]
1199 : NULL,
1200 bfsize,
1201 1 /* anonymity */,
1202 (uint32_t) tec.priority,
1203 tec.ttl,
1204 spid,
1205 GNUNET_PEER_intern (cps->ppd.peer),
1206 NULL, 0, /* replies_seen */
1208 peerreq);
1209 GNUNET_assert (NULL != pr);
1211 peerreq->pr = pr;
1214 &prd->query,
1215 peerreq,
1218 gettext_noop (
1219 "# P2P query messages received and processed"),
1220 1,
1221 GNUNET_NO);
1223 gettext_noop ("# P2P searches active"),
1224 1,
1225 GNUNET_NO);
1229 NULL);
1230}

References bound_priority(), bound_ttl(), PeerRequest::cp, GSF_ConnectedPeer::delay_queue_size, TestExistClosure::finished, GET_MESSAGE_BIT_RETURN_TO, GET_MESSAGE_BIT_TRANSMIT_TO, gettext_noop, GNUNET_assert, GNUNET_break, GNUNET_CONSTANTS_MAX_CORK_DELAY, GNUNET_CONTAINER_multihashmap_get_multiple(), GNUNET_CONTAINER_multihashmap_put(), GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE, GNUNET_CRYPTO_random_u32(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_h2s(), GNUNET_i2s(), GNUNET_LOAD_get_average(), GNUNET_LOAD_get_load(), GNUNET_log, GNUNET_MQ_get_length(), GNUNET_new, GNUNET_NO, GNUNET_OK, GNUNET_PEER_intern(), GNUNET_STATISTICS_update(), GNUNET_YES, GSF_consider_forwarding(), GSF_cover_query_count, GSF_local_lookup_(), GSF_peer_get_(), GSF_pending_request_create_(), GSF_pending_request_get_data_(), GSF_PRO_DEFAULTS, GSF_PRO_FORWARD_ONLY, GSF_rt_entry_lifetime, GSF_stats, handle_p2p_reply(), GSF_PendingRequestData::has_started, GetMessage::hash_bitmap, GetMessage::header, MAX_QUEUE_PER_PEER, GSF_ConnectedPeer::mq, options, GSF_PeerPerformanceData::peer, GSF_PeerPerformanceData::pending_replies, GSF_ConnectedPeer::ppd, PeerRequest::pr, GetMessage::priority, TestExistClosure::priority, GetMessage::query, GSF_PendingRequestData::query, GSF_ConnectedPeer::request_map, GNUNET_MessageHeader::size, test_exist_cb(), GSF_PeerPerformanceData::transmission_delay, GetMessage::ttl, TestExistClosure::ttl, TTL_DECREMENT, GetMessage::type, and TestExistClosure::type.

Here is the call graph for this function:

◆ GSF_peer_transmit_()

void GSF_peer_transmit_ ( struct GSF_ConnectedPeer cp,
int  is_query,
uint32_t  priority,
struct GNUNET_MQ_Envelope env 
)

Transmit a message to the given peer as soon as possible.

If the peer disconnects before the transmission can happen, the callback is invoked with a NULL buffer.

Parameters
cptarget peer
is_queryis this a query (GNUNET_YES) or content (GNUNET_NO) or neither (GNUNET_SYSERR)
priorityhow important is this request?
envmessage to send

Definition at line 1244 of file gnunet-service-fs_cp.c.

1248{
1249 struct GSF_PeerTransmitHandle *pth;
1250 struct GSF_PeerTransmitHandle *pos;
1252
1253 pth = GNUNET_new (struct GSF_PeerTransmitHandle);
1255 pth->env = env;
1256 pth->is_query = is_query;
1257 pth->priority = priority;
1258 pth->cp = cp;
1259 /* insertion sort (by priority, descending) */
1260 prev = NULL;
1261 pos = cp->pth_head;
1262 while ((NULL != pos) && (pos->priority > priority))
1263 {
1264 prev = pos;
1265 pos = pos->next;
1266 }
1268 cp->pth_tail,
1269 prev,
1270 pth);
1271 if (GNUNET_YES == is_query)
1273 else if (GNUNET_NO == is_query)
1276}

References GSF_PeerTransmitHandle::cp, env, GSF_PeerTransmitHandle::env, GNUNET_CONTAINER_DLL_insert_after, GNUNET_new, GNUNET_NO, GNUNET_TIME_absolute_get(), GNUNET_YES, GSF_PeerTransmitHandle::is_query, GSF_PeerTransmitHandle::next, GSF_PeerPerformanceData::pending_queries, GSF_PeerPerformanceData::pending_replies, GSF_ConnectedPeer::ppd, GSF_PeerTransmitHandle::prev, GSF_PeerTransmitHandle::priority, GSF_ConnectedPeer::pth_head, GSF_ConnectedPeer::pth_tail, schedule_transmission(), and GSF_PeerTransmitHandle::transmission_request_start_time.

Referenced by GSF_block_peer_migration_(), handle_p2p_reply(), schedule_peer_transmission(), transmit_content(), and transmit_delayed_now().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GSF_peer_update_performance_()

void GSF_peer_update_performance_ ( struct GSF_ConnectedPeer cp,
struct GNUNET_TIME_Absolute  request_time,
uint32_t  request_priority 
)

Report on receiving a reply; update the performance record of the given peer.

Parameters
cpresponding peer (will be updated)
request_timetime at which the original query was transmitted
request_prioritypriority of the original request

Definition at line 1287 of file gnunet-service-fs_cp.c.

1290{
1291 struct GNUNET_TIME_Relative delay;
1292
1293 delay = GNUNET_TIME_absolute_get_duration (request_time);
1296 + delay.rel_value_us) / RUNAVG_DELAY_N;
1297 cp->ppd.avg_priority =
1298 (cp->ppd.avg_priority * (RUNAVG_DELAY_N - 1)
1299 + request_priority) / RUNAVG_DELAY_N;
1300}

References GSF_PeerPerformanceData::avg_priority, GSF_PeerPerformanceData::avg_reply_delay, GNUNET_TIME_absolute_get_duration(), GSF_ConnectedPeer::ppd, GNUNET_TIME_Relative::rel_value_us, and RUNAVG_DELAY_N.

Referenced by update_request_performance_data().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GSF_peer_update_responder_client_()

void GSF_peer_update_responder_client_ ( struct GSF_ConnectedPeer cp,
struct GSF_LocalClient initiator_client 
)

Report on receiving a reply in response to an initiating client.

Remember that this peer is good for this client.

Parameters
cpresponding peer (will be updated)
initiator_clientlocal client on responsible for query

Definition at line 1311 of file gnunet-service-fs_cp.c.

1313{
1315 % CS2P_SUCCESS_LIST_SIZE] = initiator_client;
1316}

References CS2P_SUCCESS_LIST_SIZE, GSF_PeerPerformanceData::last_client_replies, GSF_ConnectedPeer::last_client_replies_woff, and GSF_ConnectedPeer::ppd.

◆ GSF_peer_update_responder_peer_()

void GSF_peer_update_responder_peer_ ( struct GSF_ConnectedPeer cp,
const struct GSF_ConnectedPeer initiator_peer 
)

Report on receiving a reply in response to an initiating peer.

Remember that this peer is good for this initiating peer.

Parameters
cpresponding peer (will be updated)
initiator_peerother peer responsible for query

Definition at line 1327 of file gnunet-service-fs_cp.c.

1329{
1330 unsigned int woff;
1331
1334 cp->ppd.last_p2p_replies[woff] = initiator_peer->ppd.pid;
1335 GNUNET_PEER_change_rc (initiator_peer->ppd.pid, 1);
1337}

References GNUNET_PEER_change_rc(), GSF_PeerPerformanceData::last_p2p_replies, GSF_ConnectedPeer::last_p2p_replies_woff, P2P_SUCCESS_LIST_SIZE, GSF_PeerPerformanceData::pid, and GSF_ConnectedPeer::ppd.

Here is the call graph for this function:

◆ flush_respect()

static int flush_respect ( void *  cls,
const struct GNUNET_PeerIdentity key,
void *  value 
)
static

Write peer-respect information to a file - flush the buffer entry!

Parameters
clsunused
keypeer identity
valuethe struct GSF_ConnectedPeer to flush
Returns
GNUNET_OK to continue iteration

Definition at line 1349 of file gnunet-service-fs_cp.c.

1352{
1353 struct GSF_ConnectedPeer *cp = value;
1354 struct GNUNET_PeerIdentity pid;
1355
1356 if (cp->ppd.respect == cp->disk_respect)
1357 return GNUNET_OK; /* unchanged */
1358 GNUNET_assert (0 != cp->ppd.pid);
1359 GNUNET_PEER_resolve (cp->ppd.pid, &pid);
1360 GNUNET_PEERSTORE_store (peerstore, "fs", &pid, "respect", &cp->ppd.respect,
1361 sizeof(cp->ppd.respect),
1364 NULL,
1365 NULL);
1366 return GNUNET_OK;
1367}

References GSF_ConnectedPeer::disk_respect, GNUNET_assert, GNUNET_OK, GNUNET_PEER_resolve(), GNUNET_PEERSTORE_store(), GNUNET_PEERSTORE_STOREOPTION_REPLACE, GNUNET_TIME_UNIT_FOREVER_ABS, peerstore, GSF_PeerPerformanceData::pid, GSF_ConnectedPeer::ppd, GSF_PeerPerformanceData::respect, and value.

Referenced by cron_flush_respect(), GSF_connected_peer_done_(), and GSF_peer_disconnect_handler().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GSF_peer_disconnect_handler()

void GSF_peer_disconnect_handler ( void *  cls,
const struct GNUNET_PeerIdentity peer,
void *  internal_cls 
)

A peer disconnected from us.

Tear down the connected peer record.

Parameters
clsunused
peeridentity of peer that disconnected
internal_clsthe corresponding struct GSF_ConnectedPeer

Definition at line 1371 of file gnunet-service-fs_cp.c.

1374{
1375 struct GSF_ConnectedPeer *cp = internal_cls;
1376 struct GSF_PeerTransmitHandle *pth;
1377 struct GSF_DelayedHandle *dh;
1378
1379 if (NULL == cp)
1380 return; /* must have been disconnect from core with
1381 * 'peer' == my_id, ignore */
1382 flush_respect (NULL,
1383 peer,
1384 cp);
1387 peer,
1388 cp));
1390 gettext_noop ("# peers connected"),
1392 GNUNET_NO);
1393 if (NULL != cp->respect_iterate_req)
1394 {
1396 cp->respect_iterate_req = NULL;
1397 }
1400 cp);
1402 cp->request_map = NULL;
1407 memset (cp->ppd.last_p2p_replies,
1408 0,
1409 sizeof(cp->ppd.last_p2p_replies));
1411 while (NULL != (pth = cp->pth_head))
1412 {
1414 cp->pth_tail,
1415 pth);
1416 if (GNUNET_YES == pth->is_query)
1418 else if (GNUNET_NO == pth->is_query)
1420 GNUNET_free (pth);
1421 }
1422 while (NULL != (dh = cp->delayed_head))
1423 {
1426 dh);
1427 GNUNET_MQ_discard (dh->env);
1430 GNUNET_free (dh);
1431 }
1433 if (NULL != cp->mig_revive_task)
1434 {
1436 cp->mig_revive_task = NULL;
1437 }
1440 GNUNET_free (cp);
1441}

References cancel_pending_request(), GSF_DelayedHandle::cp, cp_map, GSF_ConnectedPeer::delay_queue_size, GSF_DelayedHandle::delay_task, GSF_ConnectedPeer::delayed_head, GSF_ConnectedPeer::delayed_tail, GSF_DelayedHandle::env, flush_respect(), gettext_noop, GNUNET_assert, GNUNET_break, GNUNET_CONTAINER_DLL_remove, GNUNET_CONTAINER_multihashmap_destroy(), GNUNET_CONTAINER_multihashmap_iterate(), GNUNET_CONTAINER_multipeermap_remove(), GNUNET_CONTAINER_multipeermap_size(), GNUNET_free, GNUNET_LOAD_value_free, GNUNET_MQ_discard(), GNUNET_NO, GNUNET_PEER_change_rc(), GNUNET_PEER_decrement_rcs(), GNUNET_PEERSTORE_iteration_stop(), GNUNET_SCHEDULER_cancel(), GNUNET_STATISTICS_set(), GNUNET_YES, GSF_plan_notify_peer_disconnect_(), GSF_push_stop_(), GSF_stats, GSF_PeerTransmitHandle::is_query, GSF_PeerPerformanceData::last_p2p_replies, GSF_ConnectedPeer::mig_revive_task, P2P_SUCCESS_LIST_SIZE, GSF_PeerPerformanceData::pending_queries, GSF_PeerPerformanceData::pending_replies, GSF_PeerPerformanceData::pid, GSF_ConnectedPeer::ppd, GSF_ConnectedPeer::pth_head, GSF_ConnectedPeer::pth_tail, GSF_ConnectedPeer::request_map, GSF_ConnectedPeer::respect_iterate_req, and GSF_PeerPerformanceData::transmission_delay.

Referenced by main_init().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ call_iterator()

static int call_iterator ( void *  cls,
const struct GNUNET_PeerIdentity key,
void *  value 
)
static

Function that calls the callback for each peer.

Parameters
clsthe struct IterationContext *
keyidentity of the peer
valuethe struct GSF_ConnectedPeer *
Returns
GNUNET_YES to continue iteration

Definition at line 1470 of file gnunet-service-fs_cp.c.

1473{
1474 struct IterationContext *ic = cls;
1475 struct GSF_ConnectedPeer *cp = value;
1476
1477 ic->it (ic->it_cls,
1478 key, cp,
1479 &cp->ppd);
1480 return GNUNET_YES;
1481}

References GNUNET_YES, IterationContext::it, IterationContext::it_cls, key, GSF_ConnectedPeer::ppd, and value.

Referenced by GSF_iterate_connected_peers_().

Here is the caller graph for this function:

◆ GSF_iterate_connected_peers_()

void GSF_iterate_connected_peers_ ( GSF_ConnectedPeerIterator  it,
void *  it_cls 
)

Iterate over all connected peers.

Parameters
itfunction to call for each peer
it_clsclosure for it

Definition at line 1485 of file gnunet-service-fs_cp.c.

1487{
1488 struct IterationContext ic;
1489
1490 ic.it = it;
1491 ic.it_cls = it_cls;
1494 &ic);
1495}

References call_iterator(), cp_map, GNUNET_CONTAINER_multipeermap_iterate(), IterationContext::it, and IterationContext::it_cls.

Referenced by GSF_consider_forwarding().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GSF_connected_peer_get_identity_()

void GSF_connected_peer_get_identity_ ( const struct GSF_ConnectedPeer cp,
struct GNUNET_PeerIdentity id 
)

Obtain the identity of a connected peer.

Parameters
cppeer to get identity of
ididentity to set (written to)

Definition at line 1505 of file gnunet-service-fs_cp.c.

1507{
1508 GNUNET_assert (0 != cp->ppd.pid);
1509 GNUNET_PEER_resolve (cp->ppd.pid, id);
1510}

References GNUNET_assert, GNUNET_PEER_resolve(), GSF_PeerPerformanceData::pid, and GSF_ConnectedPeer::ppd.

Referenced by consider_peer_for_forwarding().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GSF_connected_peer_get_identity2_()

const struct GNUNET_PeerIdentity * GSF_connected_peer_get_identity2_ ( const struct GSF_ConnectedPeer cp)

Obtain the identity of a connected peer.

Parameters
cppeer to get identity of
Returns
reference to peer identity, valid until peer disconnects (!)

Definition at line 1520 of file gnunet-service-fs_cp.c.

1521{
1522 GNUNET_assert (0 != cp->ppd.pid);
1523 return GNUNET_PEER_resolve2 (cp->ppd.pid);
1524}

References GNUNET_assert, GNUNET_PEER_resolve2(), GSF_PeerPerformanceData::pid, and GSF_ConnectedPeer::ppd.

Referenced by GSF_peer_connect_handler(), GSF_plan_add_(), GSF_plan_notify_peer_disconnect_(), GSF_push_start_(), and process_migration_content().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GSF_block_peer_migration_()

void GSF_block_peer_migration_ ( struct GSF_ConnectedPeer cp,
struct GNUNET_TIME_Absolute  block_time 
)

Ask a peer to stop migrating data to us until the given point in time.

Parameters
cppeer to ask
block_timeuntil when to block

Definition at line 1535 of file gnunet-service-fs_cp.c.

1537{
1538 struct GNUNET_MQ_Envelope *env;
1539 struct MigrationStopMessage *msm;
1540
1541 if (cp->last_migration_block.abs_value_us > block_time.abs_value_us)
1542 {
1544 "Migration already blocked for another %s\n",
1547 (cp->
1548 last_migration_block), GNUNET_YES));
1549 return; /* already blocked */
1550 }
1551 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Asking to stop migration for %s\n",
1554 GNUNET_YES));
1555 cp->last_migration_block = block_time;
1556 env = GNUNET_MQ_msg (msm,
1558 msm->reserved = htonl (0);
1559 msm->duration
1561 (cp->last_migration_block));
1563 gettext_noop ("# migration stop messages sent"),
1564 1,
1565 GNUNET_NO);
1568 UINT32_MAX,
1569 env);
1570}

References GNUNET_TIME_Absolute::abs_value_us, MigrationStopMessage::duration, env, gettext_noop, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_MESSAGE_TYPE_FS_MIGRATION_STOP, GNUNET_MQ_msg, GNUNET_NO, GNUNET_STATISTICS_update(), GNUNET_STRINGS_relative_time_to_string(), GNUNET_SYSERR, GNUNET_TIME_absolute_get_remaining(), GNUNET_TIME_relative_hton(), GNUNET_YES, GSF_peer_transmit_(), GSF_stats, GSF_ConnectedPeer::last_migration_block, and MigrationStopMessage::reserved.

Referenced by handle_p2p_put(), and put_migration_continuation().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GSF_connected_peer_change_preference_()

void GSF_connected_peer_change_preference_ ( struct GSF_ConnectedPeer cp,
uint64_t  pref 
)

Notify core about a preference we have for the given peer (to allocate more resources towards it).

The change will be communicated the next time we reserve bandwidth with core (not instantly).

Parameters
cppeer to reserve bandwidth from
prefpreference change

Definition at line 1583 of file gnunet-service-fs_cp.c.

1585{
1586 cp->inc_preference += pref;
1587}

References GSF_ConnectedPeer::inc_preference.

Referenced by handle_p2p_put().

Here is the caller graph for this function:

◆ cron_flush_respect()

static void cron_flush_respect ( void *  cls)
static

Call this method periodically to flush respect information to disk.

Parameters
clsclosure, not used

Definition at line 1596 of file gnunet-service-fs_cp.c.

References cp_map, cron_flush_respect(), flush_respect(), fr_task, GNUNET_CONTAINER_multipeermap_iterate(), GNUNET_SCHEDULER_add_delayed_with_priority(), GNUNET_SCHEDULER_PRIORITY_HIGH, and RESPECT_FLUSH_FREQ.

Referenced by cron_flush_respect(), and GSF_connected_peer_init_().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GSF_connected_peer_init_()

void GSF_connected_peer_init_ ( void  )

Initialize peer management subsystem.

Definition at line 1613 of file gnunet-service-fs_cp.c.

References cp_map, cron_flush_respect(), fr_task, GNUNET_CONTAINER_multipeermap_create(), GNUNET_PEERSTORE_connect(), GNUNET_SCHEDULER_add_with_priority(), GNUNET_SCHEDULER_PRIORITY_HIGH, GNUNET_YES, GSF_cfg, and peerstore.

Referenced by run().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GSF_connected_peer_done_()

void GSF_connected_peer_done_ ( void  )

Shutdown peer management subsystem.

Definition at line 1626 of file gnunet-service-fs_cp.c.

References cp_map, flush_respect(), fr_task, GNUNET_CONTAINER_multipeermap_destroy(), GNUNET_CONTAINER_multipeermap_iterate(), GNUNET_PEERSTORE_disconnect(), GNUNET_SCHEDULER_cancel(), and peerstore.

Referenced by shutdown_task().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ clean_local_client()

static int clean_local_client ( void *  cls,
const struct GNUNET_PeerIdentity key,
void *  value 
)
static

Iterator to remove references to LC entry.

Parameters
clsthe struct GSF_LocalClient * to look for
keycurrent key code
valuevalue in the hash map (peer entry)
Returns
GNUNET_YES (we should continue to iterate)

Definition at line 1648 of file gnunet-service-fs_cp.c.

1651{
1652 const struct GSF_LocalClient *lc = cls;
1653 struct GSF_ConnectedPeer *cp = value;
1654 unsigned int i;
1655
1656 for (i = 0; i < CS2P_SUCCESS_LIST_SIZE; i++)
1657 if (cp->ppd.last_client_replies[i] == lc)
1658 cp->ppd.last_client_replies[i] = NULL;
1659 return GNUNET_YES;
1660}

References CS2P_SUCCESS_LIST_SIZE, GNUNET_YES, GSF_PeerPerformanceData::last_client_replies, GSF_ConnectedPeer::ppd, and value.

Referenced by GSF_handle_local_client_disconnect_().

Here is the caller graph for this function:

◆ GSF_handle_local_client_disconnect_()

void GSF_handle_local_client_disconnect_ ( const struct GSF_LocalClient lc)

Notification that a local client disconnected.

Clean up all of our references to the given handle.

Parameters
lchandle to the local client (henceforth invalid)

Definition at line 1670 of file gnunet-service-fs_cp.c.

1671{
1672 if (NULL == cp_map)
1673 return; /* already cleaned up */
1676 (void *) lc);
1677}

References clean_local_client(), cp_map, and GNUNET_CONTAINER_multipeermap_iterate().

Here is the call graph for this function:

Variable Documentation

◆ cp_map

◆ peerstore

struct GNUNET_PEERSTORE_Handle* peerstore
static

Handle to peerstore service.

Definition at line 273 of file gnunet-service-fs_cp.c.

Referenced by flush_respect(), GSF_connected_peer_done_(), GSF_connected_peer_init_(), and GSF_peer_connect_handler().

◆ fr_task

struct GNUNET_SCHEDULER_Task* fr_task
static

Task used to flush respect values to disk.

Definition at line 278 of file gnunet-service-fs_cp.c.

Referenced by cron_flush_respect(), GSF_connected_peer_done_(), and GSF_connected_peer_init_().