GNUnet 0.26.2
 
Loading...
Searching...
No Matches
gnunet-rest-server.c File Reference
#include "platform.h"
#include <microhttpd.h>
#include "gnunet_util_lib.h"
#include "gnunet_rest_plugin.h"
#include "gnunet_mhd_compat.h"
#include "config_plugin.h"
#include "copying_plugin.h"
#include "identity_plugin.h"
#include "namestore_plugin.h"
#include "gns_plugin.h"
#include "reclaim_plugin.h"
Include dependency graph for gnunet-rest-server.c:

Go to the source code of this file.

Data Structures

struct  PluginListEntry
 A plugin list entry. More...
 
struct  MhdConnectionHandle
 MHD Connection handle. More...
 
struct  AcceptedRequest
 Accepted requests. More...
 

Macros

#define GNUNET_REST_SERVICE_PORT   7776
 Default Socks5 listen port.
 
#define MAX_HTTP_URI_LENGTH   2048
 Maximum supported length for a URI.
 
#define HTTP_PORT   80
 Port for plaintext HTTP.
 
#define HTTPS_PORT   443
 Port for HTTPS.
 
#define MHD_CACHE_TIMEOUT    GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5)
 After how long do we clean up unused MHD SSL/TLS instances?
 
#define GN_REST_STATE_INIT   0
 
#define GN_REST_STATE_PROCESSING   1
 

Functions

static void do_httpd (void *cls)
 Task run whenever HTTP server operations are pending.
 
static void run_mhd_now ()
 Run MHD now, we have extra data ready for the callback.
 
static void plugin_callback (void *cls, struct MHD_Response *resp, int status)
 Plugin result callback.
 
static int cleanup_url_map (void *cls, const struct GNUNET_HashCode *key, void *value)
 
static void cleanup_handle (struct MhdConnectionHandle *handle)
 
static void cleanup_ar (struct AcceptedRequest *ar)
 
static int header_iterator (void *cls, enum MHD_ValueKind kind, const char *key, const char *value)
 
static int url_iterator (void *cls, enum MHD_ValueKind kind, const char *key, const char *value)
 
static MHD_RESULT post_data_iter (void *cls, enum MHD_ValueKind kind, const char *key, const char *filename, const char *content_type, const char *transfer_encoding, const char *data, uint64_t off, size_t size)
 
static MHD_RESULT create_response (void *cls, struct MHD_Connection *con, const char *url, const char *meth, const char *ver, const char *upload_data, size_t *upload_data_size, void **con_cls)
 Main MHD callback for handling requests.
 
static void kill_httpd ()
 Kill the MHD daemon.
 
static void schedule_httpd ()
 Schedule MHD.
 
static void * mhd_log_callback (void *cls, const char *url, struct MHD_Connection *connection)
 Function called when MHD first processes an incoming connection.
 
static void mhd_completed_cb (void *cls, struct MHD_Connection *connection, void **con_cls, enum MHD_RequestTerminationCode toe)
 Function called when MHD decides that we are done with a connection.
 
static void mhd_connection_cb (void *cls, struct MHD_Connection *connection, void **con_cls, enum MHD_ConnectionNotificationCode cnc)
 Function called when MHD connection is opened or closed.
 
static void do_accept (void *cls)
 Accept new incoming connections.
 
static void do_shutdown (void *cls)
 Task run on shutdown.
 
static struct GNUNET_NETWORK_Handlebind_v4 ()
 Create an IPv4 listen socket bound to our port.
 
static struct GNUNET_NETWORK_Handlebind_v6 ()
 Create an IPv6 listen socket bound to our port.
 
static enum GNUNET_GenericReturnValue setup_plugin (const char *name, GNUNET_REST_ProcessingFunction proc, void *plugin_cls)
 Callback for plugin load.
 
static void run (void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *c)
 Main function that will be run.
 

Variables

static struct GNUNET_SCHEDULER_Taskhttpd_task
 The task ID.
 
static in_addr_t address
 The address to bind to.
 
static struct in6_addr address6
 The IPv6 address to bind to.
 
static unsigned long long port = 7776
 The port the service is running on (default 7776)
 
static struct GNUNET_NETWORK_Handlelsock4
 The listen socket of the service for IPv4.
 
static struct GNUNET_NETWORK_Handlelsock6
 The listen socket of the service for IPv6.
 
static struct GNUNET_SCHEDULER_Taskltask4
 The listen task ID for IPv4.
 
static struct GNUNET_SCHEDULER_Taskltask6
 The listen task ID for IPv6.
 
static struct MHD_Daemon * httpd
 Daemon for HTTP.
 
static struct MHD_Response * failure_response
 Response we return on failures.
 
static const struct GNUNET_CONFIGURATION_Handlecfg
 Our configuration.
 
static int echo_origin
 Echo request Origin in CORS.
 
static int basic_auth_enabled
 Do basic auth of user.
 
static char * basic_auth_secret
 Basic auth secret.
 
char cuser [_POSIX_LOGIN_NAME_MAX]
 User of the service.
 
static char * allow_origins
 Allowed Origins (CORS)
 
static char * allow_headers
 Allowed Headers (CORS)
 
static char * allow_credentials
 Allowed Credentials (CORS)
 
static struct PluginListEntryplugins_head
 Plugin list head.
 
static struct PluginListEntryplugins_tail
 Plugin list tail.
 
static struct AcceptedRequestreq_list_head
 AcceptedRequest list head.
 
static struct AcceptedRequestreq_list_tail
 AcceptedRequest list tail.
 
struct GNUNET_REST_Pluginconfig_plugin
 plugins
 
struct GNUNET_REST_Plugincopying_plugin
 
struct GNUNET_REST_Pluginidentity_plugin
 
struct GNUNET_REST_Pluginnamestore_plugin
 
struct GNUNET_REST_Plugingns_plugin
 
struct GNUNET_REST_Pluginreclaim_plugin
 

Macro Definition Documentation

◆ GNUNET_REST_SERVICE_PORT

#define GNUNET_REST_SERVICE_PORT   7776

Default Socks5 listen port.

Definition at line 45 of file gnunet-rest-server.c.

◆ MAX_HTTP_URI_LENGTH

#define MAX_HTTP_URI_LENGTH   2048

Maximum supported length for a URI.

Should die.

Deprecated:

Definition at line 51 of file gnunet-rest-server.c.

◆ HTTP_PORT

#define HTTP_PORT   80

Port for plaintext HTTP.

Definition at line 56 of file gnunet-rest-server.c.

◆ HTTPS_PORT

#define HTTPS_PORT   443

Port for HTTPS.

Definition at line 61 of file gnunet-rest-server.c.

◆ MHD_CACHE_TIMEOUT

#define MHD_CACHE_TIMEOUT    GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5)

After how long do we clean up unused MHD SSL/TLS instances?

Definition at line 66 of file gnunet-rest-server.c.

