GNUnet  0.19.5
gnunet-daemon-hostlist_client.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2001-2010, 2014, 2016 GNUnet e.V.
4 
5  GNUnet is free software: you can redistribute it and/or modify it
6  under the terms of the GNU Affero General Public License as published
7  by the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  GNUnet is distributed in the hope that it will be useful, but
11  WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Affero General Public License for more details.
14 
15  You should have received a copy of the GNU Affero General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 
18  SPDX-License-Identifier: AGPL3.0-or-later
19  */
26 #include "platform.h"
28 #include "gnunet_hello_lib.h"
32 #include "gnunet-daemon-hostlist.h"
33 /* Just included for the right curl.h */
34 #include "gnunet_curl_lib.h"
35 
36 
41 #define MIN_CONNECTIONS 4
42 
46 #define MAX_NUMBER_HOSTLISTS 30
47 
51 #define SAVING_INTERVAL \
52  GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 30)
53 
57 #define TESTING_INTERVAL \
58  GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 3)
59 
63 #define WAITING_INTERVAL \
64  GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1)
65 
73 #define HOSTLIST_INITIAL 10000
74 
78 #define HOSTLIST_FAILED_DOWNLOAD 100
79 
83 #define HOSTLIST_SUCCESSFUL_DOWNLOAD 100
84 
88 #define HOSTLIST_SUCCESSFUL_HELLO 1
89 
90 
94 struct Hostlist
95 {
99  struct Hostlist *prev;
100 
104  struct Hostlist *next;
105 
109  const char *hostlist_uri;
110 
119  uint64_t quality;
120 
125 
130 
134  uint32_t hello_count;
135 
139  uint32_t times_used;
140 };
141 
142 
146 static const struct GNUNET_CONFIGURATION_Handle *cfg;
147 
152 
156 static char *proxy;
157 
161 static char *proxy_username;
162 
166 static char *proxy_password;
167 
171 static curl_proxytype proxy_type;
172 
176 static size_t download_pos;
177 
181 static char *current_url;
182 
186 static CURL *curl;
187 
191 static CURLM *multi;
192 
196 static uint32_t stat_bytes_downloaded;
197 
202 
207 
212 
217 
222 
227 
231 static struct GNUNET_TIME_Absolute end_time;
232 
236 static struct Hostlist *linked_list_head;
237 
241 static struct Hostlist *linked_list_tail;
242 
246 static struct Hostlist *current_hostlist;
247 
251 static unsigned int linked_list_size;
252 
256 static struct Hostlist *hostlist_to_test;
257 
262 
266 static int stat_bogus_url;
267 
272 
277 
282 
286 static unsigned int stat_use_bootstrap;
287 
291 static int stat_learning;
292 
296 static unsigned int stat_download_successful;
297 
301 static unsigned int stat_hellos_obtained;
302 
306 static unsigned int stat_connection_count;
307 
311 static struct GNUNET_PEERINFO_Handle *pi;
312 
313 
323 static size_t
324 callback_download (void *ptr, size_t size, size_t nmemb, void *ctx)
325 {
326  static char download_buffer[GNUNET_MAX_MESSAGE_SIZE - 1];
327  const char *cbuf = ptr;
328  const struct GNUNET_MessageHeader *msg;
329  size_t total;
330  size_t cpy;
331  size_t left;
332  uint16_t msize;
333 
334  total = size * nmemb;
335  stat_bytes_downloaded += total;
336  if ((total == 0) || (stat_bogus_url))
337  {
338  return total; /* ok, no data or bogus data */
339  }
340 
342  gettext_noop (
343  "# bytes downloaded from hostlist servers"),
344  (int64_t) total,
345  GNUNET_NO);
346  left = total;
347  while ((left > 0) || (download_pos > 0))
348  {
349  cpy = GNUNET_MIN (left, GNUNET_MAX_MESSAGE_SIZE - 1 - download_pos);
350  GNUNET_memcpy (&download_buffer[download_pos], cbuf, cpy);
351  cbuf += cpy;
352  download_pos += cpy;
353  left -= cpy;
354  if (download_pos < sizeof(struct GNUNET_MessageHeader))
355  {
356  GNUNET_assert (0 == left);
357  break;
358  }
359  msg = (const struct GNUNET_MessageHeader *) download_buffer;
360  msize = ntohs (msg->size);
361  if (msize < sizeof(struct GNUNET_MessageHeader))
362  {
364  stats,
365  gettext_noop ("# invalid HELLOs downloaded from hostlist servers"),
366  1,
367  GNUNET_NO);
369  _ ("Invalid `%s' message received from hostlist at `%s'\n"),
370  "HELLO",
371  current_url);
373  stat_bogus_url = 1;
374  return total;
375  }
376  if (download_pos < msize)
377  {
378  GNUNET_assert (left == 0);
379  break;
380  }
381  if (GNUNET_HELLO_size ((const struct GNUNET_HELLO_Message *) msg) == msize)
382  {
384  "Received valid `%s' message from hostlist server.\n",
385  "HELLO");
387  stats,
388  gettext_noop ("# valid HELLOs downloaded from hostlist servers"),
389  1,
390  GNUNET_NO);
392  (void)
394  (const struct GNUNET_HELLO_Message *) msg,
395  NULL,
396  NULL);
397  }
398  else
399  {
401  stats,
402  gettext_noop ("# invalid HELLOs downloaded from hostlist servers"),
403  1,
404  GNUNET_NO);
406  _ ("Invalid `%s' message received from hostlist at `%s'\n"),
407  "HELLO",
408  current_url);
411  return total;
412  }
413  memmove (download_buffer, &download_buffer[msize], download_pos - msize);
414  download_pos -= msize;
415  }
416  return total;
417 }
418 
419 
425 static char *
427 {
428  char *servers;
429  char *ret;
430  size_t urls;
431  size_t pos;
432 
434  "HOSTLIST",
435  "SERVERS",
436  &servers))
437  {
439  "hostlist",
440  "SERVERS");
441  return NULL;
442  }
443 
444  urls = 0;
445  if (strlen (servers) > 0)
446  {
447  urls++;
448  pos = strlen (servers) - 1;
449  while (pos > 0)
450  {
451  if (servers[pos] == ' ')
452  urls++;
453  pos--;
454  }
455  }
456  if (urls == 0)
457  {
459  "hostlist",
460  "SERVERS");
461  GNUNET_free (servers);
462  return NULL;
463  }
464 
466  pos = strlen (servers) - 1;
467  while (pos > 0)
468  {
469  if (servers[pos] == ' ')
470  {
471  urls--;
472  servers[pos] = '\0';
473  }
474  if (urls == 0)
475  {
476  pos++;
477  break;
478  }
479  pos--;
480  }
481  ret = GNUNET_strdup (&servers[pos]);
482  GNUNET_free (servers);
483  return ret;
484 }
485 
486 
491 static char *
493 {
494  uint32_t index;
495  unsigned int counter;
496  struct Hostlist *pos;
497 
498  if (GNUNET_NO == stat_learning)
499  {
501  "Using preconfigured bootstrap server\n");
502  current_hostlist = NULL;
503  return get_bootstrap_server ();
504  }
505 
506  if ((GNUNET_YES == stat_testing_hostlist) && (NULL != hostlist_to_test))
507  {
509  "Testing new advertised hostlist if it is obtainable\n");
512  }
513 
515  {
517  "Using preconfigured bootstrap server\n");
518  current_hostlist = NULL;
519  return get_bootstrap_server ();
520  }
521  index =
523  counter = 0;
524  pos = linked_list_head;
525  while (counter < index)
526  {
527  pos = pos->next;
528  counter++;
529  }
531  "Using learned hostlist `%s'\n",
532  pos->hostlist_uri);
533  current_hostlist = pos;
534  return GNUNET_strdup (pos->hostlist_uri);
535 }
536 
537 
538 #define CURL_EASY_SETOPT(c, a, b) \
539  do \
540  { \
541  ret = curl_easy_setopt (c, a, b); \
542  if (CURLE_OK != ret) \
543  GNUNET_log (GNUNET_ERROR_TYPE_WARNING, \
544  _ ("%s failed at %s:%d: `%s'\n"), \
545  "curl_easy_setopt", \
546  __FILE__, \
547  __LINE__, \
548  curl_easy_strerror (ret)); \
549  } while (0)
550 
551 
557 static void
558 save_hostlist_file (int shutdown);
559 
560 
568 static uint64_t
569 checked_add (uint64_t val1, uint64_t val2)
570 {
571  static uint64_t temp;
572  static uint64_t maxv;
573 
574  maxv = 0;
575  maxv--;
576 
577  temp = val1 + val2;
578  if (temp < val1)
579  return maxv;
580  return temp;
581 }
582 
583 
591 static uint64_t
592 checked_sub (uint64_t val1, uint64_t val2)
593 {
594  if (val1 <= val2)
595  return 0;
596  return(val1 - val2);
597 }
598 
599 
606 static int
608 {
609  struct Hostlist *pos;
610 
611  pos = linked_list_head;
612  while (pos != NULL)
613  {
614  if (0 == strcmp (pos->hostlist_uri, uri))
615  return GNUNET_YES;
616  pos = pos->next;
617  }
618  return GNUNET_NO;
619 }
620 
621 
626 static struct Hostlist *
628 {
629  struct Hostlist *pos;
630  struct Hostlist *lowest;
631 
632  if (linked_list_size == 0)
633  return NULL;
634  lowest = linked_list_head;
635  pos = linked_list_head->next;
636  while (pos != NULL)
637  {
638  if (pos->quality < lowest->quality)
639  lowest = pos;
640  pos = pos->next;
641  }
642  return lowest;
643 }
644 
645 
651 static void
653 {
654  struct Hostlist *lowest_quality;
655 
657  {
658  /* No free entries available, replace existing entry */
659  lowest_quality = linked_list_get_lowest_quality ();
660  GNUNET_assert (lowest_quality != NULL);
661  GNUNET_log (
663  "Removing hostlist with URI `%s' which has the worst quality of all (%llu)\n",
664  lowest_quality->hostlist_uri,
665  (unsigned long long) lowest_quality->quality);
668  lowest_quality);
670  GNUNET_free (lowest_quality);
671  }
677  gettext_noop ("# advertised hostlist URIs"),
679  GNUNET_NO);
681 }
682 
683 
687 static void
689 {
690  char *stat;
691 
692  if (((stat_use_bootstrap == GNUNET_NO) && (NULL != current_hostlist)) ||
694  {
696  "Updating hostlist statics for URI `%s'\n",
704  {
708  GNUNET_asprintf (&stat,
709  gettext_noop ("# advertised URI `%s' downloaded"),
711 
713  GNUNET_free (stat);
714  }
715  else
718  }
719  current_hostlist = NULL;
720  /* Alternating the usage of preconfigured and learned hostlists */
721 
723  return;
724 
725  if (GNUNET_YES == stat_learning)
726  {
729  else
731  }
732  else
734 }
735 
736 
741 static void
743 {
744  CURLMcode mret;
745 
748  {
749  GNUNET_log (
751  _ (
752  "Advertised hostlist with URI `%s' could not be downloaded. Advertised URI gets dismissed.\n"),
754  }
755 
757  {
759  }
760  if (NULL != hostlist_to_test)
761  {
763  hostlist_to_test = NULL;
764  }
765 
766  if (NULL != multi)
767  {
768  mret = curl_multi_remove_handle (multi, curl);
769  if (mret != CURLM_OK)
770  {
772  _ ("%s failed at %s:%d: `%s'\n"),
773  "curl_multi_remove_handle",
774  __FILE__,
775  __LINE__,
776  curl_multi_strerror (mret));
777  }
778  mret = curl_multi_cleanup (multi);
779  if (mret != CURLM_OK)
781  _ ("%s failed at %s:%d: `%s'\n"),
782  "curl_multi_cleanup",
783  __FILE__,
784  __LINE__,
785  curl_multi_strerror (mret));
786  multi = NULL;
787  }
788  if (NULL != curl)
789  {
790  curl_easy_cleanup (curl);
791  curl = NULL;
792  }
794  current_url = NULL;
797 }
798 
799 
806 static void
807 task_download (void *cls);
808 
809 
814 static void
816 {
817  CURLMcode mret;
818  fd_set rs;
819  fd_set ws;
820  fd_set es;
821  int max;
822  struct GNUNET_NETWORK_FDSet *grs;
823  struct GNUNET_NETWORK_FDSet *gws;
824  long timeout;
825  struct GNUNET_TIME_Relative rtime;
826 
827  max = -1;
828  FD_ZERO (&rs);
829  FD_ZERO (&ws);
830  FD_ZERO (&es);
831  mret = curl_multi_fdset (multi, &rs, &ws, &es, &max);
832  if (mret != CURLM_OK)
833  {
835  _ ("%s failed at %s:%d: `%s'\n"),
836  "curl_multi_fdset",
837  __FILE__,
838  __LINE__,
839  curl_multi_strerror (mret));
840  clean_up ();
841  return;
842  }
843  mret = curl_multi_timeout (multi, &timeout);
844  if (mret != CURLM_OK)
845  {
847  _ ("%s failed at %s:%d: `%s'\n"),
848  "curl_multi_timeout",
849  __FILE__,
850  __LINE__,
851  curl_multi_strerror (mret));
852  clean_up ();
853  return;
854  }
855  rtime = GNUNET_TIME_relative_min (
860  GNUNET_NETWORK_fdset_copy_native (grs, &rs, max + 1);
861  GNUNET_NETWORK_fdset_copy_native (gws, &ws, max + 1);
863  "Scheduling task for hostlist download using cURL\n");
865  rtime,
866  grs,
867  gws,
868  &task_download,
869  multi);
872 }
873 
874 
875 static void
876 task_download (void *cls)
877 {
878  int running;
879  struct CURLMsg *msg;
880  CURLMcode mret;
881 
882  ti_download = NULL;
883  if (0 == GNUNET_TIME_absolute_get_remaining (end_time).rel_value_us)
884  {
886  _ ("Timeout trying to download hostlist from `%s'\n"),
887  current_url);
888  update_hostlist ();
889  clean_up ();
890  return;
891  }
893  "Ready for processing hostlist client request\n");
894  do
895  {
896  running = 0;
898  {
900  _ (
901  "Download limit of %u bytes exceeded, stopping download\n"),
903  clean_up ();
904  return;
905  }
906  mret = curl_multi_perform (multi, &running);
907  if (running == 0)
908  {
909  do
910  {
911  msg = curl_multi_info_read (multi, &running);
912  GNUNET_break (msg != NULL);
913  if (msg == NULL)
914  break;
915  switch (msg->msg)
916  {
917  case CURLMSG_DONE:
918  if ((msg->data.result != CURLE_OK) &&
919  (msg->data.result != CURLE_GOT_NOTHING))
921  _ ("Download of hostlist from `%s' failed: `%s'\n"),
922  current_url,
923  curl_easy_strerror (msg->data.result));
924  else
925  {
927  _ ("Download of hostlist `%s' completed.\n"),
928  current_url);
930  update_hostlist ();
932  {
933  GNUNET_log (
935  _ ("Adding successfully tested hostlist `%s' datastore.\n"),
936  current_url);
937  insert_hostlist ();
938  hostlist_to_test = NULL;
940  }
941  }
942  clean_up ();
943  return;
944 
945  default:
946  break;
947  }
948  }
949  while ((running > 0));
950  }
951  }
952  while (mret == CURLM_CALL_MULTI_PERFORM);
953 
954  if (mret != CURLM_OK)
955  {
957  _ ("%s failed at %s:%d: `%s'\n"),
958  "curl_multi_perform",
959  __FILE__,
960  __LINE__,
961  curl_multi_strerror (mret));
962  clean_up ();
963  }
964  download_prepare ();
965 }
966 
967 
972 static void
974 {
975  CURLcode ret;
976  CURLMcode mret;
977 
978 
980  if (current_url == NULL)
981  return;
982  curl = curl_easy_init ();
983  multi = NULL;
984  if (curl == NULL)
985  {
986  GNUNET_break (0);
987  clean_up ();
988  return;
989  }
991  _ ("Bootstrapping using hostlist at `%s'.\n"),
992  current_url);
993 
998 
1000  gettext_noop ("# hostlist downloads initiated"),
1001  1,
1002  GNUNET_NO);
1003  if (NULL != proxy)
1004  {
1005  CURL_EASY_SETOPT (curl, CURLOPT_PROXY, proxy);
1006  CURL_EASY_SETOPT (curl, CURLOPT_PROXYTYPE, proxy_type);
1007  if (NULL != proxy_username)
1008  CURL_EASY_SETOPT (curl, CURLOPT_PROXYUSERNAME, proxy_username);
1009  if (NULL != proxy_password)
1010  CURL_EASY_SETOPT (curl, CURLOPT_PROXYPASSWORD, proxy_password);
1011  }
1012  download_pos = 0;
1013  stat_bogus_url = 0;
1014  CURL_EASY_SETOPT (curl, CURLOPT_WRITEFUNCTION, &callback_download);
1015  if (ret != CURLE_OK)
1016  {
1017  clean_up ();
1018  return;
1019  }
1020  CURL_EASY_SETOPT (curl, CURLOPT_WRITEDATA, NULL);
1021  if (ret != CURLE_OK)
1022  {
1023  clean_up ();
1024  return;
1025  }
1026  CURL_EASY_SETOPT (curl, CURLOPT_FOLLOWLOCATION, 1);
1028  CURLOPT_REDIR_PROTOCOLS,
1029  CURLPROTO_HTTP | CURLPROTO_HTTPS);
1030  CURL_EASY_SETOPT (curl, CURLOPT_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);
1031  CURL_EASY_SETOPT (curl, CURLOPT_MAXREDIRS, 4);
1032  /* no need to abort if the above failed */
1033  CURL_EASY_SETOPT (curl, CURLOPT_URL, current_url);
1034  if (ret != CURLE_OK)
1035  {
1036  clean_up ();
1037  return;
1038  }
1039  CURL_EASY_SETOPT (curl, CURLOPT_FAILONERROR, 1);
1040 #if 0
1041  CURL_EASY_SETOPT (curl, CURLOPT_VERBOSE, 1);
1042 #endif
1043  CURL_EASY_SETOPT (curl, CURLOPT_BUFFERSIZE, GNUNET_MAX_MESSAGE_SIZE);
1044  if (0 == strncmp (current_url, "http", 4))
1045  CURL_EASY_SETOPT (curl, CURLOPT_USERAGENT, "GNUnet");
1046  CURL_EASY_SETOPT (curl, CURLOPT_CONNECTTIMEOUT, 60L);
1047  CURL_EASY_SETOPT (curl, CURLOPT_TIMEOUT, 60L);
1048  multi = curl_multi_init ();
1049  if (multi == NULL)
1050  {
1051  GNUNET_break (0);
1052  /* clean_up (); */
1053  return;
1054  }
1055  mret = curl_multi_add_handle (multi, curl);
1056  if (mret != CURLM_OK)
1057  {
1059  _ ("%s failed at %s:%d: `%s'\n"),
1060  "curl_multi_add_handle",
1061  __FILE__,
1062  __LINE__,
1063  curl_multi_strerror (mret));
1064  mret = curl_multi_cleanup (multi);
1065  if (mret != CURLM_OK)
1067  _ ("%s failed at %s:%d: `%s'\n"),
1068  "curl_multi_cleanup",
1069  __FILE__,
1070  __LINE__,
1071  curl_multi_strerror (mret));
1072  multi = NULL;
1073  clean_up ();
1074  return;
1075  }
1077  download_prepare ();
1078 }
1079 
1080 
1081 static void
1083 {
1085  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Download is initiated...\n");
1087  {
1088  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Download can start immediately...\n");
1089  download_hostlist ();
1090  }
1091  else
1092  {
1094  "Download in progress, have to wait...\n");
1098  NULL);
1099  }
1100 }
1101 
1102 
1108 static void
1109 task_check (void *cls)
1110 {
1111  static int once;
1112  struct GNUNET_TIME_Relative delay;
1113 
1114  ti_check_download = NULL;
1115  if (stats == NULL)
1116  {
1117  curl_global_cleanup ();
1118  return; /* in shutdown */
1119  }
1121  (NULL == ti_download_dispatcher_task))
1124 
1126  if (0 == hostlist_delay.rel_value_us)
1128  else
1131  GNUNET_TIME_UNIT_HOURS.rel_value_us * (1 + stat_connection_count))
1132  hostlist_delay =
1134  (1 + stat_connection_count));
1136  gettext_noop (
1137  "# milliseconds between hostlist downloads"),
1138  hostlist_delay.rel_value_us / 1000LL,
1139  GNUNET_YES);
1140  if (0 == once)
1141  {
1143  once = 1;
1144  }
1145  GNUNET_log (
1147  _ ("Have %u/%u connections. Will consider downloading hostlist in %s\n"),
1152 }
1153 
1154 
1160 static void
1162 {
1166  "Testing new hostlist advertisements is allowed again\n");
1167 }
1168 
1169 
1175 static void
1177 {
1178  ti_saving_task = NULL;
1180 
1182  "Hostlists will be saved to file again in %s\n",
1184  GNUNET_YES));
1185  ti_saving_task =
1187 }
1188 
1189 
1197 static void *
1198 handler_connect (void *cls,
1199  const struct GNUNET_PeerIdentity *peer,
1200  struct GNUNET_MQ_Handle *mq)
1201 {
1202  GNUNET_assert (stat_connection_count < UINT_MAX);
1205  gettext_noop ("# active connections"),
1206  1,
1207  GNUNET_NO);
1208  return NULL;
1209 }
1210 
1211 
1218 static void
1220  const struct GNUNET_PeerIdentity *peer,
1221  void *internal_cls)
1222 {
1226  gettext_noop ("# active connections"),
1227  -1,
1228  GNUNET_NO);
1229 }
1230 
1231 
1237 static void
1239 {
1240  size_t uri_size;
1241  struct Hostlist *hostlist;
1242 
1243  uri_size = strlen (uri) + 1;
1245  "Hostlist client received advertisement containing URI `%s'\n",
1246  uri);
1248  {
1249  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "URI `%s' is already known\n", uri);
1250  return;
1251  }
1252 
1254  {
1255  GNUNET_log (
1257  "Currently not accepting new advertisements: interval between to advertisements is not reached\n");
1258  return;
1259  }
1261  {
1262  GNUNET_log (
1264  "Currently not accepting new advertisements: we are already testing a hostlist\n");
1265  return;
1266  }
1267 
1268  hostlist = GNUNET_malloc (sizeof(struct Hostlist) + uri_size);
1269  hostlist->hostlist_uri = (const char *) &hostlist[1];
1270  GNUNET_memcpy (&hostlist[1], uri, uri_size);
1271  hostlist->time_creation = GNUNET_TIME_absolute_get ();
1272  hostlist->quality = HOSTLIST_INITIAL;
1273  hostlist_to_test = hostlist;
1274 
1280  NULL);
1281 
1283  "Testing new hostlist advertisements is locked for the next %s\n",
1285  GNUNET_YES));
1286 
1289 }
1290 
1291 
1300 static void
1301 primary_task (void *cls, int success)
1302 {
1303  if (NULL != ti_check_download)
1304  {
1306  ti_check_download = NULL;
1307  }
1308  sget = NULL;
1309  GNUNET_assert (NULL != stats);
1311  "Statistics request done, scheduling hostlist download\n");
1313 }
1314 
1315 
1322 static void
1324 {
1326  sget = NULL;
1328 }
1329 
1330 
1340 static int
1341 process_stat (void *cls,
1342  const char *subsystem,
1343  const char *name,
1344  uint64_t value,
1345  int is_persistent)
1346 {
1347  hostlist_delay.rel_value_us = value * 1000LL;
1349  "Initial time between hostlist downloads is %s\n",
1351  GNUNET_YES));
1352  return GNUNET_OK;
1353 }
1354 
1355 
1359 static void
1361 {
1362  char *filename;
1363  char *uri;
1364  char *emsg;
1365  struct Hostlist *hostlist;
1366  uint32_t times_used;
1367  uint32_t hellos_returned;
1368  uint64_t quality;
1369  uint64_t last_used;
1370  uint64_t created;
1371  uint32_t counter;
1372  struct GNUNET_BIO_ReadHandle *rh;
1373 
1374  uri = NULL;
1376  "HOSTLIST",
1377  "HOSTLISTFILE",
1378  &filename))
1379  {
1381  "hostlist",
1382  "HOSTLISTFILE");
1383  return;
1384  }
1385 
1387  _ ("Loading saved hostlist entries from file `%s' \n"),
1388  filename);
1390  {
1392  _ ("Hostlist file `%s' does not exist\n"),
1393  filename);
1395  return;
1396  }
1397 
1399  if (NULL == rh)
1400  {
1402  _ (
1403  "Could not open file `%s' for reading to load hostlists: %s\n"),
1404  filename,
1405  strerror (errno));
1407  return;
1408  }
1409 
1410  counter = 0;
1411  struct GNUNET_BIO_ReadSpec rs[] = {
1412  GNUNET_BIO_read_spec_int32 ("times used", (int32_t *) &times_used),
1413  GNUNET_BIO_read_spec_int64 ("quality", (int64_t *) &quality),
1414  GNUNET_BIO_read_spec_int64 ("last used", (int64_t *) &last_used),
1415  GNUNET_BIO_read_spec_int64 ("created", (int64_t *) &created),
1416  GNUNET_BIO_read_spec_int32 ("hellos returned",
1417  (int32_t *) &hellos_returned),
1419  };
1420  while ((GNUNET_OK == GNUNET_BIO_read_string (rh, "url", &uri, MAX_URL_LEN)) &&
1421  (NULL != uri) &&
1423  {
1424  hostlist = GNUNET_malloc (sizeof(struct Hostlist) + strlen (uri) + 1);
1425  hostlist->hello_count = hellos_returned;
1426  hostlist->hostlist_uri = (const char *) &hostlist[1];
1427  GNUNET_memcpy (&hostlist[1], uri, strlen (uri) + 1);
1428  hostlist->quality = quality;
1429  hostlist->time_creation.abs_value_us = created;
1430  hostlist->time_last_usage.abs_value_us = last_used;
1432  linked_list_size++;
1434  "Added hostlist entry with URI `%s' \n",
1435  hostlist->hostlist_uri);
1436  GNUNET_free (uri);
1437  uri = NULL;
1438  counter++;
1439  if (counter >= MAX_NUMBER_HOSTLISTS)
1440  break;
1441  }
1442 
1444  _ ("%u hostlist URIs loaded from file\n"),
1445  counter);
1447  gettext_noop ("# hostlist URIs read from file"),
1448  counter,
1449  GNUNET_YES);
1451  gettext_noop ("# advertised hostlist URIs"),
1453  GNUNET_NO);
1454 
1455  GNUNET_free (uri);
1456  emsg = NULL;
1457  (void) GNUNET_BIO_read_close (rh, &emsg);
1458  if (emsg != NULL)
1459  GNUNET_free (emsg);
1461 }
1462 
1463 
1469 static void
1470 save_hostlist_file (int shutdown)
1471 {
1472  char *filename;
1473  struct Hostlist *pos;
1474  struct GNUNET_BIO_WriteHandle *wh;
1475  int ok;
1476  uint32_t counter;
1477 
1479  "HOSTLIST",
1480  "HOSTLISTFILE",
1481  &filename))
1482  {
1484  "hostlist",
1485  "HOSTLISTFILE");
1486  return;
1487  }
1489  {
1491  return;
1492  }
1494  if (NULL == wh)
1495  {
1497  _ (
1498  "Could not open file `%s' for writing to save hostlists: %s\n"),
1499  filename,
1500  strerror (errno));
1502  return;
1503  }
1505  _ ("Writing %u hostlist URIs to `%s'\n"),
1507  filename);
1508  /* add code to write hostlists to file using bio */
1509  ok = GNUNET_YES;
1510  counter = 0;
1511  while (NULL != (pos = linked_list_head))
1512  {
1513  if (GNUNET_YES == shutdown)
1514  {
1516  linked_list_size--;
1517  }
1518  if (GNUNET_YES == ok)
1519  {
1520  struct GNUNET_BIO_WriteSpec ws[] = {
1521  GNUNET_BIO_write_spec_string ("hostlist uri", pos->hostlist_uri),
1522  GNUNET_BIO_write_spec_int32 ("times used",
1523  (int32_t *) &pos->times_used),
1524  GNUNET_BIO_write_spec_int64 ("quality", (int64_t *) &pos->quality),
1526  "last usage",
1527  (int64_t *) &pos->time_last_usage.abs_value_us),
1529  "creation time",
1530  (int64_t *) &pos->time_creation.abs_value_us),
1531  GNUNET_BIO_write_spec_int32 ("hellos count",
1532  (int32_t *) &pos->hello_count),
1534  };
1535  if ((GNUNET_OK != GNUNET_BIO_write_spec_commit (wh, ws)))
1536  {
1538  _ ("Error writing hostlist URIs to file `%s'\n"),
1539  filename);
1540  ok = GNUNET_NO;
1541  }
1542  }
1543 
1544  if (GNUNET_YES == shutdown)
1545  GNUNET_free (pos);
1546  counter++;
1547  if (counter >= MAX_NUMBER_HOSTLISTS)
1548  break;
1549  }
1551  gettext_noop ("# hostlist URIs written to file"),
1552  counter,
1553  GNUNET_YES);
1554 
1555  if (GNUNET_OK != GNUNET_BIO_write_close (wh, NULL))
1557  _ ("Error writing hostlist URIs to file `%s'\n"),
1558  filename);
1560 }
1561 
1562 
1574 int
1576  struct GNUNET_STATISTICS_Handle *st,
1580  int learn)
1581 {
1582  char *filename;
1583  char *proxytype_str;
1584  int result;
1585 
1586  GNUNET_assert (NULL != st);
1587  if (0 != curl_global_init (CURL_GLOBAL_WIN32))
1588  {
1589  GNUNET_break (0);
1590  return GNUNET_SYSERR;
1591  }
1592  cfg = c;
1593  stats = st;
1594 
1595  /* Read proxy configuration */
1597  if (GNUNET_OK ==
1598  GNUNET_CONFIGURATION_get_value_string (cfg, "HOSTLIST", "PROXY", &proxy))
1599  {
1600  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found proxy host: `%s'\n", proxy);
1601  /* proxy username */
1603  "HOSTLIST",
1604  "PROXY_USERNAME",
1605  &proxy_username))
1606  {
1608  "Found proxy username name: `%s'\n",
1609  proxy_username);
1610  }
1611 
1612  /* proxy password */
1614  "HOSTLIST",
1615  "PROXY_PASSWORD",
1616  &proxy_password))
1617  {
1619  "Found proxy password name: `%s'\n",
1620  proxy_password);
1621  }
1622 
1623  /* proxy type */
1625  "HOSTLIST",
1626  "PROXY_TYPE",
1627  &proxytype_str))
1628  {
1629  if (GNUNET_OK != GNUNET_STRINGS_utf8_toupper (proxytype_str,
1630  proxytype_str))
1632  "Unable to convert `%s' to UTF-8 uppercase\n",
1633  proxytype_str);
1634  proxy_type = CURLPROXY_HTTP;
1635  if (0 == strcmp (proxytype_str, "HTTP"))
1636  proxy_type = CURLPROXY_HTTP;
1637  else if (0 == strcmp (proxytype_str, "HTTP_1_0"))
1638  proxy_type = CURLPROXY_HTTP_1_0;
1639  else if (0 == strcmp (proxytype_str, "SOCKS4"))
1640  proxy_type = CURLPROXY_SOCKS4;
1641  else if (0 == strcmp (proxytype_str, "SOCKS5"))
1642  proxy_type = CURLPROXY_SOCKS5;
1643  else if (0 == strcmp (proxytype_str, "SOCKS4A"))
1644  proxy_type = CURLPROXY_SOCKS4A;
1645  else if (0 == strcmp (proxytype_str, "SOCKS5_HOSTNAME"))
1646  proxy_type = CURLPROXY_SOCKS5_HOSTNAME;
1647  else
1648  {
1649  GNUNET_log (
1651  _ (
1652  "Invalid proxy type: `%s', disabling proxy! Check configuration!\n"),
1653  proxytype_str);
1654  GNUNET_free (proxytype_str);
1655  GNUNET_free (proxy);
1656  proxy = NULL;
1658  proxy_username = NULL;
1660  proxy_password = NULL;
1661 
1662  return GNUNET_SYSERR;
1663  }
1664  }
1665  GNUNET_free (proxytype_str);
1666  }
1667 
1668  stat_learning = learn;
1669  *ch = &handler_connect;
1670  *dh = &handler_disconnect;
1671  linked_list_head = NULL;
1672  linked_list_tail = NULL;
1676 
1677  if (GNUNET_YES == stat_learning)
1678  {
1679  *msgh = &handler_advertisement;
1681  _ ("Learning is enabled on this peer\n"));
1682  load_hostlist_file ();
1684  "Hostlists will be saved to file again in %s\n",
1686  GNUNET_YES));
1689  NULL);
1690  }
1691  else
1692  {
1694  _ ("Learning is not enabled on this peer\n"));
1695  *msgh = NULL;
1697  "HOSTLIST",
1698  "HOSTLISTFILE",
1699  &filename))
1700  {
1702  {
1703  result = remove (filename);
1704  if (0 == result)
1705  GNUNET_log (
1707  _ (
1708  "Since learning is not enabled on this peer, hostlist file `%s' was removed\n"),
1709  filename);
1710  else
1712  "remove",
1713  filename);
1714  }
1715  }
1717  }
1719  "Loading stats value on hostlist download frequency\n");
1721  "hostlist",
1722  gettext_noop (
1723  "# milliseconds between hostlist downloads"),
1724  &primary_task,
1725  &process_stat,
1726  NULL);
1727  if (NULL == sget)
1728  {
1730  "Statistics request failed, scheduling hostlist download\n");
1732  }
1733  else
1734  {
1737  NULL);
1738  }
1739  return GNUNET_OK;
1740 }
1741 
1742 
1746 void
1748 {
1749  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Hostlist client shutdown\n");
1750  if (NULL != sget)
1751  {
1753  sget = NULL;
1754  }
1755  stats = NULL;
1756  if (GNUNET_YES == stat_learning)
1758  if (NULL != ti_saving_task)
1759  {
1761  ti_saving_task = NULL;
1762  }
1763  if (NULL != ti_download_dispatcher_task)
1764  {
1767  }
1768  if (NULL != ti_testing_intervall_task)
1769  {
1772  }
1773  if (NULL != ti_download)
1774  {
1776  ti_download = NULL;
1777  update_hostlist ();
1778  clean_up ();
1779  }
1780  if (NULL != ti_check_download)
1781  {
1783  ti_check_download = NULL;
1784  curl_global_cleanup ();
1785  }
1786  GNUNET_free (proxy);
1787  proxy = NULL;
1789  proxy_username = NULL;
1791  proxy_password = NULL;
1792  if (NULL != pi)
1793  {
1795  pi = NULL;
1796  }
1797  cfg = NULL;
1798 }
1799 
1800 
1801 /* end of gnunet-daemon-hostlist_client.c */
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
#define gettext_noop(String)
Definition: gettext.h:70
static int once
Global to mark if we've run the initialization.
Definition: gnsrecord.c:67
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
static struct GNUNET_TIME_Relative timeout
Desired timeout for the lookup (default is no timeout).
Definition: gnunet-abd.c:61
static struct GNUNET_CADET_Channel * ch
Channel handle.
Definition: gnunet-cadet.c:117
static struct GNUNET_SCHEDULER_Task * st
The shutdown task.
common internal definitions for hostlist daemon
#define MAX_URL_LEN
How long can hostlist URLs be?
#define MAX_BYTES_PER_HOSTLISTS
How many bytes do we download at most from a hostlist server?
static void task_download_dispatcher(void *cls)
static unsigned int stat_download_successful
Value saying if hostlist download was successful.
static struct GNUNET_TIME_Absolute end_time
At what time MUST the current hostlist request be done?
#define SAVING_INTERVAL
Time interval hostlists are saved to disk.
static char * proxy
Proxy hostname or ip we are using (can be NULL).
static uint64_t checked_add(uint64_t val1, uint64_t val2)
Add val2 to val1 with overflow check.
#define HOSTLIST_SUCCESSFUL_HELLO
Value added for each valid HELLO received during a hostlist download.
static void handler_disconnect(void *cls, const struct GNUNET_PeerIdentity *peer, void *internal_cls)
Method called whenever a given peer disconnects.
static int process_stat(void *cls, const char *subsystem, const char *name, uint64_t value, int is_persistent)
We've received the previous delay value from statistics.
static void task_check(void *cls)
Task that checks if we should try to download a hostlist.
#define MAX_NUMBER_HOSTLISTS
Maximum number of hostlist that are saved.
static int stat_download_in_progress
Value controlling if a hostlist download is running at the moment.
static void task_hostlist_saving(void *cls)
Task that writes hostlist entries to a file on a regular base.
static int stat_learning
Set if we are allowed to learn new hostlists and use them.
static char * download_get_url()
Method deciding if a preconfigured or advertisied hostlist is used on a 50:50 ratio.
static struct GNUNET_TIME_Relative hostlist_delay
Amount of time we wait between hostlist downloads.
static struct Hostlist * linked_list_head
Head of the linked list used to store hostlists.
#define HOSTLIST_FAILED_DOWNLOAD
Value subtracted each time a hostlist download fails.
static void handler_advertisement(const char *uri)
Method called whenever an advertisement message arrives.
static unsigned int stat_use_bootstrap
Value saying if a preconfigured bootstrap server is used.
int GNUNET_HOSTLIST_client_start(const struct GNUNET_CONFIGURATION_Handle *c, struct GNUNET_STATISTICS_Handle *st, GNUNET_CORE_ConnectEventHandler *ch, GNUNET_CORE_DisconnectEventHandler *dh, GNUNET_HOSTLIST_UriHandler *msgh, int learn)
Start downloading hostlists from hostlist servers as necessary.
static void * handler_connect(void *cls, const struct GNUNET_PeerIdentity *peer, struct GNUNET_MQ_Handle *mq)
Method called whenever a given peer connects.
static struct GNUNET_STATISTICS_Handle * stats
Statistics handle.
static int stat_testing_allowed
Value controlling if a hostlist testing is allowed at the moment.
static const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
static void insert_hostlist()
Method to insert a hostlist into the datastore.
static size_t download_pos
Number of bytes valid in 'download_buffer'.
static CURL * curl
Current CURL handle.
static int stat_testing_hostlist
Value controlling if a hostlist is tested at the moment.
static struct GNUNET_PEERINFO_Handle * pi
Handle to peerinfo service.
static char * current_url
Current URL that we are using.
static char * proxy_password
Proxy password we are using (can be NULL).
static void stat_timeout_task(void *cls)
Continuation called by the statistics code once we go the stat.
static unsigned int linked_list_size
Size of the linked list used to store hostlists.
static struct GNUNET_STATISTICS_GetHandle * sget
Handle for our statistics GET operation.
#define CURL_EASY_SETOPT(c, a, b)
#define WAITING_INTERVAL
Time interval for download dispatcher before a download is re-scheduled.
static void load_hostlist_file()
Method to load persistent hostlist file during hostlist client startup.
static struct GNUNET_SCHEDULER_Task * ti_testing_intervall_task
ID of the task controlling the locking between two hostlist tests.
static unsigned int stat_connection_count
Number of active connections (according to core service).
static int linked_list_contains(const char *uri)
Method to check if a URI is in hostlist linked list.
static CURLM * multi
Current multi-CURL handle.
#define HOSTLIST_INITIAL
Defines concerning the hostlist quality metric.
static size_t callback_download(void *ptr, size_t size, size_t nmemb, void *ctx)
Process downloaded bits by calling callback on each HELLO.
#define TESTING_INTERVAL
Time interval between two hostlist tests.
#define MIN_CONNECTIONS
Number of connections that we must have to NOT download hostlists anymore.
static void update_hostlist()
Method updating hostlist statistics.
static int stat_bogus_url
Set to GNUNET_YES if the current URL had some problems.
static void task_download(void *cls)
Task that is run when we are ready to receive more data from the hostlist server.
static struct Hostlist * hostlist_to_test
Head of the linked list used to store hostlists.
static void download_hostlist()
Main function that will download a hostlist and process its data.
void GNUNET_HOSTLIST_client_stop()
Stop downloading hostlists from hostlist servers as necessary.
static unsigned int stat_hellos_obtained
Value saying how many valid HELLO messages were obtained during download.
static char * get_bootstrap_server()
Obtain a hostlist URL that we should use.
static struct Hostlist * linked_list_tail
Tail of the linked list used to store hostlists.
static struct GNUNET_SCHEDULER_Task * ti_download
ID of the task downloading the hostlist.
static struct Hostlist * current_hostlist
Current hostlist used for downloading.
static struct GNUNET_SCHEDULER_Task * ti_check_download
ID of the task, checking if hostlist download should take plate.
static struct Hostlist * linked_list_get_lowest_quality()
Method returning the hostlist element with the lowest quality in the datastore.
static struct GNUNET_SCHEDULER_Task * ti_saving_task
ID of the task saving the hostlsit in a regular interval.
static void save_hostlist_file(int shutdown)
Method to save hostlist to a file during hostlist client shutdown.
static uint32_t stat_bytes_downloaded
How many bytes did we download from the current hostlist URL?
static char * proxy_username
Proxy username we are using (can be NULL).
#define HOSTLIST_SUCCESSFUL_DOWNLOAD
Value added each time a hostlist download is successful.
static struct GNUNET_SCHEDULER_Task * ti_download_dispatcher_task
ID of the task called to initiate a download.
static void clean_up()
Clean up the state from the task that downloaded the hostlist and schedule the next task.
static uint64_t checked_sub(uint64_t val1, uint64_t val2)
Subtract val2 from val1 with underflow check.
static curl_proxytype proxy_type
Proxy type we are using (can be NULL).
static void task_testing_intervall_reset(void *cls)
This tasks sets hostlist testing to allowed after interval between to testings is reached.
static void primary_task(void *cls, int success)
Continuation called by the statistics code once we go the stat.
static void download_prepare()
Ask CURL for the select set and then schedule the receiving task with the scheduler.
void(* GNUNET_HOSTLIST_UriHandler)(const char *uri)
Function that handles an advertised URI.
static char * filename
static char * value
Value of the record to add/remove.
static int ok
Return value from 'main' (0 == success)
static struct GNUNET_FS_Uri * uri
Value of URI provided on command-line (when not publishing a file but just creating UBlocks to refer ...
static int result
Global testing status.
static struct GNUNET_TIME_Relative delay
When should dkg communication start?
static struct GNUNET_TESTBED_BarrierWaitHandle * wh
Our barrier wait handle.
static char * subsystem
Set to subsystem that we're going to get stats for (or NULL for all).
static struct GNUNET_DNSSTUB_Context * ctx
Context for DNS resolution.
library to make it easy to download JSON replies over HTTP
Helper library for handling HELLOs.
Maintain the list of currently known hosts.
API to create, modify and access statistics.
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message,...
int GNUNET_BIO_read_string(struct GNUNET_BIO_ReadHandle *h, const char *what, char **result, size_t max_length)
Read 0-terminated string.
Definition: bio.c:330
int GNUNET_BIO_write_spec_commit(struct GNUNET_BIO_WriteHandle *h, struct GNUNET_BIO_WriteSpec *ws)
Execute the write specifications in order.
Definition: bio.c:1359
struct GNUNET_BIO_ReadHandle * GNUNET_BIO_read_open_file(const char *fn)
Open a file for reading.
Definition: bio.c:114
int GNUNET_BIO_write_close(struct GNUNET_BIO_WriteHandle *h, char **emsg)
Close an IO handle.
Definition: bio.c:556
struct GNUNET_BIO_WriteSpec GNUNET_BIO_write_spec_string(const char *what, const char *s)
Create the specification to write a 0-terminated string.
Definition: bio.c:1201
#define GNUNET_BIO_read_spec_end()
End of specifications marker.
int GNUNET_BIO_read_spec_commit(struct GNUNET_BIO_ReadHandle *h, struct GNUNET_BIO_ReadSpec *rs)
Execute the read specifications in order.
Definition: bio.c:1108
struct GNUNET_BIO_ReadSpec GNUNET_BIO_read_spec_int32(const char *what, int32_t *i)
Create the specification to read an (u)int32_t.
Definition: bio.c:1001
#define GNUNET_BIO_write_spec_end()
End of specifications marker.
int GNUNET_BIO_read_close(struct GNUNET_BIO_ReadHandle *h, char **emsg)
Close an open handle.
Definition: bio.c:162
struct GNUNET_BIO_WriteHandle * GNUNET_BIO_write_open_file(const char *fn)
Open a file for writing.
Definition: bio.c:508
struct GNUNET_BIO_WriteSpec GNUNET_BIO_write_spec_int32(const char *what, int32_t *i)
Create the specification to write an (u)int32_t.
Definition: bio.c:1246
struct GNUNET_BIO_ReadSpec GNUNET_BIO_read_spec_int64(const char *what, int64_t *i)
Create the specification to read an (u)int64_t.
Definition: bio.c:1045
struct GNUNET_BIO_WriteSpec GNUNET_BIO_write_spec_int64(const char *what, int64_t *i)
Create the specification to write an (u)int64_t.
Definition: bio.c:1291
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_filename(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be the name of a file or directory.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_string(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be a string.
void(* GNUNET_CORE_DisconnectEventHandler)(void *cls, const struct GNUNET_PeerIdentity *peer, void *peer_cls)
Method called whenever a peer disconnects.
void *(* GNUNET_CORE_ConnectEventHandler)(void *cls, const struct GNUNET_PeerIdentity *peer, struct GNUNET_MQ_Handle *mq)
Method called whenever a given peer connects.
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).
enum GNUNET_GenericReturnValue GNUNET_DISK_file_test(const char *fil)
Check that fil corresponds to a filename (of a file that exists and that is not a directory).
Definition: disk.c:482
enum GNUNET_GenericReturnValue GNUNET_DISK_directory_create_for_file(const char *filename)
Create the directory structure for storing a file.
Definition: disk.c:582
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
uint16_t GNUNET_HELLO_size(const struct GNUNET_HELLO_Message *hello)
Return the size of the given HELLO message.
Definition: hello.c:630
#define GNUNET_log(kind,...)
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#define GNUNET_MIN(a, b)
@ GNUNET_SCHEDULER_PRIORITY_DEFAULT
Run with the default priority (normal P2P operations).
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
#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.
void GNUNET_log_config_missing(enum GNUNET_ErrorType kind, const char *section, const char *option)
Log error message about missing configuration option.
#define GNUNET_log_strerror_file(level, cmd, filename)
Log an error message at log-level 'level' that indicates a failure of the command 'cmd' with the mess...
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_BULK
@ GNUNET_ERROR_TYPE_DEBUG
@ GNUNET_ERROR_TYPE_INFO
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
struct GNUNET_NETWORK_FDSet * GNUNET_NETWORK_fdset_create(void)
Creates an fd set.
Definition: network.c:1170
void GNUNET_NETWORK_fdset_destroy(struct GNUNET_NETWORK_FDSet *fds)
Releases the associated memory of an fd set.
Definition: network.c:1186
void GNUNET_NETWORK_fdset_copy_native(struct GNUNET_NETWORK_FDSet *to, const fd_set *from, int nfds)
Copy a native fd set into the GNUnet representation.
Definition: network.c:1040
struct GNUNET_MQ_Envelope * GNUNET_PEERINFO_add_peer(struct GNUNET_PEERINFO_Handle *h, const struct GNUNET_HELLO_Message *hello, GNUNET_SCHEDULER_TaskCallback cont, void *cont_cls)
Add a host to the persistent list.
Definition: peerinfo_api.c:530
struct GNUNET_PEERINFO_Handle * GNUNET_PEERINFO_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the peerinfo service.
Definition: peerinfo_api.c:123
void GNUNET_PEERINFO_disconnect(struct GNUNET_PEERINFO_Handle *h)
Disconnect from the peerinfo service.
Definition: peerinfo_api.c:149
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:1299
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_select(enum GNUNET_SCHEDULER_Priority prio, struct GNUNET_TIME_Relative delay, const struct GNUNET_NETWORK_FDSet *rs, const struct GNUNET_NETWORK_FDSet *ws, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay or when any of the specified file descriptor set...
Definition: scheduler.c:1830
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:975
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:1272
void GNUNET_STATISTICS_get_cancel(struct GNUNET_STATISTICS_GetHandle *gh)
Cancel a GNUNET_STATISTICS_get request.
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_STATISTICS_GetHandle * GNUNET_STATISTICS_get(struct GNUNET_STATISTICS_Handle *handle, const char *subsystem, const char *name, GNUNET_STATISTICS_Callback cont, GNUNET_STATISTICS_Iterator proc, void *cls)
Get statistic from the peer.
enum GNUNET_GenericReturnValue GNUNET_STRINGS_utf8_toupper(const char *input, char *output)
Convert the utf-8 input string to upper case.
Definition: strings.c:471
struct GNUNET_TIME_Relative GNUNET_TIME_relative_min(struct GNUNET_TIME_Relative t1, struct GNUNET_TIME_Relative t2)
Return the minimum of two relative time values.
Definition: time.c:343
#define GNUNET_TIME_UNIT_HOURS
One hour.
#define GNUNET_TIME_UNIT_SECONDS
One second.
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_remaining(struct GNUNET_TIME_Absolute future)
Given a timestamp in the future, how much time remains until then?
Definition: time.c:405
#define GNUNET_TIME_UNIT_MILLISECONDS
One millisecond.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:111
#define GNUNET_TIME_UNIT_MINUTES
One minute.
struct GNUNET_TIME_Absolute GNUNET_TIME_relative_to_absolute(struct GNUNET_TIME_Relative rel)
Convert relative time to an absolute time in the future.
Definition: time.c:316
struct GNUNET_TIME_Relative GNUNET_TIME_relative_multiply(struct GNUNET_TIME_Relative rel, unsigned long long factor)
Multiply relative time by a given factor.
Definition: time.c:484
#define GNUNET_TIME_UNIT_ZERO
Relative time zero.
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:569
#define max(x, y)
static unsigned int size
Size of the "table".
Definition: peer.c:68
#define _(String)
GNU gettext support macro.
Definition: platform.h:178
const char * name
Handle for buffered reading.
Definition: bio.c:69
Structure specifying a reading operation on an IO handle.
GNUNET_BIO_ReadHandler rh
Function performing data deserialization.
Handle for buffered writing.
Definition: bio.c:466
Structure specifying a writing operation on an IO handle.
A HELLO message is used to exchange information about transports with other peers.
Handle to a message queue.
Definition: mq.c:87
Header for all communications.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
collection of IO descriptors
Handle to the peerinfo service.
Definition: peerinfo_api.c:85
The identity of the host (wraps the signing key of the peer).
Entry in list of pending tasks.
Definition: scheduler.c:136
Linked list of things we still need to do.
Handle for the service.
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 single hostlist obtained by hostlist advertisements.
struct GNUNET_TIME_Absolute time_last_usage
Last time the hostlist was obtained.
uint64_t quality
Value describing the quality of the hostlist, the bigger the better but (should) never < 0 used for d...
struct Hostlist * prev
previous entry, used to manage entries in a double linked list
uint32_t hello_count
Number of HELLO messages obtained during last download.
struct GNUNET_TIME_Absolute time_creation
Time the hostlist advertisement was received and the entry was created.
uint32_t times_used
Number of times the hostlist was successfully obtained.
struct Hostlist * next
next entry, used to manage entries in a double linked list
const char * hostlist_uri
URI where hostlist can be obtained.
struct GNUNET_TESTBED_Peer * peer
The peer associated with this model.