GNUnet  0.20.0
gnunet-daemon-hostlist_server.c File Reference

application to provide an integrated hostlist HTTP server More...

#include "platform.h"
#include <microhttpd.h>
#include "gnunet-daemon-hostlist_server.h"
#include "gnunet_hello_lib.h"
#include "gnunet_peerinfo_service.h"
#include "gnunet-daemon-hostlist.h"
#include "gnunet_resolver_service.h"
#include "gnunet_mhd_compat.h"
Include dependency graph for gnunet-daemon-hostlist_server.c:

Go to the source code of this file.

Data Structures

struct  HostSet
 Context for host_processor(). More...
 

Macros

#define GNUNET_ADV_TIMEOUT    GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5)
 How long until our hostlist advertisement transmission via CORE should time out? More...
 

Functions

static void add_cors_headers (struct MHD_Response *response)
 Add headers to a request indicating that we allow Cross-Origin Resource Sharing. More...
 
static void finish_response ()
 Function that assembles our response. More...
 
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!). More...
 
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. More...
 
static MHD_RESULT accept_policy_callback (void *cls, const struct sockaddr *addr, socklen_t addrlen)
 Hostlist access policy (very permissive, allows everything). More...
 
static MHD_RESULT 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. More...
 
static void adv_transmit (struct GNUNET_MQ_Handle *mq)
 Handler called by CORE when CORE is ready to transmit message. More...
 
static void * connect_handler (void *cls, const struct GNUNET_PeerIdentity *peer, struct GNUNET_MQ_Handle *mq)
 Method called whenever a given peer connects. More...
 
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. More...
 
static struct GNUNET_SCHEDULER_Taskprepare_daemon (struct MHD_Daemon *daemon_handle)
 Function that queries MHD's select sets and starts the task waiting for them. More...
 
static void run_daemon (void *cls)
 Call MHD to process pending requests and then go back and schedule the next run. More...
 
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. More...
 
void GNUNET_HOSTLIST_server_stop ()
 Stop server offering our hostlist. More...
 

Variables

static struct MHD_Daemon * daemon_handle_v6
 Handle to the HTTP server as provided by libmicrohttpd for IPv6. More...
 
static struct MHD_Daemon * daemon_handle_v4
 Handle to the HTTP server as provided by libmicrohttpd for IPv4. More...
 
static const struct GNUNET_CONFIGURATION_Handlecfg
 Our configuration. More...
 
static struct GNUNET_STATISTICS_Handlestats
 For keeping statistics. More...
 
static struct GNUNET_CORE_Handlecore
 Handle to the core service (NULL until we've connected to it). More...
 
static struct GNUNET_PEERINFO_NotifyContextnotify
 Handle to the peerinfo notify service (NULL until we've connected to it). More...
 
static struct GNUNET_SCHEDULER_Taskhostlist_task_v4
 Our primary task for IPv4. More...
 
static struct GNUNET_SCHEDULER_Taskhostlist_task_v6
 Our primary task for IPv6. More...
 
static struct MHD_Response * response
 Our canonical response. More...
 
static struct GNUNET_PEERINFO_Handlepeerinfo
 Handle for accessing peerinfo service. More...
 
static int advertising
 Set if we are allowed to advertise our hostlist to others. More...
 
static char * hostlist_uri
 Buffer for the hostlist address. More...
 
static struct HostSetbuilder
 NULL if we are not currently iterating over peer information. More...
 

Detailed Description

application to provide an integrated hostlist HTTP server

Author
Christian Grothoff
Matthias Wachs
David Barksdale

Definition in file gnunet-daemon-hostlist_server.c.

Macro Definition Documentation

◆ GNUNET_ADV_TIMEOUT

#define GNUNET_ADV_TIMEOUT    GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5)

How long until our hostlist advertisement transmission via CORE should time out?

Definition at line 42 of file gnunet-daemon-hostlist_server.c.

Function Documentation

◆ add_cors_headers()

static void add_cors_headers ( struct MHD_Response *  response)
static

Add headers to a request indicating that we allow Cross-Origin Resource Sharing.

Parameters
responseresponse to add headers to

Definition at line 142 of file gnunet-daemon-hostlist_server.c.

143 {
144  MHD_add_response_header (response, "Access-Control-Allow-Origin", "*");
145  MHD_add_response_header (response,
146  "Access-Control-Allow-Methods",
147  "GET, OPTIONS");
148  MHD_add_response_header (response, "Access-Control-Max-Age", "86400");
149 }
static struct MHD_Response * response
Our canonical response.

References response.

Referenced by access_handler_callback(), and finish_response().

Here is the caller graph for this function:

◆ finish_response()

static void finish_response ( )
static

Function that assembles our response.

Definition at line 156 of file gnunet-daemon-hostlist_server.c.

157 {
158  if (NULL != response)
159  MHD_destroy_response (response);
161  "Creating hostlist response with %u bytes\n",
162  (unsigned int) builder->size);
163  response = MHD_create_response_from_buffer (builder->size,
164  builder->data,
165  MHD_RESPMEM_MUST_FREE);
167  if ((NULL == daemon_handle_v4) && (NULL == daemon_handle_v6))
168  {
169  MHD_destroy_response (response);
170  response = NULL;
171  }
173  gettext_noop ("bytes in hostlist"),
174  builder->size,
175  GNUNET_YES);
177  builder = NULL;
178 }
#define gettext_noop(String)
Definition: gettext.h:70
static struct MHD_Daemon * daemon_handle_v6
Handle to the HTTP server as provided by libmicrohttpd for IPv6.
static struct MHD_Daemon * daemon_handle_v4
Handle to the HTTP server as provided by libmicrohttpd for IPv4.
static struct HostSet * builder
NULL if we are not currently iterating over peer information.
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_STATISTICS_Handle * stats
For keeping statistics.
#define GNUNET_log(kind,...)
@ GNUNET_YES
@ GNUNET_ERROR_TYPE_DEBUG
#define GNUNET_free(ptr)
Wrapper around free.
void GNUNET_STATISTICS_set(struct GNUNET_STATISTICS_Handle *handle, const char *name, uint64_t value, int make_persistent)
Set statistic value for the peer.
char * data
Place where we accumulate all of the HELLO messages.
unsigned int size
Number of bytes in data.

