GNUnet  0.10.x
gnunet-daemon-hostlist_server.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2008, 2009, 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  */
20 
28 #include "platform.h"
29 #include <microhttpd.h>
31 #include "gnunet_hello_lib.h"
33 #include "gnunet-daemon-hostlist.h"
35 
36 
41 #define GNUNET_ADV_TIMEOUT \
42  GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 5)
43 
44 
48 static struct MHD_Daemon *daemon_handle_v6;
49 
53 static struct MHD_Daemon *daemon_handle_v4;
54 
58 static const struct GNUNET_CONFIGURATION_Handle *cfg;
59 
64 
68 static struct GNUNET_CORE_Handle *core;
69 
74 
79 
84 
88 static struct MHD_Response *response;
89 
94 
98 static int advertising;
99 
103 static char *hostlist_uri;
104 
105 
109 struct HostSet {
114 
118  char *data;
119 
123  unsigned int size;
124 };
125 
126 
130 static struct HostSet *builder;
131 
132 
139 static void
140 add_cors_headers(struct MHD_Response *response)
141 {
142  MHD_add_response_header(response, "Access-Control-Allow-Origin", "*");
143  MHD_add_response_header(response,
144  "Access-Control-Allow-Methods",
145  "GET, OPTIONS");
146  MHD_add_response_header(response, "Access-Control-Max-Age", "86400");
147 }
148 
149 
153 static void
155 {
156  if (NULL != response)
157  MHD_destroy_response(response);
159  "Creating hostlist response with %u bytes\n",
160  (unsigned int)builder->size);
161  response = MHD_create_response_from_buffer(builder->size,
162  builder->data,
163  MHD_RESPMEM_MUST_FREE);
165  if ((NULL == daemon_handle_v4) && (NULL == daemon_handle_v6))
166  {
167  MHD_destroy_response(response);
168  response = NULL;
169  }
170  GNUNET_STATISTICS_set(stats,
171  gettext_noop("bytes in hostlist"),
172  builder->size,
173  GNUNET_YES);
174  GNUNET_free(builder);
175  builder = NULL;
176 }
177 
178 
187 static int
188 check_has_addr(void *cls,
189  const struct GNUNET_HELLO_Address *address,
191 {
192  int *arg = cls;
193 
194  if (0 == GNUNET_TIME_absolute_get_remaining(expiration).rel_value_us)
195  {
197  gettext_noop("expired addresses encountered"),
198  1,
199  GNUNET_YES);
200  return GNUNET_YES; /* ignore this address */
201  }
202  *arg = GNUNET_YES;
203  return GNUNET_SYSERR;
204 }
205 
206 
216 static void
217 host_processor(void *cls,
218  const struct GNUNET_PeerIdentity *peer,
219  const struct GNUNET_HELLO_Message *hello,
220  const char *err_msg)
221 {
222  size_t old;
223  size_t s;
224  int has_addr;
225 
226  if (NULL != err_msg)
227  {
228  GNUNET_assert(NULL == peer);
229  builder->pitr = NULL;
230  GNUNET_free_non_null(builder->data);
231  GNUNET_free(builder);
232  builder = NULL;
234  _("Error in communication with PEERINFO service: %s\n"),
235  err_msg);
236  return;
237  }
238  if (NULL == peer)
239  {
240  builder->pitr = NULL;
241  finish_response();
242  return;
243  }
244  if (NULL == hello)
245  return;
246  has_addr = GNUNET_NO;
248  if (GNUNET_NO == has_addr)
249  {
251  "HELLO for peer `%4s' has no address, not suitable for hostlist!\n",
252  GNUNET_i2s(peer));
254  gettext_noop(
255  "HELLOs without addresses encountered (ignored)"),
256  1,
257  GNUNET_NO);
258  return;
259  }
260  old = builder->size;
261  s = GNUNET_HELLO_size(hello);
263  "Received %u bytes of `%s' from peer `%s' for hostlist.\n",
264  (unsigned int)s,
265  "HELLO",
266  GNUNET_i2s(peer));
267  if ((old + s >= GNUNET_MAX_MALLOC_CHECKED) ||
268  (old + s >= MAX_BYTES_PER_HOSTLISTS))
269  {
270  /* too large, skip! */
272  gettext_noop(
273  "bytes not included in hostlist (size limit)"),
274  s,
275  GNUNET_NO);
276  return;
277  }
279  "Adding peer `%s' to hostlist (%u bytes)\n",
280  GNUNET_i2s(peer),
281  (unsigned int)s);
282  GNUNET_array_grow(builder->data, builder->size, old + s);
283  GNUNET_memcpy(&builder->data[old], hello, s);
284 }
285 
286 
296 static int
298  const struct sockaddr *addr,
299  socklen_t addrlen)
300 {
301  if (NULL == response)
302  {
303  GNUNET_log(
305  "Received request for hostlist, but I am not yet ready; rejecting!\n");
306  return MHD_NO;
307  }
308  return MHD_YES; /* accept all */
309 }
310 
311 
347 static int
349  struct MHD_Connection *connection,
350  const char *url,
351  const char *method,
352  const char *version,
353  const char *upload_data,
354  size_t *upload_data_size,
355  void **con_cls)
356 {
357  static int dummy;
358 
359  /* CORS pre-flight request */
360  if (0 == strcmp(MHD_HTTP_METHOD_OPTIONS, method))
361  {
362  struct MHD_Response *options_response;
363  int rc;
364 
365  options_response =
366  MHD_create_response_from_buffer(0, NULL, MHD_RESPMEM_PERSISTENT);
367  add_cors_headers(options_response);
368  rc = MHD_queue_response(connection, MHD_HTTP_OK, options_response);
369  MHD_destroy_response(options_response);
370  return rc;
371  }
372  if (0 != strcmp(method, MHD_HTTP_METHOD_GET))
373  {
375  _("Refusing `%s' request to hostlist server\n"),
376  method);
378  gettext_noop(
379  "hostlist requests refused (not HTTP GET)"),
380  1,
381  GNUNET_YES);
382  return MHD_NO;
383  }
384  if (NULL == *con_cls)
385  {
386  (*con_cls) = &dummy;
387  return MHD_YES;
388  }
389  if (0 != *upload_data_size)
390  {
392  _("Refusing `%s' request with %llu bytes of upload data\n"),
393  method,
394  (unsigned long long)*upload_data_size);
396  gettext_noop(
397  "hostlist requests refused (upload data)"),
398  1,
399  GNUNET_YES);
400  return MHD_NO; /* do not support upload data */
401  }
402  if (NULL == response)
403  {
404  GNUNET_log(
406  _(
407  "Could not handle hostlist request since I do not have a response yet\n"));
409  gettext_noop(
410  "hostlist requests refused (not ready)"),
411  1,
412  GNUNET_YES);
413  return MHD_NO; /* internal error, no response yet */
414  }
416  _("Received request for our hostlist\n"));
418  gettext_noop("hostlist requests processed"),
419  1,
420  GNUNET_YES);
421  return MHD_queue_response(connection, MHD_HTTP_OK, response);
422 }
423 
424 
434 static void
436 {
437  static uint64_t hostlist_adv_count;
438  size_t uri_size; /* Including \0 termination! */
439  struct GNUNET_MessageHeader *header;
440  struct GNUNET_MQ_Envelope *env;
441 
442  uri_size = strlen(hostlist_uri) + 1;
443  env = GNUNET_MQ_msg_extra(header,
444  uri_size,
446  GNUNET_memcpy(&header[1], hostlist_uri, uri_size);
450  GNUNET_MQ_send(mq, env);
452  "Sent advertisement message: Copied %u bytes into buffer!\n",
453  (unsigned int)uri_size);
454  hostlist_adv_count++;
456  " # Sent advertisement message: %llu\n",
457  (unsigned long long)hostlist_adv_count);
459  gettext_noop("# hostlist advertisements send"),
460  1,
461  GNUNET_NO);
462 }
463 
464 
473 static void *
474 connect_handler(void *cls,
475  const struct GNUNET_PeerIdentity *peer,
476  struct GNUNET_MQ_Handle *mq)
477 {
478  size_t size;
479 
480  if (!advertising)
481  return NULL;
482  if (NULL == hostlist_uri)
483  return NULL;
484  size = strlen(hostlist_uri) + 1;
485  if (size + sizeof(struct GNUNET_MessageHeader) >= GNUNET_MAX_MESSAGE_SIZE)
486  {
487  GNUNET_break(0);
488  return NULL;
489  }
490  size += sizeof(struct GNUNET_MessageHeader);
491  if (NULL == core)
492  {
493  GNUNET_break(0);
494  return NULL;
495  }
496  GNUNET_log(
498  "Asked CORE to transmit advertisement message with a size of %u bytes to peer `%s'\n",
499  (unsigned int)size,
500  GNUNET_i2s(peer));
501  adv_transmit(mq);
502  return NULL;
503 }
504 
505 
515 static void
516 process_notify(void *cls,
517  const struct GNUNET_PeerIdentity *peer,
518  const struct GNUNET_HELLO_Message *hello,
519  const char *err_msg)
520 {
522  "Peerinfo is notifying us to rebuild our hostlist\n");
523  if (NULL != err_msg)
525  _("Error in communication with PEERINFO service: %s\n"),
526  err_msg);
527  if (NULL != builder)
528  {
529  /* restart re-build already in progress ... */
530  if (NULL != builder->pitr)
531  {
533  builder->pitr = NULL;
534  }
535  GNUNET_free_non_null(builder->data);
536  builder->size = 0;
537  builder->data = NULL;
538  }
539  else
540  {
541  builder = GNUNET_new(struct HostSet);
542  }
543  GNUNET_assert(NULL != peerinfo);
544  builder->pitr =
545  GNUNET_PEERINFO_iterate(peerinfo, GNUNET_NO, NULL, &host_processor, NULL);
546 }
547 
548 
553 static struct GNUNET_SCHEDULER_Task *
554 prepare_daemon(struct MHD_Daemon *daemon_handle);
555 
556 
563 static void
564 run_daemon(void *cls)
565 {
566  struct MHD_Daemon *daemon_handle = cls;
567 
568  if (daemon_handle == daemon_handle_v4)
569  hostlist_task_v4 = NULL;
570  else
571  hostlist_task_v6 = NULL;
572  GNUNET_assert(MHD_YES == MHD_run(daemon_handle));
573  if (daemon_handle == daemon_handle_v4)
574  hostlist_task_v4 = prepare_daemon(daemon_handle);
575  else
576  hostlist_task_v6 = prepare_daemon(daemon_handle);
577 }
578 
579 
586 static struct GNUNET_SCHEDULER_Task *
587 prepare_daemon(struct MHD_Daemon *daemon_handle)
588 {
589  struct GNUNET_SCHEDULER_Task *ret;
590  fd_set rs;
591  fd_set ws;
592  fd_set es;
593  struct GNUNET_NETWORK_FDSet *wrs;
594  struct GNUNET_NETWORK_FDSet *wws;
595  int max;
596  MHD_UNSIGNED_LONG_LONG timeout;
597  int haveto;
598  struct GNUNET_TIME_Relative tv;
599 
600  FD_ZERO(&rs);
601  FD_ZERO(&ws);
602  FD_ZERO(&es);
605  max = -1;
606  GNUNET_assert(MHD_YES == MHD_get_fdset(daemon_handle, &rs, &ws, &es, &max));
607  haveto = MHD_get_timeout(daemon_handle, &timeout);
608  if (haveto == MHD_YES)
609  tv.rel_value_us = (uint64_t)timeout * 1000LL;
610  else
612  GNUNET_NETWORK_fdset_copy_native(wrs, &rs, max + 1);
613  GNUNET_NETWORK_fdset_copy_native(wws, &ws, max + 1);
615  tv,
616  wrs,
617  wws,
618  &run_daemon,
619  daemon_handle);
622  return ret;
623 }
624 
625 
636 int
639  struct GNUNET_CORE_Handle *co,
641  int advertise)
642 {
643  unsigned long long port;
644  char *hostname;
645  char *ipv4;
646  char *ipv6;
647  size_t size;
648  struct in_addr i4;
649  struct in6_addr i6;
650  struct sockaddr_in v4;
651  struct sockaddr_in6 v6;
652  const struct sockaddr *sa4;
653  const struct sockaddr *sa6;
654 
655  advertising = advertise;
656  if (!advertising)
657  {
659  "Advertising not enabled on this hostlist server\n");
660  }
661  else
662  {
664  "Advertising enabled on this hostlist server\n");
665  }
666  cfg = c;
667  stats = st;
668  peerinfo = GNUNET_PEERINFO_connect(cfg);
669  if (NULL == peerinfo)
670  {
672  _("Could not access PEERINFO service. Exiting.\n"));
673  return GNUNET_SYSERR;
674  }
676  "HOSTLIST",
677  "HTTPPORT",
678  &port))
679  return GNUNET_SYSERR;
680  if ((0 == port) || (port > UINT16_MAX))
681  {
683  _("Invalid port number %llu. Exiting.\n"),
684  port);
685  return GNUNET_SYSERR;
686  }
687 
688  if (GNUNET_SYSERR ==
690  "HOSTLIST",
691  "EXTERNAL_DNS_NAME",
692  &hostname))
693  hostname = GNUNET_RESOLVER_local_fqdn_get();
695  _("Hostlist service starts on %s:%llu\n"),
696  hostname,
697  port);
698  if (NULL != hostname)
699  {
700  size = strlen(hostname);
701  if (size + 15 > MAX_URL_LEN)
702  {
703  GNUNET_break(0);
704  }
705  else
706  {
708  "http://%s:%u/",
709  hostname,
710  (unsigned int)port);
712  _("Address to obtain hostlist: `%s'\n"),
713  hostlist_uri);
714  }
715  GNUNET_free(hostname);
716  }
717 
718  if (GNUNET_CONFIGURATION_have_value(cfg, "HOSTLIST", "BINDTOIPV4"))
719  {
721  "HOSTLIST",
722  "BINDTOIP",
723  &ipv4))
724  {
725  GNUNET_log(
727  _("BINDTOIP does not a valid IPv4 address! Ignoring BINDTOIPV4.\n"));
728  }
729  }
730  else
731  ipv4 = NULL;
732  if (GNUNET_CONFIGURATION_have_value(cfg, "HOSTLIST", "BINDTOIPV6"))
733  {
735  "HOSTLIST",
736  "BINDTOIP",
737  &ipv6))
738  {
739  GNUNET_log(
741  _("BINDTOIP does not a valid IPv4 address! Ignoring BINDTOIPV6.\n"));
742  }
743  }
744  else
745  ipv6 = NULL;
746  sa4 = NULL;
747  if (NULL != ipv4)
748  {
749  if (1 == inet_pton(AF_INET, ipv4, &i4))
750  {
751  memset(&v4, 0, sizeof(v4));
752  v4.sin_family = AF_INET;
753  v4.sin_addr = i4;
754  v4.sin_port = htons(port);
755 #if HAVE_SOCKADDR_IN_SIN_LEN
756  v4.sin_len = sizeof(v4);
757 #endif
758  sa4 = (const struct sockaddr *)&v4;
759  }
760  else
762  _(
763  "`%s' is not a valid IPv4 address! Ignoring BINDTOIPV4.\n"),
764  ipv4);
765  GNUNET_free(ipv4);
766  }
767  sa6 = NULL;
768  if (NULL != ipv6)
769  {
770  if (1 == inet_pton(AF_INET6, ipv6, &i6))
771  {
772  memset(&v6, 0, sizeof(v6));
773  v6.sin6_family = AF_INET6;
774  v6.sin6_addr = i6;
775  v6.sin6_port = htons(port);
776 #if HAVE_SOCKADDR_IN_SIN_LEN
777  v6.sin6_len = sizeof(v6);
778 #endif
779  sa6 = (const struct sockaddr *)&v6;
780  }
781  else
783  _(
784  "`%s' is not a valid IPv6 address! Ignoring BINDTOIPV6.\n"),
785  ipv6);
786  GNUNET_free(ipv6);
787  }
788 
789  daemon_handle_v6 = MHD_start_daemon(MHD_USE_IPv6 | MHD_USE_DEBUG,
790  (uint16_t)port,
792  NULL,
794  NULL,
795  MHD_OPTION_CONNECTION_LIMIT,
796  (unsigned int)128,
797  MHD_OPTION_PER_IP_CONNECTION_LIMIT,
798  (unsigned int)32,
799  MHD_OPTION_CONNECTION_TIMEOUT,
800  (unsigned int)16,
801  MHD_OPTION_CONNECTION_MEMORY_LIMIT,
802  (size_t)(16 * 1024),
803  MHD_OPTION_SOCK_ADDR,
804  sa6,
805  MHD_OPTION_END);
806  daemon_handle_v4 = MHD_start_daemon(MHD_NO_FLAG | MHD_USE_DEBUG,
807  (uint16_t)port,
809  NULL,
811  NULL,
812  MHD_OPTION_CONNECTION_LIMIT,
813  (unsigned int)128,
814  MHD_OPTION_PER_IP_CONNECTION_LIMIT,
815  (unsigned int)32,
816  MHD_OPTION_CONNECTION_TIMEOUT,
817  (unsigned int)16,
818  MHD_OPTION_CONNECTION_MEMORY_LIMIT,
819  (size_t)(16 * 1024),
820  MHD_OPTION_SOCK_ADDR,
821  sa4,
822  MHD_OPTION_END);
823 
824  if ((NULL == daemon_handle_v6) && (NULL == daemon_handle_v4))
825  {
827  _("Could not start hostlist HTTP server on port %u\n"),
828  (unsigned short)port);
829  return GNUNET_SYSERR;
830  }
831 
832  core = co;
833  *server_ch = &connect_handler;
834  if (NULL != daemon_handle_v4)
835  hostlist_task_v4 = prepare_daemon(daemon_handle_v4);
836  if (NULL != daemon_handle_v6)
837  hostlist_task_v6 = prepare_daemon(daemon_handle_v6);
838  notify = GNUNET_PEERINFO_notify(cfg, GNUNET_NO, &process_notify, NULL);
839  return GNUNET_OK;
840 }
841 
842 
846 void
848 {
849  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Hostlist server shutdown\n");
850  if (NULL != hostlist_task_v6)
851  {
852  GNUNET_SCHEDULER_cancel(hostlist_task_v6);
853  hostlist_task_v6 = NULL;
854  }
855  if (NULL != hostlist_task_v4)
856  {
857  GNUNET_SCHEDULER_cancel(hostlist_task_v4);
858  hostlist_task_v4 = NULL;
859  }
860  if (NULL != daemon_handle_v4)
861  {
862  MHD_stop_daemon(daemon_handle_v4);
863  daemon_handle_v4 = NULL;
864  }
865  if (NULL != daemon_handle_v6)
866  {
867  MHD_stop_daemon(daemon_handle_v6);
868  daemon_handle_v6 = NULL;
869  }
870  if (NULL != response)
871  {
872  MHD_destroy_response(response);
873  response = NULL;
874  }
875  if (NULL != notify)
876  {
878  notify = NULL;
879  }
880  if (NULL != builder)
881  {
882  if (NULL != builder->pitr)
883  {
885  builder->pitr = NULL;
886  }
887  GNUNET_free_non_null(builder->data);
888  GNUNET_free(builder);
889  builder = NULL;
890  }
891  if (NULL != peerinfo)
892  {
893  GNUNET_PEERINFO_disconnect(peerinfo);
894  peerinfo = NULL;
895  }
896  cfg = NULL;
897  stats = NULL;
898  core = NULL;
899 }
900 
901 /* end of gnunet-daemon-hostlist_server.c */
static struct MHD_Daemon * daemon_handle
Handle to the HTTP server as provided by libmicrohttpd.
Definition: gnunet-bcd.c:46
static int check_has_addr(void *cls, const struct GNUNET_HELLO_Address *address, struct GNUNET_TIME_Absolute expiration)
Set cls to GNUNET_YES (we have an address!).
common internal definitions for hostlist daemon
static struct GNUNET_SCHEDULER_Task * prepare_daemon(struct MHD_Daemon *daemon_handle)
Function that queries MHD&#39;s select sets and starts the task waiting for them.
#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?
Run with high priority (important requests).
Handle to the peerinfo service.
Definition: peerinfo_api.c:83
A HELLO message is used to exchange information about transports with other peers.
static void adv_transmit(struct GNUNET_MQ_Handle *mq)
Handler called by CORE when CORE is ready to transmit message.
static char * expiration
Credential TTL.
int GNUNET_CONFIGURATION_get_value_number(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, unsigned long long *number)
Get a configuration value that should be a number.
uint64_t rel_value_us
The actual value.
Context for the core service connection.
Definition: core_api.c:76
struct GNUNET_PEERINFO_Handle * GNUNET_PEERINFO_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the peerinfo service.
Definition: peerinfo_api.c:128
Context for the info handler.
static struct GNUNET_STATISTICS_Handle * stats
For keeping statistics.
struct GNUNET_PEERINFO_IteratorContext * pitr
Iterator used to build data (NULL when done).
int GNUNET_HOSTLIST_server_start(const struct GNUNET_CONFIGURATION_Handle *c, struct GNUNET_STATISTICS_Handle *st, struct GNUNET_CORE_Handle *co, GNUNET_CORE_ConnectEventHandler *server_ch, int advertise)
Start server offering our hostlist.
static int ipv4
Option -4: IPv4 requested.
Definition: gnunet-vpn.c:61
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
void GNUNET_PEERINFO_notify_cancel(struct GNUNET_PEERINFO_NotifyContext *nc)
Stop notifying about changes.
void GNUNET_MQ_env_set_options(struct GNUNET_MQ_Envelope *env, enum GNUNET_MQ_PriorityPreferences pp)
Set application-specific options for this envelope.
Definition: mq.c:1002
static void * connect_handler(void *cls, const struct GNUNET_PeerIdentity *peer, struct GNUNET_MQ_Handle *mq)
Method called whenever a given peer connects.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#define GNUNET_NO
Definition: gnunet_common.h:78
static char * hostlist_uri
Buffer for the hostlist address.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
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 int ret
Final status code.
Definition: gnunet-arm.c:89
Handle for the service.
static void process_notify(void *cls, const struct GNUNET_PeerIdentity *peer, const struct GNUNET_HELLO_Message *hello, const char *err_msg)
PEERINFO calls this function to let us know about a possible peer that we might want to connect to...
Context for an iteration request.
Definition: peerinfo_api.c:37
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
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:1108
struct GNUNET_PEERINFO_NotifyContext * GNUNET_PEERINFO_notify(const struct GNUNET_CONFIGURATION_Handle *cfg, int include_friend_only, GNUNET_PEERINFO_Processor callback, void *callback_cls)
Call a method whenever our known information about peers changes.
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:181
static struct GNUNET_SCHEDULER_Task * hostlist_task_v6
Our primary task for IPv6.
struct GNUNET_PEERINFO_IteratorContext * GNUNET_PEERINFO_iterate(struct GNUNET_PEERINFO_Handle *h, int include_friend_only, const struct GNUNET_PeerIdentity *peer, GNUNET_PEERINFO_Processor callback, void *callback_cls)
Call a method for each known matching host.
Definition: peerinfo_api.c:486
Context for host_processor().
static int advertising
Set if we are allowed to advertise our hostlist to others.
void GNUNET_NETWORK_fdset_destroy(struct GNUNET_NETWORK_FDSet *fds)
Releases the associated memory of an fd set.
Definition: network.c:1254
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct...
Definition: gnunet_mq_lib.h:52
struct GNUNET_NETWORK_FDSet * GNUNET_NETWORK_fdset_create(void)
Creates an fd set.
Definition: network.c:1238
void GNUNET_PEERINFO_iterate_cancel(struct GNUNET_PEERINFO_IteratorContext *ic)
Cancel an iteration over peer information.
Definition: peerinfo_api.c:519
#define GNUNET_array_grow(arr, size, tsize)
Grow a well-typed (!) array.
static struct GNUNET_TIME_Relative timeout
User defined timestamp for completing operations.
Definition: gnunet-arm.c:114
struct GNUNET_HELLO_Message * GNUNET_HELLO_iterate_addresses(const struct GNUNET_HELLO_Message *msg, int return_modified, GNUNET_HELLO_AddressIterator it, void *it_cls)
Iterate over all of the addresses in the HELLO.
Definition: hello.c:252
static void finish_response()
Function that assembles our response.
static struct GNUNET_SCHEDULER_Task * hostlist_task_v4
Our primary task for IPv4.
int GNUNET_CONFIGURATION_have_value(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option)
Test if we have a value for a particular option.
static struct GNUNET_PEERINFO_NotifyContext * notify
Handle to the peerinfo notify service (NULL until we&#39;ve connected to it).
char * GNUNET_RESOLVER_local_fqdn_get(void)
Get local fully qualified domain name.
unsigned int size
Number of bytes in data.
static void add_cors_headers(struct MHD_Response *response)
Add headers to a request indicating that we allow Cross-Origin Resource Sharing.
static struct GNUNET_PEERINFO_Handle * peerinfo
Handle for accessing peerinfo service.
collection of IO descriptors
static int access_handler_callback(void *cls, struct MHD_Connection *connection, const char *url, const char *method, const char *version, const char *upload_data, size_t *upload_data_size, void **con_cls)
Main request handler.
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:1784
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
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 int accept_policy_callback(void *cls, const struct sockaddr *addr, socklen_t addrlen)
Hostlist access policy (very permissive, allows everything).
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 const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
struct GNUNET_TESTBED_Peer * peer
The peer associated with this model.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
static struct MHD_Daemon * daemon_handle_v6
Handle to the HTTP server as provided by libmicrohttpd for IPv6.
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
#define GNUNET_MAX_MALLOC_CHECKED
Maximum allocation with GNUNET_malloc macro.
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message...
static struct in_addr dummy
Target "dummy" address of the packet we pretend to respond to.
Handle to a message queue.
Definition: mq.c:84
The identity of the host (wraps the signing key of the peer).
static void host_processor(void *cls, const struct GNUNET_PeerIdentity *peer, const struct GNUNET_HELLO_Message *hello, const char *err_msg)
Callback that processes each of the known HELLOs for the hostlist response construction.
static char * hostname
Our hostname; we give this to all the peers we start.
static uint16_t port
Port number.
Definition: gnunet-bcd.c:81
configuration data
Definition: configuration.c:83
void GNUNET_HOSTLIST_server_stop()
Stop server offering our hostlist.
An address for communicating with a peer.
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
#define GNUNET_log(kind,...)
#define GNUNET_MESSAGE_TYPE_HOSTLIST_ADVERTISEMENT
Further X-VINE DHT messages continued from 880.
Entry in list of pending tasks.
Definition: scheduler.c:131
uint16_t GNUNET_HELLO_size(const struct GNUNET_HELLO_Message *hello)
Return the size of the given HELLO message.
Definition: hello.c:643
void GNUNET_PEERINFO_disconnect(struct GNUNET_PEERINFO_Handle *h)
Disconnect from the peerinfo service.
Definition: peerinfo_api.c:154
static struct MHD_Response * response
Our canonical response.
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
static void run_daemon(void *cls)
Call MHD to process pending requests and then go back and schedule the next run.
Flag to indicate that CORKing is acceptable.
Header for all communications.
Time for absolute times used by GNUnet, in microseconds.
#define GNUNET_YES
Definition: gnunet_common.h:77
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:351
char * data
Place where we accumulate all of the HELLO messages.
Flag to indicate that unreliable delivery is acceptable.
static struct GNUNET_CORE_Handle * core
Handle to the core service (NULL until we&#39;ve connected to it).
static struct GNUNET_SCHEDULER_Task * st
The shutdown task.
static struct MHD_Daemon * daemon_handle_v4
Handle to the HTTP server as provided by libmicrohttpd for IPv4.
static char * address
GNS address for this phone.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
static struct HostSet * builder
NULL if we are not currenlty iterating over peer information.
#define GNUNET_free(ptr)
Wrapper around free.
Time for relative time used by GNUnet, in microseconds.
#define gettext_noop(String)
Definition: gettext.h:69
static int ipv6
Option -6: IPv6 requested.
Definition: gnunet-vpn.c:66
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:956