175{
176 /* DLL */
177 struct PluginListEntry *next;
178
179 /* DLL */
180 struct PluginListEntry *prev;
181
185 char *libname;
186
190 void *plugin;
191
196};
197
202{
203 struct MHD_Connection *con;
204
205 struct MHD_Response *response;
206
208
209 struct MHD_PostProcessor *pp;
210
211 int status;
212
213 int state;
214};
215
219struct AcceptedRequest
220{
224 struct AcceptedRequest *next;
225
229 struct AcceptedRequest *prev;
230
235
240
244 int socket_with_mhd;
245};
246
250static struct AcceptedRequest *req_list_head;
251
255static struct AcceptedRequest *req_list_tail;
256
257
267#if HAVE_JOSE
268struct GNUNET_REST_Plugin *openid_plugin;
269#endif
271
272/* ************************* Global helpers ********************* */
273
274
280static void
281do_httpd (void *cls);
282
283
287static void
289{
290 if (NULL != httpd_task)
291 {
293 httpd_task = NULL;
294 }
296}
297
298
307static void
308plugin_callback (void *cls, struct MHD_Response *resp, int status)
309{
310 struct MhdConnectionHandle *handle = cls;
311
312 handle->status = status;
313 handle->response = resp;
314 MHD_resume_connection (handle->con);
315 run_mhd_now ();
316}
317
318
319static int
320cleanup_url_map (void *cls, const struct GNUNET_HashCode *key, void *value)
321{
323 return GNUNET_YES;
324}
325
326
327static void
329{
330 if (NULL != handle->response)
331 MHD_destroy_response (handle->response);
332 if (NULL != handle->data_handle)
333 {
334 if (NULL != handle->data_handle->header_param_map)
335 {
337 ->header_param_map,
339 NULL);
341 handle->data_handle->header_param_map);
342 }
343 if (NULL != handle->data_handle->url_param_map)
344 {
345 GNUNET_CONTAINER_multihashmap_iterate (handle->data_handle->url_param_map,
347 NULL);
349 handle->data_handle->url_param_map);
350 }
351 GNUNET_free (handle->data_handle);
352 }
354}
355
356
357static void
358cleanup_ar (struct AcceptedRequest *ar)
359{
360 if (NULL != ar->con_handle)
361 {
363 }
364 if (GNUNET_YES == ar->socket_with_mhd)
365 {
367 }
368 else
369 {
371 }
372 ar->sock = NULL;
375 ar);
376 GNUNET_free (ar);
377}
378
379
380static int
381header_iterator (void *cls,
382 enum MHD_ValueKind kind,
383 const char *key,
384 const char *value)
385{
386 struct GNUNET_REST_RequestHandle *handle = cls;
387 struct GNUNET_HashCode hkey;
388 char *val;
389 char *lowerkey;
390
391 lowerkey = GNUNET_STRINGS_utf8_tolower (key);
392 GNUNET_CRYPTO_hash (lowerkey,
393 strlen (lowerkey),
394 &hkey);
395 GNUNET_asprintf (&val,
396 "%s",
397 value);
398 if (GNUNET_OK !=
400 handle->header_param_map,
401 &hkey,
402 val,
404 {
406 "Could not load add header `%s'=%s\n",
407 lowerkey,
408 value);
409 }
410 GNUNET_free (lowerkey);
411 return MHD_YES;
412}
413
414
415static int
416url_iterator (void *cls,
417 enum MHD_ValueKind kind,
418 const char *key,
419 const char *value)
420{
421 struct GNUNET_REST_RequestHandle *handle = cls;
422 struct GNUNET_HashCode hkey;
423 char *val;
424
425 GNUNET_CRYPTO_hash (key, strlen (key), &hkey);
426 GNUNET_asprintf (&val, "%s", value);
428 handle->url_param_map,
429 &hkey,
430 val,
432 {
434 "Could not load add url param `%s'=%s\n",
435 key,
436 value);
437 }
438 return MHD_YES;
439}
440
441
442static MHD_RESULT
443post_data_iter (void *cls,
444 enum MHD_ValueKind kind,
445 const char *key,
446 const char *filename,
447 const char *content_type,
448 const char *transfer_encoding,
449 const char *data,
450 uint64_t off,
451 size_t size)
452{
453 struct GNUNET_REST_RequestHandle *handle = cls;
454 struct GNUNET_HashCode hkey;
455 char *val;
456
457 if (MHD_POSTDATA_KIND != kind)
458 return MHD_YES;
459
460 GNUNET_CRYPTO_hash (key, strlen (key), &hkey);
461 val = GNUNET_CONTAINER_multihashmap_get (handle->url_param_map,
462 &hkey);
463 if (NULL == val)
464 {
465 val = GNUNET_malloc (65536);
467 handle->url_param_map,
468 &hkey,
469 val,
471 {
473 "Could not add url param '%s'\n",
474 key);
475 GNUNET_free (val);
476 }
477 }
478 memcpy (val + off, data, size);
479 return MHD_YES;
480}
481
482
483/* ********************************* MHD response generation ******************* */
484
508static MHD_RESULT
509create_response (void *cls,
510 struct MHD_Connection *con,
511 const char *url,
512 const char *meth,
513 const char *ver,
514 const char *upload_data,
515 size_t *upload_data_size,
516 void **con_cls)
517{
518 char *origin;
519 char *pw;
520 char *user;
521 struct AcceptedRequest *ar;
522 struct GNUNET_HashCode key;
523 struct MhdConnectionHandle *con_handle;
524 struct GNUNET_REST_RequestHandle *rest_conndata_handle;
525 struct PluginListEntry *ple;
526
527 ar = *con_cls;
528 if (NULL == ar)
529 {
530 GNUNET_break (0);
531 return MHD_NO;
532 }
533
534 if (NULL == ar->con_handle)
535 {
536 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "New connection %s\n", url);
537 con_handle = GNUNET_new (struct MhdConnectionHandle);
538 con_handle->con = con;
539 con_handle->state = GN_REST_STATE_INIT;
540 ar->con_handle = con_handle;
541 return MHD_YES;
542 }
543 con_handle = ar->con_handle;
544 if (GN_REST_STATE_INIT == con_handle->state)
545 {
546 rest_conndata_handle = GNUNET_new (struct GNUNET_REST_RequestHandle);
547 rest_conndata_handle->method = meth;
548 rest_conndata_handle->url = url;
549 rest_conndata_handle->data = upload_data;
550 rest_conndata_handle->data_size = *upload_data_size;
551 rest_conndata_handle->url_param_map =
553 rest_conndata_handle->header_param_map =
555 con_handle->data_handle = rest_conndata_handle;
556 MHD_get_connection_values (con,
557 MHD_GET_ARGUMENT_KIND,
558 (MHD_KeyValueIterator) & url_iterator,
559 rest_conndata_handle);
560 MHD_get_connection_values (con,
561 MHD_HEADER_KIND,
562 (MHD_KeyValueIterator) & header_iterator,
563 rest_conndata_handle);
565 {
566 pw = NULL;
567 user = MHD_basic_auth_get_username_password (con, &pw);
568 if ((NULL == user) ||
569 (0 != strcmp (user, cuser)))
570 {
572 "Unknown user %s\n", user);
573 MHD_queue_basic_auth_fail_response (con, "gnunet", failure_response);
574 return MHD_YES;
575 }
576 if ((NULL == pw) ||
577 (0 != strcmp (pw, basic_auth_secret)))
578 {
580 "Password incorrect\n");
581 MHD_queue_basic_auth_fail_response (con, "gnunet", failure_response);
582 GNUNET_free (pw);
583 return MHD_YES;
584 }
585 GNUNET_free (pw);
586 }
587
588 con_handle->pp = MHD_create_post_processor (con,
589 65536,
591 rest_conndata_handle);
592 if (*upload_data_size)
593 {
594 MHD_post_process (con_handle->pp, upload_data, *upload_data_size);
595 }
596 MHD_destroy_post_processor (con_handle->pp);
597
598 con_handle->state = GN_REST_STATE_PROCESSING;
599 for (ple = plugins_head; NULL != ple; ple = ple->next)
600 {
601 if (GNUNET_YES == ple->process_request (ple->plugin,
602 rest_conndata_handle,
604 con_handle))
605 break; /* Request handled */
606 }
607 if (NULL == ple)
608 {
610 MHD_queue_response (con, MHD_HTTP_NOT_FOUND, failure_response);
611 }
612 *upload_data_size = 0;
613 run_mhd_now ();
614 return MHD_YES;
615 }
616 if (NULL == con_handle->response)
617 {
618 // Suspend connection until plugin is done
619 MHD_suspend_connection (con_handle->con);
620 return MHD_YES;
621 }
622 // MHD_resume_connection (con_handle->con);
624 "Queueing response from plugin with MHD\n");
625 // Handle Preflights for extensions
626 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Checking origin\n");
627 GNUNET_CRYPTO_hash ("origin", strlen ("origin"), &key);
630 &key);
631 if (NULL != origin)
632 {
633 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Origin: %s\n", origin);
634 // Only echo for browser plugins
635 if (GNUNET_YES == echo_origin)
636 {
637 if ((0 ==
638 strncmp ("moz-extension://", origin, strlen ("moz-extension://"))) ||
639 (0 == strncmp ("chrome-extension://",
640 origin,
641 strlen ("chrome-extension://"))))
642 {
643 GNUNET_assert (MHD_NO != MHD_add_response_header (con_handle->response,
644 MHD_HTTP_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN,
645 origin));
646 }
647 }
648 if (NULL != allow_origins)
649 {
650 char *tmp = GNUNET_strdup (allow_origins);
651 char *allow_origin = strtok (tmp, ",");
652 while (NULL != allow_origin)
653 {
654 if (0 == strncmp (allow_origin, origin, strlen (allow_origin)))
655 {
656 GNUNET_assert (MHD_NO != MHD_add_response_header (
657 con_handle->response,
658 MHD_HTTP_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN,
659 allow_origin));
660 break;
661 }
662 allow_origin = strtok (NULL, ",");
663 }
664 GNUNET_free (tmp);
665 }
666 }
667 if (NULL != allow_credentials)
668 {
669 GNUNET_assert (MHD_NO != MHD_add_response_header (con_handle->response,
670 "Access-Control-Allow-Credentials",
672 }
673 if (NULL != allow_headers)
674 {
675 GNUNET_assert (MHD_NO != MHD_add_response_header (con_handle->response,
676 "Access-Control-Allow-Headers",
678 }
679 run_mhd_now ();
680 {
681 MHD_RESULT ret = MHD_queue_response (con,
682 con_handle->status,
683 con_handle->response);
684 // cleanup_handle (con_handle);
685 return ret;
686 }
687}
688
689
690/* ******************** MHD HTTP setup and event loop ******************** */
691
692
696static void
697kill_httpd ()
698{
699 if (NULL != httpd)
700 {
701 MHD_stop_daemon (httpd);
702 httpd = NULL;
703 }
704 if (NULL != httpd_task)
705 {
707 httpd_task = NULL;
708 }
709 if (NULL != ltask4)
710 {
712 ltask4 = NULL;
713 }
714 if (NULL != ltask6)
715 {
717 ltask6 = NULL;
718 }
719
720 if (NULL != lsock4)
721 {
723 lsock4 = NULL;
724 }
725 if (NULL != lsock6)
726 {
728 lsock6 = NULL;
729 }
730}
731
732
740static void
742{
743 fd_set rs;
744 fd_set ws;
745 fd_set es;
746 struct GNUNET_NETWORK_FDSet *wrs;
747 struct GNUNET_NETWORK_FDSet *wws;
748 int max;
749 int haveto;
750 MHD_UNSIGNED_LONG_LONG timeout;
751 struct GNUNET_TIME_Relative tv;
752
753 FD_ZERO (&rs);
754 FD_ZERO (&ws);
755 FD_ZERO (&es);
756 max = -1;
757 if (MHD_YES != MHD_get_fdset (httpd, &rs, &ws, &es, &max))
758 {
759 kill_httpd ();
760 return;
761 }
762 haveto = MHD_get_timeout (httpd, &timeout);
763 if (MHD_YES == haveto)
764 tv.rel_value_us = (uint64_t) timeout * 1000LL;
765 else
767 if (-1 != max)
768 {
773 }
774 else
775 {
776 wrs = NULL;
777 wws = NULL;
778 }
779 if (NULL != httpd_task)
780 {
782 httpd_task = NULL;
783 }
784 if ((MHD_YES == haveto) || (-1 != max))
785 {
787 tv,
788 wrs,
789 wws,
790 &do_httpd,
791 NULL);
792 }
793 if (NULL != wrs)
795 if (NULL != wws)
797}
798
799
813static void *
814mhd_log_callback (void *cls,
815 const char *url,
816 struct MHD_Connection *connection)
817{
818 struct AcceptedRequest *ar;
819 const union MHD_ConnectionInfo *ci;
820
821 ci = MHD_get_connection_info (connection,
822 MHD_CONNECTION_INFO_SOCKET_CONTEXT);
823 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Processing %s\n", url);
824 if (NULL == ci)
825 {
826 GNUNET_break (0);
827 return NULL;
828 }
829 ar = ci->socket_context;
830 return ar;
831}
832
833
843static void
844mhd_completed_cb (void *cls,
845 struct MHD_Connection *connection,
846 void **con_cls,
847 enum MHD_RequestTerminationCode toe)
848{
849 struct AcceptedRequest *ar = *con_cls;
850 if (MHD_REQUEST_TERMINATED_COMPLETED_OK != toe)
852 "MHD encountered error handling request: %d\n",
853 toe);
854 if (NULL == ar)
855 return;
856 if (NULL != ar->con_handle)
857 {
859 ar->con_handle = NULL;
860 }
862 *con_cls = NULL;
863}
864
865
875static void
876mhd_connection_cb (void *cls,
877 struct MHD_Connection *connection,
878 void **con_cls,
879 enum MHD_ConnectionNotificationCode cnc)
880{
881 struct AcceptedRequest *ar;
882 const union MHD_ConnectionInfo *ci;
883 int sock;
884
885 switch (cnc)
886 {
887 case MHD_CONNECTION_NOTIFY_STARTED:
888 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connection started...\n");
889 ci = MHD_get_connection_info (connection,
890 MHD_CONNECTION_INFO_CONNECTION_FD);
891 if (NULL == ci)
892 {
893 GNUNET_break (0);
894 return;
895 }
896 sock = ci->connect_fd;
897 for (ar = req_list_head; NULL != ar; ar = ar->next)
898 {
899 if (GNUNET_NETWORK_get_fd (ar->sock) == sock)
900 {
902 "Context set...\n");
903 *con_cls = ar;
904 break;
905 }
906 }
907 break;
908
909 case MHD_CONNECTION_NOTIFY_CLOSED:
911 "Connection closed... cleaning up\n");
912 ar = *con_cls;
913 if (NULL == ar)
914 {
916 "Connection stale!\n");
917 return;
918 }
919 cleanup_ar (ar);
920 *con_cls = NULL;
921 break;
922
923 default:
924 GNUNET_break (0);
925 }
926}
927
928
934static void
935do_httpd (void *cls)
936{
937 httpd_task = NULL;
938 MHD_run (httpd);
940}
941
942
948static void
949do_accept (void *cls)
950{
951 struct GNUNET_NETWORK_Handle *lsock = cls;
952 struct AcceptedRequest *ar;
953 int fd;
954 const struct sockaddr *addr;
955 socklen_t len;
956
957 GNUNET_assert (NULL != lsock);
958 if (lsock == lsock4)
959 {
961 lsock,
962 &do_accept,
963 lsock);
964 }
965 else if (lsock == lsock6)
966 {
968 lsock,
969 &do_accept,
970 lsock);
971 }
972 else
973 GNUNET_assert (0);
974 ar = GNUNET_new (struct AcceptedRequest);
976 ar->sock = GNUNET_NETWORK_socket_accept (lsock, NULL, NULL);
977 if (NULL == ar->sock)
978 {
979 GNUNET_free (ar);
981 return;
982 }
984 "Got an inbound connection, waiting for data\n");
985 fd = GNUNET_NETWORK_get_fd (ar->sock);
986 addr = GNUNET_NETWORK_get_addr (ar->sock);
990 ar);
991 if (MHD_YES != MHD_add_connection (httpd, fd, addr, len))
992 {
994 GNUNET_free (ar);
996 _ ("Failed to pass client to MHD\n"));
997 return;
998 }
1000}
1001
1002
1008static void
1009do_shutdown (void *cls)
1010{
1011 struct PluginListEntry *ple;
1012
1013 while (NULL != plugins_head)
1014 {
1015 ple = plugins_head;
1018 ple);
1019 GNUNET_free (ple->libname);
1020 GNUNET_free (ple);
1021 }
1027#if HAVE_JOSE
1028 REST_openid_done (openid_plugin);
1029#endif
1031 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Shutting down...\n");
1032 kill_httpd ();
1035 MHD_destroy_response (failure_response);
1036}
1037
1038
1044static struct GNUNET_NETWORK_Handle *
1045bind_v4 ()
1046{
1047 struct GNUNET_NETWORK_Handle *ls;
1048 struct sockaddr_in sa4;
1049 int eno;
1050
1051 memset (&sa4, 0, sizeof(sa4));
1052 sa4.sin_family = AF_INET;
1053 sa4.sin_port = htons (port);
1054 sa4.sin_addr.s_addr = address;
1055#if HAVE_SOCKADDR_IN_SIN_LEN
1056 sa4.sin_len = sizeof(sa4);
1057#endif
1058 ls = GNUNET_NETWORK_socket_create (AF_INET, SOCK_STREAM, 0);
1059 if (NULL == ls)
1060 return NULL;
1062 (const struct sockaddr *) &sa4,
1063 sizeof(sa4)))
1064 {
1065 eno = errno;
1067 errno = eno;
1068 return NULL;
1069 }
1070 return ls;
1071}
1072
1073
1079static struct GNUNET_NETWORK_Handle *
1080bind_v6 ()
1081{
1082 struct GNUNET_NETWORK_Handle *ls;
1083 struct sockaddr_in6 sa6;
1084 int eno;
1085
1086 memset (&sa6, 0, sizeof(sa6));
1087 sa6.sin6_family = AF_INET6;
1088 sa6.sin6_port = htons (port);
1089 sa6.sin6_addr = address6;
1090#if HAVE_SOCKADDR_IN_SIN_LEN
1091 sa6.sin6_len = sizeof(sa6);
1092#endif
1093 ls = GNUNET_NETWORK_socket_create (AF_INET6, SOCK_STREAM, 0);
1094 if (NULL == ls)
1095 return NULL;
1097 (const struct sockaddr *) &sa6,
1098 sizeof(sa6)))
1099 {
1100 eno = errno;
1102 errno = eno;
1103 return NULL;
1104 }
1105 return ls;
1106}
1107
1108
1116static enum GNUNET_GenericReturnValue
1117setup_plugin (const char *name,
1119 void *plugin_cls)
1120{
1121 struct PluginListEntry *ple;
1122
1123 if (NULL == plugin_cls)
1124 {
1126 "Could not load plugin\n");
1127 return GNUNET_SYSERR;
1128 }
1129 GNUNET_assert (1 < strlen (name));
1130 GNUNET_assert ('/' == *name);
1131 ple = GNUNET_new (struct PluginListEntry);
1132 ple->libname = GNUNET_strdup (name);
1133 ple->plugin = plugin_cls;
1134 ple->process_request = proc;
1137 ple);
1138 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Loaded plugin `%s'\n", name);
1139 return GNUNET_OK;
1140}
1141
1142
1151static void
1152run (void *cls,
1153 char *const *args,
1154 const char *cfgfile,
1155 const struct GNUNET_CONFIGURATION_Handle *c)
1156{
1157 static const char *err_page = "{}";
1158 char *addr_str;
1159 char *basic_auth_file;
1160 uint64_t secret;
1161
1162 cfg = c;
1163 plugins_head = NULL;
1164 plugins_tail = NULL;
1165 failure_response = MHD_create_response_from_buffer (strlen (err_page),
1166 (void *) err_page,
1167 MHD_RESPMEM_PERSISTENT);
1168 /* Get port to bind to */
1169 if (GNUNET_OK !=
1170 GNUNET_CONFIGURATION_get_value_number (cfg, "rest", "HTTP_PORT", &port))
1171 {
1172 // No address specified
1173 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Using default port...\n");
1175 }
1176
1177 /* Get address to bind to */
1178 if (GNUNET_OK !=
1179 GNUNET_CONFIGURATION_get_value_string (cfg, "rest", "BIND_TO", &addr_str))
1180 {
1181 // No address specified
1182 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Don't know what to bind to...\n");
1184 return;
1185 }
1186 if (1 != inet_pton (AF_INET, addr_str, &address))
1187 {
1189 "Unable to parse address %s\n",
1190 addr_str);
1191 GNUNET_free (addr_str);
1193 return;
1194 }
1195 GNUNET_free (addr_str);
1196 /* Get address to bind to */
1198 "rest",
1199 "BIND_TO6",
1200 &addr_str))
1201 {
1202 // No address specified
1203 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Don't know what to bind6 to...\n");
1205 return;
1206 }
1207 if (1 != inet_pton (AF_INET6, addr_str, &address6))
1208 {
1210 "Unable to parse IPv6 address %s\n",
1211 addr_str);
1212 GNUNET_free (addr_str);
1214 return;
1215 }
1216 GNUNET_free (addr_str);
1217
1219 "rest",
1220 "BASIC_AUTH_ENABLED");
1222 {
1224 "rest",
1225 "BASIC_AUTH_SECRET_FILE",
1226 &basic_auth_file))
1227 {
1229 "No basic auth secret file location set...\n");
1231 return;
1232 }
1233 if (GNUNET_YES != GNUNET_DISK_file_test (basic_auth_file))
1234 {
1236 "No basic auth secret found... generating\n");
1238 UINT64_MAX);
1240 sizeof(secret));
1241 if (GNUNET_OK !=
1242 GNUNET_DISK_fn_write (basic_auth_file,
1244 strlen (basic_auth_secret),
1248 "write",
1249 basic_auth_file);
1250 GNUNET_free (basic_auth_file);
1251 }
1252 else
1253 {
1254 char basic_auth_secret_tmp[16]; // Should be more than enough
1255 memset (basic_auth_secret_tmp, 0, 16);
1256 if (GNUNET_SYSERR == GNUNET_DISK_fn_read (basic_auth_file,
1257 basic_auth_secret_tmp,
1258 sizeof (basic_auth_secret_tmp)
1259 - 1))
1260 {
1262 "Unable to read basic auth secret file.\n");
1264 GNUNET_free (basic_auth_file);
1265 return;
1266 }
1267 GNUNET_free (basic_auth_file);
1268 if (0 != getlogin_r (cuser, _POSIX_LOGIN_NAME_MAX))
1269 {
1271 "Unable to get user.\n");
1273 return;
1274 }
1275 basic_auth_secret = GNUNET_strdup (basic_auth_secret_tmp);
1276 }
1277 }
1278
1279 /* Get CORS data from cfg */
1280 echo_origin =
1282 "rest",
1283 "REST_ECHO_ORIGIN_WEBEXT");
1284 allow_origins = NULL;
1286 "rest",
1287 "REST_ALLOW_ORIGIN",
1288 &allow_origins))
1289 {
1291 "No CORS Access-Control-Allow-Origin header will be sent...\n");
1292 }
1293 if (GNUNET_OK !=
1295 "rest",
1296 "REST_ALLOW_CREDENTIALS",
1298 {
1299 // No origin specified
1301 "No CORS Credential Header will be sent...\n");
1302 }
1303
1305 "rest",
1306 "REST_ALLOW_HEADERS",
1307 &allow_headers))
1308 {
1309 // No origin specified
1311 "No CORS Access-Control-Allow-Headers Header will be sent...\n")
1312 ;
1313 }
1314
1315/* Open listen socket proxy */
1316 lsock6 = bind_v6 ();
1317 if (NULL == lsock6)
1318 {
1320 }
1321 else
1322 {
1324 {
1327 lsock6 = NULL;
1328 }
1329 else
1330 {
1332 lsock6,
1333 &do_accept,
1334 lsock6);
1335 }
1336 }
1337 lsock4 = bind_v4 ();
1338 if (NULL == lsock4)
1339 {
1341 }
1342 else
1343 {
1345 {
1348 lsock4 = NULL;
1349 }
1350 else
1351 {
1353 lsock4,
1354 &do_accept,
1355 lsock4);
1356 }
1357 }
1358 if ((NULL == lsock4) && (NULL == lsock6))
1359 {
1361 return;
1362 }
1363 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Service listens on port %llu\n",
1364 port);
1365 httpd = MHD_start_daemon (MHD_USE_DEBUG | MHD_USE_NO_LISTEN_SOCKET
1366 | MHD_ALLOW_SUSPEND_RESUME,
1367 0,
1368 NULL,
1369 NULL,
1371 NULL,
1372 MHD_OPTION_CONNECTION_TIMEOUT,
1373 (unsigned int) 16,
1374 MHD_OPTION_NOTIFY_CONNECTION,
1376 NULL,
1377 MHD_OPTION_URI_LOG_CALLBACK,
1379 NULL,
1380 MHD_OPTION_NOTIFY_COMPLETED,
1382 NULL,
1383 MHD_OPTION_END);
1384 if (NULL == httpd)
1385 {
1387 return;
1388 }
1389 /* Load plugins */
1390 // FIXME: Use per-plugin rest plugin structs
1394 {
1396 }
1400 {
1402 }
1407 {
1409 }
1414 {
1416 }
1419 gns_plugin))
1420 {
1422 }
1423#if HAVE_JOSE
1424 openid_plugin = REST_openid_init (cfg);
1425 if (GNUNET_OK != setup_plugin (openid_plugin->name,
1426 &REST_openid_process_request, openid_plugin))
1427 {
1429 }
1430#endif
1434 {
1436 }
1438}
1439
1440
1441GNUNET_DAEMON_MAIN ("rest", _ ("GNUnet REST service"), &run)
1442
1443/* end of gnunet-rest-server.c */
void * REST_config_init(const struct GNUNET_CONFIGURATION_Handle *c)
Entry point for the plugin.
enum GNUNET_GenericReturnValue REST_config_process_request(void *plugin, struct GNUNET_REST_RequestHandle *conndata_handle, GNUNET_REST_ResultProcessor proc, void *proc_cls)
Function processing the REST call.
void REST_config_done(struct GNUNET_REST_Plugin *api)
Exit point from the plugin.
enum GNUNET_GenericReturnValue REST_copying_process_request(void *plugin, struct GNUNET_REST_RequestHandle *conndata_handle, GNUNET_REST_ResultProcessor proc, void *proc_cls)
Function processing the REST call.
void REST_copying_done(struct GNUNET_REST_Plugin *api)
Exit point from the plugin.
void * REST_copying_init(const struct GNUNET_CONFIGURATION_Handle *c)
Entry point for the plugin.
void * REST_gns_init(const struct GNUNET_CONFIGURATION_Handle *c)
Entry point for the plugin.
Definition gns_plugin.c:431
void REST_gns_done(struct GNUNET_REST_Plugin *api)
Exit point from the plugin.
Definition gns_plugin.c:463
enum GNUNET_GenericReturnValue REST_gns_process_request(void *plugin, struct GNUNET_REST_RequestHandle *rest_handle, GNUNET_REST_ResultProcessor proc, void *proc_cls)
Function processing the REST call.
Definition gns_plugin.c:386
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 int do_shutdown
Set to GNUNET_YES if we are shutting down.
static struct GNUNET_TESTING_PluginFunctions * plugin
Plugin to dynamically load a test case.
static char * data
The data to insert into the dht.
struct GNUNET_HashCode key
The key used in the DHT.
static char * filename
static char * name
Name (label) of the records to list.
static char origin[GNUNET_DNSPARSER_MAX_NAME_LENGTH]
Current origin.
static char * value
Value of the record to add/remove.
static struct GNUNET_NETWORK_Handle * ls
Listen socket for STUN processing.
Definition gnunet-nat.c:85
static int status
The program status; 0 for success.
Definition gnunet-nse.c:39
static char * allow_origins
Allowed Origins (CORS)
static void plugin_callback(void *cls, struct MHD_Response *resp, int status)
Plugin result callback.
#define GNUNET_REST_SERVICE_PORT
Default Socks5 listen port.
static struct AcceptedRequest * req_list_head
AcceptedRequest list head.
static int basic_auth_enabled
Do basic auth of user.
static struct GNUNET_NETWORK_Handle * bind_v4()
Create an IPv4 listen socket bound to our port.
static void run_mhd_now()
Run MHD now, we have extra data ready for the callback.
static struct MHD_Daemon * httpd
Daemon for HTTP.
char cuser[_POSIX_LOGIN_NAME_MAX]
User of the service.
static MHD_RESULT post_data_iter(void *cls, enum MHD_ValueKind kind, const char *key, const char *filename, const char *content_type, const char *transfer_encoding, const char *data, uint64_t off, size_t size)
static struct GNUNET_NETWORK_Handle * bind_v6()
Create an IPv6 listen socket bound to our port.
static struct GNUNET_NETWORK_Handle * lsock6
The listen socket of the service for IPv6.
#define GN_REST_STATE_INIT
static const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
static char * allow_headers
Allowed Headers (CORS)
static char * basic_auth_secret
Basic auth secret.
static MHD_RESULT create_response(void *cls, struct MHD_Connection *con, const char *url, const char *meth, const char *ver, const char *upload_data, size_t *upload_data_size, void **con_cls)
Main MHD callback for handling requests.
static struct GNUNET_NETWORK_Handle * lsock4
The listen socket of the service for IPv4.
static void kill_httpd()
Kill the MHD daemon.
static struct in6_addr address6
The IPv6 address to bind to.
static unsigned long long port
The port the service is running on (default 7776)
struct GNUNET_REST_Plugin * copying_plugin
#define GN_REST_STATE_PROCESSING
static void cleanup_ar(struct AcceptedRequest *ar)
static void * mhd_log_callback(void *cls, const char *url, struct MHD_Connection *connection)
Function called when MHD first processes an incoming connection.
static void mhd_completed_cb(void *cls, struct MHD_Connection *connection, void **con_cls, enum MHD_RequestTerminationCode toe)
Function called when MHD decides that we are done with a connection.
static int url_iterator(void *cls, enum MHD_ValueKind kind, const char *key, const char *value)
static int cleanup_url_map(void *cls, const struct GNUNET_HashCode *key, void *value)
static void run(void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *c)
Main function that will be run.
static void do_httpd(void *cls)
Task run whenever HTTP server operations are pending.
struct GNUNET_REST_Plugin * reclaim_plugin
static enum GNUNET_GenericReturnValue setup_plugin(const char *name, GNUNET_REST_ProcessingFunction proc, void *plugin_cls)
Callback for plugin load.
struct GNUNET_REST_Plugin * namestore_plugin
static void do_accept(void *cls)
Accept new incoming connections.
static int header_iterator(void *cls, enum MHD_ValueKind kind, const char *key, const char *value)
static struct PluginListEntry * plugins_tail
Plugin list tail.
static struct GNUNET_SCHEDULER_Task * httpd_task
The task ID.
static int echo_origin
Echo request Origin in CORS.
struct GNUNET_REST_Plugin * gns_plugin
static struct AcceptedRequest * req_list_tail
AcceptedRequest list tail.
static char * allow_credentials
Allowed Credentials (CORS)
struct GNUNET_REST_Plugin * config_plugin
plugins
static void schedule_httpd()
Schedule MHD.
static struct MHD_Response * failure_response
Response we return on failures.
struct GNUNET_REST_Plugin * identity_plugin
static in_addr_t address
The address to bind to.
static void mhd_connection_cb(void *cls, struct MHD_Connection *connection, void **con_cls, enum MHD_ConnectionNotificationCode cnc)
Function called when MHD connection is opened or closed.
static struct PluginListEntry * plugins_head
Plugin list head.
static void cleanup_handle(struct MhdConnectionHandle *handle)
static struct GNUNET_SCHEDULER_Task * ltask6
The listen task ID for IPv6.
static struct GNUNET_SCHEDULER_Task * ltask4
The listen task ID for IPv4.
static struct GNUNET_VPN_Handle * handle
Handle to vpn service.
Definition gnunet-vpn.c:35
#define MHD_RESULT
Data type to use for functions return an "MHD result".
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_filename(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be the name of a file or directory.
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_yesno(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option)
Get a configuration value that should be in a set of "YES" or "NO".
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.
uint64_t GNUNET_CRYPTO_random_u64(enum GNUNET_CRYPTO_Quality mode, uint64_t max)
Generate a random unsigned 64-bit value.
@ GNUNET_CRYPTO_QUALITY_WEAK
No good quality of the operation is needed (i.e., random numbers can be pseudo-random).
enum GNUNET_GenericReturnValue GNUNET_DISK_file_test(const char *fil)
Check that fil corresponds to a filename (of a file that exists and that is not a directory).
Definition disk.c:533
enum GNUNET_GenericReturnValue GNUNET_DISK_fn_write(const char *fn, const void *buf, size_t buf_size, enum GNUNET_DISK_AccessPermissions mode)
Write a buffer to a file atomically.
Definition disk.c:750
ssize_t GNUNET_DISK_fn_read(const char *fn, void *result, size_t len)
Read the contents of a binary file into a buffer.
Definition disk.c:687
@ GNUNET_DISK_PERM_USER_READ
Owner can read.
@ GNUNET_DISK_PERM_USER_WRITE
Owner can write.
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition crypto_hash.c:41
int GNUNET_CONTAINER_multihashmap_iterate(struct GNUNET_CONTAINER_MultiHashMap *map, GNUNET_CONTAINER_MultiHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map.
void * GNUNET_CONTAINER_multihashmap_get(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Given a key find a value in the map matching the key.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap_put(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash 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...
#define GNUNET_log(kind,...)
GNUNET_GenericReturnValue
Named constants for return values.
@ GNUNET_SCHEDULER_PRIORITY_DEFAULT
Run with the default priority (normal P2P operations).
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
#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.
#define GNUNET_log_strerror(level, cmd)
Log an error message at log-level 'level' that indicates a failure of the command 'cmd' with the mess...
#define GNUNET_log_strerror_file(level, cmd, filename)
Log an error message at log-level 'level' that indicates a failure of the command 'cmd' with the mess...
@ 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_strdup(a)
Wrapper around GNUNET_xstrdup_.
#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.
struct sockaddr * GNUNET_NETWORK_get_addr(const struct GNUNET_NETWORK_Handle *desc)
Return the sockaddr for this network handle.
Definition network.c:1014
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_accept(const struct GNUNET_NETWORK_Handle *desc, struct sockaddr *address, socklen_t *address_len)
Accept a new connection on a socket.
Definition network.c:392
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_close(struct GNUNET_NETWORK_Handle *desc)
Close a socket.
Definition network.c:508
void GNUNET_NETWORK_fdset_destroy(struct GNUNET_NETWORK_FDSet *fds)
Releases the associated memory of an fd set.
Definition network.c:1185
socklen_t GNUNET_NETWORK_get_addrlen(const struct GNUNET_NETWORK_Handle *desc)
Return sockaddr length for this network handle.
Definition network.c:1027
int GNUNET_NETWORK_get_fd(const struct GNUNET_NETWORK_Handle *desc)
Return file descriptor for this network handle.
Definition network.c:1001
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
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_create(int domain, int type, int protocol)
Create a new socket.
Definition network.c:833
void GNUNET_NETWORK_socket_free_memory_only_(struct GNUNET_NETWORK_Handle *desc)
Only free memory of a socket, keep the file descriptor untouched.
Definition network.c:566
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_bind(struct GNUNET_NETWORK_Handle *desc, const struct sockaddr *address, socklen_t address_len)
Bind a socket to a particular address.
Definition network.c:439
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_listen(const struct GNUNET_NETWORK_Handle *desc, int backlog)
Listen on a socket.
Definition network.c:652
#define GNUNET_DAEMON_MAIN(daemon_name, daemon_help, init_cb)
enum GNUNET_GenericReturnValue(* GNUNET_REST_ProcessingFunction)(void *plugin, struct GNUNET_REST_RequestHandle *handle, GNUNET_REST_ResultProcessor proc, void *proc_cls)
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition scheduler.c:567
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_read_net(struct GNUNET_TIME_Relative delay, struct GNUNET_NETWORK_Handle *rfd, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay or when the specified file descriptor is ready f...
Definition scheduler.c:1511
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
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_shutdown(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run on shutdown, that is when a CTRL-C signal is received,...
Definition scheduler.c:1339
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_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition scheduler.c:1304
char * GNUNET_STRINGS_data_to_string_alloc(const void *buf, size_t size)
Return the base32crockford encoding of the given buffer.
Definition strings.c:812
char * GNUNET_STRINGS_utf8_tolower(const char *input)
Convert the utf-8 input string to lower case.
Definition strings.c:475
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
void REST_identity_done(struct GNUNET_REST_Plugin *api)
Exit point from the plugin.
void * REST_identity_init(const struct GNUNET_CONFIGURATION_Handle *c)
Entry point for the plugin.
enum GNUNET_GenericReturnValue REST_identity_process_request(void *plugin, struct GNUNET_REST_RequestHandle *rest_handle, GNUNET_REST_ResultProcessor proc, void *proc_cls)
Function processing the REST call.
#define max(x, y)
void REST_namestore_done(struct GNUNET_REST_Plugin *api)
Exit point from the plugin.
void * REST_namestore_init(const struct GNUNET_CONFIGURATION_Handle *c)
Entry point for the plugin.
enum GNUNET_GenericReturnValue REST_namestore_process_request(void *plugin, struct GNUNET_REST_RequestHandle *rest_handle, GNUNET_REST_ResultProcessor proc, void *proc_cls)
Function processing the REST call.
void REST_openid_done(struct GNUNET_REST_Plugin *api)
Exit point from the plugin.
enum GNUNET_GenericReturnValue REST_openid_process_request(void *plugin, struct GNUNET_REST_RequestHandle *rest_handle, GNUNET_REST_ResultProcessor proc, void *proc_cls)
Function processing the REST call.
void * REST_openid_init(const struct GNUNET_CONFIGURATION_Handle *c)
Entry point for the plugin.
static unsigned int size
Size of the "table".
Definition peer.c:68
#define _(String)
GNU gettext support macro.
Definition platform.h:179
void * REST_reclaim_init(const struct GNUNET_CONFIGURATION_Handle *c)
Entry point for the plugin.
void REST_reclaim_done(struct GNUNET_REST_Plugin *api)
Exit point from the plugin.
enum GNUNET_GenericReturnValue REST_reclaim_process_request(void *plugin, struct GNUNET_REST_RequestHandle *rest_handle, GNUNET_REST_ResultProcessor proc, void *proc_cls)
Function processing the REST call.
Accepted requests.
struct AcceptedRequest * prev
DLL.
struct MhdConnectionHandle * con_handle
Connection.
struct GNUNET_NETWORK_Handle * sock
Socket.
struct AcceptedRequest * next
DLL.
A 512-bit hashcode.
collection of IO descriptors
handle to a socket
Definition network.c:53
struct returned by the initialization function of the plugin
void * cls
The closure of the plugin.
const char * name
Plugin name.
struct GNUNET_CONTAINER_MultiHashMap * header_param_map
Map of headers.
const char * data
The POST data.
const char * url
The url as string.
const char * method
The HTTP method as MHD value (see microhttpd.h)
struct GNUNET_CONTAINER_MultiHashMap * url_param_map
Map of url parameters.
size_t data_size
The POST data size.
Time for relative time used by GNUnet, in microseconds.
MHD Connection handle.
struct GNUNET_REST_RequestHandle * data_handle
struct MHD_PostProcessor * pp
struct MHD_Response * response
struct MHD_Connection * con
A plugin list entry.
struct PluginListEntry * prev
char * libname
libname (to cleanup)
GNUNET_REST_ProcessingFunction process_request
Request function.
struct PluginListEntry * next
void * plugin
The plugin.

◆ GN_REST_STATE_INIT

#define GN_REST_STATE_INIT   0

Definition at line 69 of file gnunet-rest-server.c.

◆ GN_REST_STATE_PROCESSING

#define GN_REST_STATE_PROCESSING   1

Definition at line 70 of file gnunet-rest-server.c.

Function Documentation

◆ do_httpd()

static void do_httpd ( void *  cls)
static

Task run whenever HTTP server operations are pending.

Parameters
clsNULL

Definition at line 936 of file gnunet-rest-server.c.

937{
938 httpd_task = NULL;
939 MHD_run (httpd);
941}

References httpd, httpd_task, and schedule_httpd().

Referenced by run_mhd_now(), and schedule_httpd().

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

◆ run_mhd_now()

static void run_mhd_now ( )
static

Run MHD now, we have extra data ready for the callback.

Definition at line 289 of file gnunet-rest-server.c.

290{
291 if (NULL != httpd_task)
292 {
294 httpd_task = NULL;
295 }
297}

References do_httpd(), GNUNET_SCHEDULER_add_now(), GNUNET_SCHEDULER_cancel(), and httpd_task.

Referenced by create_response(), create_response(), curl_download_cb(), curl_task_download(), curl_upload_cb(), and plugin_callback().

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

◆ plugin_callback()

static void plugin_callback ( void *  cls,
struct MHD_Response *  resp,
int  status 
)
static

Plugin result callback.

Parameters
clsclosure (MHD connection handle)
datathe data to return to the caller
lenlength of the data
statusGNUNET_OK if successful

Definition at line 309 of file gnunet-rest-server.c.

310{
311 struct MhdConnectionHandle *handle = cls;
312
313 handle->status = status;
314 handle->response = resp;
315 MHD_resume_connection (handle->con);
316 run_mhd_now ();
317}

References handle, run_mhd_now(), and status.

Referenced by create_response().

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

◆ cleanup_url_map()

static int cleanup_url_map ( void *  cls,
const struct GNUNET_HashCode key,
void *  value 
)
static

Definition at line 321 of file gnunet-rest-server.c.

322{
324 return GNUNET_YES;
325}

References GNUNET_free, GNUNET_YES, and value.

Referenced by cleanup_handle().

Here is the caller graph for this function:

◆ cleanup_handle()

static void cleanup_handle ( struct MhdConnectionHandle handle)
static

Definition at line 329 of file gnunet-rest-server.c.

330{
331 if (NULL != handle->response)
332 MHD_destroy_response (handle->response);
333 if (NULL != handle->data_handle)
334 {
335 if (NULL != handle->data_handle->header_param_map)
336 {
338 ->header_param_map,
340 NULL);
342 handle->data_handle->header_param_map);
343 }
344 if (NULL != handle->data_handle->url_param_map)
345 {
346 GNUNET_CONTAINER_multihashmap_iterate (handle->data_handle->url_param_map,
348 NULL);
350 handle->data_handle->url_param_map);
351 }
352 GNUNET_free (handle->data_handle);
353 }
355}

References cleanup_url_map(), GNUNET_CONTAINER_multihashmap_destroy(), GNUNET_CONTAINER_multihashmap_iterate(), GNUNET_free, and handle.

Referenced by cleanup_ar(), and mhd_completed_cb().

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

◆ cleanup_ar()

static void cleanup_ar ( struct AcceptedRequest ar)
static

Definition at line 359 of file gnunet-rest-server.c.

360{
361 if (NULL != ar->con_handle)
362 {
364 }
365 if (GNUNET_YES == ar->socket_with_mhd)
366 {
368 }
369 else
370 {
372 }
373 ar->sock = NULL;
376 ar);
377 GNUNET_free (ar);
378}

References cleanup_handle(), AcceptedRequest::con_handle, GNUNET_CONTAINER_DLL_remove, GNUNET_free, GNUNET_NETWORK_socket_close(), GNUNET_NETWORK_socket_free_memory_only_(), GNUNET_YES, req_list_head, req_list_tail, AcceptedRequest::sock, and AcceptedRequest::socket_with_mhd.

Referenced by mhd_connection_cb().

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

◆ header_iterator()

static int header_iterator ( void *  cls,
enum MHD_ValueKind  kind,
const char *  key,
const char *  value 
)
static

Definition at line 382 of file gnunet-rest-server.c.

386{
387 struct GNUNET_REST_RequestHandle *handle = cls;
388 struct GNUNET_HashCode hkey;
389 char *val;
390 char *lowerkey;
391
392 lowerkey = GNUNET_STRINGS_utf8_tolower (key);
393 GNUNET_CRYPTO_hash (lowerkey,
394 strlen (lowerkey),
395 &hkey);
396 GNUNET_asprintf (&val,
397 "%s",
398 value);
399 if (GNUNET_OK !=
401 handle->header_param_map,
402 &hkey,
403 val,
405 {
407 "Could not load add header `%s'=%s\n",
408 lowerkey,
409 value);
410 }
411 GNUNET_free (lowerkey);
412 return MHD_YES;
413}

