GNUnet  0.10.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(GNUNET_TIME_UNIT_MINUTES, 5)
47 
51 #define REPLY_TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 2)
52 
56 #define INSANE_STATISTICS GNUNET_NO
57 
58 
67 
72 
77 
82 
87 
91  int is_query;
92 
97 
101  uint32_t priority;
102 };
103 
104 
113 
118 
123 
128 
133 
137  size_t msize;
138 };
139 
140 
144 struct PeerRequest {
149 
154 
159 };
160 
161 
170 
175  struct GNUNET_TIME_Absolute last_migration_block;
176 
181 
187 
193 
199 
205 
210 
215 
220 
226 
231  uint64_t inc_preference;
232 
236  unsigned int delay_queue_size;
237 
241  uint32_t disk_respect;
242 
247  unsigned int last_p2p_replies_woff;
248 
254 
259 
265 
270 };
271 
272 
277 
282 
287 
288 
295 void
297  struct GNUNET_TIME_Relative latency)
298 {
299  struct GSF_ConnectedPeer *cp;
300 
301  cp = GSF_peer_get_(id);
302  if (NULL == cp)
303  return; /* we're not yet connected at the core level, ignore */
305  latency);
306 }
307 
308 
317 {
318  return &cp->ppd;
319 }
320 
321 
327 static void
329 
330 
341 static void
342 ats_reserve_callback(void *cls,
343  const struct GNUNET_PeerIdentity *peer,
344  int32_t amount,
345  struct GNUNET_TIME_Relative res_delay);
346 
347 
354 static void
356 {
357  struct GSF_ConnectedPeer *cp;
358  struct GNUNET_PeerIdentity target;
359 
360  cp = pth->cp;
361  GNUNET_assert(0 != cp->ppd.pid);
362  GNUNET_PEER_resolve(cp->ppd.pid, &target);
363 
364  if (0 != cp->inc_preference)
365  {
367  &target,
369  (double)cp->inc_preference,
371  cp->inc_preference = 0;
372  }
373 
374  if ((GNUNET_YES == pth->is_query) &&
375  (GNUNET_YES != pth->was_reserved))
376  {
377  /* query, need reservation */
378  if (GNUNET_YES != cp->did_reserve)
379  return; /* not ready */
380  cp->did_reserve = GNUNET_NO;
381  /* reservation already done! */
382  pth->was_reserved = GNUNET_YES;
384  &target,
385  DBLOCK_SIZE,
387  cp);
388  return;
389  }
390  peer_transmit(cp);
391 }
392 
393 
399 static void
401 {
402  struct GSF_PeerTransmitHandle *pth = cp->pth_head;
403  struct GSF_PeerTransmitHandle *pos;
404 
405  if (NULL == pth)
406  return;
408  cp->pth_tail,
409  pth);
410  if (GNUNET_YES == pth->is_query)
411  {
415  GNUNET_assert(0 < cp->ppd.pending_queries--);
416  }
417  else if (GNUNET_NO == pth->is_query)
418  {
419  GNUNET_assert(0 < cp->ppd.pending_replies--);
420  }
424  GNUNET_MQ_send(cp->mq,
425  pth->env);
426  GNUNET_free(pth);
427  if (NULL != (pos = cp->pth_head))
428  {
429  GNUNET_assert(pos != pth);
431  }
432 }
433 
434 
440 static void
442 {
443  struct GSF_ConnectedPeer *cp = cls;
444  struct GNUNET_PeerIdentity target;
445 
446  GNUNET_PEER_resolve(cp->ppd.pid, &target);
447  cp->rc_delay_task = NULL;
448  cp->rc =
450  &target,
451  DBLOCK_SIZE,
452  &ats_reserve_callback, cp);
453 }
454 
455 
466 static void
468  const struct GNUNET_PeerIdentity *peer,
469  int32_t amount,
470  struct GNUNET_TIME_Relative res_delay)
471 {
472  struct GSF_ConnectedPeer *cp = cls;
473  struct GSF_PeerTransmitHandle *pth;
474 
476  "Reserved %d bytes / need to wait %s for reservation\n",
477  (int)amount,
479  cp->rc = NULL;
480  if (0 == amount)
481  {
482  cp->rc_delay_task =
485  cp);
486  return;
487  }
488  cp->did_reserve = GNUNET_YES;
489  pth = cp->pth_head;
490  if (NULL != pth)
491  {
492  /* reservation success, try transmission now! */
493  peer_transmit(cp);
494  }
495 }
496 
497 
505 static void
506 peer_respect_cb(void *cls,
507  const struct GNUNET_PEERSTORE_Record *record,
508  const char *emsg)
509 {
510  struct GSF_ConnectedPeer *cp = cls;
511 
512  GNUNET_assert(NULL != cp->respect_iterate_req);
513  if ((NULL != record) &&
514  (sizeof(cp->disk_respect) == record->value_size))
515  {
516  cp->disk_respect = *((uint32_t *)record->value);
517  cp->ppd.respect += *((uint32_t *)record->value);
518  }
519  GSF_push_start_(cp);
520  if (NULL != record)
522  cp->respect_iterate_req = NULL;
523 }
524 
525 
536 static int
538  const struct GNUNET_HashCode *key,
539  struct GSF_PendingRequest *pr)
540 {
541  struct GSF_ConnectedPeer *cp = cls;
542  struct GNUNET_PeerIdentity pid;
543 
544  if (GNUNET_YES !=
546  return GNUNET_YES; /* request is not actually active, skip! */
548  if (GNUNET_YES !=
550  {
552  gettext_noop("# Loopback routes suppressed"),
553  1,
554  GNUNET_NO);
555  return GNUNET_YES;
556  }
557  GSF_plan_add_(cp, pr);
558  return GNUNET_YES;
559 }
560 
561 
571 void *
573  const struct GNUNET_PeerIdentity *peer,
574  struct GNUNET_MQ_Handle *mq)
575 {
576  struct GSF_ConnectedPeer *cp;
577 
578  if (0 ==
580  peer))
581  return NULL;
583  "Connected to peer %s\n",
584  GNUNET_i2s(peer));
585  cp = GNUNET_new(struct GSF_ConnectedPeer);
586  cp->ppd.pid = GNUNET_PEER_intern(peer);
587  cp->ppd.peer = peer;
588  cp->mq = mq;
590  cp->rc =
592  peer,
593  DBLOCK_SIZE,
594  &ats_reserve_callback, cp);
596  GNUNET_YES);
600  cp,
603  gettext_noop("# peers connected"),
605  GNUNET_NO);
607  = GNUNET_PEERSTORE_iterate(peerstore,
608  "fs",
609  peer,
610  "respect",
612  cp);
614  cp);
615  return cp;
616 }
617 
618 
625 static void
627 {
628  struct GSF_ConnectedPeer *cp = cls;
629  struct GNUNET_TIME_Relative bt;
630 
631  cp->mig_revive_task = NULL;
633  if (0 != bt.rel_value_us)
634  {
635  /* still time left... */
636  cp->mig_revive_task =
638  return;
639  }
640  GSF_push_start_(cp);
641 }
642 
643 
650 struct GSF_ConnectedPeer *
652 {
653  if (NULL == cp_map)
654  return NULL;
655  return GNUNET_CONTAINER_multipeermap_get(cp_map, peer);
656 }
657 
658 
665 void
667  const struct MigrationStopMessage *msm)
668 {
669  struct GSF_ConnectedPeer *cp = cls;
670  struct GNUNET_TIME_Relative bt;
671 
673  gettext_noop("# migration stop messages received"),
674  1, GNUNET_NO);
677  _("Migration of content to peer `%s' blocked for %s\n"),
678  GNUNET_i2s(cp->ppd.peer),
681  if ((NULL == cp->mig_revive_task) &&
682  (NULL == cp->respect_iterate_req))
683  {
684  GSF_push_stop_(cp);
685  cp->mig_revive_task =
687  &revive_migration, cp);
688  }
689 }
690 
691 
697 static void
699 {
700  struct GSF_ConnectedPeer *cp = peerreq->cp;
701  struct GSF_PendingRequestData *prd;
702 
703  prd = GSF_pending_request_get_data_(peerreq->pr);
704  if (NULL != peerreq->kill_task)
705  {
707  peerreq->kill_task = NULL;
708  }
710  gettext_noop("# P2P searches active"),
711  -1,
712  GNUNET_NO);
715  &prd->query,
716  peerreq));
717  GNUNET_free(peerreq);
718 }
719 
720 
729 static int
731  const struct GNUNET_HashCode *query,
732  void *value)
733 {
734  struct PeerRequest *peerreq = value;
735  struct GSF_PendingRequest *pr = peerreq->pr;
736 
737  free_pending_request(peerreq);
739  GNUNET_NO);
740  return GNUNET_OK;
741 }
742 
743 
749 static void
751 {
752  struct PeerRequest *peerreq = cls;
753  struct GSF_PendingRequest *pr = peerreq->pr;
754  struct GSF_PendingRequestData *prd;
755 
756  peerreq->kill_task = NULL;
759  &prd->query,
760  peerreq);
761 }
762 
763 
769 static void
771 {
772  struct GSF_DelayedHandle *dh = cls;
773  struct GSF_ConnectedPeer *cp = dh->cp;
774 
776  cp->delayed_tail,
777  dh);
778  cp->delay_queue_size--;
780  GNUNET_NO,
781  UINT32_MAX,
782  dh->env);
783  GNUNET_free(dh);
784 }
785 
786 
792 static struct GNUNET_TIME_Relative
794 {
795  struct GNUNET_TIME_Relative ret;
796 
797  ret =
801  2 * GSF_avg_latency.rel_value_us + 1));
802 #if INSANE_STATISTICS
805  ("# artificial delays introduced (ms)"),
806  ret.rel_value_us / 1000LL, GNUNET_NO);
807 #endif
808  return ret;
809 }
810 
811 
830 static void
833  struct GSF_PendingRequest *pr,
834  uint32_t reply_anonymity_level,
837  enum GNUNET_BLOCK_Type type,
838  const void *data,
839  size_t data_len)
840 {
841  struct PeerRequest *peerreq = cls;
842  struct GSF_ConnectedPeer *cp = peerreq->cp;
843  struct GSF_PendingRequestData *prd;
844  struct GNUNET_MQ_Envelope *env;
845  struct PutMessage *pm;
846  size_t msize;
847 
848  GNUNET_assert(data_len + sizeof(struct PutMessage) <
850  GNUNET_assert(peerreq->pr == pr);
852  if (NULL == data)
853  {
854  free_pending_request(peerreq);
855  return;
856  }
858  if ((prd->type != type) && (GNUNET_BLOCK_TYPE_ANY != prd->type))
859  {
862  ("# replies dropped due to type mismatch"),
863  1, GNUNET_NO);
864  return;
865  }
867  "Transmitting result for query `%s' to peer\n",
868  GNUNET_h2s(&prd->query));
870  gettext_noop("# replies received for other peers"),
871  1, GNUNET_NO);
872  msize = sizeof(struct PutMessage) + data_len;
873  if (msize >= GNUNET_MAX_MESSAGE_SIZE)
874  {
875  GNUNET_break(0);
876  return;
877  }
878  if ((UINT32_MAX != reply_anonymity_level) && (reply_anonymity_level > 1))
879  {
880  if (reply_anonymity_level - 1 > GSF_cover_content_count)
881  {
884  ("# replies dropped due to insufficient cover traffic"),
885  1, GNUNET_NO);
886  return;
887  }
888  GSF_cover_content_count -= (reply_anonymity_level - 1);
889  }
890 
891  env = GNUNET_MQ_msg_extra(pm,
892  data_len,
894  pm->type = htonl(type);
895  pm->expiration = GNUNET_TIME_absolute_hton(expiration);
896  GNUNET_memcpy(&pm[1],
897  data,
898  data_len);
899  if ((UINT32_MAX != reply_anonymity_level) &&
900  (0 != reply_anonymity_level) &&
902  {
903  struct GSF_DelayedHandle *dh;
904 
905  dh = GNUNET_new(struct GSF_DelayedHandle);
906  dh->cp = cp;
907  dh->env = env;
908  dh->msize = msize;
910  cp->delayed_tail,
911  dh);
912  cp->delay_queue_size++;
913  dh->delay_task =
916  dh);
917  }
918  else
919  {
921  GNUNET_NO,
922  UINT32_MAX,
923  env);
924  }
926  return;
927  if (NULL == peerreq->kill_task)
928  {
931  ("# P2P searches destroyed due to ultimate reply"),
932  1,
933  GNUNET_NO);
934  peerreq->kill_task =
936  peerreq);
937  }
938 }
939 
940 
949 static int
951 {
952  if (0 == value)
953  return 0;
954  GNUNET_assert(NULL != cp);
955  if (value > 0)
956  {
957  if (cp->ppd.respect + value < cp->ppd.respect)
958  {
959  value = UINT32_MAX - cp->ppd.respect;
960  cp->ppd.respect = UINT32_MAX;
961  }
962  else
963  cp->ppd.respect += value;
964  }
965  else
966  {
967  if (cp->ppd.respect < -value)
968  {
969  value = -cp->ppd.respect;
970  cp->ppd.respect = 0;
971  }
972  else
973  cp->ppd.respect += value;
974  }
975  return value;
976 }
977 
978 
987 static int32_t
988 bound_priority(uint32_t prio_in,
989  struct GSF_ConnectedPeer *cp)
990 {
991 #define N ((double)128.0)
992  uint32_t ret;
993  double rret;
994  int ld;
995 
997  if (GNUNET_SYSERR == ld)
998  {
999 #if INSANE_STATISTICS
1001  gettext_noop
1002  ("# requests done for free (low load)"), 1,
1003  GNUNET_NO);
1004 #endif
1005  return 0; /* excess resources */
1006  }
1007  if (prio_in > INT32_MAX)
1008  prio_in = INT32_MAX;
1009  ret = -change_peer_respect(cp, -(int)prio_in);
1010  if (ret > 0)
1011  {
1012  if (ret > GSF_current_priorities + N)
1013  rret = GSF_current_priorities + N;
1014  else
1015  rret = ret;
1016  GSF_current_priorities = (GSF_current_priorities * (N - 1) + rret) / N;
1017  }
1018  if ((GNUNET_YES == ld) && (ret > 0))
1019  {
1020  /* try with charging */
1021  ld = GSF_test_get_load_too_high_(ret);
1022  }
1023  if (GNUNET_YES == ld)
1024  {
1026  gettext_noop
1027  ("# request dropped, priority insufficient"), 1,
1028  GNUNET_NO);
1029  /* undo charge */
1030  change_peer_respect(cp, (int)ret);
1031  return -1; /* not enough resources */
1032  }
1033  else
1034  {
1036  gettext_noop
1037  ("# requests done for a price (normal load)"), 1,
1038  GNUNET_NO);
1039  }
1040 #undef N
1041  return ret;
1042 }
1043 
1044 
1054 static int32_t
1055 bound_ttl(int32_t ttl_in,
1056  uint32_t prio)
1057 {
1058  unsigned long long allowed;
1059 
1060  if (ttl_in <= 0)
1061  return ttl_in;
1062  allowed = ((unsigned long long)prio) * TTL_DECREMENT / 1000;
1063  if (ttl_in > allowed)
1064  {
1065  if (allowed >= (1 << 30))
1066  return 1 << 30;
1067  return allowed;
1068  }
1069  return ttl_in;
1070 }
1071 
1072 
1080  int32_t priority;
1081 
1085  int32_t ttl;
1086 
1091 
1096 };
1097 
1098 
1109 static int
1110 test_exist_cb(void *cls,
1111  const struct GNUNET_HashCode *hc,
1112  void *value)
1113 {
1114  struct TestExistClosure *tec = cls;
1115  struct PeerRequest *peerreq = value;
1116  struct GSF_PendingRequest *pr;
1117  struct GSF_PendingRequestData *prd;
1118 
1119  pr = peerreq->pr;
1121  if (prd->type != tec->type)
1122  return GNUNET_YES;
1123  if (prd->ttl.abs_value_us >=
1124  GNUNET_TIME_absolute_get().abs_value_us + tec->ttl * 1000LL)
1125  {
1126  /* existing request has higher TTL, drop new one! */
1127  prd->priority += tec->priority;
1129  "Have existing request with higher TTL, dropping new request.\n");
1131  gettext_noop
1132  ("# requests dropped due to higher-TTL request"),
1133  1, GNUNET_NO);
1134  tec->finished = GNUNET_YES;
1135  return GNUNET_NO;
1136  }
1137  /* existing request has lower TTL, drop old one! */
1138  tec->priority += prd->priority;
1139  free_pending_request(peerreq);
1141  GNUNET_YES);
1142  return GNUNET_NO;
1143 }
1144 
1145 
1155 void
1156 handle_p2p_get(void *cls,
1157  const struct GetMessage *gm)
1158 {
1159  struct GSF_ConnectedPeer *cps = cls;
1160  struct PeerRequest *peerreq;
1161  struct GSF_PendingRequest *pr;
1162  struct GSF_ConnectedPeer *cp;
1163  const struct GNUNET_PeerIdentity *target;
1165  uint16_t msize;
1166  unsigned int bits;
1167  const struct GNUNET_PeerIdentity *opt;
1168  uint32_t bm;
1169  size_t bfsize;
1170  uint32_t ttl_decrement;
1171  struct TestExistClosure tec;
1172  GNUNET_PEER_Id spid;
1173  const struct GSF_PendingRequestData *prd;
1174 
1175  msize = ntohs(gm->header.size);
1176  tec.type = ntohl(gm->type);
1177  bm = ntohl(gm->hash_bitmap);
1178  bits = 0;
1179  while (bm > 0)
1180  {
1181  if (1 == (bm & 1))
1182  bits++;
1183  bm >>= 1;
1184  }
1185  opt = (const struct GNUNET_PeerIdentity *)&gm[1];
1186  bfsize = msize - sizeof(struct GetMessage) - bits * sizeof(struct GNUNET_PeerIdentity);
1188  gettext_noop
1189  ("# GET requests received (from other peers)"),
1190  1,
1191  GNUNET_NO);
1193  bm = ntohl(gm->hash_bitmap);
1194  bits = 0;
1195  if (0 != (bm & GET_MESSAGE_BIT_RETURN_TO))
1196  cp = GSF_peer_get_(&opt[bits++]);
1197  else
1198  cp = cps;
1199  if (NULL == cp)
1200  {
1201  if (0 != (bm & GET_MESSAGE_BIT_RETURN_TO))
1203  "Failed to find RETURN-TO peer `%s' in connection set. Dropping query.\n",
1204  GNUNET_i2s(&opt[bits - 1]));
1205 
1206  else
1208  "Failed to find peer `%s' in connection set. Dropping query.\n",
1209  GNUNET_i2s(cps->ppd.peer));
1211  gettext_noop
1212  ("# requests dropped due to missing reverse route"),
1213  1,
1214  GNUNET_NO);
1215  return;
1216  }
1217  unsigned int queue_size = GNUNET_MQ_get_length(cp->mq);
1218  queue_size += cp->ppd.pending_replies + cp->delay_queue_size;
1219  if (queue_size > MAX_QUEUE_PER_PEER)
1220  {
1222  "Peer `%s' has too many replies queued already. Dropping query.\n",
1223  GNUNET_i2s(cps->ppd.peer));
1225  gettext_noop("# requests dropped due to full reply queue"),
1226  1,
1227  GNUNET_NO);
1228  return;
1229  }
1230  /* note that we can really only check load here since otherwise
1231  * peers could find out that we are overloaded by not being
1232  * disconnected after sending us a malformed query... */
1233  tec.priority = bound_priority(ntohl(gm->priority),
1234  cps);
1235  if (tec.priority < 0)
1236  {
1238  "Dropping query from `%s', this peer is too busy.\n",
1239  GNUNET_i2s(cps->ppd.peer));
1240  return;
1241  }
1243  "Received request for `%s' of type %u from peer `%s' with flags %u\n",
1244  GNUNET_h2s(&gm->query),
1245  (unsigned int)tec.type,
1246  GNUNET_i2s(cps->ppd.peer),
1247  (unsigned int)bm);
1248  target =
1249  (0 !=
1250  (bm & GET_MESSAGE_BIT_TRANSMIT_TO)) ? (&opt[bits++]) : NULL;
1251  options = GSF_PRO_DEFAULTS;
1252  spid = 0;
1253  if ((GNUNET_LOAD_get_load(cp->ppd.transmission_delay) > 3 * (1 + tec.priority))
1255  GNUNET_CONSTANTS_MAX_CORK_DELAY.rel_value_us * 2 +
1257  {
1258  /* don't have BW to send to peer, or would likely take longer than we have for it,
1259  * so at best indirect the query */
1260  tec.priority = 0;
1261  options |= GSF_PRO_FORWARD_ONLY;
1262  spid = GNUNET_PEER_intern(cps->ppd.peer);
1263  GNUNET_assert(0 != spid);
1264  }
1265  tec.ttl = bound_ttl(ntohl(gm->ttl),
1266  tec.priority);
1267  /* decrement ttl (always) */
1268  ttl_decrement =
1270  TTL_DECREMENT);
1271  if ((tec.ttl < 0) &&
1272  (((int32_t)(tec.ttl - ttl_decrement)) > 0))
1273  {
1275  "Dropping query from `%s' due to TTL underflow (%d - %u).\n",
1276  GNUNET_i2s(cps->ppd.peer),
1277  tec.ttl,
1278  ttl_decrement);
1280  gettext_noop
1281  ("# requests dropped due TTL underflow"), 1,
1282  GNUNET_NO);
1283  /* integer underflow => drop (should be very rare)! */
1284  return;
1285  }
1286  tec.ttl -= ttl_decrement;
1287 
1288  /* test if the request already exists */
1289  tec.finished = GNUNET_NO;
1291  &gm->query,
1292  &test_exist_cb,
1293  &tec);
1294  if (GNUNET_YES == tec.finished)
1295  return; /* merged into existing request, we're done */
1296 
1297  peerreq = GNUNET_new(struct PeerRequest);
1298  peerreq->cp = cp;
1299  pr = GSF_pending_request_create_(options,
1300  tec.type,
1301  &gm->query,
1302  target,
1303  (bfsize > 0)
1304  ? (const char *)&opt[bits]
1305  : NULL,
1306  bfsize,
1307  ntohl(gm->filter_mutator),
1308  1 /* anonymity */,
1309  (uint32_t)tec.priority,
1310  tec.ttl,
1311  spid,
1312  GNUNET_PEER_intern(cps->ppd.peer),
1313  NULL, 0, /* replies_seen */
1315  peerreq);
1316  GNUNET_assert(NULL != pr);
1318  peerreq->pr = pr;
1321  &prd->query,
1322  peerreq,
1325  gettext_noop("# P2P query messages received and processed"),
1326  1,
1327  GNUNET_NO);
1329  gettext_noop("# P2P searches active"),
1330  1,
1331  GNUNET_NO);
1333  GSF_local_lookup_(pr,
1335  NULL);
1336 }
1337 
1338 
1351 void
1353  int is_query,
1354  uint32_t priority,
1355  struct GNUNET_MQ_Envelope *env)
1356 {
1357  struct GSF_PeerTransmitHandle *pth;
1358  struct GSF_PeerTransmitHandle *pos;
1359  struct GSF_PeerTransmitHandle *prev;
1360 
1361  pth = GNUNET_new(struct GSF_PeerTransmitHandle);
1363  pth->env = env;
1364  pth->is_query = is_query;
1365  pth->priority = priority;
1366  pth->cp = cp;
1367  /* insertion sort (by priority, descending) */
1368  prev = NULL;
1369  pos = cp->pth_head;
1370  while ((NULL != pos) && (pos->priority > priority))
1371  {
1372  prev = pos;
1373  pos = pos->next;
1374  }
1376  cp->pth_tail,
1377  prev,
1378  pth);
1379  if (GNUNET_YES == is_query)
1380  cp->ppd.pending_queries++;
1381  else if (GNUNET_NO == is_query)
1382  cp->ppd.pending_replies++;
1383  schedule_transmission(pth);
1384 }
1385 
1386 
1394 void
1396  struct GNUNET_TIME_Absolute request_time,
1397  uint32_t request_priority)
1398 {
1399  struct GNUNET_TIME_Relative delay;
1400 
1401  delay = GNUNET_TIME_absolute_get_duration(request_time);
1404  delay.rel_value_us) / RUNAVG_DELAY_N;
1405  cp->ppd.avg_priority =
1406  (cp->ppd.avg_priority * (RUNAVG_DELAY_N - 1) +
1407  request_priority) / RUNAVG_DELAY_N;
1408 }
1409 
1410 
1418 void
1420  struct GSF_LocalClient *initiator_client)
1421 {
1423  CS2P_SUCCESS_LIST_SIZE] = initiator_client;
1424 }
1425 
1426 
1434 void
1436  const struct GSF_ConnectedPeer *initiator_peer)
1437 {
1438  unsigned int woff;
1439 
1442  cp->ppd.last_p2p_replies[woff] = initiator_peer->ppd.pid;
1443  GNUNET_PEER_change_rc(initiator_peer->ppd.pid, 1);
1444  cp->last_p2p_replies_woff = (woff + 1) % P2P_SUCCESS_LIST_SIZE;
1445 }
1446 
1447 
1456 static int
1457 flush_respect(void *cls,
1458  const struct GNUNET_PeerIdentity *key,
1459  void *value)
1460 {
1461  struct GSF_ConnectedPeer *cp = value;
1462  struct GNUNET_PeerIdentity pid;
1463 
1464  if (cp->ppd.respect == cp->disk_respect)
1465  return GNUNET_OK; /* unchanged */
1466  GNUNET_assert(0 != cp->ppd.pid);
1467  GNUNET_PEER_resolve(cp->ppd.pid, &pid);
1468  GNUNET_PEERSTORE_store(peerstore, "fs", &pid, "respect", &cp->ppd.respect,
1469  sizeof(cp->ppd.respect),
1472  NULL,
1473  NULL);
1474  return GNUNET_OK;
1475 }
1476 
1477 
1486 void
1488  const struct GNUNET_PeerIdentity *peer,
1489  void *internal_cls)
1490 {
1491  struct GSF_ConnectedPeer *cp = internal_cls;
1492  struct GSF_PeerTransmitHandle *pth;
1493  struct GSF_DelayedHandle *dh;
1494 
1495  if (NULL == cp)
1496  return; /* must have been disconnect from core with
1497  * 'peer' == my_id, ignore */
1498  flush_respect(NULL,
1499  peer,
1500  cp);
1503  peer,
1504  cp));
1506  gettext_noop("# peers connected"),
1508  GNUNET_NO);
1509  if (NULL != cp->respect_iterate_req)
1510  {
1512  cp->respect_iterate_req = NULL;
1513  }
1514  if (NULL != cp->rc)
1515  {
1517  cp->rc = NULL;
1518  }
1519  if (NULL != cp->rc_delay_task)
1520  {
1522  cp->rc_delay_task = NULL;
1523  }
1526  cp);
1528  cp->request_map = NULL;
1533  memset(cp->ppd.last_p2p_replies,
1534  0,
1535  sizeof(cp->ppd.last_p2p_replies));
1536  GSF_push_stop_(cp);
1537  while (NULL != (pth = cp->pth_head))
1538  {
1540  cp->pth_tail,
1541  pth);
1542  if (GNUNET_YES == pth->is_query)
1543  GNUNET_assert(0 < cp->ppd.pending_queries--);
1544  else if (GNUNET_NO == pth->is_query)
1545  GNUNET_assert(0 < cp->ppd.pending_replies--);
1546  GNUNET_free(pth);
1547  }
1548  while (NULL != (dh = cp->delayed_head))
1549  {
1551  cp->delayed_tail,
1552  dh);
1553  GNUNET_MQ_discard(dh->env);
1554  cp->delay_queue_size--;
1556  GNUNET_free(dh);
1557  }
1558  GNUNET_PEER_change_rc(cp->ppd.pid, -1);
1559  if (NULL != cp->mig_revive_task)
1560  {
1562  cp->mig_revive_task = NULL;
1563  }
1564  GNUNET_break(0 == cp->ppd.pending_queries);
1565  GNUNET_break(0 == cp->ppd.pending_replies);
1566  GNUNET_free(cp);
1567 }
1568 
1569 
1578 
1582  void *it_cls;
1583 };
1584 
1585 
1594 static int
1595 call_iterator(void *cls,
1596  const struct GNUNET_PeerIdentity *key,
1597  void *value)
1598 {
1599  struct IterationContext *ic = cls;
1600  struct GSF_ConnectedPeer *cp = value;
1601 
1602  ic->it(ic->it_cls,
1603  key, cp,
1604  &cp->ppd);
1605  return GNUNET_YES;
1606 }
1607 
1608 
1615 void
1617  void *it_cls)
1618 {
1619  struct IterationContext ic;
1620 
1621  ic.it = it;
1622  ic.it_cls = it_cls;
1624  &call_iterator,
1625  &ic);
1626 }
1627 
1628 
1635 void
1637  struct GNUNET_PeerIdentity *id)
1638 {
1639  GNUNET_assert(0 != cp->ppd.pid);
1640  GNUNET_PEER_resolve(cp->ppd.pid, id);
1641 }
1642 
1643 
1650 const struct GNUNET_PeerIdentity *
1652 {
1653  GNUNET_assert(0 != cp->ppd.pid);
1654  return GNUNET_PEER_resolve2(cp->ppd.pid);
1655 }
1656 
1657 
1665 void
1667  struct GNUNET_TIME_Absolute block_time)
1668 {
1669  struct GNUNET_MQ_Envelope *env;
1670  struct MigrationStopMessage *msm;
1671 
1672  if (cp->last_migration_block.abs_value_us > block_time.abs_value_us)
1673  {
1675  "Migration already blocked for another %s\n",
1678  return; /* already blocked */
1679  }
1680  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Asking to stop migration for %s\n",
1682  GNUNET_YES));
1683  cp->last_migration_block = block_time;
1684  env = GNUNET_MQ_msg(msm,
1686  msm->reserved = htonl(0);
1687  msm->duration
1689  (cp->last_migration_block));
1691  gettext_noop("# migration stop messages sent"),
1692  1,
1693  GNUNET_NO);
1694  GSF_peer_transmit_(cp,
1695  GNUNET_SYSERR,
1696  UINT32_MAX,
1697  env);
1698 }
1699 
1700 
1710 void
1712  uint64_t pref)
1713 {
1714  cp->inc_preference += pref;
1715 }
1716 
1717 
1723 static void
1725 {
1726  fr_task = NULL;
1728  &flush_respect,
1729  NULL);
1732  &cron_flush_respect, NULL);
1733 }
1734 
1735 
1739 void
1741 {
1743  peerstore = GNUNET_PEERSTORE_connect(GSF_cfg);
1745  &cron_flush_respect, NULL);
1746 }
1747 
1748 
1752 void
1754 {
1756  &flush_respect,
1757  NULL);
1758  GNUNET_SCHEDULER_cancel(fr_task);
1759  fr_task = NULL;
1761  cp_map = NULL;
1762  GNUNET_PEERSTORE_disconnect(peerstore,
1763  GNUNET_YES);
1764 }
1765 
1766 
1775 static int
1777  const struct GNUNET_PeerIdentity *key,
1778  void *value)
1779 {
1780  const struct GSF_LocalClient *lc = cls;
1781  struct GSF_ConnectedPeer *cp = value;
1782  unsigned int i;
1783 
1784  for (i = 0; i < CS2P_SUCCESS_LIST_SIZE; i++)
1785  if (cp->ppd.last_client_replies[i] == lc)
1786  cp->ppd.last_client_replies[i] = NULL;
1787  return GNUNET_YES;
1788 }
1789 
1790 
1797 void
1799 {
1800  if (NULL == cp_map)
1801  return; /* already cleaned up */
1804  (void *)lc);
1805 }
1806 
1807 
1808 /* end of gnunet-service-fs_cp.c */
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)...
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
const struct GNUNET_PeerIdentity * GNUNET_PEER_resolve2(GNUNET_PEER_Id id)
Convert an interned PID to a normal peer identity.
Definition: peer.c:245
API to handle &#39;connected peers&#39;.
struct GNUNET_CONTAINER_MultiHashMap * request_map
Active requests from this neighbour, map of query to struct PeerRequest.
unsigned int pending_queries
Number of pending queries (replies are not counted)
static int call_iterator(void *cls, const struct GNUNET_PeerIdentity *key, void *value)
Function that calls the callback for each peer.
Closure for call_iterator().
#define P2P_SUCCESS_LIST_SIZE
Length of the P2P success tracker.
int is_query
GNUNET_YES if this is a query, GNUNET_NO for content.
Run with high priority (important requests).
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.
int GSF_enable_randomized_delays
Are we introducing randomized delays for better anonymity?
static char * expiration
Credential TTL.
void GSF_plan_add_(struct GSF_ConnectedPeer *cp, struct GSF_PendingRequest *pr)
Create a new query plan entry.
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_DATASTORE_GET.
Definition: datastore.h:140
void GSF_connected_peer_get_identity_(const struct GSF_ConnectedPeer *cp, struct GNUNET_PeerIdentity *id)
Obtain the identity of a connected peer.
uint64_t rel_value_us
The actual value.
struct GNUNET_LOAD_Value * GNUNET_LOAD_value_init(struct GNUNET_TIME_Relative autodecline)
Create a new load value.
Definition: load.c:122
static int32_t bound_priority(uint32_t prio_in, struct GSF_ConnectedPeer *cp)
We&#39;ve received a request with the specified priority.
#define CS2P_SUCCESS_LIST_SIZE
Length of the CS-2-P success tracker.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
void GSF_push_stop_(struct GSF_ConnectedPeer *peer)
A peer disconnected from us.
Any type of block, used as a wildcard when searching.
static GNUNET_CronTime last_transmission
void GSF_connected_peer_init_()
Initialize peer management subsystem.
Response from FS service with a result for a previous FS search.
Definition: fs.h:321
struct GNUNET_GETOPT_CommandLineOption options[]
Definition: 002.c:5
Information per peer and request.
struct GNUNET_TIME_AbsoluteNBO expiration
When does this result expire?
Definition: fs.h:335
void handle_p2p_get(void *cls, const struct GetMessage *gm)
Handle P2P "QUERY" message.
#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 ...
int32_t ttl
Relative time to live in MILLISECONDS (network byte order)
static int cancel_pending_request(void *cls, const struct GNUNET_HashCode *query, void *value)
Cancel all requests associated with the peer.
size_t msize
Size of the message.
GNUNET_BLOCK_Type
Blocks in the datastore and the datacache must have a unique type.
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:1169
struct GSF_PeerTransmitHandle * next
Kept in a doubly-linked list.
double GSF_current_priorities
Typical priorities we&#39;re seeing from other peers right now.
uint32_t priority
How important is this request (network byte order)
Delete any previous values for the given key before storing the given value.
struct GNUNET_TIME_Absolute ttl
Current TTL for the request.
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.
Handle for an entry in our delay list.
void GSF_peer_disconnect_handler(void *cls, const struct GNUNET_PeerIdentity *peer, void *internal_cls)
A peer disconnected from us.
size_t value_size
Size of value BLOB.
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...
const struct GNUNET_PeerIdentity * peer
The peer&#39;s identity (pointer).
#define RUNAVG_DELAY_N
Ratio for moving average delay calculation.
struct GNUNET_TIME_Absolute GNUNET_TIME_relative_to_absolute(struct GNUNET_TIME_Relative rel)
Convert relative time to an absolute time in the future.
Definition: time.c:246
uint32_t GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i)
Produce a random value.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
No special options (P2P-default).
static struct GNUNET_CONTAINER_MultiPeerMap * cp_map
Map from peer identities to struct GSF_ConnectPeer entries.
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.
struct GSF_PendingRequest * pr
Handle to generic request (generic: from peer or local client).
double GNUNET_LOAD_get_load(struct GNUNET_LOAD_Value *load)
Get the current load.
Definition: load.c:199
struct GNUNET_ATS_PerformanceHandle * GSF_ats
Handle to ATS service.
static void handle_p2p_reply(void *cls, enum GNUNET_BLOCK_EvaluationResult 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.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
struct GSF_DelayedHandle * next
Kept in a doubly-linked list.
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:67
unsigned int GSF_cover_query_count
How many query messages have we received &#39;recently&#39; that have not yet been claimed as cover traffic...
struct GNUNET_STATISTICS_Handle * GSF_stats
Handle for reporting statistics.
int GNUNET_CONTAINER_multipeermap_remove(struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key, const void *value)
Remove the given key-value pair from the map.
#define GNUNET_NO
Definition: gnunet_common.h:78
double GNUNET_LOAD_get_average(struct GNUNET_LOAD_Value *load)
Get the average value given to update so far.
Definition: load.c:214
unsigned int last_client_replies_woff
Which offset in last_client_replies will be updated next? (we go round-robin).
shared data structures of gnunet-service-fs.c
const char * GNUNET_h2s(const struct GNUNET_HashCode *hc)
Convert a hash value to a string (for printing debug messages).
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
struct GSF_PeerTransmitHandle * pth_head
Messages (replies, queries, content migration) we would like to send to this peer in the near future...
static int test_exist_cb(void *cls, const struct GNUNET_HashCode *hc, void *value)
Test if the query already exists.
struct GSF_ConnectedPeer * cp
Peer this request targets.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
struct GNUNET_SCHEDULER_Task * rc_delay_task
Task scheduled if we need to retry bandwidth reservation later.
struct GSF_DelayedHandle * delayed_tail
Messages (replies, queries, content migration) we would like to send to this peer in the near future...
uint32_t disk_respect
Respect rating for this peer on disk.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
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.
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_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).
static int ret
Final status code.
Definition: gnunet-arm.c:89
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
uint64_t abs_value_us
The actual value.
GSF_ConnectedPeerIterator it
Function to call on each entry.
const struct GNUNET_CONFIGURATION_Handle * GSF_cfg
Our configuration.
void GSF_iterate_connected_peers_(GSF_ConnectedPeerIterator it, void *it_cls)
Iterate over all connected peers.
Internal representation of the hash map.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
uint32_t filter_mutator
The content hash should be mutated using this value before checking against the bloomfilter (used to ...
int did_reserve
GNUNET_YES if we did successfully reserve 32k bandwidth, GNUNET_NO if not.
End of preference list.
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 GNUNET_CONTAINER_multipeermap_destroy(struct GNUNET_CONTAINER_MultiPeerMap *map)
Destroy a hash map.
void GNUNET_LOAD_update(struct GNUNET_LOAD_Value *load, uint64_t data)
Update the current load.
Definition: load.c:235
#define GNUNET_TIME_UNIT_FOREVER_ABS
Constant used to specify "forever".
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
struct GNUNET_HashCode query
Primary query hash for this request.
A local client.
static void free_pending_request(struct PeerRequest *peerreq)
Free resources associated with the given peer request.
static struct GNUNET_TIME_Relative get_randomized_delay()
Get the randomized delay a response should be subjected to.
API to handle pending requests.
Public data (in the sense of not encapsulated within &#39;gnunet-service-fs_pr&#39;, not in the sense of netw...
enum GNUNET_BLOCK_Type type
Type of the incoming request.
double avg_priority
Average priority of successful replies.
#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
static void peer_request_destroy(void *cls)
Free the given request.
struct GNUNET_TIME_Relative avg_reply_delay
Average delay between sending the peer a request and getting a reply (only calculated over the reques...
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:1237
API to manage query plan.
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 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:1191
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.
unsigned int GNUNET_PEER_Id
A GNUNET_PEER_Id is simply a shorter version of a "struct GNUNET_PeerIdentifier" that can be used ins...
struct GSF_DelayedHandle * delayed_head
Messages (replies, queries, content migration) we would like to send to this peer in the near future...
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.
void * value
Record value BLOB.
unsigned int pending_replies
Number of pending replies (queries are not counted)
static char * value
Value of the record to add/remove.
struct GNUNET_ATS_ReservationContext * rc
Context of our GNUNET_ATS_reserve_bandwidth call (or NULL).
static void schedule_transmission(struct GSF_PeerTransmitHandle *pth)
If ready (bandwidth reserved), try to schedule transmission via core for the given handle...
int GSF_pending_request_test_active_(struct GSF_PendingRequest *pr)
Check if the given request is still active.
uint32_t respect
Respect rating for this peer.
Message to the datastore service asking about specific content.
Definition: datastore.h:136
void GNUNET_PEERSTORE_disconnect(struct GNUNET_PEERSTORE_Handle *h, int sync_first)
Disconnect from the PEERSTORE service.
unsigned int GNUNET_MQ_get_length(struct GNUNET_MQ_Handle *mq)
Obtain the current length of the message queue.
Definition: mq.c:333
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...
uint32_t hash_bitmap
Which of the optional hash codes are present at the end of the message? See GET_MESSAGE_BIT_xx consta...
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_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
struct GSF_PeerPerformanceData * GSF_get_peer_performance_data_(struct GSF_ConnectedPeer *cp)
Return the performance data record for the given peer.
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:1264
void GSF_handle_local_client_disconnect_(const struct GSF_LocalClient *lc)
Notification that a local client disconnected.
struct GSF_PeerPerformanceData ppd
Performance data for this peer.
struct GNUNET_HashCode query
Hashcodes of the file(s) we&#39;re looking for.
uint32_t reserved
Always zero.
struct GSF_ConnectedPeer * GSF_peer_get_(const struct GNUNET_PeerIdentity *peer)
Get a handle for a connected peer.
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:686
static void revive_migration(void *cls)
It may be time to re-start migrating content to this peer.
#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...
Last possible valid result.
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.
struct GNUNET_PeerIdentity GSF_my_id
Identity of this peer.
void GSF_local_lookup_(struct GSF_PendingRequest *pr, GSF_LocalLookupContinuation cont, void *cont_cls)
Look up the request in the local datastore.
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.
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:440
#define GNUNET_CONTAINER_DLL_insert_after(head, tail, other, element)
Insert an element into a DLL after the given other element.
Closure for test_exist_cb().
enum GNUNET_BLOCK_Type type
Type of the requested block.
int finished
Set to GNUNET_YES if we are done handling the query.
Internal representation of the hash map.
static struct GNUNET_PEERSTORE_Handle * peerstore
Handle to peerstore service.
static void peer_transmit(struct GSF_ConnectedPeer *cp)
Core is ready to transmit to a peer, get the message.
Handle to the PEERSTORE service.
Definition: peerstore_api.c:40
struct GNUNET_TIME_Relative GNUNET_TIME_relative_ntoh(struct GNUNET_TIME_RelativeNBO a)
Convert relative time from network byte order.
Definition: time.c:639
void GNUNET_STATISTICS_set(struct GNUNET_STATISTICS_Handle *handle, const char *name, uint64_t value, int make_persistent)
Set statistic value for the peer.
static void retry_reservation(void *cls)
(re)try to reserve bandwidth from the given peer.
A 512-bit hashcode.
uint32_t priority
Priority of this request.
#define GNUNET_TIME_UNIT_MILLISECONDS
One millisecond.
uint32_t type
Desired content type.
Definition: datastore.h:145
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:118
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
#define DBLOCK_SIZE
Size of the individual blocks used for file-sharing.
Definition: fs.h:40
void GNUNET_MQ_discard(struct GNUNET_MQ_Envelope *mqm)
Discard the message queue message, free all allocated resources.
Definition: mq.c:319
struct GNUNET_SCHEDULER_Task * delay_task
Task for the delay.
There must only be one value per key; storing a value should fail if a value under the same key alrea...
struct GSF_ConnectedPeer * cp
Which specific peer issued this request?
struct GNUNET_MQ_Envelope * env
Envelope with the actual message.
struct GNUNET_TESTBED_Peer * peer
The peer associated with this model.
struct GNUNET_HashCode key
The key used in the DHT.
unsigned int last_request_times_off
Current offset into last_request_times ring buffer.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
int32_t ttl
Relative TTL of the incoming request.
struct GNUNET_TIME_RelativeNBO GNUNET_TIME_relative_hton(struct GNUNET_TIME_Relative a)
Convert relative time to network byte order.
Definition: time.c:623
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...
unsigned int delay_queue_size
Number of entries in delayed_head DLL.
struct GNUNET_PEERSTORE_Handle * GNUNET_PEERSTORE_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the PEERSTORE service.
static struct GNUNET_SCHEDULER_Task * fr_task
Task used to flush respect values to disk.
GNUNET_BLOCK_EvaluationResult
Possible ways for how a block may relate to a query.
void GSF_iterate_pending_requests_(GSF_PendingRequestIterator it, void *cls)
Iterate over all pending requests.
struct GNUNET_TIME_Absolute last_request_times[24]
Transmission times for the last MAX_QUEUE_PER_PEER requests for this peer.
void GSF_consider_forwarding(void *cls, struct GSF_PendingRequest *pr, enum GNUNET_BLOCK_EvaluationResult result)
Function to be called after we&#39;re done processing replies from the local lookup.
static int change_peer_respect(struct GSF_ConnectedPeer *cp, int value)
Increase the peer&#39;s respect by a value.
Message send by a peer that wants to be excluded from migration for a while.
struct GSF_PeerTransmitHandle * prev
Kept in a doubly-linked list.
static void peer_respect_cb(void *cls, const struct GNUNET_PEERSTORE_Record *record, const char *emsg)
Function called by PEERSTORE with peer respect record.
struct GNUNET_SCHEDULER_Task * kill_task
Task for asynchronous stopping of this request.
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.
void * it_cls
Closure for it.
uint32_t type
Type of the block (in big endian).
Definition: fs.h:330
GNUNET_PEER_Id pid
The peer&#39;s identity (interned version).
#define GNUNET_TIME_UNIT_ZERO
Relative time zero.
int was_reserved
Did we get a reservation already?
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message...
struct GNUNET_TIME_RelativeNBO duration
How long should the block last?
Allow multiple values with the same key.
Handle to a message queue.
Definition: mq.c:84
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_push_start_(struct GSF_ConnectedPeer *peer)
A peer connected to us.
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.
struct GNUNET_SCHEDULER_Task * mig_revive_task
Task scheduled to revive migration to this peer.
int GNUNET_CONTAINER_multipeermap_iterate(struct GNUNET_CONTAINER_MultiPeerMap *map, GNUNET_CONTAINER_PeerMapIterator it, void *it_cls)
Iterate over all entries in the map.
#define N
The identity of the host (wraps the signing key of the peer).
#define RESPECT_FLUSH_FREQ
How often do we flush respect values to disk?
struct GNUNET_TIME_Absolute migration_blocked_until
Point in time until which this peer does not want us to migrate content to it.
struct GNUNET_LOAD_Value * GSF_rt_entry_lifetime
How long do requests typically stay in the routing table?
struct GSF_PendingRequestData * GSF_pending_request_get_data_(struct GSF_PendingRequest *pr)
Obtain the public data associated with a pending request.
void * GSF_peer_connect_handler(void *cls, const struct GNUNET_PeerIdentity *peer, struct GNUNET_MQ_Handle *mq)
A peer connected to us.
int32_t priority
Priority of the incoming request.
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.
void GNUNET_ATS_reserve_bandwidth_cancel(struct GNUNET_ATS_ReservationContext *rc)
Cancel request for reserving bandwidth.
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...
Request must only be forwarded (no routing)
Performance data kept for a peer.
struct GSF_ConnectedPeer * cp
Peer this transmission belongs to.
const struct GNUNET_PeerIdentity * GSF_connected_peer_get_identity2_(const struct GSF_ConnectedPeer *cp)
Obtain the identity of a connected peer.
struct GSF_PeerTransmitHandle * pth_tail
Messages (replies, queries, content migration) we would like to send to this peer in the near future...
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:373
struct GNUNET_MQ_Handle * mq
Handle for an active request for transmission to this peer.
#define GNUNET_LOAD_value_free(lv)
Free a load value.
void GNUNET_ATS_performance_change_preference(struct GNUNET_ATS_PerformanceHandle *ph, const struct GNUNET_PeerIdentity *peer,...)
Change preferences for the given peer.
struct GNUNET_PEERSTORE_IterateContext * respect_iterate_req
Handle to the PEERSTORE iterate request for peer respect value.
#define GNUNET_MESSAGE_TYPE_FS_MIGRATION_STOP
Peer asks us to stop migrating content towards it for a while.
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.
Single PEERSTORE record.
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
void GNUNET_PEER_change_rc(GNUNET_PEER_Id id, int delta)
Change the reference counter of an interned PID.
Definition: peer.c:197
#define GNUNET_log(kind,...)
static void cron_flush_respect(void *cls)
Call this method periodically to flush respect information to disk.
Entry in list of pending tasks.
Definition: scheduler.c:131
#define TTL_DECREMENT
By which amount do we decrement the TTL for simple forwarding / indirection of the query; in milli-se...
Change the peer&#39;s bandwidth value (value per byte of bandwidth in the goal function) to the given amo...
A connected peer.
void GNUNET_PEERSTORE_iterate_cancel(struct GNUNET_PEERSTORE_IterateContext *ic)
Cancel an iterate request Please do not call after the iterate request is done.
struct GSF_LocalClient * last_client_replies[8]
List of the last clients for which this peer successfully answered a query.
static void record(void *cls, size_t data_size, const void *data)
Process recorded audio data.
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
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...
unsigned int GSF_cover_content_count
How many content messages have we received &#39;recently&#39; that have not yet been claimed as cover traffic...
static int flush_respect(void *cls, const struct GNUNET_PeerIdentity *key, void *value)
Write peer-respect information to a file - flush the buffer entry!
struct GNUNET_TIME_Relative GSF_avg_latency
Running average of the observed latency to other peers (round trip).
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.
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_remaining(struct GNUNET_TIME_Absolute future)
Given a timestamp in the future, how much time remains until then?
Definition: time.c:331
struct GNUNET_MQ_Envelope * env
Envelope of the message that was delayed.
enum GNUNET_TESTBED_UnderlayLinkModelType type
the type of this model
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.
Time for absolute times used by GNUnet, in microseconds.
#define GNUNET_YES
Definition: gnunet_common.h:77
struct GSF_DelayedHandle * prev
Kept in a doubly-linked list.
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:351
void handle_p2p_migration_stop(void *cls, const struct MigrationStopMessage *msm)
Handle P2P GNUNET_MESSAGE_TYPE_FS_MIGRATION_STOP message.
struct GNUNET_TIME_Absolute transmission_request_start_time
Time when this transmission request was issued.
uint32_t priority
Priority that this request (still) has for us.
void GSF_connected_peer_done_()
Shutdown peer management subsystem.
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:140
#define MAX_QUEUE_PER_PEER
Maximum number of outgoing messages we queue per peer.
unsigned int GNUNET_CONTAINER_multipeermap_size(const struct GNUNET_CONTAINER_MultiPeerMap *map)
Get the number of key-value pairs in the map.
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.
An active request.
support for pushing out content
#define GNUNET_CONSTANTS_MAX_CORK_DELAY
How long do we delay messages to get larger packet sizes (CORKing)?
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.
void GSF_pending_request_cancel_(struct GSF_PendingRequest *pr, int full_cleanup)
Explicitly cancel a pending request.
uint64_t inc_preference
Increase in traffic preference still to be submitted to the core service for this peer...
int GNUNET_CONTAINER_multihashmap_iterate(struct GNUNET_CONTAINER_MultiHashMap *map, GNUNET_CONTAINER_MulitHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map.
uint32_t data
The data value.
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition: time.c:655
#define GNUNET_MESSAGE_TYPE_FS_PUT
P2P response with content or active migration of content.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
int has_started
Has this request been started yet (local/p2p operations)? Or are we still constructing it...
GSF_PendingRequestOptions
Options for pending requests (bits to be ORed).
No good quality of the operation is needed (i.e., random numbers can be pseudo-random).
static void transmit_delayed_now(void *cls)
The artificial delay is over, transmit the message now.
Context for a iterate request.
GNUNET_PEER_Id GNUNET_PEER_intern(const struct GNUNET_PeerIdentity *pid)
Intern an peer identity.
Definition: peer.c:106
#define GNUNET_free(ptr)
Wrapper around free.
Time for relative time used by GNUnet, in microseconds.
static int clean_local_client(void *cls, const struct GNUNET_PeerIdentity *key, void *value)
Iterator to remove references to LC entry.
Linked list of pending reservations.
static struct GNUNET_TRANSPORT_PluginMonitor * pm
Handle if we are monitoring plugin session activity.
#define gettext_noop(String)
Definition: gettext.h:69
Handle to cancel a transmission request.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:956