References add_cors_headers(), builder, daemon_handle_v4, daemon_handle_v6, HostSet::data, gettext_noop, GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_log, GNUNET_STATISTICS_set(), GNUNET_YES, response, HostSet::size, and stats.

Referenced by host_processor().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_has_addr()

static int check_has_addr ( void *  cls,
const struct GNUNET_HELLO_Address address,
struct GNUNET_TIME_Absolute  expiration 
)
static

Set cls to GNUNET_YES (we have an address!).

Parameters
clsclosure, an int *
addressthe address (ignored)
expirationexpiration time (call is ignored if this is in the past)
Returns
GNUNET_SYSERR to stop iterating (unless expiration has occurred)

Definition at line 190 of file gnunet-daemon-hostlist_server.c.

193 {
194  int *arg = cls;
195 
196  if (0 == GNUNET_TIME_absolute_get_remaining (expiration).rel_value_us)
197  {
199  gettext_noop ("expired addresses encountered"),
200  1,
201  GNUNET_YES);
202  return GNUNET_YES; /* ignore this address */
203  }
204  *arg = GNUNET_YES;
205  return GNUNET_SYSERR;
206 }
static char * expiration
Credential TTL.
Definition: gnunet-abd.c:96
@ GNUNET_SYSERR
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_remaining(struct GNUNET_TIME_Absolute future)
Given a timestamp in the future, how much time remains until then?
Definition: time.c:405

References find_typedefs::arg, expiration, gettext_noop, GNUNET_STATISTICS_update(), GNUNET_SYSERR, GNUNET_TIME_absolute_get_remaining(), GNUNET_YES, and stats.

Referenced by host_processor().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ host_processor()

static void host_processor ( void *  cls,
const struct GNUNET_PeerIdentity peer,
const struct GNUNET_HELLO_Message hello,
const char *  err_msg 
)
static

Callback that processes each of the known HELLOs for the hostlist response construction.

Parameters
clsclosure, NULL
peerid of the peer, NULL for last call
hellohello message for the peer (can be NULL)
err_msgmessage

Definition at line 219 of file gnunet-daemon-hostlist_server.c.

223 {
224  size_t old;
225  size_t s;
226  int has_addr;
227 
228  if (NULL != err_msg)
229  {
230  GNUNET_assert (NULL == peer);
231  builder->pitr = NULL;
234  builder = NULL;
236  _ ("Error in communication with PEERINFO service: %s\n"),
237  err_msg);
238  return;
239  }
240  if (NULL == peer)
241  {
242  builder->pitr = NULL;
243  finish_response ();
244  return;
245  }
246  if (NULL == hello)
247  return;
248  has_addr = GNUNET_NO;
250  if (GNUNET_NO == has_addr)
251  {
253  "HELLO for peer `%4s' has no address, not suitable for hostlist!\n",
254  GNUNET_i2s (peer));
256  gettext_noop (
257  "HELLOs without addresses encountered (ignored)"),
258  1,
259  GNUNET_NO);
260  return;
261  }
262  old = builder->size;
263  s = GNUNET_HELLO_size (hello);
265  "Received %u bytes of `%s' from peer `%s' for hostlist.\n",
266  (unsigned int) s,
267  "HELLO",
268  GNUNET_i2s (peer));
269  if ((old + s >= GNUNET_MAX_MALLOC_CHECKED) ||
270  (old + s >= MAX_BYTES_PER_HOSTLISTS))
271  {
272  /* too large, skip! */
274  gettext_noop (
275  "bytes not included in hostlist (size limit)"),
276  s,
277  GNUNET_NO);
278  return;
279  }
281  "Adding peer `%s' to hostlist (%u bytes)\n",
282  GNUNET_i2s (peer),
283  (unsigned int) s);
284  GNUNET_array_grow (builder->data, builder->size, old + s);
285  GNUNET_memcpy (&builder->data[old], hello, s);
286 }
#define MAX_BYTES_PER_HOSTLISTS
How many bytes do we download at most from a hostlist server?
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!).
static void finish_response()
Function that assembles our response.
uint16_t GNUNET_HELLO_size(const struct GNUNET_HELLO_Message *hello)
Return the size of the given HELLO message.
Definition: hello.c:630
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:254
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
@ GNUNET_NO
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
@ GNUNET_ERROR_TYPE_INFO
#define GNUNET_MAX_MALLOC_CHECKED
Maximum allocation with GNUNET_malloc macro.
#define GNUNET_array_grow(arr, size, tsize)
Grow a well-typed (!) array.
#define _(String)
GNU gettext support macro.
Definition: platform.h:178
struct GNUNET_PEERINFO_IteratorContext * pitr
Iterator used to build data (NULL when done).
struct GNUNET_TESTBED_Peer * peer
The peer associated with this model.