References GNUNET_asprintf(), GNUNET_CONTAINER_multihashmap_put(), GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY, GNUNET_CRYPTO_hash(), GNUNET_ERROR_TYPE_ERROR, GNUNET_free, GNUNET_log, GNUNET_OK, GNUNET_STRINGS_utf8_tolower(), handle, key, and value.

Referenced by create_response().

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

◆ url_iterator()

static int url_iterator ( void *  cls,
enum MHD_ValueKind  kind,
const char *  key,
const char *  value 
)
static

Definition at line 417 of file gnunet-rest-server.c.

421{
422 struct GNUNET_REST_RequestHandle *handle = cls;
423 struct GNUNET_HashCode hkey;
424 char *val;
425
426 GNUNET_CRYPTO_hash (key, strlen (key), &hkey);
427 GNUNET_asprintf (&val, "%s", value);
429 handle->url_param_map,
430 &hkey,
431 val,
433 {
435 "Could not load add url param `%s'=%s\n",
436 key,
437 value);
438 }
439 return MHD_YES;
440}

References GNUNET_asprintf(), GNUNET_CONTAINER_multihashmap_put(), GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY, GNUNET_CRYPTO_hash(), GNUNET_ERROR_TYPE_ERROR, GNUNET_log, GNUNET_OK, handle, key, and value.

