29 #include <microhttpd.h>
42 #define GNUNET_ADV_TIMEOUT \
43 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5)
144 MHD_add_response_header (
response,
"Access-Control-Allow-Origin",
"*");
146 "Access-Control-Allow-Methods",
148 MHD_add_response_header (
response,
"Access-Control-Max-Age",
"86400");
161 "Creating hostlist response with %u bytes\n",
165 MHD_RESPMEM_MUST_FREE);
236 _ (
"Error in communication with PEERINFO service: %s\n"),
253 "HELLO for peer `%4s' has no address, not suitable for hostlist!\n",
257 "HELLOs without addresses encountered (ignored)"),
265 "Received %u bytes of `%s' from peer `%s' for hostlist.\n",
275 "bytes not included in hostlist (size limit)"),
281 "Adding peer `%s' to hostlist (%u bytes)\n",
300 const struct sockaddr *addr,
307 "Received request for hostlist, but I am not yet ready; rejecting!\n");
351 struct MHD_Connection *connection,
355 const char *upload_data,
356 size_t *upload_data_size,
362 if (0 == strcmp (MHD_HTTP_METHOD_OPTIONS, method))
364 struct MHD_Response *options_response;
368 MHD_create_response_from_buffer (0, NULL, MHD_RESPMEM_PERSISTENT);
370 rc = MHD_queue_response (connection,
MHD_HTTP_OK, options_response);
371 MHD_destroy_response (options_response);
374 if (0 != strcmp (method, MHD_HTTP_METHOD_GET))
377 _ (
"Refusing `%s' request to hostlist server\n"),
381 "hostlist requests refused (not HTTP GET)"),
386 if (NULL == *con_cls)
391 if (0 != *upload_data_size)
394 _ (
"Refusing `%s' request with %llu bytes of upload data\n"),
396 (
unsigned long long) *upload_data_size);
399 "hostlist requests refused (upload data)"),
409 "Could not handle hostlist request since I do not have a response yet\n"));
412 "hostlist requests refused (not ready)"),
418 _ (
"Received request for our hostlist\n"));
439 static uint64_t hostlist_adv_count;
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);
500 "Asked CORE to transmit advertisement message with a size of %u bytes to peer `%s'\n",
524 "Peerinfo is notifying us to rebuild our hostlist\n");
527 _ (
"Error in communication with PEERINFO service: %s\n"),
568 struct MHD_Daemon *daemon_handle = cls;
598 MHD_UNSIGNED_LONG_LONG
timeout;
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)
645 unsigned long long port;
652 struct sockaddr_in v4;
653 struct sockaddr_in6 v6;
654 const struct sockaddr *sa4;
655 const struct sockaddr *sa6;
661 "Advertising not enabled on this hostlist server\n");
666 "Advertising enabled on this hostlist server\n");
674 _ (
"Could not access PEERINFO service. Exiting.\n"));
682 if ((0 ==
port) || (
port > UINT16_MAX))
685 _ (
"Invalid port number %llu. Exiting.\n"),
697 _ (
"Hostlist service starts on %s:%llu\n"),
712 (
unsigned int)
port);
714 _ (
"Address to obtain hostlist: `%s'\n"),
729 _ (
"BINDTOIP does not a valid IPv4 address! Ignoring BINDTOIPV4.\n"));
743 _ (
"BINDTOIP does not a valid IPv4 address! Ignoring BINDTOIPV6.\n"));
751 if (1 == inet_pton (AF_INET,
ipv4, &i4))
753 memset (&v4, 0,
sizeof(v4));
754 v4.sin_family = AF_INET;
756 v4.sin_port = htons (
port);
757 #if HAVE_SOCKADDR_IN_SIN_LEN
758 v4.sin_len =
sizeof(v4);
760 sa4 = (
const struct sockaddr *) &v4;
765 "`%s' is not a valid IPv4 address! Ignoring BINDTOIPV4.\n"),
772 if (1 == inet_pton (AF_INET6,
ipv6, &i6))
774 memset (&v6, 0,
sizeof(v6));
775 v6.sin6_family = AF_INET6;
777 v6.sin6_port = htons (
port);
778 #if HAVE_SOCKADDR_IN_SIN_LEN
779 v6.sin6_len =
sizeof(v6);
781 sa6 = (
const struct sockaddr *) &v6;
786 "`%s' is not a valid IPv6 address! Ignoring BINDTOIPV6.\n"),
797 MHD_OPTION_CONNECTION_LIMIT,
799 MHD_OPTION_PER_IP_CONNECTION_LIMIT,
801 MHD_OPTION_CONNECTION_TIMEOUT,
803 MHD_OPTION_CONNECTION_MEMORY_LIMIT,
804 (
size_t) (16 * 1024),
805 MHD_OPTION_SOCK_ADDR,
814 MHD_OPTION_CONNECTION_LIMIT,
816 MHD_OPTION_PER_IP_CONNECTION_LIMIT,
818 MHD_OPTION_CONNECTION_TIMEOUT,
820 MHD_OPTION_CONNECTION_MEMORY_LIMIT,
821 (
size_t) (16 * 1024),
822 MHD_OPTION_SOCK_ADDR,
829 _ (
"Could not start hostlist HTTP server on port %u\n"),
830 (
unsigned short)
port);
struct GNUNET_MQ_Handle * mq
struct GNUNET_MQ_Envelope * env
#define gettext_noop(String)
static char * expiration
Credential TTL.
static int ret
Return value of the commandline.
static struct GNUNET_TIME_Relative timeout
Desired timeout for the lookup (default is no timeout).
static uint16_t port
Port number.
static struct GNUNET_SCHEDULER_Task * st
The shutdown task.
static char * address
GNS address for this phone.
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 void * connect_handler(void *cls, const struct GNUNET_PeerIdentity *peer, struct GNUNET_MQ_Handle *mq)
Method called whenever a given peer connects.
static struct MHD_Daemon * daemon_handle_v6
Handle to the HTTP server as provided by libmicrohttpd for IPv6.
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 MHD_Response * response
Our canonical response.
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 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.
static const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
static struct GNUNET_SCHEDULER_Task * hostlist_task_v6
Our primary task for IPv6.
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 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 struct GNUNET_PEERINFO_Handle * peerinfo
Handle for accessing peerinfo service.
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 adv_transmit(struct GNUNET_MQ_Handle *mq)
Handler called by CORE when CORE is ready to transmit message.
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 void finish_response()
Function that assembles our response.
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).
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 in_addr dummy
Target "dummy" address of the packet we pretend to respond to.
static char * hostname
Our hostname; we give this to all the peers we start.
static int ipv4
Option -4: IPv4 requested.
static int ipv6
Option -6: IPv6 requested.
Helper library for handling HELLOs.
Maintain the list of currently known hosts.
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.
void *(* GNUNET_CORE_ConnectEventHandler)(void *cls, const struct GNUNET_PeerIdentity *peer, struct GNUNET_MQ_Handle *mq)
Method called whenever a given peer connects.
uint16_t GNUNET_HELLO_size(const struct GNUNET_HELLO_Message *hello)
Return the size of the given HELLO message.
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.
#define GNUNET_log(kind,...)
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
@ GNUNET_SCHEDULER_PRIORITY_HIGH
Run with high priority (important requests).
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_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.
struct GNUNET_NETWORK_FDSet * GNUNET_NETWORK_fdset_create(void)
Creates an fd set.
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_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.
void GNUNET_PEERINFO_notify_cancel(struct GNUNET_PEERINFO_NotifyContext *nc)
Stop notifying about changes.
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.
void GNUNET_PEERINFO_iterate_cancel(struct GNUNET_PEERINFO_IteratorContext *ic)
Cancel an iteration over peer information.
void GNUNET_PEERINFO_disconnect(struct GNUNET_PEERINFO_Handle *h)
Disconnect from the peerinfo service.
#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.
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".
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?
@ MHD_HTTP_OK
OK [RFC7231, Section 6.3.1].
static unsigned int size
Size of the "table".
Context for the core service connection.
An address for communicating with a peer.
A HELLO message is used to exchange information about transports with other peers.
Handle to a message queue.
collection of IO descriptors
Handle to the peerinfo service.
Context for an iteration request.
Context for the info handler.
The identity of the host (wraps the signing key of the peer).
Entry in list of pending tasks.
Time for absolute times used by GNUnet, in microseconds.
Time for relative time used by GNUnet, in microseconds.
uint64_t rel_value_us
The actual value.
Context for host_processor().
struct GNUNET_PEERINFO_IteratorContext * pitr
Iterator used to build data (NULL when done).
char * data
Place where we accumulate all of the HELLO messages.
unsigned int size
Number of bytes in data.
struct GNUNET_TESTBED_Peer * peer
The peer associated with this model.