GNUnet  0.16.x
gnunet-service-fs_cp.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2011, 2016 GNUnet e.V.
4 
5  GNUnet is free software: you can redistribute it and/or modify it
6  under the terms of the GNU Affero General Public License as published
7  by the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  GNUnet is distributed in the hope that it will be useful, but
11  WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Affero General Public License for more details.
14 
15  You should have received a copy of the GNU Affero General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 
18  SPDX-License-Identifier: AGPL3.0-or-later
19  */
25 #include "platform.h"
26 #include "gnunet_util_lib.h"
27 #include "gnunet_load_lib.h"
28 #include "gnunet-service-fs.h"
29 #include "gnunet-service-fs_cp.h"
30 #include "gnunet-service-fs_pe.h"
31 #include "gnunet-service-fs_pr.h"
32 #include "gnunet-service-fs_push.h"
34 
35 
41 #define RUNAVG_DELAY_N 16
42 
46 #define RESPECT_FLUSH_FREQ GNUNET_TIME_relative_multiply ( \
47  GNUNET_TIME_UNIT_MINUTES, 5)
48 
52 #define REPLY_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, \
53  2)
54 
58 #define INSANE_STATISTICS GNUNET_NO
59 
60 
65 {
70 
75 
80 
85 
90 
94  int is_query;
95 
100 
104  uint32_t priority;
105 };
106 
107 
112 {
117 
122 
127 
132 
137 
141  size_t msize;
142 };
143 
144 
149 {
154 
159 
164 };
165 
166 
171 {
176 
182 
187 
193 
199 
205 
211 
216 
221 
226 
232 
237  uint64_t inc_preference;
238 
242  unsigned int delay_queue_size;
243 
247  uint32_t disk_respect;
248 
253  unsigned int last_p2p_replies_woff;
254 
260 
265 
271 
276 };
277 
278 
283 
288 
293 
294 
301 void
303  struct GNUNET_TIME_Relative latency)
304 {
305  struct GSF_ConnectedPeer *cp;
306 
307  cp = GSF_peer_get_ (id);
308  if (NULL == cp)
309  return; /* we're not yet connected at the core level, ignore */
311  latency);
312 }
313 
314 
323 {
324  return &cp->ppd;
325 }
326 
327 
333 static void
334 peer_transmit (struct GSF_ConnectedPeer *cp);
335 
336 
347 static void
348 ats_reserve_callback (void *cls,
349  const struct GNUNET_PeerIdentity *peer,
350  int32_t amount,
351  struct GNUNET_TIME_Relative res_delay);
352 
353 
360 static void
362 {
363  struct GSF_ConnectedPeer *cp;
364  struct GNUNET_PeerIdentity target;
365 
366  cp = pth->cp;
367  GNUNET_assert (0 != cp->ppd.pid);
368  GNUNET_PEER_resolve (cp->ppd.pid, &target);
369 
370  if (0 != cp->inc_preference)
371  {
373  &target,
375  (double) cp->inc_preference,
377  cp->inc_preference = 0;
378  }
379 
380  if ((GNUNET_YES == pth->is_query) &&
381  (GNUNET_YES != pth->was_reserved))
382  {
383  /* query, need reservation */
384  if (GNUNET_YES != cp->did_reserve)
385  return; /* not ready */
386  cp->did_reserve = GNUNET_NO;
387  /* reservation already done! */
388  pth->was_reserved = GNUNET_YES;
390  &target,
391  DBLOCK_SIZE,
393  cp);
394  return;
395  }
396  peer_transmit (cp);
397 }
398 
399 
405 static void
407 {
408  struct GSF_PeerTransmitHandle *pth = cp->pth_head;
409  struct GSF_PeerTransmitHandle *pos;
410 
411  if (NULL == pth)
412  return;
414  cp->pth_tail,
415  pth);
416  if (GNUNET_YES == pth->is_query)
417  {
419  % MAX_QUEUE_PER_PEER] =
422  }
423  else if (GNUNET_NO == pth->is_query)
424  {
426  }
430  GNUNET_MQ_send (cp->mq,
431  pth->env);
432  GNUNET_free (pth);
433  if (NULL != (pos = cp->pth_head))
434  {
435  GNUNET_assert (pos != pth);
436  schedule_transmission (pos);
437  }
438 }
439 
440 
446 static void
447 retry_reservation (void *cls)
448 {
449  struct GSF_ConnectedPeer *cp = cls;
450  struct GNUNET_PeerIdentity target;
451 
452  GNUNET_PEER_resolve (cp->ppd.pid, &target);
453  cp->rc_delay_task = NULL;
454  cp->rc =
456  &target,
457  DBLOCK_SIZE,
458  &ats_reserve_callback, cp);
459 }
460 
461 
472 static void
474  const struct GNUNET_PeerIdentity *peer,
475  int32_t amount,
476  struct GNUNET_TIME_Relative res_delay)
477 {
478  struct GSF_ConnectedPeer *cp = cls;
479  struct GSF_PeerTransmitHandle *pth;
480 
482  "Reserved %d bytes / need to wait %s for reservation\n",
483  (int) amount,
485  cp->rc = NULL;
486  if (0 == amount)
487  {
488  cp->rc_delay_task =
489  GNUNET_SCHEDULER_add_delayed (res_delay,
491  cp);
492  return;
493  }
495  pth = cp->pth_head;
496  if (NULL != pth)
497  {
498  /* reservation success, try transmission now! */
499  peer_transmit (cp);
500  }
501 }
502 
503 
511 static void
512 peer_respect_cb (void *cls,
513  const struct GNUNET_PEERSTORE_Record *record,
514  const char *emsg)
515 {
516  struct GSF_ConnectedPeer *cp = cls;
517 
518  GNUNET_assert (NULL != cp->respect_iterate_req);
519  if ((NULL != record) &&
520  (sizeof(cp->disk_respect) == record->value_size))
521  {
522  cp->disk_respect = *((uint32_t *) record->value);
523  cp->ppd.respect += *((uint32_t *) record->value);
524  }
525  GSF_push_start_ (cp);
526  if (NULL != record)
528  cp->respect_iterate_req = NULL;
529 }
530 
531 
542 static int
544  const struct GNUNET_HashCode *key,
545  struct GSF_PendingRequest *pr)
546 {
547  struct GSF_ConnectedPeer *cp = cls;
548  struct GNUNET_PeerIdentity pid;
549 
550  if (GNUNET_YES !=
552  return GNUNET_YES; /* request is not actually active, skip! */
554  if (GNUNET_YES !=
556  {
558  gettext_noop ("# Loopback routes suppressed"),
559  1,
560  GNUNET_NO);
561  return GNUNET_YES;
562  }
563  GSF_plan_add_ (cp, pr);
564  return GNUNET_YES;
565 }
566 
567 
577 void *
579  const struct GNUNET_PeerIdentity *peer,
580  struct GNUNET_MQ_Handle *mq)
581 {
582  struct GSF_ConnectedPeer *cp;
583 
584  if (0 ==
586  peer))
587  return NULL;
589  "Connected to peer %s\n",
590  GNUNET_i2s (peer));
591  cp = GNUNET_new (struct GSF_ConnectedPeer);
592  cp->ppd.pid = GNUNET_PEER_intern (peer);
593  cp->ppd.peer = peer;
594  cp->mq = mq;
596  cp->rc =
598  peer,
599  DBLOCK_SIZE,
600  &ats_reserve_callback, cp);
602  GNUNET_YES);
606  cp),
607  cp,
610  gettext_noop ("# peers connected"),
612  GNUNET_NO);
615  "fs",
616  peer,
617  "respect",
619  cp);
621  cp);
622  return cp;
623 }
624 
625 
632 static void
633 revive_migration (void *cls)
634 {
635  struct GSF_ConnectedPeer *cp = cls;
636  struct GNUNET_TIME_Relative bt;
637 
638  cp->mig_revive_task = NULL;
640  if (0 != bt.rel_value_us)
641  {
642  /* still time left... */
643  cp->mig_revive_task =
645  return;
646  }
647  GSF_push_start_ (cp);
648 }
649 
650 
657 struct GSF_ConnectedPeer *
659 {
660  if (NULL == cp_map)
661  return NULL;
663 }
664 
665 
672 void
674  const struct MigrationStopMessage *msm)
675 {
676  struct GSF_ConnectedPeer *cp = cls;
677  struct GNUNET_TIME_Relative bt;
678 
680  gettext_noop ("# migration stop messages received"),
681  1, GNUNET_NO);
684  _ ("Migration of content to peer `%s' blocked for %s\n"),
685  GNUNET_i2s (cp->ppd.peer),
688  if ((NULL == cp->mig_revive_task) &&
689  (NULL == cp->respect_iterate_req))
690  {
691  GSF_push_stop_ (cp);
692  cp->mig_revive_task =
694  &revive_migration, cp);
695  }
696 }
697 
698 
704 static void
706 {
707  struct GSF_ConnectedPeer *cp = peerreq->cp;
708  struct GSF_PendingRequestData *prd;
709 
710  prd = GSF_pending_request_get_data_ (peerreq->pr);
711  if (NULL != peerreq->kill_task)
712  {
714  peerreq->kill_task = NULL;
715  }
717  gettext_noop ("# P2P searches active"),
718  -1,
719  GNUNET_NO);
722  &prd->query,
723  peerreq));
724  GNUNET_free (peerreq);
725 }
726 
727 
736 static int
738  const struct GNUNET_HashCode *query,
739  void *value)
740 {
741  struct PeerRequest *peerreq = value;
742  struct GSF_PendingRequest *pr = peerreq->pr;
743 
744  free_pending_request (peerreq);
746  GNUNET_NO);
747  return GNUNET_OK;
748 }
749 
750 
756 static void
758 {
759  struct PeerRequest *peerreq = cls;
760  struct GSF_PendingRequest *pr = peerreq->pr;
761  struct GSF_PendingRequestData *prd;
762 
763  peerreq->kill_task = NULL;
766  &prd->query,
767  peerreq);
768 }
769 
770 
776 static void
778 {
779  struct GSF_DelayedHandle *dh = cls;
780  struct GSF_ConnectedPeer *cp = dh->cp;
781 
783  cp->delayed_tail,
784  dh);
785  cp->delay_queue_size--;
786  GSF_peer_transmit_ (cp,
787  GNUNET_NO,
788  UINT32_MAX,
789  dh->env);
790  GNUNET_free (dh);
791 }
792 
793 
799 static struct GNUNET_TIME_Relative
801 {
802  struct GNUNET_TIME_Relative ret;
803 
804  ret =
808  2 * GSF_avg_latency.rel_value_us + 1));
809 #if INSANE_STATISTICS
812  ("# artificial delays introduced (ms)"),
813  ret.rel_value_us / 1000LL, GNUNET_NO);
814 #endif
815  return ret;
816 }
817 
818 
837 static void
838 handle_p2p_reply (void *cls,
840  struct GSF_PendingRequest *pr,
841  uint32_t reply_anonymity_level,
844  enum GNUNET_BLOCK_Type type,
845  const void *data,
846  size_t data_len)
847 {
848  struct PeerRequest *peerreq = cls;
849  struct GSF_ConnectedPeer *cp = peerreq->cp;
850  struct GSF_PendingRequestData *prd;
851  struct GNUNET_MQ_Envelope *env;
852  struct PutMessage *pm;
853  size_t msize;
854 
855  GNUNET_assert (data_len + sizeof(struct PutMessage) <
857  GNUNET_assert (peerreq->pr == pr);
859  if (NULL == data)
860  {
861  free_pending_request (peerreq);
862  return;
863  }
865  if ( (prd->type != type) &&
866  (GNUNET_BLOCK_TYPE_ANY != prd->type) )
867  {
869  "# replies dropped due to type mismatch",
870  1, GNUNET_NO);
871  return;
872  }
874  "Transmitting result for query `%s' to peer\n",
875  GNUNET_h2s (&prd->query));
877  "# replies received for other peers",
878  1,
879  GNUNET_NO);
880  msize = sizeof(struct PutMessage) + data_len;
881  if (msize >= GNUNET_MAX_MESSAGE_SIZE)
882  {
883  GNUNET_break (0);
884  return;
885  }
886  if ( (UINT32_MAX != reply_anonymity_level) &&
887  (reply_anonymity_level > 1) )
888  {
889  if (reply_anonymity_level - 1 > GSF_cover_content_count)
890  {
892  "# replies dropped due to insufficient cover traffic",
893  1, GNUNET_NO);
894  return;
895  }
896  GSF_cover_content_count -= (reply_anonymity_level - 1);
897  }
898 
900  data_len,
902  pm->type = htonl (type);
903  pm->expiration = GNUNET_TIME_absolute_hton (expiration);
904  GNUNET_memcpy (&pm[1],
905  data,
906  data_len);
907  if ((UINT32_MAX != reply_anonymity_level) &&
908  (0 != reply_anonymity_level) &&
910  {
911  struct GSF_DelayedHandle *dh;
912 
913  dh = GNUNET_new (struct GSF_DelayedHandle);
914  dh->cp = cp;
915  dh->env = env;
916  dh->msize = msize;
918  cp->delayed_tail,
919  dh);
920  cp->delay_queue_size++;
921  dh->delay_task =
924  dh);
925  }
926  else
927  {
929  GNUNET_NO,
930  UINT32_MAX,
931  env);
932  }
933  if (GNUNET_BLOCK_REPLY_OK_LAST != eval)
934  return;
935  if (NULL == peerreq->kill_task)
936  {
938  "# P2P searches destroyed due to ultimate reply",
939  1,
940  GNUNET_NO);
941  peerreq->kill_task =
943  peerreq);
944  }
945 }
946 
947 
956 static int
958 {
959  if (0 == value)
960  return 0;
961  GNUNET_assert (NULL != cp);
962  if (value > 0)
963  {
964  if (cp->ppd.respect + value < cp->ppd.respect)
965  {
966  value = UINT32_MAX - cp->ppd.respect;
967  cp->ppd.respect = UINT32_MAX;
968  }
969  else
970  cp->ppd.respect += value;
971  }
972  else
973  {
974  if (cp->ppd.respect < -value)
975  {
976  value = -cp->ppd.respect;
977  cp->ppd.respect = 0;
978  }
979  else
980  cp->ppd.respect += value;
981  }
982  return value;
983 }
984 
985 
994 static int32_t
995 bound_priority (uint32_t prio_in,
996  struct GSF_ConnectedPeer *cp)
997 {
998 #define N ((double) 128.0)
999  uint32_t ret;
1000  double rret;
1001  int ld;
1002 
1003  ld = GSF_test_get_load_too_high_ (0);
1004  if (GNUNET_SYSERR == ld)
1005  {
1006 #if INSANE_STATISTICS
1008  gettext_noop
1009  ("# requests done for free (low load)"), 1,
1010  GNUNET_NO);
1011 #endif
1012  return 0; /* excess resources */
1013  }
1014  if (prio_in > INT32_MAX)
1015  prio_in = INT32_MAX;
1016  ret = -change_peer_respect (cp, -(int) prio_in);
1017  if (ret > 0)
1018  {
1019  if (ret > GSF_current_priorities + N)
1020  rret = GSF_current_priorities + N;
1021  else
1022  rret = ret;
1023  GSF_current_priorities = (GSF_current_priorities * (N - 1) + rret) / N;
1024  }
1025  if ((GNUNET_YES == ld) && (ret > 0))
1026  {
1027  /* try with charging */
1029  }
1030  if (GNUNET_YES == ld)
1031  {
1033  gettext_noop
1034  ("# request dropped, priority insufficient"), 1,
1035  GNUNET_NO);
1036  /* undo charge */
1037  change_peer_respect (cp, (int) ret);
1038  return -1; /* not enough resources */
1039  }
1040  else
1041  {
1043  gettext_noop
1044  ("# requests done for a price (normal load)"),
1045  1,
1046  GNUNET_NO);
1047  }
1048 #undef N
1049  return ret;
1050 }
1051 
1052 
1062 static int32_t
1063 bound_ttl (int32_t ttl_in,
1064  uint32_t prio)
1065 {
1066  unsigned long long allowed;
1067 
1068  if (ttl_in <= 0)
1069  return ttl_in;
1070  allowed = ((unsigned long long) prio) * TTL_DECREMENT / 1000;
1071  if (ttl_in > allowed)
1072  {
1073  if (allowed >= (1 << 30))
1074  return 1 << 30;
1075  return allowed;
1076  }
1077  return ttl_in;
1078 }
1079 
1080 
1085 {
1089  int32_t priority;
1090 
1094  int32_t ttl;
1095 
1099  enum GNUNET_BLOCK_Type type;
1100 
1105 };
1106 
1107 
1118 static int
1119 test_exist_cb (void *cls,
1120  const struct GNUNET_HashCode *hc,
1121  void *value)
1122 {
1123  struct TestExistClosure *tec = cls;
1124  struct PeerRequest *peerreq = value;
1125  struct GSF_PendingRequest *pr;
1126  struct GSF_PendingRequestData *prd;
1127 
1128  pr = peerreq->pr;
1129  prd = GSF_pending_request_get_data_ (pr);
1130  if (prd->type != tec->type)
1131  return GNUNET_YES;
1132  if (prd->ttl.abs_value_us >=
1133  GNUNET_TIME_absolute_get ().abs_value_us + tec->ttl * 1000LL)
1134  {
1135  /* existing request has higher TTL, drop new one! */
1136  prd->priority += tec->priority;
1138  "Have existing request with higher TTL, dropping new request.\n");
1140  gettext_noop
1141  ("# requests dropped due to higher-TTL request"),
1142  1, GNUNET_NO);
1143  tec->finished = GNUNET_YES;
1144  return GNUNET_NO;
1145  }
1146  /* existing request has lower TTL, drop old one! */
1147  tec->priority += prd->priority;
1148  free_pending_request (peerreq);
1150  GNUNET_YES);
1151  return GNUNET_NO;
1152 }
1153 
1154 
1164 void
1165 handle_p2p_get (void *cls,
1166  const struct GetMessage *gm)
1167 {
1168  struct GSF_ConnectedPeer *cps = cls;
1169  struct PeerRequest *peerreq;
1170  struct GSF_PendingRequest *pr;
1171  struct GSF_ConnectedPeer *cp;
1172  const struct GNUNET_PeerIdentity *target;
1174  uint16_t msize;
1175  unsigned int bits;
1176  const struct GNUNET_PeerIdentity *opt;
1177  uint32_t bm;
1178  size_t bfsize;
1179  uint32_t ttl_decrement;
1180  struct TestExistClosure tec;
1181  GNUNET_PEER_Id spid;
1182  const struct GSF_PendingRequestData *prd;
1183 
1184  msize = ntohs (gm->header.size);
1185  tec.type = ntohl (gm->type);
1186  bm = ntohl (gm->hash_bitmap);
1187  bits = 0;
1188  while (bm > 0)
1189  {
1190  if (1 == (bm & 1))
1191  bits++;
1192  bm >>= 1;
1193  }
1194  opt = (const struct GNUNET_PeerIdentity *) &gm[1];
1195  bfsize = msize - sizeof(struct GetMessage) - bits * sizeof(struct
1198  gettext_noop
1199  ("# GET requests received (from other peers)"),
1200  1,
1201  GNUNET_NO);
1203  bm = ntohl (gm->hash_bitmap);
1204  bits = 0;
1205  if (0 != (bm & GET_MESSAGE_BIT_RETURN_TO))
1206  cp = GSF_peer_get_ (&opt[bits++]);
1207  else
1208  cp = cps;
1209  if (NULL == cp)
1210  {
1211  if (0 != (bm & GET_MESSAGE_BIT_RETURN_TO))
1213  "Failed to find RETURN-TO peer `%s' in connection set. Dropping query.\n",
1214  GNUNET_i2s (&opt[bits - 1]));
1215 
1216  else
1218  "Failed to find peer `%s' in connection set. Dropping query.\n",
1219  GNUNET_i2s (cps->ppd.peer));
1221  gettext_noop
1222  (
1223  "# requests dropped due to missing reverse route"),
1224  1,
1225  GNUNET_NO);
1226  return;
1227  }
1228  unsigned int queue_size = GNUNET_MQ_get_length (cp->mq);
1229  queue_size += cp->ppd.pending_replies + cp->delay_queue_size;
1230  if (queue_size > MAX_QUEUE_PER_PEER)
1231  {
1233  "Peer `%s' has too many replies queued already. Dropping query.\n",
1234  GNUNET_i2s (cps->ppd.peer));
1236  gettext_noop (
1237  "# requests dropped due to full reply queue"),
1238  1,
1239  GNUNET_NO);
1240  return;
1241  }
1242  /* note that we can really only check load here since otherwise
1243  * peers could find out that we are overloaded by not being
1244  * disconnected after sending us a malformed query... */
1245  tec.priority = bound_priority (ntohl (gm->priority),
1246  cps);
1247  if (tec.priority < 0)
1248  {
1250  "Dropping query from `%s', this peer is too busy.\n",
1251  GNUNET_i2s (cps->ppd.peer));
1252  return;
1253  }
1255  "Received request for `%s' of type %u from peer `%s' with flags %u\n",
1256  GNUNET_h2s (&gm->query),
1257  (unsigned int) tec.type,
1258  GNUNET_i2s (cps->ppd.peer),
1259  (unsigned int) bm);
1260  target =
1261  (0 !=
1262  (bm & GET_MESSAGE_BIT_TRANSMIT_TO)) ? (&opt[bits++]) : NULL;
1264  spid = 0;
1265  if ((GNUNET_LOAD_get_load (cp->ppd.transmission_delay) > 3 * (1
1266  + tec.priority))
1268  GNUNET_CONSTANTS_MAX_CORK_DELAY.rel_value_us * 2
1270  {
1271  /* don't have BW to send to peer, or would likely take longer than we have for it,
1272  * so at best indirect the query */
1273  tec.priority = 0;
1275  spid = GNUNET_PEER_intern (cps->ppd.peer);
1276  GNUNET_assert (0 != spid);
1277  }
1278  tec.ttl = bound_ttl (ntohl (gm->ttl),
1279  tec.priority);
1280  /* decrement ttl (always) */
1281  ttl_decrement =
1283  TTL_DECREMENT);
1284  if ((tec.ttl < 0) &&
1285  (((int32_t) (tec.ttl - ttl_decrement)) > 0))
1286  {
1288  "Dropping query from `%s' due to TTL underflow (%d - %u).\n",
1289  GNUNET_i2s (cps->ppd.peer),
1290  tec.ttl,
1291  ttl_decrement);
1293  gettext_noop
1294  ("# requests dropped due TTL underflow"), 1,
1295  GNUNET_NO);
1296  /* integer underflow => drop (should be very rare)! */
1297  return;
1298  }
1299  tec.ttl -= ttl_decrement;
1300 
1301  /* test if the request already exists */
1302  tec.finished = GNUNET_NO;
1304  &gm->query,
1305  &test_exist_cb,
1306  &tec);
1307  if (GNUNET_YES == tec.finished)
1308  return; /* merged into existing request, we're done */
1309 
1310  peerreq = GNUNET_new (struct PeerRequest);
1311  peerreq->cp = cp;
1313  tec.type,
1314  &gm->query,
1315  target,
1316  (bfsize > 0)
1317  ? (const char *) &opt[bits]
1318  : NULL,
1319  bfsize,
1320  ntohl (gm->filter_mutator),
1321  1 /* anonymity */,
1322  (uint32_t) tec.priority,
1323  tec.ttl,
1324  spid,
1325  GNUNET_PEER_intern (cps->ppd.peer),
1326  NULL, 0, /* replies_seen */
1328  peerreq);
1329  GNUNET_assert (NULL != pr);
1330  prd = GSF_pending_request_get_data_ (pr);
1331  peerreq->pr = pr;
1334  &prd->query,
1335  peerreq,
1338  gettext_noop (
1339  "# P2P query messages received and processed"),
1340  1,
1341  GNUNET_NO);
1343  gettext_noop ("# P2P searches active"),
1344  1,
1345  GNUNET_NO);
1347  GSF_local_lookup_ (pr,
1349  NULL);
1350 }
1351 
1352 
1365 void
1367  int is_query,
1368  uint32_t priority,
1369  struct GNUNET_MQ_Envelope *env)
1370 {
1371  struct GSF_PeerTransmitHandle *pth;
1372  struct GSF_PeerTransmitHandle *pos;
1373  struct GSF_PeerTransmitHandle *prev;
1374 
1375  pth = GNUNET_new (struct GSF_PeerTransmitHandle);
1377  pth->env = env;
1378  pth->is_query = is_query;
1379  pth->priority = priority;
1380  pth->cp = cp;
1381  /* insertion sort (by priority, descending) */
1382  prev = NULL;
1383  pos = cp->pth_head;
1384  while ((NULL != pos) && (pos->priority > priority))
1385  {
1386  prev = pos;
1387  pos = pos->next;
1388  }
1390  cp->pth_tail,
1391  prev,
1392  pth);
1393  if (GNUNET_YES == is_query)
1394  cp->ppd.pending_queries++;
1395  else if (GNUNET_NO == is_query)
1396  cp->ppd.pending_replies++;
1397  schedule_transmission (pth);
1398 }
1399 
1400 
1408 void
1410  struct GNUNET_TIME_Absolute request_time,
1411  uint32_t request_priority)
1412 {
1413  struct GNUNET_TIME_Relative delay;
1414 
1415  delay = GNUNET_TIME_absolute_get_duration (request_time);
1419  cp->ppd.avg_priority =
1420  (cp->ppd.avg_priority * (RUNAVG_DELAY_N - 1)
1421  + request_priority) / RUNAVG_DELAY_N;
1422 }
1423 
1424 
1432 void
1434  struct GSF_LocalClient *initiator_client)
1435 {
1437  % CS2P_SUCCESS_LIST_SIZE] = initiator_client;
1438 }
1439 
1440 
1448 void
1450  const struct GSF_ConnectedPeer *initiator_peer)
1451 {
1452  unsigned int woff;
1453 
1455  GNUNET_PEER_change_rc (cp->ppd.last_p2p_replies[woff], -1);
1456  cp->ppd.last_p2p_replies[woff] = initiator_peer->ppd.pid;
1457  GNUNET_PEER_change_rc (initiator_peer->ppd.pid, 1);
1458  cp->last_p2p_replies_woff = (woff + 1) % P2P_SUCCESS_LIST_SIZE;
1459 }
1460 
1461 
1470 static int
1471 flush_respect (void *cls,
1472  const struct GNUNET_PeerIdentity *key,
1473  void *value)
1474 {
1475  struct GSF_ConnectedPeer *cp = value;
1476  struct GNUNET_PeerIdentity pid;
1477 
1478  if (cp->ppd.respect == cp->disk_respect)
1479  return GNUNET_OK; /* unchanged */
1480  GNUNET_assert (0 != cp->ppd.pid);
1481  GNUNET_PEER_resolve (cp->ppd.pid, &pid);
1482  GNUNET_PEERSTORE_store (peerstore, "fs", &pid, "respect", &cp->ppd.respect,
1483  sizeof(cp->ppd.respect),
1486  NULL,
1487  NULL);
1488  return GNUNET_OK;
1489 }
1490 
1491 
1500 void
1502  const struct GNUNET_PeerIdentity *peer,
1503  void *internal_cls)
1504 {
1505  struct GSF_ConnectedPeer *cp = internal_cls;
1506  struct GSF_PeerTransmitHandle *pth;
1507  struct GSF_DelayedHandle *dh;
1508 
1509  if (NULL == cp)
1510  return; /* must have been disconnect from core with
1511  * 'peer' == my_id, ignore */
1512  flush_respect (NULL,
1513  peer,
1514  cp);
1517  peer,
1518  cp));
1520  gettext_noop ("# peers connected"),
1522  GNUNET_NO);
1523  if (NULL != cp->respect_iterate_req)
1524  {
1526  cp->respect_iterate_req = NULL;
1527  }
1528  if (NULL != cp->rc)
1529  {
1531  cp->rc = NULL;
1532  }
1533  if (NULL != cp->rc_delay_task)
1534  {
1536  cp->rc_delay_task = NULL;
1537  }
1540  cp);
1542  cp->request_map = NULL;
1547  memset (cp->ppd.last_p2p_replies,
1548  0,
1549  sizeof(cp->ppd.last_p2p_replies));
1550  GSF_push_stop_ (cp);
1551  while (NULL != (pth = cp->pth_head))
1552  {
1554  cp->pth_tail,
1555  pth);
1556  if (GNUNET_YES == pth->is_query)
1558  else if (GNUNET_NO == pth->is_query)
1560  GNUNET_free (pth);
1561  }
1562  while (NULL != (dh = cp->delayed_head))
1563  {
1565  cp->delayed_tail,
1566  dh);
1567  GNUNET_MQ_discard (dh->env);
1568  cp->delay_queue_size--;
1570  GNUNET_free (dh);
1571  }
1573  if (NULL != cp->mig_revive_task)
1574  {
1576  cp->mig_revive_task = NULL;
1577  }
1580  GNUNET_free (cp);
1581 }
1582 
1583 
1588 {
1593 
1597  void *it_cls;
1598 };
1599 
1600 
1609 static int
1610 call_iterator (void *cls,
1611  const struct GNUNET_PeerIdentity *key,
1612  void *value)
1613 {
1614  struct IterationContext *ic = cls;
1615  struct GSF_ConnectedPeer *cp = value;
1616 
1617  ic->it (ic->it_cls,
1618  key, cp,
1619  &cp->ppd);
1620  return GNUNET_YES;
1621 }
1622 
1623 
1630 void
1632  void *it_cls)
1633 {
1634  struct IterationContext ic;
1635 
1636  ic.it = it;
1637  ic.it_cls = it_cls;
1639  &call_iterator,
1640  &ic);
1641 }
1642 
1643 
1650 void
1652  struct GNUNET_PeerIdentity *id)
1653 {
1654  GNUNET_assert (0 != cp->ppd.pid);
1655  GNUNET_PEER_resolve (cp->ppd.pid, id);
1656 }
1657 
1658 
1665 const struct GNUNET_PeerIdentity *
1667 {
1668  GNUNET_assert (0 != cp->ppd.pid);
1669  return GNUNET_PEER_resolve2 (cp->ppd.pid);
1670 }
1671 
1672 
1680 void
1682  struct GNUNET_TIME_Absolute block_time)
1683 {
1684  struct GNUNET_MQ_Envelope *env;
1685  struct MigrationStopMessage *msm;
1686 
1687  if (cp->last_migration_block.abs_value_us > block_time.abs_value_us)
1688  {
1690  "Migration already blocked for another %s\n",
1693  (cp->
1694  last_migration_block), GNUNET_YES));
1695  return; /* already blocked */
1696  }
1697  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Asking to stop migration for %s\n",
1700  GNUNET_YES));
1701  cp->last_migration_block = block_time;
1702  env = GNUNET_MQ_msg (msm,
1704  msm->reserved = htonl (0);
1705  msm->duration
1707  (cp->last_migration_block));
1709  gettext_noop ("# migration stop messages sent"),
1710  1,
1711  GNUNET_NO);
1712  GSF_peer_transmit_ (cp,
1713  GNUNET_SYSERR,
1714  UINT32_MAX,
1715  env);
1716 }
1717 
1718 
1728 void
1730  uint64_t pref)
1731 {
1732  cp->inc_preference += pref;
1733 }
1734 
1735 
1741 static void
1743 {
1744  fr_task = NULL;
1746  &flush_respect,
1747  NULL);
1751  NULL);
1752 }
1753 
1754 
1758 void
1760 {
1764  &cron_flush_respect, NULL);
1765 }
1766 
1767 
1771 void
1773 {
1775  &flush_respect,
1776  NULL);
1778  fr_task = NULL;
1780  cp_map = NULL;
1782  GNUNET_YES);
1783 }
1784 
1785 
1794 static int
1796  const struct GNUNET_PeerIdentity *key,
1797  void *value)
1798 {
1799  const struct GSF_LocalClient *lc = cls;
1800  struct GSF_ConnectedPeer *cp = value;
1801  unsigned int i;
1802 
1803  for (i = 0; i < CS2P_SUCCESS_LIST_SIZE; i++)
1804  if (cp->ppd.last_client_replies[i] == lc)
1805  cp->ppd.last_client_replies[i] = NULL;
1806  return GNUNET_YES;
1807 }
1808 
1809 
1816 void
1818 {
1819  if (NULL == cp_map)
1820  return; /* already cleaned up */
1823  (void *) lc);
1824 }
1825 
1826 
1827 /* end of gnunet-service-fs_cp.c */
struct GNUNET_GETOPT_CommandLineOption options[]
Definition: 002.c:5
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
#define DBLOCK_SIZE
Size of the individual blocks used for file-sharing.
Definition: fs.h:40
#define gettext_noop(String)
Definition: gettext.h:69
static char * expiration
Credential TTL.
Definition: gnunet-abd.c:96
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
static void record(void *cls, size_t data_size, const void *data)
Process recorded audio data.
struct GNUNET_HashCode key
The key used in the DHT.
uint32_t data
The data value.
static char * value
Value of the record to add/remove.
static struct GNUNET_TIME_Relative delay
When should dkg communication start?
int GSF_enable_randomized_delays
Are we introducing randomized delays for better anonymity?
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.
struct GNUNET_PeerIdentity GSF_my_id
Identity of this peer.
struct GNUNET_ATS_PerformanceHandle * GSF_ats
Handle to ATS service.
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?
shared data structures of gnunet-service-fs.c
#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.
const struct GNUNET_PeerIdentity * GSF_connected_peer_get_identity2_(const struct GSF_ConnectedPeer *cp)
Obtain the identity of a connected peer.
static void cron_flush_respect(void *cls)
Call this method periodically to flush respect information to disk.
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.
struct GSF_ConnectedPeer * GSF_peer_get_(const struct GNUNET_PeerIdentity *peer)
Get a handle for a connected peer.
static void ats_reserve_callback(void *cls, const struct GNUNET_PeerIdentity *peer, int32_t amount, struct GNUNET_TIME_Relative res_delay)
Function called by core upon success or failure of our bandwidth reservation request.
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.
static void retry_reservation(void *cls)
(re)try to reserve bandwidth from the given 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.
void * GSF_peer_connect_handler(void *cls, const struct GNUNET_PeerIdentity *peer, struct GNUNET_MQ_Handle *mq)
A peer connected to us.
static struct GNUNET_CONTAINER_MultiPeerMap * cp_map
Map from peer identities to struct GSF_ConnectPeer entries.
void GSF_connected_peer_init_()
Initialize peer management subsystem.
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.
struct GSF_PeerPerformanceData * GSF_get_peer_performance_data_(struct GSF_ConnectedPeer *cp)
Return the performance data record for the given peer.
API to handle 'connected peers'.
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.
API to manage query plan.
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?
void GSF_iterate_pending_requests_(GSF_PendingRequestIterator it, void *cls)
Iterate over all pending requests.
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 mingle, 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_local_lookup_(struct GSF_PendingRequest *pr, GSF_LocalLookupContinuation cont, void *cont_cls)
Look up the request in the local datastore.
int GSF_pending_request_test_active_(struct GSF_PendingRequest *pr)
Check if the given request is still active.
struct GSF_PendingRequestData * GSF_pending_request_get_data_(struct GSF_PendingRequest *pr)
Obtain the public data associated with a pending request.
void GSF_pending_request_cancel_(struct GSF_PendingRequest *pr, int full_cleanup)
Explicitly cancel a pending request.
API to handle pending requests.
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.
support for pushing out content
static struct GNUNET_PeerIdentity pid
Identity of the peer we transmit to / connect to.
static struct GNUNET_TRANSPORT_PluginMonitor * pm
Handle if we are monitoring plugin session activity.
#define GNUNET_log(kind,...)
@ GNUNET_SCHEDULER_PRIORITY_HIGH
Run with high priority (important requests).
#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.
@ GNUNET_OK
Definition: gnunet_common.h:95
@ GNUNET_YES
Definition: gnunet_common.h:97
@ GNUNET_NO
Definition: gnunet_common.h:94
@ GNUNET_SYSERR
Definition: gnunet_common.h:93
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.
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message,...
void GNUNET_ATS_reserve_bandwidth_cancel(struct GNUNET_ATS_ReservationContext *rc)
Cancel request for reserving bandwidth.
void GNUNET_ATS_performance_change_preference(struct GNUNET_ATS_PerformanceHandle *ph, const struct GNUNET_PeerIdentity *peer,...)
Change preferences for the given peer.
struct GNUNET_ATS_ReservationContext * GNUNET_ATS_reserve_bandwidth(struct GNUNET_ATS_PerformanceHandle *ph, const struct GNUNET_PeerIdentity *peer, int32_t amount, GNUNET_ATS_ReservationCallback rcb, void *rcb_cls)
Reserve inbound bandwidth from the given peer.
@ GNUNET_ATS_PREFERENCE_BANDWIDTH
Change the peer's bandwidth value (value per byte of bandwidth in the goal function) to the given amo...
@ GNUNET_ATS_PREFERENCE_END
End of preference list.
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)?
uint32_t GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i)
Produce a random value.
@ GNUNET_CRYPTO_QUALITY_WEAK
No good quality of the operation is needed (i.e., random numbers can be pseudo-random).
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_CONTAINER_DLL_insert_after(head, tail, other, element)
Insert an element into a DLL after the given other element.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
int GNUNET_CONTAINER_multihashmap_get_multiple(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, GNUNET_CONTAINER_MulitHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map that match a particular key.
int 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.
void GNUNET_CONTAINER_multipeermap_destroy(struct GNUNET_CONTAINER_MultiPeerMap *map)
Destroy a hash map.
int GNUNET_CONTAINER_multipeermap_iterate(struct GNUNET_CONTAINER_MultiPeerMap *map, GNUNET_CONTAINER_PeerMapIterator it, void *it_cls)
Iterate over all entries in the map.
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
int 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.
int GNUNET_CONTAINER_multihashmap_iterate(struct GNUNET_CONTAINER_MultiHashMap *map, GNUNET_CONTAINER_MulitHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map.
struct GNUNET_CONTAINER_MultiPeerMap * GNUNET_CONTAINER_multipeermap_create(unsigned int len, int do_not_copy_keys)
Create a multi peer map (hash map for public keys of peers).
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
int GNUNET_CONTAINER_multipeermap_remove(struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key, const void *value)
Remove the given key-value pair from the map.
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.
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.
@ 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...
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_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:291
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:302
void GNUNET_MQ_discard(struct GNUNET_MQ_Envelope *mqm)
Discard the message queue message, free all allocated resources.
Definition: mq.c:283
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct.
Definition: gnunet_mq_lib.h:52
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:67
void GNUNET_PEER_decrement_rcs(const GNUNET_PEER_Id *ids, unsigned int count)
Decrement multiple RCs of peer identities by one.
Definition: peer.c:162
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:197
void GNUNET_PEER_resolve(GNUNET_PEER_Id id, struct GNUNET_PeerIdentity *pid)
Convert an interned PID to a normal peer identity.
Definition: peer.c:225
const struct GNUNET_PeerIdentity * GNUNET_PEER_resolve2(GNUNET_PEER_Id id)
Convert an interned PID to a normal peer identity.
Definition: peer.c:245
GNUNET_PEER_Id GNUNET_PEER_intern(const struct GNUNET_PeerIdentity *pid)
Intern an peer identity.
Definition: peer.c:107
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_iterate_cancel(struct GNUNET_PEERSTORE_IterateContext *ic)
Cancel an iterate request Please do not call after the iterate request is done.
void GNUNET_PEERSTORE_disconnect(struct GNUNET_PEERSTORE_Handle *h, int sync_first)
Disconnect from the PEERSTORE service.
struct GNUNET_PEERSTORE_IterateContext * GNUNET_PEERSTORE_iterate(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 records matching supplied key information.
@ 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.
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:1281
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:1184
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:1208
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:957
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:1254
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:627
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:435
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:404
#define GNUNET_TIME_UNIT_MILLISECONDS
One millisecond.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:110
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:315
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:483
#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:617
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:570
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition: time.c:637
#define GNUNET_TIME_UNIT_FOREVER_ABS
Constant used to specify "forever".
#define _(String)
GNU gettext support macro.
Definition: platform.h:177
static GNUNET_CronTime last_transmission
Linked list of pending reservations.
Internal representation of the hash map.
Internal representation of the hash map.
A 512-bit hashcode.
Handle to a message queue.
Definition: mq.c:86
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
Handle to the PEERSTORE service.
Definition: peerstore_api.c:41
Context for a iterate request.
Single PEERSTORE record.
The identity of the host (wraps the signing key of the peer).
Entry in list of pending tasks.
Definition: scheduler.c:135
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.
A connected peer.
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.
int did_reserve
GNUNET_YES if we did successfully reserve 32k bandwidth, GNUNET_NO if not.
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 GNUNET_ATS_ReservationContext * rc
Context of our GNUNET_ATS_reserve_bandwidth call (or NULL).
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.
int was_reserved
Did we get a reservation already?
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)
uint32_t filter_mutator
The content hash should be mutated using this value before checking against the bloomfilter (used to ...
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:329
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.
enum GNUNET_TESTBED_UnderlayLinkModelType type
the type of this model
struct GNUNET_TESTBED_Peer * peer
The peer associated with this model.