Referenced by create_response().

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

◆ post_data_iter()

static MHD_RESULT post_data_iter ( void *  cls,
enum MHD_ValueKind  kind,
const char *  key,
const char *  filename,
const char *  content_type,
const char *  transfer_encoding,
const char *  data,
uint64_t  off,
size_t  size 
)
static

Definition at line 444 of file gnunet-rest-server.c.

453{
454 struct GNUNET_REST_RequestHandle *handle = cls;
455 struct GNUNET_HashCode hkey;
456 char *val;
457
458 if (MHD_POSTDATA_KIND != kind)
459 return MHD_YES;
460
461 GNUNET_CRYPTO_hash (key, strlen (key), &hkey);
462 val = GNUNET_CONTAINER_multihashmap_get (handle->url_param_map,
463 &hkey);
464 if (NULL == val)
465 {
466 val = GNUNET_malloc (65536);
468 handle->url_param_map,
469 &hkey,
470 val,
472 {
474 "Could not add url param '%s'\n",
475 key);
476 GNUNET_free (val);
477 }
478 }
479 memcpy (val + off, data, size);
480 return MHD_YES;
481}

References data, GNUNET_CONTAINER_multihashmap_get(), GNUNET_CONTAINER_multihashmap_put(), GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY, GNUNET_CRYPTO_hash(), GNUNET_ERROR_TYPE_ERROR, GNUNET_free, GNUNET_log, GNUNET_malloc, GNUNET_OK, handle, key, and size.