References _, builder, check_has_addr(), HostSet::data, finish_response(), gettext_noop, GNUNET_array_grow, GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_INFO, GNUNET_free, GNUNET_HELLO_iterate_addresses(), GNUNET_HELLO_size(), GNUNET_i2s(), GNUNET_log, GNUNET_MAX_MALLOC_CHECKED, GNUNET_memcpy, GNUNET_NO, GNUNET_STATISTICS_update(), MAX_BYTES_PER_HOSTLISTS, peer, HostSet::pitr, HostSet::size, and stats.

Referenced by process_notify().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ accept_policy_callback()

static MHD_RESULT accept_policy_callback ( void *  cls,
const struct sockaddr *  addr,
socklen_t  addrlen 
)
static

Hostlist access policy (very permissive, allows everything).

Returns #MHD_NO only if we are not yet ready to serve.

Parameters
clsclosure
addraddress information from the client
addrlenlength of addr
Returns
#MHD_YES if connection is allowed, #MHD_NO if not (we are not ready)

Definition at line 299 of file gnunet-daemon-hostlist_server.c.

302 {
303  if (NULL == response)
304  {
305  GNUNET_log (
307  "Received request for hostlist, but I am not yet ready; rejecting!\n");
308  return MHD_NO;
309  }
310  return MHD_YES; /* accept all */
311 }

References GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, and response.

Referenced by GNUNET_HOSTLIST_server_start().

Here is the caller graph for this function:

◆ access_handler_callback()

static MHD_RESULT 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 
)
static

Main request handler.

Parameters
clsargument given together with the function pointer when the handler was registered with MHD
connection
urlthe requested url
methodthe HTTP method used (#MHD_HTTP_METHOD_GET, #MHD_HTTP_METHOD_PUT, etc.)
versionthe HTTP version string (e.g. #MHD_HTTP_VERSION_1_1)
upload_datathe data being uploaded (excluding HEADERS, for a POST that fits into memory and that is encoded with a supported encoding, the POST data will NOT be given in upload_data and is instead available as part of #MHD_get_connection_values; very large POST data will be made available incrementally in upload_data)
upload_data_sizeset initially to the size of the upload_data provided; the method must update this value to the number of bytes NOT processed;
con_clspointer that the callback can set to some address and that will be preserved by MHD for future calls for this request; since the access handler may be called many times (e.g. for a PUT/POST operation with plenty of upload data) this allows the application to easily associate some request-specific state. If necessary, this state can be cleaned up in the global #MHD_RequestCompletedCallback (which can be set with the #MHD_OPTION_NOTIFY_COMPLETED). Initially, *con_cls will be NULL.
Returns
#MHD_YES if the connection was handled successfully, #MHD_NO if the socket must be closed due to a serious error while handling the request

Definition at line 350 of file gnunet-daemon-hostlist_server.c.

358 {
359  static int dummy;
360 
361  /* CORS pre-flight request */
362  if (0 == strcmp (MHD_HTTP_METHOD_OPTIONS, method))
363  {
364  struct MHD_Response *options_response;
365  int rc;
366 
367  options_response =
368  MHD_create_response_from_buffer (0, NULL, MHD_RESPMEM_PERSISTENT);
369  add_cors_headers (options_response);
370  rc = MHD_queue_response (connection, MHD_HTTP_OK, options_response);
371  MHD_destroy_response (options_response);
372  return rc;
373  }
374  if (0 != strcmp (method, MHD_HTTP_METHOD_GET))
375  {
377  _ ("Refusing `%s' request to hostlist server\n"),
378  method);
380  gettext_noop (
381  "hostlist requests refused (not HTTP GET)"),
382  1,
383  GNUNET_YES);
384  return MHD_NO;
385  }
386  if (NULL == *con_cls)
387  {
388  (*con_cls) = &dummy;
389  return MHD_YES;
390  }
391  if (0 != *upload_data_size)
392  {
394  _ ("Refusing `%s' request with %llu bytes of upload data\n"),
395  method,
396  (unsigned long long) *upload_data_size);
398  gettext_noop (
399  "hostlist requests refused (upload data)"),
400  1,
401  GNUNET_YES);
402  return MHD_NO; /* do not support upload data */
403  }
404  if (NULL == response)
405  {
406  GNUNET_log (
408  _ (
409  "Could not handle hostlist request since I do not have a response yet\n"));
411  gettext_noop (
412  "hostlist requests refused (not ready)"),
413  1,
414  GNUNET_YES);
415  return MHD_NO; /* internal error, no response yet */
416  }
418  _ ("Received request for our hostlist\n"));
420  gettext_noop ("hostlist requests processed"),
421  1,
422  GNUNET_YES);
423  return MHD_queue_response (connection, MHD_HTTP_OK, response);
424 }
static struct in_addr dummy
Target "dummy" address of the packet we pretend to respond to.
@ GNUNET_ERROR_TYPE_WARNING
@ MHD_HTTP_OK
OK [RFC7231, Section 6.3.1].

