30#include <microhttpd.h>
44#define GNUNET_ADV_TIMEOUT \
45 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5)
55#define REBUILD_DELAY \
56 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1)
175 MHD_add_response_header (resp,
176 "Access-Control-Allow-Origin",
"*"));
178 MHD_add_response_header (resp,
179 "Access-Control-Allow-Methods",
182 MHD_add_response_header (resp,
"Access-Control-Max-Age",
187static struct MHD_Response*
198 hello_uri_j = json_object ();
199 hello_array = json_array ();
200 while (offset < host_set->
size)
210 "HELLO from host set malformed, skipping...\n");
211 offset += ntohs (hello->
size);
215 json_array_append_new (hello_array, json_string (hello_uri));
218 offset += ntohs (hello->
size);
220 json_object_set_new (hello_uri_j,
"hellos", hello_array);
221 hello_uris = json_dumps (hello_uri_j, JSON_INDENT (2));
222 json_decref (hello_uri_j);
223 return MHD_create_response_from_buffer (strlen (hello_uris),
225 MHD_RESPMEM_MUST_FREE);
240 "Creating hostlist response with %u bytes\n",
244 MHD_RESPMEM_MUST_FREE);
248 "application/json"));
288 s = ntohs (hello->
size);
290 "Received %u bytes of `%s' from peer `%s' for hostlist.\n",
300 "bytes not included in hostlist (size limit)"),
306 "Adding peer `%s' to hostlist (%u bytes)\n",
357 "Rebuilding hostlist from %u HELLOs\n",
391 const struct sockaddr *addr,
398 "Received request for hostlist, but I am not yet ready; rejecting!\n");
407 enum MHD_ValueKind kind,
413 if (0 != strcasecmp (
key,
"Accept"))
415 if (0 == strcasecmp (
value,
"application/json"))
458 struct MHD_Connection *connection,
462 const char *upload_data,
463 size_t *upload_data_size,
467 struct MHD_Response *selected_response;
471 if (0 == strcmp (MHD_HTTP_METHOD_OPTIONS, method))
473 struct MHD_Response *options_response;
477 MHD_create_response_from_buffer (0, NULL, MHD_RESPMEM_PERSISTENT);
479 rc = MHD_queue_response (connection, MHD_HTTP_OK, options_response);
480 MHD_destroy_response (options_response);
483 if (0 != strcmp (method, MHD_HTTP_METHOD_GET))
486 _ (
"Refusing `%s' request to hostlist server\n"),
490 "hostlist requests refused (not HTTP GET)"),
495 if (NULL == *con_cls)
500 if (0 != *upload_data_size)
503 _ (
"Refusing `%s' request with %llu bytes of upload data\n"),
505 (
unsigned long long) *upload_data_size);
508 "hostlist requests refused (upload data)"),
514 MHD_get_connection_values (connection,
522 if (NULL == selected_response)
527 "Could not handle hostlist request since I do not have a response yet\n"));
530 "hostlist requests refused (not ready)"),
536 _ (
"Received request for our hostlist\n"));
541 return MHD_queue_response (connection, MHD_HTTP_OK, selected_response);
557 static uint64_t hostlist_adv_count;
572 "Sent advertisement message: Copied %u bytes into buffer!\n",
573 (
unsigned int) uri_size);
574 hostlist_adv_count++;
576 " # Sent advertisement message: %llu\n",
577 (
unsigned long long) hostlist_adv_count);
620 "Asked CORE to transmit advertisement message with a size of %u bytes to peer `%s'\n",
649 "Peerstore is notifying us to rebuild our hostlist map size %u\n",
654 _ (
"Error in communication with PEERSTORE service: %s\n"),
670 if ((NULL == hello) ||
671 (
record->value_size < sizeof (*hello)) ||
695 "HELLO for `%s' is expired or does not verify, skipping\n",
723 if (NULL != old_hello)
739 "1 Peerstore is notifying us to rebuild our hostlist map size %u peer %s\n",
763 struct MHD_Daemon *daemon_handle = cls;
793 MHD_UNSIGNED_LONG_LONG
timeout;
803 GNUNET_assert (MHD_YES == MHD_get_fdset (daemon_handle, &rs, &ws, &es, &
max));
804 haveto = MHD_get_timeout (daemon_handle, &
timeout);
805 if (haveto == MHD_YES)
827 "Error in PEERSTORE monitoring\n");
835 "Done with initial PEERSTORE iteration during monitoring\n");
845 "Starting to process new hellos to add to hostlist.\n");
876 unsigned long long port;
883 struct sockaddr_in v4;
884 struct sockaddr_in6 v6;
885 const struct sockaddr *sa4;
886 const struct sockaddr *sa6;
895 "Advertising not enabled on this hostlist server\n");
900 "Advertising enabled on this hostlist server\n");
908 _ (
"Could not access PEERSTORE service. Exiting.\n"));
916 if ((0 ==
port) || (
port > UINT16_MAX))
919 _ (
"Invalid port number %llu. Exiting.\n"),
931 _ (
"Hostlist service starts on %s:%llu\n"),
934 if (NULL != hostname)
936 size = strlen (hostname);
946 (
unsigned int)
port);
948 _ (
"Address to obtain hostlist: `%s'\n"),
963 _ (
"BINDTOIP does not a valid IPv4 address! Ignoring BINDTOIPV4.\n"));
977 _ (
"BINDTOIP does not a valid IPv4 address! Ignoring BINDTOIPV6.\n"));
985 if (1 == inet_pton (AF_INET,
ipv4, &i4))
987 memset (&v4, 0,
sizeof(v4));
988 v4.sin_family = AF_INET;
990 v4.sin_port = htons (
port);
991#if HAVE_SOCKADDR_IN_SIN_LEN
992 v4.sin_len =
sizeof(v4);
994 sa4 = (
const struct sockaddr *) &v4;
999 "`%s' is not a valid IPv4 address! Ignoring BINDTOIPV4.\n"),
1006 if (1 == inet_pton (AF_INET6,
ipv6, &i6))
1008 memset (&v6, 0,
sizeof(v6));
1009 v6.sin6_family = AF_INET6;
1011 v6.sin6_port = htons (
port);
1012#if HAVE_SOCKADDR_IN_SIN_LEN
1013 v6.sin6_len =
sizeof(v6);
1015 sa6 = (
const struct sockaddr *) &v6;
1020 "`%s' is not a valid IPv6 address! Ignoring BINDTOIPV6.\n"),
1031 MHD_OPTION_CONNECTION_LIMIT,
1033 MHD_OPTION_PER_IP_CONNECTION_LIMIT,
1035 MHD_OPTION_CONNECTION_TIMEOUT,
1037 MHD_OPTION_CONNECTION_MEMORY_LIMIT,
1038 (
size_t) (16 * 1024),
1039 MHD_OPTION_SOCK_ADDR,
1048 MHD_OPTION_CONNECTION_LIMIT,
1050 MHD_OPTION_PER_IP_CONNECTION_LIMIT,
1052 MHD_OPTION_CONNECTION_TIMEOUT,
1054 MHD_OPTION_CONNECTION_MEMORY_LIMIT,
1055 (
size_t) (16 * 1024),
1056 MHD_OPTION_SOCK_ADDR,
1063 _ (
"Could not start hostlist HTTP server on port %u\n"),
1064 (
unsigned short)
port);
struct GNUNET_MQ_Envelope * env
#define gettext_noop(String)
static int ret
Final status code.
static struct GNUNET_TIME_Relative timeout
User defined timestamp for completing operations.
static uint16_t port
Port number.
static struct GNUNET_SCHEDULER_Task * st
The shutdown task.
static void record(void *cls, size_t data_size, const void *data)
Process recorded audio data.
static GNUNET_CORE_ConnectEventHandler server_ch
Handle to hostlist server's connect handler.
common internal definitions for hostlist daemon
#define MAX_URL_LEN
How long can hostlist URLs be?
#define MAX_BYTES_PER_HOSTLISTS
How many bytes do we download at most from a hostlist server?
static struct MHD_Daemon * daemon_handle_v6
Handle to the HTTP server as provided by libmicrohttpd for IPv6.
static struct MHD_Response * response
Our canonical response.
static void * connect_handler(void *cls, const struct GNUNET_PeerIdentity *peer, struct GNUNET_MQ_Handle *mq, enum GNUNET_CORE_PeerClass class)
Method called whenever a given peer connects.
static void sync_cb(void *cls)
static struct MHD_Daemon * daemon_handle_v4
Handle to the HTTP server as provided by libmicrohttpd for IPv4.
static struct GNUNET_SCHEDULER_Task * hostlist_task_v4
Our primary task for IPv4.
static struct HostSet * builder
NULL if we are not currently iterating over peer information.
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 schedule_rebuild()
Ask for the hostlist to be rebuilt, unless that is already pending.
static struct MHD_Response * build_json_response(const struct HostSet *host_set)
static void add_cors_headers(struct MHD_Response *resp)
Add headers to a request indicating that we allow Cross-Origin Resource Sharing.
static struct GNUNET_PEERSTORE_Monitor * peerstore_notify
Our peerstore notification context.
static struct GNUNET_STATISTICS_Handle * stats
For keeping statistics.
struct GNUNET_CONTAINER_MultiPeerMap * hellos
Map with hellos we build the hostlist with.
static const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
static struct GNUNET_SCHEDULER_Task * hostlist_task_v6
Our primary task for IPv6.
static struct GNUNET_PEERSTORE_Handle * peerstore
Handle to the PEERSTORE service.
static void rebuild_hostlist(void *cls)
Rebuild the hostlist we serve from all the HELLOs we know.
static enum GNUNET_GenericReturnValue host_processor(void *cls, const struct GNUNET_PeerIdentity *peer, void *value)
Callback that processes each of the known HELLOs for the hostlist response construction.
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.
static void start_notify(void *cls)
static struct MHD_Response * response_json
Our json response.
static void adv_transmit(struct GNUNET_MQ_Handle *mq)
Handler called by CORE when CORE is ready to transmit message.
struct GNUNET_SCHEDULER_Task * peerstore_notify_task
The task to delayed start the notification process initially.
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 void run_daemon(void *cls)
Call MHD to process pending requests and then go back and schedule the next run.
static int header_iterator(void *cls, enum MHD_ValueKind kind, const char *key, const char *value)
static void finish_response()
Function that assembles our response.
#define REBUILD_DELAY
How long do we wait after learning about a HELLO before we rebuild the hostlist we serve?...
static void error_cb(void *cls)
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 void process_notify(void *cls, const struct GNUNET_PEERSTORE_Record *record, const char *err_msg)
PEERSTORE calls this function to let us know about a possible peer that we might want to connect to.
static enum GNUNET_GenericReturnValue free_hello(void *cls, const struct GNUNET_PeerIdentity *peer, void *value)
Free one HELLO of hellos.
void GNUNET_HOSTLIST_server_stop()
Stop server offering our hostlist.
static char * hostlist_uri
Buffer for the hostlist address.
static MHD_RESULT accept_policy_callback(void *cls, const struct sockaddr *addr, socklen_t addrlen)
Hostlist access policy (very permissive, allows everything).
static struct GNUNET_SCHEDULER_Task * rebuild_task
Task that rebuilds our response from hellos, or NULL if no rebuild is pending.
struct GNUNET_HashCode key
The key used in the DHT.
static struct in_addr dummy
Target "dummy" address of the packet we pretend to respond to.
static char * value
Value of the record to add/remove.
static int ipv4
Option -4: IPv4 requested.
static int ipv6
Option -6: IPv6 requested.
static unsigned int map_size
Command-line argument specifying desired size of the hash map with all of our pending names.
commonly used definitions; globals in this file are exempt from the rule that the module name ("commo...
Helper library for handling HELLO URIs.
#define MHD_RESULT
Data type to use for functions return an "MHD result".
API to the peerstore service.
Functions related to doing DNS lookups.
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message,...
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_CORE_PeerClass
The peer class gives a hint about the capabilities of a peer.
void *(* GNUNET_CORE_ConnectEventHandler)(void *cls, const struct GNUNET_PeerIdentity *peer, struct GNUNET_MQ_Handle *mq, enum GNUNET_CORE_PeerClass class)
Method called whenever a given peer connects.
void * GNUNET_CONTAINER_multipeermap_get(const struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key)
Given a key find a value in the map matching the key.
void GNUNET_CONTAINER_multipeermap_destroy(struct GNUNET_CONTAINER_MultiPeerMap *map)
Destroy a hash map.
int GNUNET_CONTAINER_multipeermap_iterate(struct GNUNET_CONTAINER_MultiPeerMap *map, GNUNET_CONTAINER_PeerMapIterator it, void *it_cls)
Iterate over all entries in the map.
struct GNUNET_CONTAINER_MultiPeerMap * GNUNET_CONTAINER_multipeermap_create(unsigned int len, int do_not_copy_keys)
Create a multi peer map (hash map for public keys of peers).
unsigned int GNUNET_CONTAINER_multipeermap_size(const struct GNUNET_CONTAINER_MultiPeerMap *map)
Get the number of key-value pairs in the map.
int GNUNET_CONTAINER_multipeermap_put(struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multipeermap_remove(struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key, const void *value)
Remove the given key-value pair from the map.
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY
There must only be one value per key; storing a value should fail if a value under the same key alrea...
void GNUNET_HELLO_parser_free(struct GNUNET_HELLO_Parser *parser)
Release resources of a builder.
char * GNUNET_HELLO_parser_to_url(const struct GNUNET_HELLO_Parser *parser)
Generate GNUnet HELLO URI from a parser.
struct GNUNET_HELLO_Parser * GNUNET_HELLO_parser_from_msg_(const struct GNUNET_MessageHeader *msg, const struct GNUNET_PeerIdentity *pid, int noverify)
Parse msg.
const struct GNUNET_PeerIdentity * GNUNET_HELLO_parser_get_id(const struct GNUNET_HELLO_Parser *parser)
Get the PeerIdentity for this builder.
struct GNUNET_HELLO_Parser * GNUNET_HELLO_parser_from_msg(const struct GNUNET_MessageHeader *msg, const struct GNUNET_PeerIdentity *pid)
Parse msg.
#define GNUNET_log(kind,...)
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
GNUNET_GenericReturnValue
Named constants for return values.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
@ GNUNET_SCHEDULER_PRIORITY_HIGH
Run with high priority (important requests).
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
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.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_DEBUG
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
#define GNUNET_MAX_MALLOC_CHECKED
Maximum allocation with GNUNET_malloc macro.
#define GNUNET_array_grow(arr, size, tsize)
Grow a well-typed (!) array.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
void GNUNET_MQ_env_set_options(struct GNUNET_MQ_Envelope *env, enum GNUNET_MQ_PriorityPreferences pp)
Set application-specific options for this envelope.
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct.
@ GNUNET_MQ_PREF_CORK_ALLOWED
Flag to indicate that CORKing is acceptable.
@ GNUNET_MQ_PREF_UNRELIABLE
Flag to indicate that unreliable delivery is acceptable.
void GNUNET_NETWORK_fdset_destroy(struct GNUNET_NETWORK_FDSet *fds)
Releases the associated memory of an fd set.
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.
struct GNUNET_NETWORK_FDSet * GNUNET_NETWORK_fdset_create(void)
Creates an fd set.
void GNUNET_PEERSTORE_monitor_stop(struct GNUNET_PEERSTORE_Monitor *zm)
Stop monitoring.
void GNUNET_PEERSTORE_disconnect(struct GNUNET_PEERSTORE_Handle *h)
Disconnect from the PEERSTORE service.
struct GNUNET_PEERSTORE_Monitor * GNUNET_PEERSTORE_monitor_start(const struct GNUNET_CONFIGURATION_Handle *cfg, int iterate_first, const char *sub_system, const struct GNUNET_PeerIdentity *peer, const char *key, GNUNET_SCHEDULER_TaskCallback error_cb, void *error_cb_cls, GNUNET_SCHEDULER_TaskCallback sync_cb, void *sync_cb_cls, GNUNET_PEERSTORE_Processor callback, void *callback_cls)
Request watching a given key The monitoring can be filtered to contain only records matching peer and...
struct GNUNET_PEERSTORE_Handle * GNUNET_PEERSTORE_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the PEERSTORE service.
void GNUNET_PEERSTORE_monitor_next(struct GNUNET_PEERSTORE_Monitor *zm, uint64_t limit)
Calls the monitor processor specified in GNUNET_PEERSTORE_monitor_start for the next record(s).
#define GNUNET_PEERSTORE_HELLO_KEY
Key used for storing HELLO in the peerstore.
#define GNUNET_MESSAGE_TYPE_HOSTLIST_ADVERTISEMENT
Hostlist advertisement message.
char * GNUNET_RESOLVER_local_fqdn_get(void)
Get local fully qualified domain name.
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...
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
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.
void GNUNET_STATISTICS_set(struct GNUNET_STATISTICS_Handle *handle, const char *name, uint64_t value, int make_persistent)
Set statistic value for the peer.
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
#define GNUNET_TIME_UNIT_MINUTES
One minute.
static unsigned int size
Size of the "table".
static struct GNUNET_MQ_Handle * mq
Our connection to the resolver service, created on-demand, but then persists until error or shutdown.
Internal representation of the hash map.
Context for the core service connection.
Context for parsing HELLOs.
Handle to a message queue.
collection of IO descriptors
Handle to the PEERSTORE service.
The identity of the host (wraps the signing key of the peer).
Entry in list of pending tasks.
Time for relative time used by GNUnet, in microseconds.
uint64_t rel_value_us
The actual value.
Context for host_processor().
char * data
Place where we accumulate all of the HELLO messages.
unsigned int size
Number of bytes in data.