Referenced by create_response().

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

◆ create_response()

static MHD_RESULT create_response ( void *  cls,
struct MHD_Connection *  con,
const char *  url,
const char *  meth,
const char *  ver,
const char *  upload_data,
size_t *  upload_data_size,
void **  con_cls 
)
static

Main MHD callback for handling requests.

Parameters
clsunused
conMHD connection handle
urlthe url in the request
meththe HTTP method used ("GET", "PUT", etc.)
verthe HTTP version string ("HTTP/1.1" for version 1.1, etc.)
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 to location where we store the 'struct Request'
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

Request not handled

Definition at line 510 of file gnunet-rest-server.c.

518{
519 char *origin;
520 char *pw;
521 char *user;
522 struct AcceptedRequest *ar;
523 struct GNUNET_HashCode key;
524 struct MhdConnectionHandle *con_handle;
525 struct GNUNET_REST_RequestHandle *rest_conndata_handle;
526 struct PluginListEntry *ple;
527
528 ar = *con_cls;
529 if (NULL == ar)
530 {
531 GNUNET_break (0);
532 return MHD_NO;
533 }
534
535 if (NULL == ar->con_handle)
536 {
537 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "New connection %s\n", url);
538 con_handle = GNUNET_new (struct MhdConnectionHandle);
539 con_handle->con = con;
540 con_handle->state = GN_REST_STATE_INIT;
541 ar->con_handle = con_handle;
542 return MHD_YES;
543 }
544 con_handle = ar->con_handle;
545 if (GN_REST_STATE_INIT == con_handle->state)
546 {
547 rest_conndata_handle = GNUNET_new (struct GNUNET_REST_RequestHandle);
548 rest_conndata_handle->method = meth;
549 rest_conndata_handle->url = url;
550 rest_conndata_handle->data = upload_data;
551 rest_conndata_handle->data_size = *upload_data_size;
552 rest_conndata_handle->url_param_map =
554 rest_conndata_handle->header_param_map =
556 con_handle->data_handle = rest_conndata_handle;
557 MHD_get_connection_values (con,
558 MHD_GET_ARGUMENT_KIND,
559 (MHD_KeyValueIterator) & url_iterator,
560 rest_conndata_handle);
561 MHD_get_connection_values (con,
562 MHD_HEADER_KIND,
563 (MHD_KeyValueIterator) & header_iterator,
564 rest_conndata_handle);
566 {
567 pw = NULL;
568 user = MHD_basic_auth_get_username_password (con, &pw);
569 if ((NULL == user) ||
570 (0 != strcmp (user, cuser)))
571 {
573 "Unknown user %s\n", user);
574 MHD_queue_basic_auth_fail_response (con, "gnunet", failure_response);
575 return MHD_YES;
576 }
577 if ((NULL == pw) ||
578 (0 != strcmp (pw, basic_auth_secret)))
579 {
581 "Password incorrect\n");
582 MHD_queue_basic_auth_fail_response (con, "gnunet", failure_response);
583 GNUNET_free (pw);
584 return MHD_YES;
585 }
586 GNUNET_free (pw);
587 }
588
589 con_handle->pp = MHD_create_post_processor (con,
590 65536,
592 rest_conndata_handle);
593 if (*upload_data_size)
594 {
595 MHD_post_process (con_handle->pp, upload_data, *upload_data_size);
596 }
597 MHD_destroy_post_processor (con_handle->pp);
598
599 con_handle->state = GN_REST_STATE_PROCESSING;
600 for (ple = plugins_head; NULL != ple; ple = ple->next)
601 {
602 if (GNUNET_YES == ple->process_request (ple->plugin,
603 rest_conndata_handle,
605 con_handle))
606 break; /* Request handled */
607 }
608 if (NULL == ple)
609 {
611 MHD_queue_response (con, MHD_HTTP_NOT_FOUND, failure_response);
612 }
613 *upload_data_size = 0;
614 run_mhd_now ();
615 return MHD_YES;
616 }
617 if (NULL == con_handle->response)
618 {
619 // Suspend connection until plugin is done
620 MHD_suspend_connection (con_handle->con);
621 return MHD_YES;
622 }
623 // MHD_resume_connection (con_handle->con);
625 "Queueing response from plugin with MHD\n");
626 // Handle Preflights for extensions
627 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Checking origin\n");
628 GNUNET_CRYPTO_hash ("origin", strlen ("origin"), &key);
631 &key);
632 if (NULL != origin)
633 {
634 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Origin: %s\n", origin);
635 // Only echo for browser plugins
636 if (GNUNET_YES == echo_origin)
637 {
638 if ((0 ==
639 strncmp ("moz-extension://", origin, strlen ("moz-extension://"))) ||
640 (0 == strncmp ("chrome-extension://",
641 origin,
642 strlen ("chrome-extension://"))))
643 {
644 GNUNET_assert (MHD_NO != MHD_add_response_header (con_handle->response,
645 MHD_HTTP_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN,
646 origin));
647 }
648 }
649 if (NULL != allow_origins)
650 {
651 char *tmp = GNUNET_strdup (allow_origins);
652 char *allow_origin = strtok (tmp, ",");
653 while (NULL != allow_origin)
654 {
655 if (0 == strncmp (allow_origin, origin, strlen (allow_origin)))
656 {
657 GNUNET_assert (MHD_NO != MHD_add_response_header (
658 con_handle->response,
659 MHD_HTTP_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN,
660 allow_origin));
661 break;
662 }
663 allow_origin = strtok (NULL, ",");
664 }
665 GNUNET_free (tmp);
666 }
667 }
668 if (NULL != allow_credentials)
669 {
670 GNUNET_assert (MHD_NO != MHD_add_response_header (con_handle->response,
671 "Access-Control-Allow-Credentials",
673 }
674 if (NULL != allow_headers)
675 {
676 GNUNET_assert (MHD_NO != MHD_add_response_header (con_handle->response,
677 "Access-Control-Allow-Headers",
679 }
680 run_mhd_now ();
681 {
682 MHD_RESULT ret = MHD_queue_response (con,
683 con_handle->status,
684 con_handle->response);
685 // cleanup_handle (con_handle);
686 return ret;
687 }
688}

References allow_credentials, allow_headers, allow_origins, basic_auth_enabled, basic_auth_secret, MhdConnectionHandle::con, AcceptedRequest::con_handle, cuser, GNUNET_REST_RequestHandle::data, MhdConnectionHandle::data_handle, GNUNET_REST_RequestHandle::data_size, echo_origin, failure_response, GN_REST_STATE_INIT, GN_REST_STATE_PROCESSING, GNUNET_assert, GNUNET_break, GNUNET_CONTAINER_multihashmap_create(), GNUNET_CONTAINER_multihashmap_get(), GNUNET_CRYPTO_hash(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_WARNING, GNUNET_free, GNUNET_log, GNUNET_new, GNUNET_NO, GNUNET_strdup, GNUNET_YES, header_iterator(), GNUNET_REST_RequestHandle::header_param_map, key, GNUNET_REST_RequestHandle::method, MHD_RESULT, PluginListEntry::next, origin, PluginListEntry::plugin, plugin_callback(), plugins_head, post_data_iter(), MhdConnectionHandle::pp, PluginListEntry::process_request, MhdConnectionHandle::response, ret, run_mhd_now(), MhdConnectionHandle::state, MhdConnectionHandle::status, GNUNET_REST_RequestHandle::url, url_iterator(), and GNUNET_REST_RequestHandle::url_param_map.

Referenced by run().

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

◆ kill_httpd()

static void kill_httpd ( )
static

Kill the MHD daemon.

Definition at line 698 of file gnunet-rest-server.c.

699{
700 if (NULL != httpd)
701 {
702 MHD_stop_daemon (httpd);
703 httpd = NULL;
704 }
705 if (NULL != httpd_task)
706 {
708 httpd_task = NULL;
709 }
710 if (NULL != ltask4)
711 {
713 ltask4 = NULL;
714 }
715 if (NULL != ltask6)
716 {
718 ltask6 = NULL;
719 }
720
721 if (NULL != lsock4)
722 {
724 lsock4 = NULL;
725 }
726 if (NULL != lsock6)
727 {
729 lsock6 = NULL;
730 }
731}

References GNUNET_NETWORK_socket_close(), GNUNET_SCHEDULER_cancel(), httpd, httpd_task, lsock4, lsock6, ltask4, and ltask6.

Referenced by do_shutdown(), do_shutdown(), kill_httpd_task(), schedule_httpd(), and schedule_httpd().

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

◆ schedule_httpd()

static void schedule_httpd ( )
static

Schedule MHD.

This function should be called initially when an MHD is first getting its client socket, and will then automatically always be called later whenever there is work to be done.

Parameters
hdthe daemon to schedule

Definition at line 742 of file gnunet-rest-server.c.

743{
744 fd_set rs;
745 fd_set ws;
746 fd_set es;
747 struct GNUNET_NETWORK_FDSet *wrs;
748 struct GNUNET_NETWORK_FDSet *wws;
749 int max;
750 int haveto;
751 MHD_UNSIGNED_LONG_LONG timeout;
752 struct GNUNET_TIME_Relative tv;
753
754 FD_ZERO (&rs);
755 FD_ZERO (&ws);
756 FD_ZERO (&es);
757 max = -1;
758 if (MHD_YES != MHD_get_fdset (httpd, &rs, &ws, &es, &max))
759 {
760 kill_httpd ();
761 return;
762 }
763 haveto = MHD_get_timeout (httpd, &timeout);
764 if (MHD_YES == haveto)
765 tv.rel_value_us = (uint64_t) timeout * 1000LL;
766 else
768 if (-1 != max)
769 {
774 }
775 else
776 {
777 wrs = NULL;
778 wws = NULL;
779 }
780 if (NULL != httpd_task)
781 {
783 httpd_task = NULL;
784 }
785 if ((MHD_YES == haveto) || (-1 != max))
786 {
788 tv,
789 wrs,
790 wws,
791 &do_httpd,
792 NULL);
793 }
794 if (NULL != wrs)
796 if (NULL != wws)
798}

References do_httpd(), GNUNET_NETWORK_fdset_copy_native(), GNUNET_NETWORK_fdset_create(), GNUNET_NETWORK_fdset_destroy(), GNUNET_SCHEDULER_add_select(), GNUNET_SCHEDULER_cancel(), GNUNET_SCHEDULER_PRIORITY_DEFAULT, GNUNET_TIME_UNIT_FOREVER_REL, httpd, httpd_task, kill_httpd(), max, GNUNET_TIME_Relative::rel_value_us, and timeout.

Referenced by do_accept(), do_httpd(), do_httpd(), and setup_data_transfer().

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

◆ mhd_log_callback()

static void * mhd_log_callback ( void *  cls,
const char *  url,
struct MHD_Connection *  connection 
)
static

Function called when MHD first processes an incoming connection.

Gives us the respective URI information.

We use this to associate the struct MHD_Connection with our internal struct AcceptedRequest data structure (by checking for matching sockets).

Parameters
clsthe HTTP server handle (a struct MhdHttpList)
urlthe URL that is being requested
connectionMHD connection object for the request
Returns
the struct Socks5Request that this connection is for

Definition at line 815 of file gnunet-rest-server.c.

818{
819 struct AcceptedRequest *ar;
820 const union MHD_ConnectionInfo *ci;
821
822 ci = MHD_get_connection_info (connection,
823 MHD_CONNECTION_INFO_SOCKET_CONTEXT);
824 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Processing %s\n", url);
825 if (NULL == ci)
826 {
827 GNUNET_break (0);
828 return NULL;
829 }
830 ar = ci->socket_context;
831 return ar;
832}

References GNUNET_break, GNUNET_ERROR_TYPE_DEBUG, and GNUNET_log.

Referenced by run().

Here is the caller graph for this function:

◆ mhd_completed_cb()

static void mhd_completed_cb ( void *  cls,
struct MHD_Connection *  connection,
void **  con_cls,
enum MHD_RequestTerminationCode  toe 
)
static

Function called when MHD decides that we are done with a connection.

Parameters
clsNULL
connectionconnection handle
con_clsvalue as set by the last call to the MHD_AccessHandlerCallback, should be our handle
toereason for request termination (ignored)

Definition at line 845 of file gnunet-rest-server.c.

849{
850 struct AcceptedRequest *ar = *con_cls;
851 if (MHD_REQUEST_TERMINATED_COMPLETED_OK != toe)
853 "MHD encountered error handling request: %d\n",
854 toe);
855 if (NULL == ar)
856 return;
857 if (NULL != ar->con_handle)
858 {
860 ar->con_handle = NULL;
861 }
863 *con_cls = NULL;
864}

References cleanup_handle(), AcceptedRequest::con_handle, GNUNET_ERROR_TYPE_ERROR, GNUNET_log, GNUNET_YES, and AcceptedRequest::socket_with_mhd.

Referenced by run().

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

◆ mhd_connection_cb()

static void mhd_connection_cb ( void *  cls,
struct MHD_Connection *  connection,
void **  con_cls,
enum MHD_ConnectionNotificationCode  cnc 
)
static

Function called when MHD connection is opened or closed.

Parameters
clsNULL
connectionconnection handle
con_clsvalue as set by the last call to the MHD_AccessHandlerCallback, should be our struct Socks5Request *
toeconnection notification type

Definition at line 877 of file gnunet-rest-server.c.

881{
882 struct AcceptedRequest *ar;
883 const union MHD_ConnectionInfo *ci;
884 int sock;
885
886 switch (cnc)
887 {
888 case MHD_CONNECTION_NOTIFY_STARTED:
889 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connection started...\n");
890 ci = MHD_get_connection_info (connection,
891 MHD_CONNECTION_INFO_CONNECTION_FD);
892 if (NULL == ci)
893 {
894 GNUNET_break (0);
895 return;
896 }
897 sock = ci->connect_fd;
898 for (ar = req_list_head; NULL != ar; ar = ar->next)
899 {
900 if (GNUNET_NETWORK_get_fd (ar->sock) == sock)
901 {
903 "Context set...\n");
904 *con_cls = ar;
905 break;
906 }
907 }
908 break;
909
910 case MHD_CONNECTION_NOTIFY_CLOSED:
912 "Connection closed... cleaning up\n");
913 ar = *con_cls;
914 if (NULL == ar)
915 {
917 "Connection stale!\n");
918 return;
919 }
920 cleanup_ar (ar);
921 *con_cls = NULL;
922 break;
923
924 default:
925 GNUNET_break (0);
926 }
927}