References _, add_cors_headers(), dummy, gettext_noop, GNUNET_ERROR_TYPE_INFO, GNUNET_ERROR_TYPE_WARNING, GNUNET_log, GNUNET_STATISTICS_update(), GNUNET_YES, MHD_HTTP_OK, response, and stats.

Referenced by GNUNET_HOSTLIST_server_start().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ adv_transmit()

static void adv_transmit ( struct GNUNET_MQ_Handle mq)
static

Handler called by CORE when CORE is ready to transmit message.

Parameters
clsclosure with the const struct GNUNET_PeerIdentity * of the peer we are sending to
sizesize of buffer to copy message to
bufbuffer to copy message to
Returns
number of bytes copied to buf

Definition at line 437 of file gnunet-daemon-hostlist_server.c.

438 {
439  static uint64_t hostlist_adv_count;
440  size_t uri_size; /* Including \0 termination! */
441  struct GNUNET_MessageHeader *header;
442  struct GNUNET_MQ_Envelope *env;
443 
444  uri_size = strlen (hostlist_uri) + 1;
445  env = GNUNET_MQ_msg_extra (header,
446  uri_size,
448  GNUNET_memcpy (&header[1], hostlist_uri, uri_size);
452  GNUNET_MQ_send (mq, env);
454  "Sent advertisement message: Copied %u bytes into buffer!\n",
455  (unsigned int) uri_size);
456  hostlist_adv_count++;
458  " # Sent advertisement message: %llu\n",
459  (unsigned long long) hostlist_adv_count);
461  gettext_noop ("# hostlist advertisements send"),
462  1,
463  GNUNET_NO);
464 }
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
static char * hostlist_uri
Buffer for the hostlist address.
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:830
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:304
#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:63
@ GNUNET_MQ_PREF_CORK_ALLOWED
Flag to indicate that CORKing is acceptable.
@ GNUNET_MQ_PREF_UNRELIABLE
Flag to indicate that unreliable delivery is acceptable.
#define GNUNET_MESSAGE_TYPE_HOSTLIST_ADVERTISEMENT
Hostlist advertisement message.
Header for all communications.

References env, gettext_noop, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_memcpy, GNUNET_MESSAGE_TYPE_HOSTLIST_ADVERTISEMENT, GNUNET_MQ_env_set_options(), GNUNET_MQ_msg_extra, GNUNET_MQ_PREF_CORK_ALLOWED, GNUNET_MQ_PREF_UNRELIABLE, GNUNET_MQ_send(), GNUNET_NO, GNUNET_STATISTICS_update(), hostlist_uri, mq, and stats.

Referenced by connect_handler().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ connect_handler()

static void* connect_handler ( void *  cls,
const struct GNUNET_PeerIdentity peer,
struct GNUNET_MQ_Handle mq 
)
static

Method called whenever a given peer connects.

Parameters
clsclosure
peerpeer identity this notification is about
mqqueue for transmission to peer
Returns
NULL (must!)

Definition at line 476 of file gnunet-daemon-hostlist_server.c.

