GNUnet  0.10.x
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 
37 
42 #define MIN_CONNECTIONS 4
43 
47 #define MAX_NUMBER_HOSTLISTS 30
48 
52 #define SAVING_INTERVAL GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 30)
53 
57 #define TESTING_INTERVAL GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 3)
58 
62 #define WAITING_INTERVAL GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1)
63 
71 #define HOSTLIST_INITIAL 10000
72 
76 #define HOSTLIST_FAILED_DOWNLOAD 100
77 
81 #define HOSTLIST_SUCCESSFUL_DOWNLOAD 100
82 
86 #define HOSTLIST_SUCCESSFUL_HELLO 1
87 
88 
89 
93 struct Hostlist
94 {
98  struct Hostlist *prev;
99 
103  struct Hostlist *next;
104 
108  const char *hostlist_uri;
109 
118  uint64_t quality;
119 
124 
129 
133  uint32_t hello_count;
134 
138  uint32_t times_used;
139 
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 
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,
325  size_t size,
326  size_t nmemb,
327  void *ctx)
328 {
329  static char download_buffer[GNUNET_MAX_MESSAGE_SIZE - 1];
330  const char *cbuf = ptr;
331  const struct GNUNET_MessageHeader *msg;
332  size_t total;
333  size_t cpy;
334  size_t left;
335  uint16_t msize;
336 
337  total = size * nmemb;
338  stat_bytes_downloaded += total;
339  if ((total == 0) || (stat_bogus_url))
340  {
341  return total; /* ok, no data or bogus data */
342  }
343 
346  ("# bytes downloaded from hostlist servers"),
347  (int64_t) total, GNUNET_NO);
348  left = total;
349  while ((left > 0) || (download_pos > 0))
350  {
351  cpy = GNUNET_MIN (left, GNUNET_MAX_MESSAGE_SIZE - 1 - download_pos);
352  GNUNET_memcpy (&download_buffer[download_pos], cbuf, cpy);
353  cbuf += cpy;
354  download_pos += cpy;
355  left -= cpy;
356  if (download_pos < sizeof (struct GNUNET_MessageHeader))
357  {
358  GNUNET_assert (0 == left);
359  break;
360  }
361  msg = (const struct GNUNET_MessageHeader *) download_buffer;
362  msize = ntohs (msg->size);
363  if (msize < sizeof (struct GNUNET_MessageHeader))
364  {
367  ("# invalid HELLOs downloaded from hostlist servers"),
368  1, GNUNET_NO);
370  _("Invalid `%s' message received from hostlist at `%s'\n"),
371  "HELLO", 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");
388  ("# valid HELLOs downloaded from hostlist servers"),
389  1, GNUNET_NO);
391  (void) GNUNET_PEERINFO_add_peer (pi,
392  (const struct GNUNET_HELLO_Message *) msg,
393  NULL,
394  NULL);
395  }
396  else
397  {
400  ("# invalid HELLOs downloaded from hostlist servers"),
401  1, GNUNET_NO);
403  _("Invalid `%s' message received from hostlist at `%s'\n"),
404  "HELLO", current_url);
407  return total;
408  }
409  memmove (download_buffer,
410  &download_buffer[msize],
411  download_pos - msize);
412  download_pos -= msize;
413  }
414  return total;
415 }
416 
417 
423 static char *
425 {
426  char *servers;
427  char *ret;
428  size_t urls;
429  size_t pos;
430 
431  if (GNUNET_OK !=
432  GNUNET_CONFIGURATION_get_value_string (cfg, "HOSTLIST", "SERVERS",
433  &servers))
434  {
436  "hostlist", "SERVERS");
437  return NULL;
438  }
439 
440  urls = 0;
441  if (strlen (servers) > 0)
442  {
443  urls++;
444  pos = strlen (servers) - 1;
445  while (pos > 0)
446  {
447  if (servers[pos] == ' ')
448  urls++;
449  pos--;
450  }
451  }
452  if (urls == 0)
453  {
455  "hostlist", "SERVERS");
456  GNUNET_free (servers);
457  return NULL;
458  }
459 
461  pos = strlen (servers) - 1;
462  while (pos > 0)
463  {
464  if (servers[pos] == ' ')
465  {
466  urls--;
467  servers[pos] = '\0';
468  }
469  if (urls == 0)
470  {
471  pos++;
472  break;
473  }
474  pos--;
475  }
476  ret = GNUNET_strdup (&servers[pos]);
477  GNUNET_free (servers);
478  return ret;
479 }
480 
481 
486 static char *
488 {
489  uint32_t index;
490  unsigned int counter;
491  struct Hostlist *pos;
492 
493  if (GNUNET_NO == stat_learning)
494  {
496  "Using preconfigured bootstrap server\n");
497  current_hostlist = NULL;
498  return get_bootstrap_server ();
499  }
500 
501  if ((GNUNET_YES == stat_testing_hostlist) && (NULL != hostlist_to_test))
502  {
504  "Testing new advertised hostlist if it is obtainable\n");
505  current_hostlist = hostlist_to_test;
506  return GNUNET_strdup (hostlist_to_test->hostlist_uri);
507  }
508 
510  {
512  "Using preconfigured bootstrap server\n");
513  current_hostlist = NULL;
514  return get_bootstrap_server ();
515  }
516  index =
518  counter = 0;
519  pos = linked_list_head;
520  while (counter < index)
521  {
522  pos = pos->next;
523  counter++;
524  }
525  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using learned hostlist `%s'\n",
526  pos->hostlist_uri);
527  current_hostlist = pos;
528  return GNUNET_strdup (pos->hostlist_uri);
529 }
530 
531 
532 #define CURL_EASY_SETOPT(c, a, b) do { ret = curl_easy_setopt (c, a, b); if (CURLE_OK != ret) GNUNET_log(GNUNET_ERROR_TYPE_WARNING, _("%s failed at %s:%d: `%s'\n"), "curl_easy_setopt", __FILE__, __LINE__, curl_easy_strerror (ret)); } while (0)
533 
534 
540 static void
541 save_hostlist_file (int shutdown);
542 
543 
551 static uint64_t
552 checked_add (uint64_t val1,
553  uint64_t val2)
554 {
555  static uint64_t temp;
556  static uint64_t maxv;
557 
558  maxv = 0;
559  maxv--;
560 
561  temp = val1 + val2;
562  if (temp < val1)
563  return maxv;
564  return temp;
565 }
566 
567 
575 static uint64_t
576 checked_sub (uint64_t val1,
577  uint64_t val2)
578 {
579  if (val1 <= val2)
580  return 0;
581  return (val1 - val2);
582 }
583 
584 
591 static int
593 {
594  struct Hostlist *pos;
595 
596  pos = linked_list_head;
597  while (pos != NULL)
598  {
599  if (0 == strcmp (pos->hostlist_uri, uri))
600  return GNUNET_YES;
601  pos = pos->next;
602  }
603  return GNUNET_NO;
604 }
605 
606 
611 static struct Hostlist *
613 {
614  struct Hostlist *pos;
615  struct Hostlist *lowest;
616 
617  if (linked_list_size == 0)
618  return NULL;
619  lowest = linked_list_head;
620  pos = linked_list_head->next;
621  while (pos != NULL)
622  {
623  if (pos->quality < lowest->quality)
624  lowest = pos;
625  pos = pos->next;
626  }
627  return lowest;
628 }
629 
630 
636 static void
638 {
639  struct Hostlist *lowest_quality;
640 
642  {
643  /* No free entries available, replace existing entry */
644  lowest_quality = linked_list_get_lowest_quality ();
645  GNUNET_assert (lowest_quality != NULL);
647  "Removing hostlist with URI `%s' which has the worst quality of all (%llu)\n",
648  lowest_quality->hostlist_uri,
649  (unsigned long long) lowest_quality->quality);
650  GNUNET_CONTAINER_DLL_remove (linked_list_head, linked_list_tail,
651  lowest_quality);
653  GNUNET_free (lowest_quality);
654  }
655  GNUNET_CONTAINER_DLL_insert (linked_list_head, linked_list_tail,
656  hostlist_to_test);
658  GNUNET_STATISTICS_set (stats, gettext_noop ("# advertised hostlist URIs"),
661 }
662 
663 
667 static void
669 {
670  char *stat;
671 
672  if (((stat_use_bootstrap == GNUNET_NO) && (NULL != current_hostlist)) ||
673  ((stat_testing_hostlist == GNUNET_YES) && (NULL != current_hostlist)))
674  {
676  "Updating hostlist statics for URI `%s'\n",
677  current_hostlist->hostlist_uri);
678  current_hostlist->hello_count = stat_hellos_obtained;
679  current_hostlist->time_last_usage = GNUNET_TIME_absolute_get ();
680  current_hostlist->quality =
681  checked_add (current_hostlist->quality,
684  {
685  current_hostlist->times_used++;
686  current_hostlist->quality =
687  checked_add (current_hostlist->quality, HOSTLIST_SUCCESSFUL_DOWNLOAD);
688  GNUNET_asprintf (&stat, gettext_noop ("# advertised URI `%s' downloaded"),
689  current_hostlist->hostlist_uri);
690 
691  GNUNET_STATISTICS_update (stats, stat, 1, GNUNET_YES);
692  GNUNET_free (stat);
693  }
694  else
695  current_hostlist->quality =
696  checked_sub (current_hostlist->quality, HOSTLIST_FAILED_DOWNLOAD);
697  }
698  current_hostlist = NULL;
699  /* Alternating the usage of preconfigured and learned hostlists */
700 
702  return;
703 
704  if (GNUNET_YES == stat_learning)
705  {
708  else
710  }
711  else
713 }
714 
715 
720 static void
722 {
723  CURLMcode mret;
724 
725  if ( (stat_testing_hostlist == GNUNET_YES) &&
727  (NULL != hostlist_to_test) )
728  {
730  _
731  ("Advertised hostlist with URI `%s' could not be downloaded. Advertised URI gets dismissed.\n"),
732  hostlist_to_test->hostlist_uri);
733  }
734 
736  {
738  }
739  if (NULL != hostlist_to_test)
740  {
741  GNUNET_free (hostlist_to_test);
742  hostlist_to_test = NULL;
743  }
744 
745  if (NULL != multi)
746  {
747  mret = curl_multi_remove_handle (multi, curl);
748  if (mret != CURLM_OK)
749  {
750  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("%s failed at %s:%d: `%s'\n"),
751  "curl_multi_remove_handle", __FILE__, __LINE__,
752  curl_multi_strerror (mret));
753  }
754  mret = curl_multi_cleanup (multi);
755  if (mret != CURLM_OK)
756  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("%s failed at %s:%d: `%s'\n"),
757  "curl_multi_cleanup", __FILE__, __LINE__,
758  curl_multi_strerror (mret));
759  multi = NULL;
760  }
761  if (NULL != curl)
762  {
763  curl_easy_cleanup (curl);
764  curl = NULL;
765  }
767  current_url = NULL;
770 }
771 
772 
780 static void
781 task_download (void *cls);
782 
783 
788 static void
790 {
791  CURLMcode mret;
792  fd_set rs;
793  fd_set ws;
794  fd_set es;
795  int max;
796  struct GNUNET_NETWORK_FDSet *grs;
797  struct GNUNET_NETWORK_FDSet *gws;
798  long timeout;
799  struct GNUNET_TIME_Relative rtime;
800 
801  max = -1;
802  FD_ZERO (&rs);
803  FD_ZERO (&ws);
804  FD_ZERO (&es);
805  mret = curl_multi_fdset (multi, &rs, &ws, &es, &max);
806  if (mret != CURLM_OK)
807  {
808  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("%s failed at %s:%d: `%s'\n"),
809  "curl_multi_fdset", __FILE__, __LINE__,
810  curl_multi_strerror (mret));
811  clean_up ();
812  return;
813  }
814  mret = curl_multi_timeout (multi, &timeout);
815  if (mret != CURLM_OK)
816  {
817  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("%s failed at %s:%d: `%s'\n"),
818  "curl_multi_timeout", __FILE__, __LINE__,
819  curl_multi_strerror (mret));
820  clean_up ();
821  return;
822  }
823  rtime =
826  (GNUNET_TIME_UNIT_MILLISECONDS, timeout));
829  GNUNET_NETWORK_fdset_copy_native (grs, &rs, max + 1);
830  GNUNET_NETWORK_fdset_copy_native (gws, &ws, max + 1);
832  "Scheduling task for hostlist download using cURL\n");
833  ti_download =
835  rtime, grs, gws,
836  &task_download, multi);
839 }
840 
841 
848 static void
849 task_download (void *cls)
850 {
851  int running;
852  struct CURLMsg *msg;
853  CURLMcode mret;
854 
855  ti_download = NULL;
856  if (0 == GNUNET_TIME_absolute_get_remaining (end_time).rel_value_us)
857  {
859  _("Timeout trying to download hostlist from `%s'\n"),
860  current_url);
861  update_hostlist ();
862  clean_up ();
863  return;
864  }
866  "Ready for processing hostlist client request\n");
867  do
868  {
869  running = 0;
871  {
873  _("Download limit of %u bytes exceeded, stopping download\n"),
875  clean_up ();
876  return;
877  }
878  mret = curl_multi_perform (multi, &running);
879  if (running == 0)
880  {
881  do
882  {
883  msg = curl_multi_info_read (multi, &running);
884  GNUNET_break (msg != NULL);
885  if (msg == NULL)
886  break;
887  switch (msg->msg)
888  {
889  case CURLMSG_DONE:
890  if ((msg->data.result != CURLE_OK) &&
891  (msg->data.result != CURLE_GOT_NOTHING))
893  _("Download of hostlist from `%s' failed: `%s'\n"),
894  current_url,
895  curl_easy_strerror (msg->data.result));
896  else
897  {
899  _("Download of hostlist `%s' completed.\n"),
900  current_url);
902  update_hostlist ();
904  {
906  _
907  ("Adding successfully tested hostlist `%s' datastore.\n"),
908  current_url);
909  insert_hostlist ();
910  hostlist_to_test = NULL;
912  }
913  }
914  clean_up ();
915  return;
916  default:
917  break;
918  }
919 
920  }
921  while ((running > 0));
922  }
923  }
924  while (mret == CURLM_CALL_MULTI_PERFORM);
925 
926  if (mret != CURLM_OK)
927  {
928  GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("%s failed at %s:%d: `%s'\n"),
929  "curl_multi_perform", __FILE__, __LINE__,
930  curl_multi_strerror (mret));
931  clean_up ();
932  }
933  download_prepare ();
934 }
935 
936 
941 static void
943 {
944  CURLcode ret;
945  CURLMcode mret;
946 
947 
949  if (current_url == NULL)
950  return;
951  curl = curl_easy_init ();
952  multi = NULL;
953  if (curl == NULL)
954  {
955  GNUNET_break (0);
956  clean_up ();
957  return;
958  }
960  _("Bootstrapping using hostlist at `%s'.\n"), current_url);
961 
966 
968  gettext_noop ("# hostlist downloads initiated"), 1,
969  GNUNET_NO);
970  if (NULL != proxy)
971  {
972  CURL_EASY_SETOPT (curl, CURLOPT_PROXY, proxy);
973  CURL_EASY_SETOPT (curl, CURLOPT_PROXYTYPE, proxy_type);
974  if (NULL != proxy_username)
975  CURL_EASY_SETOPT (curl, CURLOPT_PROXYUSERNAME, proxy_username);
976  if (NULL != proxy_password)
977  CURL_EASY_SETOPT (curl, CURLOPT_PROXYPASSWORD, proxy_password);
978  }
979  download_pos = 0;
980  stat_bogus_url = 0;
981  CURL_EASY_SETOPT (curl, CURLOPT_WRITEFUNCTION, &callback_download);
982  if (ret != CURLE_OK)
983  {
984  clean_up ();
985  return;
986  }
987  CURL_EASY_SETOPT (curl, CURLOPT_WRITEDATA, NULL);
988  if (ret != CURLE_OK)
989  {
990  clean_up ();
991  return;
992  }
993  CURL_EASY_SETOPT (curl, CURLOPT_FOLLOWLOCATION, 1);
994  CURL_EASY_SETOPT (curl, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);
995  CURL_EASY_SETOPT (curl, CURLOPT_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);
996  CURL_EASY_SETOPT (curl, CURLOPT_MAXREDIRS, 4);
997  /* no need to abort if the above failed */
998  CURL_EASY_SETOPT (curl, CURLOPT_URL, current_url);
999  if (ret != CURLE_OK)
1000  {
1001  clean_up ();
1002  return;
1003  }
1004  CURL_EASY_SETOPT (curl, CURLOPT_FAILONERROR, 1);
1005 #if 0
1006  CURL_EASY_SETOPT (curl, CURLOPT_VERBOSE, 1);
1007 #endif
1008  CURL_EASY_SETOPT (curl, CURLOPT_BUFFERSIZE, GNUNET_MAX_MESSAGE_SIZE);
1009  if (0 == strncmp (current_url, "http", 4))
1010  CURL_EASY_SETOPT (curl, CURLOPT_USERAGENT, "GNUnet");
1011  CURL_EASY_SETOPT (curl, CURLOPT_CONNECTTIMEOUT, 60L);
1012  CURL_EASY_SETOPT (curl, CURLOPT_TIMEOUT, 60L);
1013  multi = curl_multi_init ();
1014  if (multi == NULL)
1015  {
1016  GNUNET_break (0);
1017  /* clean_up (); */
1018  return;
1019  }
1020  mret = curl_multi_add_handle (multi, curl);
1021  if (mret != CURLM_OK)
1022  {
1023  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("%s failed at %s:%d: `%s'\n"),
1024  "curl_multi_add_handle", __FILE__, __LINE__,
1025  curl_multi_strerror (mret));
1026  mret = curl_multi_cleanup (multi);
1027  if (mret != CURLM_OK)
1028  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("%s failed at %s:%d: `%s'\n"),
1029  "curl_multi_cleanup", __FILE__, __LINE__,
1030  curl_multi_strerror (mret));
1031  multi = NULL;
1032  clean_up ();
1033  return;
1034  }
1036  download_prepare ();
1037 }
1038 
1039 
1040 static void
1042 {
1043  ti_download_dispatcher_task = NULL;
1044  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Download is initiated...\n");
1046  {
1047  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Download can start immediately...\n");
1048  download_hostlist ();
1049  }
1050  else
1051  {
1053  "Download in progess, have to wait...\n");
1054  ti_download_dispatcher_task =
1056  &task_download_dispatcher, NULL);
1057  }
1058 }
1059 
1060 
1066 static void
1067 task_check (void *cls)
1068 {
1069  static int once;
1070  struct GNUNET_TIME_Relative delay;
1071 
1072  ti_check_download = NULL;
1073  if (stats == NULL)
1074  {
1075  curl_global_cleanup ();
1076  return; /* in shutdown */
1077  }
1079  (NULL == ti_download_dispatcher_task) )
1080  ti_download_dispatcher_task =
1082 
1083  delay = hostlist_delay;
1084  if (0 == hostlist_delay.rel_value_us)
1086  else
1089  GNUNET_TIME_UNIT_HOURS.rel_value_us * (1 + stat_connection_count))
1090  hostlist_delay =
1092  (1 + stat_connection_count));
1093  GNUNET_STATISTICS_set (stats,
1094  gettext_noop
1095  ("# milliseconds between hostlist downloads"),
1096  hostlist_delay.rel_value_us / 1000LL,
1097  GNUNET_YES);
1098  if (0 == once)
1099  {
1100  delay = GNUNET_TIME_UNIT_ZERO;
1101  once = 1;
1102  }
1104  _("Have %u/%u connections. Will consider downloading hostlist in %s\n"),
1107  ti_check_download = GNUNET_SCHEDULER_add_delayed (delay,
1108  &task_check, NULL);
1109 }
1110 
1111 
1117 static void
1119 {
1120  ti_testing_intervall_task = NULL;
1123  "Testing new hostlist advertisements is allowed again\n");
1124 }
1125 
1126 
1132 static void
1134 {
1135  ti_saving_task = NULL;
1137 
1139  "Hostlists will be saved to file again in %s\n",
1141  ti_saving_task =
1144  NULL);
1145 }
1146 
1147 
1155 static void *
1156 handler_connect (void *cls,
1157  const struct GNUNET_PeerIdentity *peer,
1158  struct GNUNET_MQ_Handle *mq)
1159 {
1160  GNUNET_assert (stat_connection_count < UINT_MAX);
1162  GNUNET_STATISTICS_update (stats,
1163  gettext_noop ("# active connections"),
1164  1,
1165  GNUNET_NO);
1166  return NULL;
1167 }
1168 
1169 
1176 static void
1178  const struct GNUNET_PeerIdentity *peer,
1179  void *internal_cls)
1180 {
1183  GNUNET_STATISTICS_update (stats,
1184  gettext_noop ("# active connections"),
1185  -1,
1186  GNUNET_NO);
1187 }
1188 
1189 
1195 static void
1197 {
1198  size_t uri_size;
1199  struct Hostlist *hostlist;
1200 
1201  uri_size = strlen (uri) + 1;
1203  "Hostlist client recieved advertisement containing URI `%s'\n",
1204  uri);
1205  if (GNUNET_NO != linked_list_contains (uri))
1206  {
1208  "URI `%s' is already known\n",
1209  uri);
1210  return;
1211  }
1212 
1214  {
1216  "Currently not accepting new advertisements: interval between to advertisements is not reached\n");
1217  return;
1218  }
1220  {
1222  "Currently not accepting new advertisements: we are already testing a hostlist\n");
1223  return;
1224  }
1225 
1226  hostlist = GNUNET_malloc (sizeof (struct Hostlist) + uri_size);
1227  hostlist->hostlist_uri = (const char *) &hostlist[1];
1228  GNUNET_memcpy (&hostlist[1],
1229  uri,
1230  uri_size);
1231  hostlist->time_creation = GNUNET_TIME_absolute_get ();
1232  hostlist->quality = HOSTLIST_INITIAL;
1233  hostlist_to_test = hostlist;
1234 
1237  ti_testing_intervall_task =
1240  NULL);
1241 
1243  "Testing new hostlist advertisements is locked for the next %s\n",
1245  GNUNET_YES));
1246 
1247  ti_download_dispatcher_task =
1249  NULL);
1250 }
1251 
1252 
1261 static void
1262 primary_task (void *cls,
1263  int success)
1264 {
1265  if (NULL != ti_check_download)
1266  {
1267  GNUNET_SCHEDULER_cancel (ti_check_download);
1268  ti_check_download = NULL;
1269  }
1270  sget = NULL;
1271  GNUNET_assert (NULL != stats);
1273  "Statistics request done, scheduling hostlist download\n");
1274  ti_check_download = GNUNET_SCHEDULER_add_now (&task_check, NULL);
1275 }
1276 
1277 
1286 static void
1288 {
1290  sget = NULL;
1291  ti_check_download = GNUNET_SCHEDULER_add_now (&task_check,
1292  NULL);
1293 }
1294 
1295 
1305 static int
1306 process_stat (void *cls,
1307  const char *subsystem,
1308  const char *name,
1309  uint64_t value,
1310  int is_persistent)
1311 {
1312  hostlist_delay.rel_value_us = value * 1000LL;
1314  "Initial time between hostlist downloads is %s\n",
1316  GNUNET_YES));
1317  return GNUNET_OK;
1318 }
1319 
1320 
1324 static void
1326 {
1327  char *filename;
1328  char *uri;
1329  char *emsg;
1330  struct Hostlist *hostlist;
1331  uint32_t times_used;
1332  uint32_t hellos_returned;
1333  uint64_t quality;
1334  uint64_t last_used;
1335  uint64_t created;
1336  uint32_t counter;
1337  struct GNUNET_BIO_ReadHandle *rh;
1338 
1339  uri = NULL;
1340  if (GNUNET_OK !=
1341  GNUNET_CONFIGURATION_get_value_filename (cfg, "HOSTLIST", "HOSTLISTFILE",
1342  &filename))
1343  {
1345  "hostlist", "HOSTLISTFILE");
1346  return;
1347  }
1348 
1350  _("Loading saved hostlist entries from file `%s' \n"),
1351  filename);
1352  if (GNUNET_NO == GNUNET_DISK_file_test (filename))
1353  {
1355  _("Hostlist file `%s' does not exist\n"), filename);
1356  GNUNET_free (filename);
1357  return;
1358  }
1359 
1360  rh = GNUNET_BIO_read_open (filename);
1361  if (NULL == rh)
1362  {
1364  _("Could not open file `%s' for reading to load hostlists: %s\n"),
1365  filename, STRERROR (errno));
1366  GNUNET_free (filename);
1367  return;
1368  }
1369 
1370  counter = 0;
1371  while ((GNUNET_OK == GNUNET_BIO_read_string (rh, "url", &uri, MAX_URL_LEN)) &&
1372  (NULL != uri) && (GNUNET_OK == GNUNET_BIO_read_int32 (rh, &times_used))
1373  && (GNUNET_OK == GNUNET_BIO_read_int64 (rh, &quality)) &&
1374  (GNUNET_OK == GNUNET_BIO_read_int64 (rh, &last_used)) &&
1375  (GNUNET_OK == GNUNET_BIO_read_int64 (rh, &created)) &&
1376  (GNUNET_OK == GNUNET_BIO_read_int32 (rh, &hellos_returned)))
1377  {
1378  hostlist = GNUNET_malloc (sizeof (struct Hostlist) + strlen (uri) + 1);
1379  hostlist->hello_count = hellos_returned;
1380  hostlist->hostlist_uri = (const char *) &hostlist[1];
1381  GNUNET_memcpy (&hostlist[1], uri, strlen (uri) + 1);
1382  hostlist->quality = quality;
1383  hostlist->time_creation.abs_value_us = created;
1384  hostlist->time_last_usage.abs_value_us = last_used;
1385  GNUNET_CONTAINER_DLL_insert (linked_list_head, linked_list_tail, hostlist);
1386  linked_list_size++;
1388  "Added hostlist entry eith URI `%s' \n",
1389  hostlist->hostlist_uri);
1390  GNUNET_free (uri);
1391  uri = NULL;
1392  counter++;
1393  if (counter >= MAX_NUMBER_HOSTLISTS)
1394  break;
1395  }
1396 
1398  _("%u hostlist URIs loaded from file\n"),
1399  counter);
1400  GNUNET_STATISTICS_set (stats,
1401  gettext_noop ("# hostlist URIs read from file"),
1402  counter, GNUNET_YES);
1403  GNUNET_STATISTICS_set (stats,
1404  gettext_noop ("# advertised hostlist URIs"),
1406 
1407  GNUNET_free_non_null (uri);
1408  emsg = NULL;
1409  (void) GNUNET_BIO_read_close (rh, &emsg);
1410  if (emsg != NULL)
1411  GNUNET_free (emsg);
1412  GNUNET_free (filename);
1413 }
1414 
1415 
1421 static void
1422 save_hostlist_file (int shutdown)
1423 {
1424  char *filename;
1425  struct Hostlist *pos;
1426  struct GNUNET_BIO_WriteHandle *wh;
1427  int ok;
1428  uint32_t counter;
1429 
1430  if (GNUNET_OK !=
1431  GNUNET_CONFIGURATION_get_value_filename (cfg, "HOSTLIST", "HOSTLISTFILE",
1432  &filename))
1433  {
1435  "hostlist", "HOSTLISTFILE");
1436  return;
1437  }
1439  {
1440  GNUNET_free (filename);
1441  return;
1442  }
1443  wh = GNUNET_BIO_write_open (filename);
1444  if (NULL == wh)
1445  {
1447  _("Could not open file `%s' for writing to save hostlists: %s\n"),
1448  filename,
1449  STRERROR (errno));
1450  GNUNET_free (filename);
1451  return;
1452  }
1454  _("Writing %u hostlist URIs to `%s'\n"),
1455  linked_list_size, filename);
1456  /* add code to write hostlists to file using bio */
1457  ok = GNUNET_YES;
1458  counter = 0;
1459  while (NULL != (pos = linked_list_head))
1460  {
1461  if (GNUNET_YES == shutdown)
1462  {
1463  GNUNET_CONTAINER_DLL_remove (linked_list_head, linked_list_tail, pos);
1464  linked_list_size--;
1465  }
1466  if (GNUNET_YES == ok)
1467  {
1468  if ((GNUNET_OK != GNUNET_BIO_write_string (wh, pos->hostlist_uri)) ||
1469  (GNUNET_OK != GNUNET_BIO_write_int32 (wh, pos->times_used)) ||
1470  (GNUNET_OK != GNUNET_BIO_write_int64 (wh, pos->quality)) ||
1471  (GNUNET_OK !=
1473  (GNUNET_OK !=
1476  {
1478  _("Error writing hostlist URIs to file `%s'\n"), filename);
1479  ok = GNUNET_NO;
1480  }
1481  }
1482 
1483  if (GNUNET_YES == shutdown)
1484  GNUNET_free (pos);
1485  counter++;
1486  if (counter >= MAX_NUMBER_HOSTLISTS)
1487  break;
1488  }
1489  GNUNET_STATISTICS_set (stats,
1490  gettext_noop ("# hostlist URIs written to file"),
1491  counter, GNUNET_YES);
1492 
1493  if (GNUNET_OK != GNUNET_BIO_write_close (wh))
1495  _("Error writing hostlist URIs to file `%s'\n"), filename);
1496  GNUNET_free (filename);
1497 }
1498 
1499 
1511 int
1513  struct GNUNET_STATISTICS_Handle *st,
1517  int learn)
1518 {
1519  char *filename;
1520  char *proxytype_str;
1521  int result;
1522 
1523  GNUNET_assert (NULL != st);
1524  if (0 != curl_global_init (CURL_GLOBAL_WIN32))
1525  {
1526  GNUNET_break (0);
1527  return GNUNET_SYSERR;
1528  }
1529  cfg = c;
1530  stats = st;
1531 
1532  /* Read proxy configuration */
1533  pi = GNUNET_PEERINFO_connect (c);
1534  if (GNUNET_OK ==
1536  "HOSTLIST",
1537  "PROXY",
1538  &proxy))
1539  {
1541  "Found proxy host: `%s'\n",
1542  proxy);
1543  /* proxy username */
1544  if (GNUNET_OK ==
1546  "HOSTLIST",
1547  "PROXY_USERNAME",
1548  &proxy_username))
1549  {
1551  "Found proxy username name: `%s'\n",
1552  proxy_username);
1553  }
1554 
1555  /* proxy password */
1556  if (GNUNET_OK ==
1558  "HOSTLIST",
1559  "PROXY_PASSWORD",
1560  &proxy_password))
1561  {
1563  "Found proxy password name: `%s'\n",
1564  proxy_password);
1565  }
1566 
1567  /* proxy type */
1568  if (GNUNET_OK ==
1570  "HOSTLIST",
1571  "PROXY_TYPE",
1572  &proxytype_str))
1573  {
1574  GNUNET_STRINGS_utf8_toupper (proxytype_str,
1575  proxytype_str);
1576  proxy_type = CURLPROXY_HTTP;
1577  if (0 == strcmp (proxytype_str, "HTTP"))
1578  proxy_type = CURLPROXY_HTTP;
1579  else if (0 == strcmp (proxytype_str, "HTTP_1_0"))
1580  proxy_type = CURLPROXY_HTTP_1_0;
1581  else if (0 == strcmp (proxytype_str, "SOCKS4"))
1582  proxy_type = CURLPROXY_SOCKS4;
1583  else if (0 == strcmp (proxytype_str, "SOCKS5"))
1584  proxy_type = CURLPROXY_SOCKS5;
1585  else if (0 == strcmp (proxytype_str, "SOCKS4A"))
1586  proxy_type = CURLPROXY_SOCKS4A;
1587  else if (0 == strcmp (proxytype_str, "SOCKS5_HOSTNAME"))
1588  proxy_type = CURLPROXY_SOCKS5_HOSTNAME;
1589  else
1590  {
1592  _("Invalid proxy type: `%s', disabling proxy! Check configuration!\n"),
1593  proxytype_str);
1594  GNUNET_free (proxytype_str);
1595  GNUNET_free (proxy);
1596  proxy = NULL;
1598  proxy_username = NULL;
1600  proxy_password = NULL;
1601 
1602  return GNUNET_SYSERR;
1603  }
1604  }
1605  GNUNET_free_non_null (proxytype_str);
1606  }
1607 
1608  stat_learning = learn;
1609  *ch = &handler_connect;
1610  *dh = &handler_disconnect;
1611  linked_list_head = NULL;
1612  linked_list_tail = NULL;
1616 
1617  if (GNUNET_YES == stat_learning)
1618  {
1619  *msgh = &handler_advertisement;
1621  _("Learning is enabled on this peer\n"));
1622  load_hostlist_file ();
1624  "Hostlists will be saved to file again in %s\n",
1626  GNUNET_YES));
1627  ti_saving_task =
1630  NULL);
1631  }
1632  else
1633  {
1635  _("Learning is not enabled on this peer\n"));
1636  *msgh = NULL;
1637  if (GNUNET_OK ==
1639  "HOSTLIST",
1640  "HOSTLISTFILE",
1641  &filename))
1642  {
1643  if (GNUNET_YES == GNUNET_DISK_file_test (filename))
1644  {
1645  result = remove (filename);
1646  if (0 == result)
1648  _("Since learning is not enabled on this peer, hostlist file `%s' was removed\n"),
1649  filename);
1650  else
1652  "remove",
1653  filename);
1654  }
1655  }
1656  GNUNET_free (filename);
1657  }
1659  "Loading stats value on hostlist download frequency\n");
1660  sget = GNUNET_STATISTICS_get (stats, "hostlist",
1661  gettext_noop
1662  ("# milliseconds between hostlist downloads"),
1663  &primary_task,
1664  &process_stat,
1665  NULL);
1666  if (NULL == sget)
1667  {
1669  "Statistics request failed, scheduling hostlist download\n");
1670  ti_check_download = GNUNET_SCHEDULER_add_now (&task_check,
1671  NULL);
1672  }
1673  else
1674  {
1675  ti_check_download
1678  NULL);
1679  }
1680  return GNUNET_OK;
1681 }
1682 
1683 
1687 void
1689 {
1691  "Hostlist client shutdown\n");
1692  if (NULL != sget)
1693  {
1695  sget = NULL;
1696  }
1697  stats = NULL;
1698  if (GNUNET_YES == stat_learning)
1700  if (NULL != ti_saving_task)
1701  {
1702  GNUNET_SCHEDULER_cancel (ti_saving_task);
1703  ti_saving_task = NULL;
1704  }
1705  if (NULL != ti_download_dispatcher_task)
1706  {
1707  GNUNET_SCHEDULER_cancel (ti_download_dispatcher_task);
1708  ti_download_dispatcher_task = NULL;
1709  }
1710  if (NULL != ti_testing_intervall_task)
1711  {
1712  GNUNET_SCHEDULER_cancel (ti_testing_intervall_task);
1713  ti_testing_intervall_task = NULL;
1714  }
1715  if (NULL != ti_download)
1716  {
1717  GNUNET_SCHEDULER_cancel (ti_download);
1718  ti_download = NULL;
1719  update_hostlist ();
1720  clean_up ();
1721  }
1722  if (NULL != ti_check_download)
1723  {
1724  GNUNET_SCHEDULER_cancel (ti_check_download);
1725  ti_check_download = NULL;
1726  curl_global_cleanup ();
1727  }
1729  proxy = NULL;
1731  proxy_username = NULL;
1733  proxy_password = NULL;
1734  if (NULL != pi)
1735  {
1737  pi = NULL;
1738  }
1739  cfg = NULL;
1740 }
1741 
1742 /* end of gnunet-daemon-hostlist_client.c */
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
int 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:669
struct GNUNET_TIME_Absolute time_last_usage
Last time the hostlist was obtained.
common internal definitions for hostlist daemon
static struct GNUNET_CADET_Channel * ch
Channel handle.
Definition: gnunet-cadet.c:117
#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?
Handle to the peerinfo service.
Definition: peerinfo_api.c:86
A HELLO message is used to exchange information about transports with other peers.
static char * subsystem
Set to subsystem that we&#39;re going to get stats for (or NULL for all).
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
#define GNUNET_TIME_UNIT_HOURS
One hour.
uint64_t rel_value_us
The actual value.
static uint64_t checked_add(uint64_t val1, uint64_t val2)
Add val2 to val1 with overflow check.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
void GNUNET_HOSTLIST_client_stop()
Stop downloading hostlists from hostlist servers as necessary.
#define TESTING_INTERVAL
Time interval between two hostlist tests.
struct GNUNET_TIME_Absolute time_creation
Time the hostlist advertisement was recieved and the entry was created.
uint64_t quality
Value describing the quality of the hostlist, the bigger the better but (should) never < 0 used for d...
static void task_download(void *cls)
Task that is run when we are ready to receive more data from the hostlist server. ...
static unsigned int stat_connection_count
Number of active connections (according to core service).
struct GNUNET_PEERINFO_Handle * GNUNET_PEERINFO_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the peerinfo service.
Definition: peerinfo_api.c:133
#define HOSTLIST_INITIAL
Defines concerning the hostlist quality metric.
#define WAITING_INTERVAL
Time interval for download dispatcher before a download is re-scheduled.
library to make it easy to download JSON replies over HTTP
static int stat_learning
Set if we are allowed to learn new hostlists and use them.
static struct GNUNET_TIME_Absolute end_time
At what time MUST the current hostlist request be done?
#define GNUNET_TIME_UNIT_MINUTES
One minute.
int GNUNET_BIO_write_string(struct GNUNET_BIO_WriteHandle *h, const char *s)
Write a string to a file.
Definition: bio.c:547
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:245
uint32_t GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i)
Produce a random value.
static struct GNUNET_SCHEDULER_Task * ti_download_dispatcher_task
ID of the task called to initiate a download.
static struct GNUNET_SCHEDULER_Task * ti_saving_task
ID of the task saving the hostlsit in a regular intervall.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
int GNUNET_BIO_write_int64(struct GNUNET_BIO_WriteHandle *h, int64_t i)
Write an (u)int64_t.
Definition: bio.c:623
static void load_hostlist_file()
Method to load persistent hostlist file during hostlist client startup.
void(* GNUNET_CORE_DisconnectEventHandler)(void *cls, const struct GNUNET_PeerIdentity *peer, void *peer_cls)
Method called whenever a peer disconnects.
#define GNUNET_TIME_UNIT_SECONDS
One second.
static void handler_advertisement(const char *uri)
Method called whenever an advertisement message arrives.
#define STRERROR(i)
Definition: plibc.h:676
void GNUNET_STATISTICS_get_cancel(struct GNUNET_STATISTICS_GetHandle *gh)
Cancel a GNUNET_STATISTICS_get request.
static struct GNUNET_SCHEDULER_Task * ti_download
ID of the task downloading the hostlist.
static int ok
Return value from &#39;main&#39; (0 == success)
static curl_proxytype proxy_type
Proxy type we are using (can be NULL).
int GNUNET_DISK_directory_create_for_file(const char *filename)
Create the directory structure for storing a file.
Definition: disk.c:833
static int process_stat(void *cls, const char *subsystem, const char *name, uint64_t value, int is_persistent)
We&#39;ve received the previous delay value from statistics.
static void * handler_connect(void *cls, const struct GNUNET_PeerIdentity *peer, struct GNUNET_MQ_Handle *mq)
Method called whenever a given peer connects.
Linked list of things we still need to do.
#define GNUNET_NO
Definition: gnunet_common.h:81
static size_t download_pos
Number of bytes valid in &#39;download_buffer&#39;.
static void primary_task(void *cls, int success)
Continuation called by the statistics code once we go the stat.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
struct Hostlist * next
next entry, used to manage entries in a double linked list
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
static void update_hostlist()
Method updating hostlist statistics.
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
static char * proxy_username
Proxy username we are using (can be NULL).
static struct GNUNET_PEERINFO_Handle * pi
Handle to peerinfo service.
static int ret
Final status code.
Definition: gnunet-arm.c:89
Handle for the service.
static char * current_url
Current URL that we are using.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define HOSTLIST_SUCCESSFUL_HELLO
Value added for each valid HELLO recived during a hostlist download.
uint64_t abs_value_us
The actual value.
static char * proxy
Proxy hostname or ip we are using (can be NULL).
int GNUNET_BIO_read_close(struct GNUNET_BIO_ReadHandle *h, char **emsg)
Close an open file.
Definition: bio.c:119
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
static struct GNUNET_DNSSTUB_Context * ctx
Context for DNS resolution.
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:1308
#define CURL_EASY_SETOPT(c, a, b)
static char * proxy_password
Proxy password we are using (can be NULL).
void *(* GNUNET_CORE_ConnectEventHandler)(void *cls, const struct GNUNET_PeerIdentity *peer, struct GNUNET_MQ_Handle *mq)
Method called whenever a given peer connects.
#define _(String)
GNU gettext support macro.
Definition: platform.h:208
static void stat_timeout_task(void *cls)
Continuation called by the statistics code once we go the stat.
struct GNUNET_BIO_ReadHandle * GNUNET_BIO_read_open(const char *fn)
Open a file for reading.
Definition: bio.c:94
uint32_t hello_count
Number of HELLO messages obtained during last download.
#define GNUNET_BIO_read_int64(h, i)
Read an (u)int64_t.
static struct GNUNET_FS_Uri * uri
Value of URI provided on command-line (when not publishing a file but just creating UBlocks to refer ...
void GNUNET_NETWORK_fdset_destroy(struct GNUNET_NETWORK_FDSet *fds)
Releases the associated memory of an fd set.
Definition: network.c:1554
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
static void insert_hostlist()
Method to insert a hostlist into the datastore.
void(* GNUNET_HOSTLIST_UriHandler)(const char *uri)
Function that handles an advertised URI.
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:1246
struct GNUNET_NETWORK_FDSet * GNUNET_NETWORK_fdset_create(void)
Creates an fd set.
Definition: network.c:1538
void GNUNET_STRINGS_utf8_toupper(const char *input, char *output)
Convert the utf-8 input string to upper case.
Definition: strings.c:580
static struct GNUNET_TIME_Relative timeout
User defined timestamp for completing operations.
Definition: gnunet-arm.c:114
#define GNUNET_memcpy(dst, src, n)
void GNUNET_log_config_missing(enum GNUNET_ErrorType kind, const char *section, const char *option)
Log error message about missing configuration option.
static char * value
Value of the record to add/remove.
#define GNUNET_log_strerror_file(level, cmd, filename)
Log an error message at log-level &#39;level&#39; that indicates a failure of the command &#39;cmd&#39; with the mess...
static int stat_testing_allowed
Value controlling if a hostlist testing is allowed at the moment.
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:1273
#define GNUNET_MIN(a, b)
Definition: gnunet_common.h:83
static CURLM * multi
Current multi-CURL handle.
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:727
static int once
Global to mark if we&#39;ve run the initialization.
Definition: gnsrecord.c:68
static unsigned int stat_download_successful
Value saying if hostlist download was successful.
collection of IO descriptors
static char * filename
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:1829
static int result
Global testing status.
static int linked_list_contains(const char *uri)
Method to check if a URI is in hostlist linked list.
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:439
const char * hostlist_uri
URI where hostlist can be obtained.
static unsigned int stat_use_bootstrap
Value saying if a preconfigured bootstrap server is used.
static void task_download_dispatcher(void *cls)
static int stat_bogus_url
Set to GNUNET_YES if the current URL had some problems.
struct Hostlist * prev
previous entry, used to manage entries in a double linked list
static struct Hostlist * linked_list_head
Head of the linked list used to store hostlists.
Handle for buffered writing.
Definition: bio.c:399
static size_t callback_download(void *ptr, size_t size, size_t nmemb, void *ctx)
Process downloaded bits by calling callback on each HELLO.
static struct Hostlist * linked_list_tail
Tail of the linked list used to store hostlists.
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 handler_disconnect(void *cls, const struct GNUNET_PeerIdentity *peer, void *internal_cls)
Method called whenever a given peer disconnects.
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:557
static struct GNUNET_SCHEDULER_Task * ti_testing_intervall_task
ID of the task controlling the locking between two hostlist tests.
#define GNUNET_TIME_UNIT_MILLISECONDS
One millisecond.
int GNUNET_BIO_read_string(struct GNUNET_BIO_ReadHandle *h, const char *what, char **result, size_t max_length)
Read 0-terminated string from a file.
Definition: bio.c:237
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:118
static void task_check(void *cls)
Task that checks if we should try to download a hostlist.
static void download_hostlist()
Main function that will download a hostlist and process its data.
int 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.
static struct Hostlist * current_hostlist
Current hostlist used for downloading.
static CURL * curl
Current CURL handle.
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:271
static char * get_bootstrap_server()
Obtain a hostlist URL that we should use.
static unsigned int linked_list_size
Size of the linke list used to store hostlists.
struct GNUNET_TESTBED_Peer * peer
The peer associated with this model.
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
static unsigned int size
Size of the "table".
Definition: peer.c:67
#define HOSTLIST_SUCCESSFUL_DOWNLOAD
Value added each time a hostlist download is successful.
#define GNUNET_BIO_read_int32(h, i)
Read an (u)int32_t.
const char * name
static const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
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 struct GNUNET_TESTBED_BarrierWaitHandle * wh
Our barrier wait handle.
static unsigned int stat_hellos_obtained
Value saying how many valid HELLO messages were obtained during download.
int GNUNET_BIO_write_close(struct GNUNET_BIO_WriteHandle *h)
Close an open file for writing.
Definition: bio.c:457
#define GNUNET_TIME_UNIT_ZERO
Relative time zero.
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message...
Handle to a message queue.
Definition: mq.c:85
static void download_prepare()
Ask CURL for the select set and then schedule the receiving task with the scheduler.
static void save_hostlist_file(int shutdown)
Method to save hostlist to a file during hostlist client shutdown.
static void clean_up()
Clean up the state from the task that downloaded the hostlist and schedule the next task...
static void task_testing_intervall_reset(void *cls)
This tasks sets hostlist testing to allowed after intervall between to testings is reached...
static struct GNUNET_STATISTICS_GetHandle * sget
Handle for our statistics GET operation.
The identity of the host (wraps the signing key of 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.
static struct GNUNET_SCHEDULER_Task * ti_check_download
ID of the task, checking if hostlist download should take plate.
configuration data
Definition: configuration.c:85
struct GNUNET_BIO_WriteHandle * GNUNET_BIO_write_open(const char *fn)
Open a file for writing.
Definition: bio.c:430
uint32_t times_used
Number of times the hostlist was successfully obtained.
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
#define GNUNET_log(kind,...)
Entry in list of pending tasks.
Definition: scheduler.c:134
#define SAVING_INTERVAL
Time interval hostlists are saved to disk.
static uint32_t stat_bytes_downloaded
How many bytes did we download from the current hostlist URL?
static char * download_get_url()
Method deciding if a preconfigured or advertisied hostlist is used on a 50:50 ratio.
uint16_t GNUNET_HELLO_size(const struct GNUNET_HELLO_Message *hello)
Return the size of the given HELLO message.
Definition: hello.c:649
int 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.
void GNUNET_PEERINFO_disconnect(struct GNUNET_PEERINFO_Handle *h)
Disconnect from the peerinfo service.
Definition: peerinfo_api.c:159
int GNUNET_BIO_write_int32(struct GNUNET_BIO_WriteHandle *h, int32_t i)
Write an (u)int32_t.
Definition: bio.c:605
static void task_hostlist_saving(void *cls)
Task that writes hostlist entries to a file on a regular base.
static struct Hostlist * linked_list_get_lowest_quality()
Method returning the hostlist element with the lowest quality in the datastore.
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
#define MAX_NUMBER_HOSTLISTS
Maximum number of hostlist that are saved.
Header for all communications.
Time for absolute times used by GNUnet, in microseconds.
#define GNUNET_YES
Definition: gnunet_common.h:80
static int stat_download_in_progress
Value controlling if a hostlist download is running at the moment.
#define HOSTLIST_FAILED_DOWNLOAD
Value subtracted each time a hostlist download fails.
A single hostlist obtained by hostlist advertisements.
#define MIN_CONNECTIONS
Number of connections that we must have to NOT download hostlists anymore.
Run with the default priority (normal P2P operations).
static uint64_t checked_sub(uint64_t val1, uint64_t val2)
Subtract val2 from val1 with underflow check.
static struct GNUNET_SCHEDULER_Task * st
The shutdown task.
static struct GNUNET_STATISTICS_Handle * stats
Statistics handle.
static int stat_testing_hostlist
Value controlling if a hostlist is tested at the moment.
No good quality of the operation is needed (i.e., random numbers can be pseudo-random).
#define GNUNET_malloc(size)
Wrapper around malloc.
Handle for buffered reading.
Definition: bio.c:53
static struct Hostlist * hostlist_to_test
Head of the linked list used to store hostlists.
static struct GNUNET_TIME_Relative hostlist_delay
Amount of time we wait between hostlist downloads.
#define GNUNET_free(ptr)
Wrapper around free.
Time for relative time used by GNUnet, in microseconds.
#define gettext_noop(String)
Definition: gettext.h:69
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:965