References cleanup_ar(), GNUNET_break, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_log, GNUNET_NETWORK_get_fd(), AcceptedRequest::next, req_list_head, and AcceptedRequest::sock.

Referenced by run().

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

◆ do_accept()

static void do_accept ( void *  cls)
static

Accept new incoming connections.

Parameters
clsthe closure with the lsock4 or lsock6

Definition at line 950 of file gnunet-rest-server.c.

951{
952 struct GNUNET_NETWORK_Handle *lsock = cls;
953 struct AcceptedRequest *ar;
954 int fd;
955 const struct sockaddr *addr;
956 socklen_t len;
957
958 GNUNET_assert (NULL != lsock);
959 if (lsock == lsock4)
960 {
962 lsock,
963 &do_accept,
964 lsock);
965 }
966 else if (lsock == lsock6)
967 {
969 lsock,
970 &do_accept,
971 lsock);
972 }
973 else
974 GNUNET_assert (0);
975 ar = GNUNET_new (struct AcceptedRequest);
977 ar->sock = GNUNET_NETWORK_socket_accept (lsock, NULL, NULL);
978 if (NULL == ar->sock)
979 {
980 GNUNET_free (ar);
982 return;
983 }
985 "Got an inbound connection, waiting for data\n");
986 fd = GNUNET_NETWORK_get_fd (ar->sock);
987 addr = GNUNET_NETWORK_get_addr (ar->sock);
991 ar);
992 if (MHD_YES != MHD_add_connection (httpd, fd, addr, len))
993 {
995 GNUNET_free (ar);
997 _ ("Failed to pass client to MHD\n"));
998 return;
999 }
1000 schedule_httpd ();
1001}