479 {
480  size_t size;
481 
482  if (! advertising)
483  return NULL;
484  if (NULL == hostlist_uri)
485  return NULL;
486  size = strlen (hostlist_uri) + 1;
487  if (size + sizeof(struct GNUNET_MessageHeader) >= GNUNET_MAX_MESSAGE_SIZE)
488  {
489  GNUNET_break (0);
490  return NULL;
491  }
492  size += sizeof(struct GNUNET_MessageHeader);
493  if (NULL == core)
494  {
495  GNUNET_break (0);
496  return NULL;
497  }
498  GNUNET_log (
500  "Asked CORE to transmit advertisement message with a size of %u bytes to peer `%s'\n",
501  (unsigned int) size,
502  GNUNET_i2s (peer));
503  adv_transmit (mq);
504  return NULL;
505 }
static struct GNUNET_CORE_Handle * core
Handle to the core service (NULL until we've connected to it).
static int advertising
Set if we are allowed to advertise our hostlist to others.
static void adv_transmit(struct GNUNET_MQ_Handle *mq)
Handler called by CORE when CORE is ready to transmit message.
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message,...
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
static unsigned int size
Size of the "table".
Definition: peer.c:68

References adv_transmit(), advertising, core, GNUNET_break, GNUNET_ERROR_TYPE_DEBUG, GNUNET_i2s(), GNUNET_log, GNUNET_MAX_MESSAGE_SIZE, hostlist_uri, mq, peer, and size.

Referenced by GNUNET_HOSTLIST_server_start().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ process_notify()

static void process_notify ( void *  cls,
const struct GNUNET_PeerIdentity peer,
const struct GNUNET_HELLO_Message hello,
const char *  err_msg 
)
static

PEERINFO calls this function to let us know about a possible peer that we might want to connect to.

Parameters
clsclosure (not used)
peerpotential peer to connect to
helloHELLO for this peer (or NULL)
err_msgNULL if successful, otherwise contains error message

Definition at line 518 of file gnunet-daemon-hostlist_server.c.

522 {
524  "Peerinfo is notifying us to rebuild our hostlist\n");
525  if (NULL != err_msg)
527  _ ("Error in communication with PEERINFO service: %s\n"),
528  err_msg);
529  if (NULL != builder)
530  {
531  /* restart re-build already in progress ... */
532  if (NULL != builder->pitr)
533  {
535  builder->pitr = NULL;
536  }
538  builder->size = 0;
539  builder->data = NULL;
540  }
541  else
542  {
543  builder = GNUNET_new (struct HostSet);
544  }
545  GNUNET_assert (NULL != peerinfo);
546  builder->pitr =
548 }
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 struct GNUNET_PEERINFO_Handle * peerinfo
Handle for accessing peerinfo service.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
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:464
void GNUNET_PEERINFO_iterate_cancel(struct GNUNET_PEERINFO_IteratorContext *ic)
Cancel an iteration over peer information.
Definition: peerinfo_api.c:497
Context for host_processor().

References _, builder, HostSet::data, GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_INFO, GNUNET_free, GNUNET_log, GNUNET_new, GNUNET_NO, GNUNET_PEERINFO_iterate(), GNUNET_PEERINFO_iterate_cancel(), host_processor(), peerinfo, HostSet::pitr, and HostSet::size.

Referenced by GNUNET_HOSTLIST_server_start().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ prepare_daemon()

static struct GNUNET_SCHEDULER_Task * prepare_daemon ( struct MHD_Daemon *  daemon_handle)
static

Function that queries MHD's select sets and starts the task waiting for them.

Parameters
daemon_handleHTTP server to prepare to run

Definition at line 589 of file gnunet-daemon-hostlist_server.c.

590 {
591  struct GNUNET_SCHEDULER_Task *ret;
592  fd_set rs;
593  fd_set ws;
594  fd_set es;
595  struct GNUNET_NETWORK_FDSet *wrs;
596  struct GNUNET_NETWORK_FDSet *wws;
597  int max;
598  MHD_UNSIGNED_LONG_LONG timeout;
599  int haveto;
600  struct GNUNET_TIME_Relative tv;
601 
602  FD_ZERO (&rs);
603  FD_ZERO (&ws);
604  FD_ZERO (&es);
607  max = -1;
608  GNUNET_assert (MHD_YES == MHD_get_fdset (daemon_handle, &rs, &ws, &es, &max));
609  haveto = MHD_get_timeout (daemon_handle, &timeout);
610  if (haveto == MHD_YES)
611  tv.rel_value_us = (uint64_t) timeout * 1000LL;
612  else
614  GNUNET_NETWORK_fdset_copy_native (wrs, &rs, max + 1);
615  GNUNET_NETWORK_fdset_copy_native (wws, &ws, max + 1);
617  tv,
618  wrs,
619  wws,
620  &run_daemon,
621  daemon_handle);
624  return ret;
625 }
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 void run_daemon(void *cls)
Call MHD to process pending requests and then go back and schedule the next run.
@ GNUNET_SCHEDULER_PRIORITY_HIGH
Run with high priority (important requests).
struct GNUNET_NETWORK_FDSet * GNUNET_NETWORK_fdset_create(void)
Creates an fd set.
Definition: network.c:1171
void GNUNET_NETWORK_fdset_destroy(struct GNUNET_NETWORK_FDSet *fds)
Releases the associated memory of an fd set.
Definition: network.c:1187
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:1041
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
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
#define max(x, y)
collection of IO descriptors
Entry in list of pending tasks.
Definition: scheduler.c:136
Time for relative time used by GNUnet, in microseconds.

References GNUNET_assert, GNUNET_NETWORK_fdset_copy_native(), GNUNET_NETWORK_fdset_create(), GNUNET_NETWORK_fdset_destroy(), GNUNET_SCHEDULER_add_select(), GNUNET_SCHEDULER_PRIORITY_HIGH, GNUNET_TIME_UNIT_FOREVER_REL, max, GNUNET_TIME_Relative::rel_value_us, ret, run_daemon(), and timeout.

Referenced by GNUNET_HOSTLIST_server_start(), and run_daemon().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ run_daemon()

static void run_daemon ( void *  cls)
static

