GNUnet 0.22.2
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 "gnunet_common.h"
30#include <microhttpd.h>
36#include "gnunet_mhd_compat.h"
37#include <jansson.h>
38#include <strings.h>
39
44#define GNUNET_ADV_TIMEOUT \
45 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5)
46
51
55static struct MHD_Daemon *daemon_handle_v6;
56
60static struct MHD_Daemon *daemon_handle_v4;
61
65static const struct GNUNET_CONFIGURATION_Handle *cfg;
66
71
75static struct GNUNET_CORE_Handle *core;
76
82
88
93
98
102static struct MHD_Response *response;
103
107static struct MHD_Response *response_json;
108
113
117static int advertising;
118
122static char *hostlist_uri;
123
124
129{
133 char *data;
134
138 unsigned int size;
139};
140
141
145static struct HostSet *builder;
146
147
154static void
155add_cors_headers (struct MHD_Response *resp)
156{
157 GNUNET_assert (MHD_NO !=
158 MHD_add_response_header (resp,
159 "Access-Control-Allow-Origin", "*"));
160 GNUNET_assert (MHD_NO !=
161 MHD_add_response_header (resp,
162 "Access-Control-Allow-Methods",
163 "GET, OPTIONS"));
164 GNUNET_assert (MHD_NO !=
165 MHD_add_response_header (resp, "Access-Control-Max-Age",
166 "86400"));
167}
168
169
170static struct MHD_Response*
171build_json_response (const struct HostSet *bu)
172{
173 struct GNUNET_MessageHeader *hello;
174 struct GNUNET_HELLO_Parser *hparser;
175 json_t*hello_uri_j;
176 json_t*hello_array;
177 char *hello_uri;
178 char *hello_uris;
179 size_t offset = 0;
180
181 hello_uri_j = json_object ();
182 hello_array = json_array ();
183 while (offset < bu->size)
184 {
185 hello = (struct GNUNET_MessageHeader*) (bu->data + offset);
186 hparser = GNUNET_HELLO_parser_from_msg (hello);
187 hello_uri = GNUNET_HELLO_parser_to_url (hparser);
188 json_array_append_new (hello_array, json_string (hello_uri));
189 GNUNET_free (hello_uri);
190 GNUNET_HELLO_parser_free (hparser);
191 offset += ntohs (hello->size);
192 }
193 json_object_set_new (hello_uri_j, "hellos", hello_array);
194 hello_uris = json_dumps (hello_uri_j, JSON_INDENT (2));
195 json_decref (hello_uri_j);
196 return MHD_create_response_from_buffer (strlen (hello_uris),
197 hello_uris,
198 MHD_RESPMEM_MUST_FREE);
199}
200
201
205static void
207{
208 if (NULL != response)
209 MHD_destroy_response (response);
210 if (NULL != response_json)
211 MHD_destroy_response (response_json);
213 "Creating hostlist response with %u bytes\n",
214 (unsigned int) builder->size);
215 response = MHD_create_response_from_buffer (builder->size,
216 builder->data,
217 MHD_RESPMEM_MUST_FREE);
219 GNUNET_assert (MHD_NO != MHD_add_response_header (response_json,
220 "Content-Type",
221 "application/json"));
223 if ((NULL == daemon_handle_v4) && (NULL == daemon_handle_v6))
224 {
225 MHD_destroy_response (response);
226 response = NULL;
227 MHD_destroy_response (response_json);
228 response_json = NULL;
229 }
231 gettext_noop ("bytes in hostlist"),
232 builder->size,
233 GNUNET_YES);
235 builder = NULL;
236}
237
238
249host_processor (void *cls,
250 const struct GNUNET_PeerIdentity *peer,
251 void *value)
252{
253 size_t old;
254 size_t s;
255 struct GNUNET_MessageHeader *hello = value;
256 (void) cls;
257
259 "host_processor\n");
260 old = builder->size;
261 s = ntohs (hello->size);
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! */
273 "bytes not included in hostlist (size limit)"),
274 s,
275 GNUNET_NO);
276 return GNUNET_YES;
277 }
279 "Adding peer `%s' to hostlist (%u bytes)\n",
280 GNUNET_i2s (peer),
281 (unsigned int) s);
283 GNUNET_memcpy (&builder->data[old], hello, s);
284
285 return GNUNET_YES;
286}
287
288
298static MHD_RESULT
300 const struct sockaddr *addr,
301 socklen_t addrlen)
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}
312
313
314static int
316 enum MHD_ValueKind kind,
317 const char *key,
318 const char *value)
319{
320 enum GNUNET_GenericReturnValue *want_json = cls;
321
322 if (0 != strcasecmp (key, "Accept"))
323 return GNUNET_YES;
324 if (0 == strcasecmp (value, "application/json"))
325 *want_json = GNUNET_YES;
326 return MHD_YES;
327}
328
329
365static MHD_RESULT
367 struct MHD_Connection *connection,
368 const char *url,
369 const char *method,
370 const char *version,
371 const char *upload_data,
372 size_t *upload_data_size,
373 void **con_cls)
374{
375 static int dummy;
376 struct MHD_Response *selected_response;
377 enum GNUNET_GenericReturnValue want_json = GNUNET_NO;
378
379 /* CORS pre-flight request */
380 if (0 == strcmp (MHD_HTTP_METHOD_OPTIONS, method))
381 {
382 struct MHD_Response *options_response;
383 int rc;
384
385 options_response =
386 MHD_create_response_from_buffer (0, NULL, MHD_RESPMEM_PERSISTENT);
387 add_cors_headers (options_response);
388 rc = MHD_queue_response (connection, MHD_HTTP_OK, options_response);
389 MHD_destroy_response (options_response);
390 return rc;
391 }
392 if (0 != strcmp (method, MHD_HTTP_METHOD_GET))
393 {
395 _ ("Refusing `%s' request to hostlist server\n"),
396 method);
399 "hostlist requests refused (not HTTP GET)"),
400 1,
401 GNUNET_YES);
402 return MHD_NO;
403 }
404 if (NULL == *con_cls)
405 {
406 (*con_cls) = &dummy;
407 return MHD_YES;
408 }
409 if (0 != *upload_data_size)
410 {
412 _ ("Refusing `%s' request with %llu bytes of upload data\n"),
413 method,
414 (unsigned long long) *upload_data_size);
417 "hostlist requests refused (upload data)"),
418 1,
419 GNUNET_YES);
420 return MHD_NO; /* do not support upload data */
421 }
422 selected_response = response;
423 MHD_get_connection_values (connection,
424 MHD_HEADER_KIND,
425 (MHD_KeyValueIterator) & header_iterator,
426 &want_json);
427 if (GNUNET_YES == want_json)
428 {
429 selected_response = response_json;
430 }
431 if (NULL == selected_response)
432 {
433 GNUNET_log (
435 _ (
436 "Could not handle hostlist request since I do not have a response yet\n"));
439 "hostlist requests refused (not ready)"),
440 1,
441 GNUNET_YES);
442 return MHD_NO; /* internal error, no response yet */
443 }
445 _ ("Received request for our hostlist\n"));
447 gettext_noop ("hostlist requests processed"),
448 1,
449 GNUNET_YES);
450 return MHD_queue_response (connection, MHD_HTTP_OK, selected_response);
451}
452
453
463static void
465{
466 static uint64_t hostlist_adv_count;
467 size_t uri_size; /* Including \0 termination! */
468 struct GNUNET_MessageHeader *header;
469 struct GNUNET_MQ_Envelope *env;
470
471 uri_size = strlen (hostlist_uri) + 1;
472 env = GNUNET_MQ_msg_extra (header,
473 uri_size,
475 GNUNET_memcpy (&header[1], hostlist_uri, uri_size);
481 "Sent advertisement message: Copied %u bytes into buffer!\n",
482 (unsigned int) uri_size);
483 hostlist_adv_count++;
485 " # Sent advertisement message: %llu\n",
486 (unsigned long long) hostlist_adv_count);
488 gettext_noop ("# hostlist advertisements send"),
489 1,
490 GNUNET_NO);
491}
492
493
502static void *
504 const struct GNUNET_PeerIdentity *peer,
505 struct GNUNET_MQ_Handle *mq)
506{
507 size_t size;
508
509 if (! advertising)
510 return NULL;
511 if (NULL == hostlist_uri)
512 return NULL;
513 size = strlen (hostlist_uri) + 1;
514 if (size + sizeof(struct GNUNET_MessageHeader) >= GNUNET_MAX_MESSAGE_SIZE)
515 {
516 GNUNET_break (0);
517 return NULL;
518 }
519 size += sizeof(struct GNUNET_MessageHeader);
520 if (NULL == core)
521 {
522 GNUNET_break (0);
523 return NULL;
524 }
525 GNUNET_log (
527 "Asked CORE to transmit advertisement message with a size of %u bytes to peer `%s'\n",
528 (unsigned int) size,
529 GNUNET_i2s (peer));
531 return NULL;
532}
533
534
544static void
545process_notify (void *cls,
546 const struct GNUNET_PEERSTORE_Record *record,
547 const char *err_msg)
548{
549 unsigned int map_size;
550 struct GNUNET_MessageHeader *hello_cpy;
551 struct GNUNET_PeerIdentity *peer_cpy;
552 struct GNUNET_MessageHeader *hello;
553
556 "Peerstore is notifying us to rebuild our hostlist map size %u\n",
557 map_size);
558 if (NULL != err_msg)
559 {
561 _ ("Error in communication with PEERSTORE service: %s\n"),
562 err_msg);
563 return;
564 }
565 hello = record->value;
566 if (NULL != builder)
567 {
569 builder->size = 0;
570 builder->data = NULL;
571 }
572 else
573 {
574 builder = GNUNET_new (struct HostSet);
575 }
576
577 peer_cpy = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
578 GNUNET_memcpy (peer_cpy, &record->peer, sizeof (struct GNUNET_PeerIdentity));
579 hello_cpy = GNUNET_malloc (ntohs (hello->size));
580 GNUNET_memcpy (hello_cpy, hello, ntohs (hello->size));
583 peer_cpy,
584 (struct
586 hello_cpy,
590 NULL))
594 "1 Peerstore is notifying us to rebuild our hostlist map size %u peer %s\n",
595 map_size,
596 GNUNET_i2s (&record->peer));
598}
599
600
605static struct GNUNET_SCHEDULER_Task *
606prepare_daemon (struct MHD_Daemon *daemon_handle);
607
608
615static void
616run_daemon (void *cls)
617{
618 struct MHD_Daemon *daemon_handle = cls;
619
620 if (daemon_handle == daemon_handle_v4)
621 hostlist_task_v4 = NULL;
622 else
623 hostlist_task_v6 = NULL;
624 GNUNET_assert (MHD_YES == MHD_run (daemon_handle));
625 if (daemon_handle == daemon_handle_v4)
626 hostlist_task_v4 = prepare_daemon (daemon_handle);
627 else
628 hostlist_task_v6 = prepare_daemon (daemon_handle);
629}
630
631
638static struct GNUNET_SCHEDULER_Task *
639prepare_daemon (struct MHD_Daemon *daemon_handle)
640{
642 fd_set rs;
643 fd_set ws;
644 fd_set es;
645 struct GNUNET_NETWORK_FDSet *wrs;
646 struct GNUNET_NETWORK_FDSet *wws;
647 int max;
648 MHD_UNSIGNED_LONG_LONG timeout;
649 int haveto;
650 struct GNUNET_TIME_Relative tv;
651
652 FD_ZERO (&rs);
653 FD_ZERO (&ws);
654 FD_ZERO (&es);
657 max = -1;
658 GNUNET_assert (MHD_YES == MHD_get_fdset (daemon_handle, &rs, &ws, &es, &max));
659 haveto = MHD_get_timeout (daemon_handle, &timeout);
660 if (haveto == MHD_YES)
661 tv.rel_value_us = (uint64_t) timeout * 1000LL;
662 else
667 tv,
668 wrs,
669 wws,
670 &run_daemon,
671 daemon_handle);
674 return ret;
675}
676
677
678static void
679error_cb (void *cls)
680{
682 "Error in PEERSTORE monitoring\n");
683}
684
685
686static void
687sync_cb (void *cls)
688{
690 "Done with initial PEERSTORE iteration during monitoring\n");
691}
692
693
694static void
695start_notify (void *cls)
696{
697 (void) cls;
698
700 "Starting to process new hellos to add to hostlist.\n");
703 "peerstore",
704 NULL,
706 &error_cb,
707 NULL,
708 &sync_cb,
709 NULL,
710 &process_notify, NULL);
711}
712
713
724int
727 struct GNUNET_CORE_Handle *co,
729 int advertise)
730{
731 unsigned long long port;
732 char *hostname;
733 char *ipv4;
734 char *ipv6;
735 size_t size;
736 struct in_addr i4;
737 struct in6_addr i6;
738 struct sockaddr_in v4;
739 struct sockaddr_in6 v6;
740 const struct sockaddr *sa4;
741 const struct sockaddr *sa6;
742
744 advertising = advertise;
745 if (! advertising)
746 {
748 "Advertising not enabled on this hostlist server\n");
749 }
750 else
751 {
753 "Advertising enabled on this hostlist server\n");
754 }
755 cfg = c;
756 stats = st;
758 if (NULL == peerstore)
759 {
761 _ ("Could not access PEERSTORE service. Exiting.\n"));
762 return GNUNET_SYSERR;
763 }
765 "HOSTLIST",
766 "HTTPPORT",
767 &port))
768 return GNUNET_SYSERR;
769 if ((0 == port) || (port > UINT16_MAX))
770 {
772 _ ("Invalid port number %llu. Exiting.\n"),
773 port);
774 return GNUNET_SYSERR;
775 }
776
777 if (GNUNET_SYSERR ==
779 "HOSTLIST",
780 "EXTERNAL_DNS_NAME",
781 &hostname))
782 hostname = GNUNET_RESOLVER_local_fqdn_get ();
784 _ ("Hostlist service starts on %s:%llu\n"),
785 hostname,
786 port);
787 if (NULL != hostname)
788 {
789 size = strlen (hostname);
790 if (size + 15 > MAX_URL_LEN)
791 {
792 GNUNET_break (0);
793 }
794 else
795 {
797 "http://%s:%u/",
798 hostname,
799 (unsigned int) port);
801 _ ("Address to obtain hostlist: `%s'\n"),
803 }
804 GNUNET_free (hostname);
805 }
806
807 if (GNUNET_CONFIGURATION_have_value (cfg, "HOSTLIST", "BINDTOIPV4"))
808 {
810 "HOSTLIST",
811 "BINDTOIP",
812 &ipv4))
813 {
814 GNUNET_log (
816 _ ("BINDTOIP does not a valid IPv4 address! Ignoring BINDTOIPV4.\n"));
817 }
818 }
819 else
820 ipv4 = NULL;
821 if (GNUNET_CONFIGURATION_have_value (cfg, "HOSTLIST", "BINDTOIPV6"))
822 {
824 "HOSTLIST",
825 "BINDTOIP",
826 &ipv6))
827 {
828 GNUNET_log (
830 _ ("BINDTOIP does not a valid IPv4 address! Ignoring BINDTOIPV6.\n"));
831 }
832 }
833 else
834 ipv6 = NULL;
835 sa4 = NULL;
836 if (NULL != ipv4)
837 {
838 if (1 == inet_pton (AF_INET, ipv4, &i4))
839 {
840 memset (&v4, 0, sizeof(v4));
841 v4.sin_family = AF_INET;
842 v4.sin_addr = i4;
843 v4.sin_port = htons (port);
844#if HAVE_SOCKADDR_IN_SIN_LEN
845 v4.sin_len = sizeof(v4);
846#endif
847 sa4 = (const struct sockaddr *) &v4;
848 }
849 else
851 _ (
852 "`%s' is not a valid IPv4 address! Ignoring BINDTOIPV4.\n"),
853 ipv4);
855 }
856 sa6 = NULL;
857 if (NULL != ipv6)
858 {
859 if (1 == inet_pton (AF_INET6, ipv6, &i6))
860 {
861 memset (&v6, 0, sizeof(v6));
862 v6.sin6_family = AF_INET6;
863 v6.sin6_addr = i6;
864 v6.sin6_port = htons (port);
865#if HAVE_SOCKADDR_IN_SIN_LEN
866 v6.sin6_len = sizeof(v6);
867#endif
868 sa6 = (const struct sockaddr *) &v6;
869 }
870 else
872 _ (
873 "`%s' is not a valid IPv6 address! Ignoring BINDTOIPV6.\n"),
874 ipv6);
876 }
877
878 daemon_handle_v6 = MHD_start_daemon (MHD_USE_IPv6 | MHD_USE_DEBUG,
879 (uint16_t) port,
881 NULL,
883 NULL,
884 MHD_OPTION_CONNECTION_LIMIT,
885 (unsigned int) 128,
886 MHD_OPTION_PER_IP_CONNECTION_LIMIT,
887 (unsigned int) 32,
888 MHD_OPTION_CONNECTION_TIMEOUT,
889 (unsigned int) 16,
890 MHD_OPTION_CONNECTION_MEMORY_LIMIT,
891 (size_t) (16 * 1024),
892 MHD_OPTION_SOCK_ADDR,
893 sa6,
894 MHD_OPTION_END);
895 daemon_handle_v4 = MHD_start_daemon (MHD_NO_FLAG | MHD_USE_DEBUG,
896 (uint16_t) port,
898 NULL,
900 NULL,
901 MHD_OPTION_CONNECTION_LIMIT,
902 (unsigned int) 128,
903 MHD_OPTION_PER_IP_CONNECTION_LIMIT,
904 (unsigned int) 32,
905 MHD_OPTION_CONNECTION_TIMEOUT,
906 (unsigned int) 16,
907 MHD_OPTION_CONNECTION_MEMORY_LIMIT,
908 (size_t) (16 * 1024),
909 MHD_OPTION_SOCK_ADDR,
910 sa4,
911 MHD_OPTION_END);
912
913 if ((NULL == daemon_handle_v6) && (NULL == daemon_handle_v4))
914 {
916 _ ("Could not start hostlist HTTP server on port %u\n"),
917 (unsigned short) port);
918 return GNUNET_SYSERR;
919 }
920
921 core = co;
923 if (NULL != daemon_handle_v4)
925 if (NULL != daemon_handle_v6)
930 NULL);
931 return GNUNET_OK;
932}
933
934
938void
940{
941 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Hostlist server shutdown\n");
942 if (NULL != hostlist_task_v6)
943 {
945 hostlist_task_v6 = NULL;
946 }
947 if (NULL != hostlist_task_v4)
948 {
950 hostlist_task_v4 = NULL;
951 }
952 if (NULL != daemon_handle_v4)
953 {
954 MHD_stop_daemon (daemon_handle_v4);
955 daemon_handle_v4 = NULL;
956 }
957 if (NULL != daemon_handle_v6)
958 {
959 MHD_stop_daemon (daemon_handle_v6);
960 daemon_handle_v6 = NULL;
961 }
962 if (NULL != response)
963 {
964 MHD_destroy_response (response);
965 response = NULL;
966 }
967 if (NULL != response_json)
968 {
969 MHD_destroy_response (response_json);
970 response_json = NULL;
971 }
972 if (NULL != peerstore_notify)
973 {
975 peerstore_notify = NULL;
976 }
977 else if (NULL != peerstore_notify_task)
978 {
980 }
981 if (NULL != builder)
982 {
985 builder = NULL;
986 }
987 if (NULL != peerstore)
988 {
990 peerstore = NULL;
991 }
992 cfg = NULL;
993 stats = NULL;
994 core = NULL;
995}
996
997
998/* end of gnunet-daemon-hostlist_server.c */
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
#define gettext_noop(String)
Definition: gettext.h:74
static int ret
Final status code.
Definition: gnunet-arm.c:93
static struct GNUNET_TIME_Relative timeout
User defined timestamp for completing operations.
Definition: gnunet-arm.c:118
static uint16_t port
Port number.
Definition: gnunet-bcd.c:146
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 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 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 void * connect_handler(void *cls, const struct GNUNET_PeerIdentity *peer, struct GNUNET_MQ_Handle *mq)
Method called whenever a given peer connects.
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 struct MHD_Response * build_json_response(const struct HostSet *bu)
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.
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.
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).
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.
Definition: gnunet-vpn.c:60
static int ipv6
Option -6: IPv6 requested.
Definition: gnunet-vpn.c:65
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.
void *(* GNUNET_CORE_ConnectEventHandler)(void *cls, const struct GNUNET_PeerIdentity *peer, struct GNUNET_MQ_Handle *mq)
Method called whenever a given peer connects.
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.
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE
Allow multiple values with the same key.
void GNUNET_HELLO_parser_free(struct GNUNET_HELLO_Parser *parser)
Release resources of a builder.
Definition: hello-uri.c:435
struct GNUNET_HELLO_Parser * GNUNET_HELLO_parser_from_msg(const struct GNUNET_MessageHeader *msg)
Parse msg.
Definition: hello-uri.c:471
char * GNUNET_HELLO_parser_to_url(const struct GNUNET_HELLO_Parser *parser)
Generate GNUnet HELLO URI from a parser.
Definition: hello-uri.c:940
#define GNUNET_log(kind,...)
#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).
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
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
@ GNUNET_ERROR_TYPE_INFO
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.
Definition: mq.c:847
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:305
#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:61
@ 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.
Definition: network.c:1185
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_NETWORK_FDSet * GNUNET_NETWORK_fdset_create(void)
Creates an fd set.
Definition: network.c:1169
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...
Definition: scheduler.c:1835
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:980
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1277
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.
@ MHD_HTTP_OK
OK [RFC7231, Section 6.3.1].
#define max(x, y)
static unsigned int size
Size of the "table".
Definition: peer.c:68
#define _(String)
GNU gettext support macro.
Definition: platform.h:178
Internal representation of the hash map.
Context for the core service connection.
Definition: core_api.c:78
Context for parsing HELLOs.
Definition: hello-uri.c:258
Handle to a message queue.
Definition: mq.c:87
Header for all communications.
collection of IO descriptors
Handle to the PEERSTORE service.
Definition: peerstore_api.c:44
Context for a monitor.
Single PEERSTORE record.
The identity of the host (wraps the signing key of the peer).
Entry in list of pending tasks.
Definition: scheduler.c:136
Handle for the service.
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.