References _, do_accept(), GNUNET_assert, GNUNET_CONTAINER_DLL_insert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_ERROR_TYPE_WARNING, GNUNET_free, GNUNET_log, GNUNET_log_strerror, GNUNET_NETWORK_get_addr(), GNUNET_NETWORK_get_addrlen(), GNUNET_NETWORK_get_fd(), GNUNET_NETWORK_socket_accept(), GNUNET_NETWORK_socket_close(), GNUNET_new, GNUNET_SCHEDULER_add_read_net(), GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_YES, httpd, lsock4, lsock6, ltask4, ltask6, req_list_head, req_list_tail, schedule_httpd(), AcceptedRequest::sock, and AcceptedRequest::socket_with_mhd.

Referenced by do_accept(), and run().

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

◆ do_shutdown()

static void do_shutdown ( void *  cls)
static

Task run on shutdown.

Parameters
clsclosure

Definition at line 1010 of file gnunet-rest-server.c.

1011{
1012 struct PluginListEntry *ple;
1013
1014 while (NULL != plugins_head)
1015 {
1016 ple = plugins_head;
1019 ple);
1020 GNUNET_free (ple->libname);
1021 GNUNET_free (ple);
1022 }
1028#if HAVE_JOSE
1029 REST_openid_done (openid_plugin);
1030#endif
1032 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Shutting down...\n");
1033 kill_httpd ();
1036 MHD_destroy_response (failure_response);
1037}

References allow_credentials, allow_headers, config_plugin, copying_plugin, failure_response, gns_plugin, GNUNET_CONTAINER_DLL_remove, GNUNET_ERROR_TYPE_INFO, GNUNET_free, GNUNET_log, identity_plugin, kill_httpd(), PluginListEntry::libname, namestore_plugin, plugins_head, plugins_tail, reclaim_plugin, REST_config_done(), REST_copying_done(), REST_gns_done(), REST_identity_done(), REST_namestore_done(), REST_openid_done(), and REST_reclaim_done().

Here is the call graph for this function:

◆ bind_v4()

static struct GNUNET_NETWORK_Handle * bind_v4 ( )
static

Create an IPv4 listen socket bound to our port.

Returns
NULL on error

Definition at line 1046 of file gnunet-rest-server.c.

1047{
1048 struct GNUNET_NETWORK_Handle *ls;
1049 struct sockaddr_in sa4;
1050 int eno;
1051
1052 memset (&sa4, 0, sizeof(sa4));
1053 sa4.sin_family = AF_INET;
1054 sa4.sin_port = htons (port);
1055 sa4.sin_addr.s_addr = address;
1056#if HAVE_SOCKADDR_IN_SIN_LEN
1057 sa4.sin_len = sizeof(sa4);
1058#endif
1059 ls = GNUNET_NETWORK_socket_create (AF_INET, SOCK_STREAM, 0);
1060 if (NULL == ls)
1061 return NULL;
1063 (const struct sockaddr *) &sa4,
1064 sizeof(sa4)))
1065 {
1066 eno = errno;
1068 errno = eno;
1069 return NULL;
1070 }
1071 return ls;
1072}

References address, GNUNET_NETWORK_socket_bind(), GNUNET_NETWORK_socket_close(), GNUNET_NETWORK_socket_create(), GNUNET_OK, ls, and port.

Referenced by run().

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

◆ bind_v6()

static struct GNUNET_NETWORK_Handle * bind_v6 ( )
static

Create an IPv6 listen socket bound to our port.

Returns
NULL on error

Definition at line 1081 of file gnunet-rest-server.c.

1082{
1083 struct GNUNET_NETWORK_Handle *ls;
1084 struct sockaddr_in6 sa6;
1085 int eno;
1086
1087 memset (&sa6, 0, sizeof(sa6));
1088 sa6.sin6_family = AF_INET6;
1089 sa6.sin6_port = htons (port);
1090 sa6.sin6_addr = address6;
1091#if HAVE_SOCKADDR_IN_SIN_LEN
1092 sa6.sin6_len = sizeof(sa6);
1093#endif
1094 ls = GNUNET_NETWORK_socket_create (AF_INET6, SOCK_STREAM, 0);
1095 if (NULL == ls)
1096 return NULL;
1098 (const struct sockaddr *) &sa6,
1099 sizeof(sa6)))
1100 {
1101 eno = errno;
1103 errno = eno;
1104 return NULL;
1105 }
1106 return ls;
1107}

References address6, GNUNET_NETWORK_socket_bind(), GNUNET_NETWORK_socket_close(), GNUNET_NETWORK_socket_create(), GNUNET_OK, ls, and port.

Referenced by run().

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

◆ setup_plugin()

static enum GNUNET_GenericReturnValue setup_plugin ( const char *  name,
GNUNET_REST_ProcessingFunction  proc,
void *  plugin_cls 
)
static

Callback for plugin load.

Parameters
clsNULL
libnamethe name of the library loaded
lib_retthe object returned by the plugin initializer

Definition at line 1118 of file gnunet-rest-server.c.