Call MHD to process pending requests and then go back and schedule the next run.

Parameters
clsthe struct MHD_Daemon of the HTTP server to run

Definition at line 566 of file gnunet-daemon-hostlist_server.c.

567 {
568  struct MHD_Daemon *daemon_handle = cls;
569 
570  if (daemon_handle == daemon_handle_v4)
571  hostlist_task_v4 = NULL;
572  else
573  hostlist_task_v6 = NULL;
574  GNUNET_assert (MHD_YES == MHD_run (daemon_handle));
575  if (daemon_handle == daemon_handle_v4)
576  hostlist_task_v4 = prepare_daemon (daemon_handle);
577  else
578  hostlist_task_v6 = prepare_daemon (daemon_handle);
579 }
static struct GNUNET_SCHEDULER_Task * hostlist_task_v4
Our primary task for IPv4.
static struct GNUNET_SCHEDULER_Task * hostlist_task_v6
Our primary task for IPv6.
static struct GNUNET_SCHEDULER_Task * prepare_daemon(struct MHD_Daemon *daemon_handle)
Function that queries MHD's select sets and starts the task waiting for them.

References daemon_handle_v4, GNUNET_assert, hostlist_task_v4, hostlist_task_v6, and prepare_daemon().

Referenced by prepare_daemon().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GNUNET_HOSTLIST_server_start()

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.

Parameters
cconfiguration to use
ststatistics handle to use
cocore handle to use
[out]server_chset to handler for CORE connect events
advertiseGNUNET_YES if we should advertise our hostlist
Returns
GNUNET_OK on success

Definition at line 639 of file gnunet-daemon-hostlist_server.c.

644 {
645  unsigned long long port;
646  char *hostname;
647  char *ipv4;
648  char *ipv6;
649  size_t size;
650  struct in_addr i4;
651  struct in6_addr i6;
652  struct sockaddr_in v4;
653  struct sockaddr_in6 v6;
654  const struct sockaddr *sa4;
655  const struct sockaddr *sa6;
656 
657  advertising = advertise;
658  if (! advertising)
659  {
661  "Advertising not enabled on this hostlist server\n");
662  }
663  else
664  {
666  "Advertising enabled on this hostlist server\n");
667  }
668  cfg = c;
669  stats = st;
671  if (NULL == peerinfo)
672  {
674  _ ("Could not access PEERINFO service. Exiting.\n"));
675  return GNUNET_SYSERR;
676  }
678  "HOSTLIST",
679  "HTTPPORT",
680  &port))
681  return GNUNET_SYSERR;
682  if ((0 == port) || (port > UINT16_MAX))
683  {
685  _ ("Invalid port number %llu. Exiting.\n"),
686  port);
687  return GNUNET_SYSERR;
688  }
689 
690  if (GNUNET_SYSERR ==
692  "HOSTLIST",
693  "EXTERNAL_DNS_NAME",
694  &hostname))
697  _ ("Hostlist service starts on %s:%llu\n"),
698  hostname,
699  port);
700  if (NULL != hostname)
701  {
702  size = strlen (hostname);
703  if (size + 15 > MAX_URL_LEN)
704  {
705  GNUNET_break (0);
706  }
707  else
708  {
710  "http://%s:%u/",
711  hostname,
712  (unsigned int) port);
714  _ ("Address to obtain hostlist: `%s'\n"),
715  hostlist_uri);
716  }
718  }
719 
720  if (GNUNET_CONFIGURATION_have_value (cfg, "HOSTLIST", "BINDTOIPV4"))
721  {
723  "HOSTLIST",
724  "BINDTOIP",
725  &ipv4))
726  {
727  GNUNET_log (
729  _ ("BINDTOIP does not a valid IPv4 address! Ignoring BINDTOIPV4.\n"));
730  }
731  }
732  else
733  ipv4 = NULL;
734  if (GNUNET_CONFIGURATION_have_value (cfg, "HOSTLIST", "BINDTOIPV6"))
735  {
737  "HOSTLIST",
738  "BINDTOIP",
739  &ipv6))
740  {
741  GNUNET_log (
743  _ ("BINDTOIP does not a valid IPv4 address! Ignoring BINDTOIPV6.\n"));
744  }
745  }
746  else
747  ipv6 = NULL;
748  sa4 = NULL;
749  if (NULL != ipv4)
750  {
751  if (1 == inet_pton (AF_INET, ipv4, &i4))
752  {
753  memset (&v4, 0, sizeof(v4));
754  v4.sin_family = AF_INET;
755  v4.sin_addr = i4;
756  v4.sin_port = htons (port);
757 #if HAVE_SOCKADDR_IN_SIN_LEN
758  v4.sin_len = sizeof(v4);
759 #endif
760  sa4 = (const struct sockaddr *) &v4;
761  }
762  else
764  _ (
765  "`%s' is not a valid IPv4 address! Ignoring BINDTOIPV4.\n"),
766  ipv4);
767  GNUNET_free (ipv4);
768  }
769  sa6 = NULL;
770  if (NULL != ipv6)
771  {
772  if (1 == inet_pton (AF_INET6, ipv6, &i6))
773  {
774  memset (&v6, 0, sizeof(v6));
775  v6.sin6_family = AF_INET6;
776  v6.sin6_addr = i6;
777  v6.sin6_port = htons (port);
778 #if HAVE_SOCKADDR_IN_SIN_LEN
779  v6.sin6_len = sizeof(v6);
780 #endif
781  sa6 = (const struct sockaddr *) &v6;
782  }
783  else
785  _ (
786  "`%s' is not a valid IPv6 address! Ignoring BINDTOIPV6.\n"),
787  ipv6);
788  GNUNET_free (ipv6);
789  }
790 
791  daemon_handle_v6 = MHD_start_daemon (MHD_USE_IPv6 | MHD_USE_DEBUG,
792  (uint16_t) port,
794  NULL,
796  NULL,
797  MHD_OPTION_CONNECTION_LIMIT,
798  (unsigned int) 128,
799  MHD_OPTION_PER_IP_CONNECTION_LIMIT,
800  (unsigned int) 32,
801  MHD_OPTION_CONNECTION_TIMEOUT,
802  (unsigned int) 16,
803  MHD_OPTION_CONNECTION_MEMORY_LIMIT,
804  (size_t) (16 * 1024),
805  MHD_OPTION_SOCK_ADDR,
806  sa6,
807  MHD_OPTION_END);
808  daemon_handle_v4 = MHD_start_daemon (MHD_NO_FLAG | MHD_USE_DEBUG,
809  (uint16_t) port,
811  NULL,
813  NULL,
814  MHD_OPTION_CONNECTION_LIMIT,
815  (unsigned int) 128,
816  MHD_OPTION_PER_IP_CONNECTION_LIMIT,
817  (unsigned int) 32,
818  MHD_OPTION_CONNECTION_TIMEOUT,
819  (unsigned int) 16,
820  MHD_OPTION_CONNECTION_MEMORY_LIMIT,
821  (size_t) (16 * 1024),
822  MHD_OPTION_SOCK_ADDR,
823  sa4,
824  MHD_OPTION_END);
825 
826  if ((NULL == daemon_handle_v6) && (NULL == daemon_handle_v4))
827  {
829  _ ("Could not start hostlist HTTP server on port %u\n"),
830  (unsigned short) port);
831  return GNUNET_SYSERR;
832  }
833 
834  core = co;
836  if (NULL != daemon_handle_v4)
838  if (NULL != daemon_handle_v6)
841  return GNUNET_OK;
842 }
static uint16_t port
Port number.
Definition: gnunet-bcd.c:147
static struct GNUNET_SCHEDULER_Task * st
The shutdown task.
static GNUNET_CORE_ConnectEventHandler server_ch
Handle to hostlist server's connect handler.
#define MAX_URL_LEN
How long can hostlist URLs be?
static void * connect_handler(void *cls, const struct GNUNET_PeerIdentity *peer, struct GNUNET_MQ_Handle *mq)
Method called whenever a given peer connects.
static const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
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.
static MHD_RESULT 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.
static struct GNUNET_PEERINFO_NotifyContext * notify
Handle to the peerinfo notify service (NULL until we've connected to it).
static MHD_RESULT accept_policy_callback(void *cls, const struct sockaddr *addr, socklen_t addrlen)
Hostlist access policy (very permissive, allows everything).
static char * hostname
Our hostname; we give this to all the peers we start.
static int ipv4
Option -4: IPv4 requested.
Definition: gnunet-vpn.c:60
static int ipv6
Option -6: IPv6 requested.
Definition: gnunet-vpn.c:65
enum GNUNET_GenericReturnValue 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.
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.
enum GNUNET_GenericReturnValue 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.
@ GNUNET_OK
@ GNUNET_ERROR_TYPE_ERROR
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
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.
struct GNUNET_PEERINFO_Handle * GNUNET_PEERINFO_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the peerinfo service.
Definition: peerinfo_api.c:123
char * GNUNET_RESOLVER_local_fqdn_get(void)
Get local fully qualified domain name.

References _, accept_policy_callback(), access_handler_callback(), advertising, cfg, connect_handler(), core, daemon_handle_v4, daemon_handle_v6, GNUNET_asprintf(), GNUNET_break, GNUNET_CONFIGURATION_get_value_number(), GNUNET_CONFIGURATION_get_value_string(), GNUNET_CONFIGURATION_have_value(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_ERROR_TYPE_INFO, GNUNET_ERROR_TYPE_WARNING, GNUNET_free, GNUNET_log, GNUNET_NO, GNUNET_OK, GNUNET_PEERINFO_connect(), GNUNET_PEERINFO_notify(), GNUNET_RESOLVER_local_fqdn_get(), GNUNET_SYSERR, hostlist_task_v4, hostlist_task_v6, hostlist_uri, hostname, ipv4, ipv6, MAX_URL_LEN, notify, peerinfo, port, prepare_daemon(), process_notify(), server_ch, size, st, and stats.

Referenced by run().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GNUNET_HOSTLIST_server_stop()

void GNUNET_HOSTLIST_server_stop ( void  )

Stop server offering our hostlist.

Definition at line 849 of file gnunet-daemon-hostlist_server.c.

850 {
851  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Hostlist server shutdown\n");
852  if (NULL != hostlist_task_v6)
853  {
855  hostlist_task_v6 = NULL;
856  }
857  if (NULL != hostlist_task_v4)
858  {
860  hostlist_task_v4 = NULL;
861  }
862  if (NULL != daemon_handle_v4)
863  {
864  MHD_stop_daemon (daemon_handle_v4);
865  daemon_handle_v4 = NULL;
866  }
867  if (NULL != daemon_handle_v6)
868  {
869  MHD_stop_daemon (daemon_handle_v6);
870  daemon_handle_v6 = NULL;
871  }
872  if (NULL != response)
873  {
874  MHD_destroy_response (response);
875  response = NULL;
876  }
877  if (NULL != notify)
878  {
880  notify = NULL;
881  }
882  if (NULL != builder)
883  {
884  if (NULL != builder->pitr)
885  {
887  builder->pitr = NULL;
888  }
891  builder = NULL;
892  }
893  if (NULL != peerinfo)
894  {
896  peerinfo = NULL;
897  }
898  cfg = NULL;
899  stats = NULL;
900  core = NULL;
901 }
void GNUNET_PEERINFO_notify_cancel(struct GNUNET_PEERINFO_NotifyContext *nc)
Stop notifying about changes.
void GNUNET_PEERINFO_disconnect(struct GNUNET_PEERINFO_Handle *h)
Disconnect from the peerinfo service.
Definition: peerinfo_api.c:149
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:975

References builder, cfg, core, daemon_handle_v4, daemon_handle_v6, HostSet::data, GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_log, GNUNET_PEERINFO_disconnect(), GNUNET_PEERINFO_iterate_cancel(), GNUNET_PEERINFO_notify_cancel(), GNUNET_SCHEDULER_cancel(), hostlist_task_v4, hostlist_task_v6, notify, peerinfo, HostSet::pitr, response, and stats.

Referenced by cleaning_task().

Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ daemon_handle_v6

struct MHD_Daemon* daemon_handle_v6
static

Handle to the HTTP server as provided by libmicrohttpd for IPv6.

Definition at line 49 of file gnunet-daemon-hostlist_server.c.

Referenced by finish_response(), GNUNET_HOSTLIST_server_start(), and GNUNET_HOSTLIST_server_stop().

◆ daemon_handle_v4

struct MHD_Daemon* daemon_handle_v4
static

Handle to the HTTP server as provided by libmicrohttpd for IPv4.

Definition at line 54 of file gnunet-daemon-hostlist_server.c.

Referenced by finish_response(), GNUNET_HOSTLIST_server_start(), GNUNET_HOSTLIST_server_stop(), and run_daemon().

◆ cfg

const struct GNUNET_CONFIGURATION_Handle* cfg
static

Our configuration.

Definition at line 59 of file gnunet-daemon-hostlist_server.c.

Referenced by GNUNET_HOSTLIST_server_start(), and GNUNET_HOSTLIST_server_stop().

◆ stats

◆ core

struct GNUNET_CORE_Handle* core
static

Handle to the core service (NULL until we've connected to it).

Definition at line 69 of file gnunet-daemon-hostlist_server.c.

Referenced by connect_handler(), GNUNET_HOSTLIST_server_start(), and GNUNET_HOSTLIST_server_stop().

◆ notify

◆ hostlist_task_v4

struct GNUNET_SCHEDULER_Task* hostlist_task_v4
static

Our primary task for IPv4.

Definition at line 79 of file gnunet-daemon-hostlist_server.c.

Referenced by GNUNET_HOSTLIST_server_start(), GNUNET_HOSTLIST_server_stop(), and run_daemon().

◆ hostlist_task_v6

struct GNUNET_SCHEDULER_Task* hostlist_task_v6
static

Our primary task for IPv6.

Definition at line 84 of file gnunet-daemon-hostlist_server.c.

Referenced by GNUNET_HOSTLIST_server_start(), GNUNET_HOSTLIST_server_stop(), and run_daemon().

◆ response

◆ peerinfo

struct GNUNET_PEERINFO_Handle* peerinfo
static

Handle for accessing peerinfo service.

Definition at line 94 of file gnunet-daemon-hostlist_server.c.

Referenced by GNUNET_HOSTLIST_server_start(), GNUNET_HOSTLIST_server_stop(), and process_notify().

◆ advertising

int advertising
static

Set if we are allowed to advertise our hostlist to others.

Definition at line 99 of file gnunet-daemon-hostlist_server.c.

Referenced by connect_handler(), and GNUNET_HOSTLIST_server_start().

◆ hostlist_uri

char* hostlist_uri
static

Buffer for the hostlist address.

Definition at line 104 of file gnunet-daemon-hostlist_server.c.

Referenced by adv_transmit(), connect_handler(), and GNUNET_HOSTLIST_server_start().

◆ builder