1121{
1122 struct PluginListEntry *ple;
1123
1124 if (NULL == plugin_cls)
1125 {
1127 "Could not load plugin\n");
1128 return GNUNET_SYSERR;
1129 }
1130 GNUNET_assert (1 < strlen (name));
1131 GNUNET_assert ('/' == *name);
1132 ple = GNUNET_new (struct PluginListEntry);
1133 ple->libname = GNUNET_strdup (name);
1134 ple->plugin = plugin_cls;
1135 ple->process_request = proc;
1138 ple);
1139 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Loaded plugin `%s'\n", name);
1140 return GNUNET_OK;
1141}

References GNUNET_assert, GNUNET_CONTAINER_DLL_insert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_new, GNUNET_OK, GNUNET_strdup, GNUNET_SYSERR, PluginListEntry::libname, name, PluginListEntry::plugin, plugins_head, plugins_tail, and PluginListEntry::process_request.

Referenced by run().

Here is the caller graph for this function:

◆ run()

static void run ( void *  cls,
char *const *  args,
const char *  cfgfile,
const struct GNUNET_CONFIGURATION_Handle c 
)
static

Main function that will be run.

Parameters
clsclosure
argsremaining command-line arguments
cfgfilename of the configuration file used (for saving, can be NULL)
cconfiguration

Definition at line 1153 of file gnunet-rest-server.c.

1157{
1158 static const char *err_page = "{}";
1159 char *addr_str;
1160 char *basic_auth_file;
1161 uint64_t secret;
1162
1163 cfg = c;
1164 plugins_head = NULL;
1165 plugins_tail = NULL;
1166 failure_response = MHD_create_response_from_buffer (strlen (err_page),
1167 (void *) err_page,
1168 MHD_RESPMEM_PERSISTENT);
1169 /* Get port to bind to */
1170 if (GNUNET_OK !=
1171 GNUNET_CONFIGURATION_get_value_number (cfg, "rest", "HTTP_PORT", &port))
1172 {
1173 // No address specified
1174 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Using default port...\n");
1176 }
1177
1178 /* Get address to bind to */
1179 if (GNUNET_OK !=
1180 GNUNET_CONFIGURATION_get_value_string (cfg, "rest", "BIND_TO", &addr_str))
1181 {
1182 // No address specified
1183 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Don't know what to bind to...\n");
1185 return;
1186 }
1187 if (1 != inet_pton (AF_INET, addr_str, &address))
1188 {
1190 "Unable to parse address %s\n",
1191 addr_str);
1192 GNUNET_free (addr_str);
1194 return;
1195 }
1196 GNUNET_free (addr_str);
1197 /* Get address to bind to */
1199 "rest",
1200 "BIND_TO6",
1201 &addr_str))
1202 {
1203 // No address specified
1204 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Don't know what to bind6 to...\n");
1206 return;
1207 }
1208 if (1 != inet_pton (AF_INET6, addr_str, &address6))
1209 {
1211 "Unable to parse IPv6 address %s\n",
1212 addr_str);
1213 GNUNET_free (addr_str);
1215 return;
1216 }
1217 GNUNET_free (addr_str);
1218
1220 "rest",
1221 "BASIC_AUTH_ENABLED");
1223 {
1225 "rest",
1226 "BASIC_AUTH_SECRET_FILE",
1227 &basic_auth_file))
1228 {
1230 "No basic auth secret file location set...\n");
1232 return;
1233 }
1234 if (GNUNET_YES != GNUNET_DISK_file_test (basic_auth_file))
1235 {
1237 "No basic auth secret found... generating\n");
1239 UINT64_MAX);
1241 sizeof(secret));
1242 if (GNUNET_OK !=
1243 GNUNET_DISK_fn_write (basic_auth_file,
1245 strlen (basic_auth_secret),
1249 "write",
1250 basic_auth_file);
1251 GNUNET_free (basic_auth_file);
1252 }
1253 else
1254 {
1255 char basic_auth_secret_tmp[16]; // Should be more than enough
1256 memset (basic_auth_secret_tmp, 0, 16);
1257 if (GNUNET_SYSERR == GNUNET_DISK_fn_read (basic_auth_file,
1258 basic_auth_secret_tmp,
1259 sizeof (basic_auth_secret_tmp)
1260 - 1))
1261 {
1263 "Unable to read basic auth secret file.\n");
1265 GNUNET_free (basic_auth_file);
1266 return;
1267 }
1268 GNUNET_free (basic_auth_file);
1269 if (0 != getlogin_r (cuser, _POSIX_LOGIN_NAME_MAX))
1270 {
1272 "Unable to get user.\n");
1274 return;
1275 }
1276 basic_auth_secret = GNUNET_strdup (basic_auth_secret_tmp);
1277 }
1278 }
1279
1280 /* Get CORS data from cfg */
1281 echo_origin =
1283 "rest",
1284 "REST_ECHO_ORIGIN_WEBEXT");
1285 allow_origins = NULL;
1287 "rest",
1288 "REST_ALLOW_ORIGIN",
1289 &allow_origins))
1290 {
1292 "No CORS Access-Control-Allow-Origin header will be sent...\n");
1293 }
1294 if (GNUNET_OK !=
1296 "rest",
1297 "REST_ALLOW_CREDENTIALS",
1299 {
1300 // No origin specified
1302 "No CORS Credential Header will be sent...\n");
1303 }
1304
1306 "rest",
1307 "REST_ALLOW_HEADERS",
1308 &allow_headers))
1309 {
1310 // No origin specified
1312 "No CORS Access-Control-Allow-Headers Header will be sent...\n")
1313 ;
1314 }
1315
1316/* Open listen socket proxy */
1317 lsock6 = bind_v6 ();
1318 if (NULL == lsock6)
1319 {
1321 }
1322 else
1323 {
1325 {
1328 lsock6 = NULL;
1329 }
1330 else
1331 {
1333 lsock6,
1334 &do_accept,
1335 lsock6);
1336 }
1337 }
1338 lsock4 = bind_v4 ();
1339 if (NULL == lsock4)
1340 {
1342 }
1343 else
1344 {
1346 {
1349 lsock4 = NULL;
1350 }
1351 else
1352 {
1354 lsock4,
1355 &do_accept,
1356 lsock4);
1357 }
1358 }
1359 if ((NULL == lsock4) && (NULL == lsock6))
1360 {
1362 return;
1363 }
1364 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Service listens on port %llu\n",
1365 port);
1366 httpd = MHD_start_daemon (MHD_USE_DEBUG | MHD_USE_NO_LISTEN_SOCKET
1367 | MHD_ALLOW_SUSPEND_RESUME,
1368 0,
1369 NULL,
1370 NULL,
1372 NULL,
1373 MHD_OPTION_CONNECTION_TIMEOUT,
1374 (unsigned int) 16,
1375 MHD_OPTION_NOTIFY_CONNECTION,
1377 NULL,
1378 MHD_OPTION_URI_LOG_CALLBACK,
1380 NULL,
1381 MHD_OPTION_NOTIFY_COMPLETED,
1383 NULL,
1384 MHD_OPTION_END);
1385 if (NULL == httpd)
1386 {
1388 return;
1389 }
1390 /* Load plugins */
1391 // FIXME: Use per-plugin rest plugin structs
1395 {
1397 }
1401 {
1403 }
1408 {
1410 }
1415 {
1417 }
1420 gns_plugin))
1421 {
1423 }
1424#if HAVE_JOSE
1425 openid_plugin = REST_openid_init (cfg);
1426 if (GNUNET_OK != setup_plugin (openid_plugin->name,
1427 &REST_openid_process_request, openid_plugin))
1428 {
1430 }
1431#endif
1435 {
1437 }
1439}

References address, address6, allow_credentials, allow_headers, allow_origins, basic_auth_enabled, basic_auth_secret, bind_v4(), bind_v6(), cfg, config_plugin, copying_plugin, create_response(), cuser, do_accept(), do_shutdown, echo_origin, failure_response, gns_plugin, GNUNET_CONFIGURATION_get_value_filename(), GNUNET_CONFIGURATION_get_value_number(), GNUNET_CONFIGURATION_get_value_string(), GNUNET_CONFIGURATION_get_value_yesno(), GNUNET_CRYPTO_QUALITY_WEAK, GNUNET_CRYPTO_random_u64(), GNUNET_DISK_file_test(), GNUNET_DISK_fn_read(), GNUNET_DISK_fn_write(), GNUNET_DISK_PERM_USER_READ, GNUNET_DISK_PERM_USER_WRITE, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_ERROR_TYPE_INFO, GNUNET_ERROR_TYPE_WARNING, GNUNET_free, GNUNET_log, GNUNET_log_strerror, GNUNET_log_strerror_file, GNUNET_NETWORK_socket_close(), GNUNET_NETWORK_socket_listen(), GNUNET_OK, GNUNET_REST_SERVICE_PORT, GNUNET_SCHEDULER_add_read_net(), GNUNET_SCHEDULER_add_shutdown(), GNUNET_SCHEDULER_shutdown(), GNUNET_strdup, GNUNET_STRINGS_data_to_string_alloc(), GNUNET_SYSERR, GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_YES, httpd, identity_plugin, lsock4, lsock6, ltask4, ltask6, mhd_completed_cb(), mhd_connection_cb(), mhd_log_callback(), GNUNET_REST_Plugin::name, namestore_plugin, plugins_head, plugins_tail, port, reclaim_plugin, REST_config_init(), REST_config_process_request(), REST_copying_init(), REST_copying_process_request(), REST_gns_init(), REST_gns_process_request(), REST_identity_init(), REST_identity_process_request(), REST_namestore_init(), REST_namestore_process_request(), REST_openid_init(), REST_openid_process_request(), REST_reclaim_init(), REST_reclaim_process_request(), and setup_plugin().

Here is the call graph for this function:

Variable Documentation

◆ httpd_task

struct GNUNET_SCHEDULER_Task* httpd_task
static

The task ID.

Definition at line 75 of file gnunet-rest-server.c.

Referenced by do_httpd(), kill_httpd(), run_mhd_now(), and schedule_httpd().

◆ address

in_addr_t address
static

The address to bind to.

Definition at line 80 of file gnunet-rest-server.c.

Referenced by bind_v4(), and run().

◆ address6

struct in6_addr address6
static

The IPv6 address to bind to.

Definition at line 85 of file gnunet-rest-server.c.

Referenced by bind_v6(), and run().

◆ port

unsigned long long port = 7776
static

The port the service is running on (default 7776)

Definition at line 90 of file gnunet-rest-server.c.

Referenced by bind_v4(), bind_v6(), and run().

◆ lsock4

struct GNUNET_NETWORK_Handle* lsock4
static

The listen socket of the service for IPv4.

Definition at line 95 of file gnunet-rest-server.c.

Referenced by do_accept(), kill_httpd(), and run().

◆ lsock6

struct GNUNET_NETWORK_Handle* lsock6
static

The listen socket of the service for IPv6.

Definition at line 100 of file gnunet-rest-server.c.

Referenced by do_accept(), kill_httpd(), and run().

◆ ltask4

struct GNUNET_SCHEDULER_Task* ltask4
static

The listen task ID for IPv4.

Definition at line 105 of file gnunet-rest-server.c.

Referenced by do_accept(), kill_httpd(), and run().

◆ ltask6

struct GNUNET_SCHEDULER_Task* ltask6
static

The listen task ID for IPv6.

Definition at line 110 of file gnunet-rest-server.c.

Referenced by do_accept(), kill_httpd(), and run().

◆ httpd

struct MHD_Daemon* httpd
static

Daemon for HTTP.

Definition at line 115 of file gnunet-rest-server.c.

Referenced by do_accept(), do_httpd(), kill_httpd(), run(), and schedule_httpd().

◆ failure_response

struct MHD_Response* failure_response
static

Response we return on failures.

Definition at line 120 of file gnunet-rest-server.c.

Referenced by create_response(), do_shutdown(), and run().

◆ cfg

const struct GNUNET_CONFIGURATION_Handle* cfg
static

Our configuration.

Definition at line 125 of file gnunet-rest-server.c.

Referenced by run().

◆ echo_origin

int echo_origin
static

Echo request Origin in CORS.

Definition at line 130 of file gnunet-rest-server.c.

Referenced by create_response(), and run().

◆ basic_auth_enabled

int basic_auth_enabled
static

Do basic auth of user.

Definition at line 135 of file gnunet-rest-server.c.

Referenced by create_response(), and run().

◆ basic_auth_secret

char* basic_auth_secret
static

Basic auth secret.

Definition at line 140 of file gnunet-rest-server.c.

Referenced by create_response(), and run().

◆ cuser

char cuser[_POSIX_LOGIN_NAME_MAX]

User of the service.

Definition at line 145 of file gnunet-rest-server.c.

Referenced by create_response(), and run().

◆ allow_origins

char* allow_origins
static

Allowed Origins (CORS)

Definition at line 150 of file gnunet-rest-server.c.

Referenced by create_response(), and run().

◆ allow_headers

char* allow_headers
static

Allowed Headers (CORS)

Definition at line 155 of file gnunet-rest-server.c.

Referenced by create_response(), do_shutdown(), and run().

◆ allow_credentials

char* allow_credentials
static

Allowed Credentials (CORS)

Definition at line 160 of file gnunet-rest-server.c.

Referenced by create_response(), do_shutdown(), and run().

◆ plugins_head

struct PluginListEntry* plugins_head
static

Plugin list head.

Definition at line 165 of file gnunet-rest-server.c.

Referenced by create_response(), do_shutdown(), run(), and setup_plugin().

◆ plugins_tail

struct PluginListEntry* plugins_tail
static

Plugin list tail.

Definition at line 170 of file gnunet-rest-server.c.

Referenced by do_shutdown(), run(), and setup_plugin().

◆ req_list_head

struct AcceptedRequest* req_list_head
static

AcceptedRequest list head.

Definition at line 251 of file gnunet-rest-server.c.

Referenced by cleanup_ar(), do_accept(), and mhd_connection_cb().

◆ req_list_tail

struct AcceptedRequest* req_list_tail
static

AcceptedRequest list tail.

Definition at line 256 of file gnunet-rest-server.c.

Referenced by cleanup_ar(), and do_accept().

◆ config_plugin

struct GNUNET_REST_Plugin* config_plugin

plugins

Definition at line 263 of file gnunet-rest-server.c.

Referenced by do_shutdown(), and run().

◆ copying_plugin

struct GNUNET_REST_Plugin* copying_plugin

Definition at line 264 of file gnunet-rest-server.c.

Referenced by do_shutdown(), and run().

◆ identity_plugin

struct GNUNET_REST_Plugin* identity_plugin

Definition at line 265 of file gnunet-rest-server.c.

Referenced by do_shutdown(), and run().

◆ namestore_plugin

struct GNUNET_REST_Plugin* namestore_plugin

Definition at line 266 of file gnunet-rest-server.c.

Referenced by do_shutdown(), and run().

◆ gns_plugin

struct GNUNET_REST_Plugin* gns_plugin

Definition at line 267 of file gnunet-rest-server.c.

Referenced by do_shutdown(), and run().

◆ reclaim_plugin

struct GNUNET_REST_Plugin* reclaim_plugin

Definition at line 271 of file gnunet-rest-server.c.

Referenced by do_shutdown(), and run().