GNUnet  0.19.4
gnunet-rest-server.c File Reference

REST service for GNUnet services. More...

#include "platform.h"
#include <microhttpd.h>
#include "gnunet_util_lib.h"
#include "gnunet_rest_plugin.h"
#include "gnunet_mhd_compat.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. More...
 
#define MAX_HTTP_URI_LENGTH   2048
 Maximum supported length for a URI. More...
 
#define HTTP_PORT   80
 Port for plaintext HTTP. More...
 
#define HTTPS_PORT   443
 Port for HTTPS. More...
 
#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? More...
 
#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. More...
 
static void run_mhd_now ()
 Run MHD now, we have extra data ready for the callback. More...
 
static void plugin_callback (void *cls, struct MHD_Response *resp, int status)
 Plugin result callback. More...
 
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. More...
 
static void kill_httpd ()
 Kill the MHD daemon. More...
 
static void schedule_httpd ()
 Schedule MHD. More...
 
static void * mhd_log_callback (void *cls, const char *url, struct MHD_Connection *connection)
 Function called when MHD first processes an incoming connection. More...
 
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. More...
 
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. More...
 
static void do_accept (void *cls)
 Accept new incoming connections. More...
 
static void do_shutdown (void *cls)
 Task run on shutdown. More...
 
static struct GNUNET_NETWORK_Handlebind_v4 ()
 Create an IPv4 listen socket bound to our port. More...
 
static struct GNUNET_NETWORK_Handlebind_v6 ()
 Create an IPv6 listen socket bound to our port. More...
 
static void load_plugin (void *cls, const char *libname, void *lib_ret)
 Callback for plugin load. More...
 
static void run (void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *c)
 Main function that will be run. More...
 
int main (int argc, char *const *argv)
 The main function for gnunet-rest-service. More...
 

Variables

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

Detailed Description

REST service for GNUnet services.

Author
Martin Schanzenbach

Definition in file gnunet-rest-server.c.

Macro Definition Documentation

◆ GNUNET_REST_SERVICE_PORT

#define GNUNET_REST_SERVICE_PORT   7776

Default Socks5 listen port.

Definition at line 35 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 41 of file gnunet-rest-server.c.

◆ HTTP_PORT

#define HTTP_PORT   80

Port for plaintext HTTP.

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

◆ HTTPS_PORT

#define HTTPS_PORT   443

Port for HTTPS.

Definition at line 51 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 56 of file gnunet-rest-server.c.

◆ GN_REST_STATE_INIT

#define GN_REST_STATE_INIT   0

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

◆ GN_REST_STATE_PROCESSING

#define GN_REST_STATE_PROCESSING   1

Definition at line 60 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 896 of file gnunet-rest-server.c.

897 {
898  httpd_task = NULL;
899  MHD_run (httpd);
900  schedule_httpd ();
901 }
static struct MHD_Daemon * httpd
Daemon for HTTP.
static struct GNUNET_SCHEDULER_Task * httpd_task
The task ID.
static void schedule_httpd()
Schedule MHD.

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 259 of file gnunet-rest-server.c.

260 {
261  if (NULL != httpd_task)
262  {
264  httpd_task = NULL;
265  }
267 }
static void do_httpd(void *cls)
Task run whenever HTTP server operations are pending.
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:1299
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:975

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

Referenced by create_response(), 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 279 of file gnunet-rest-server.c.

280 {
281  struct MhdConnectionHandle *handle = cls;
282 
283  handle->status = status;
284  handle->response = resp;
285  MHD_resume_connection (handle->con);
286  run_mhd_now ();
287 }
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
uint16_t status
See PRISM_STATUS_*-constants.
static void run_mhd_now()
Run MHD now, we have extra data ready for the callback.
MHD Connection handle.

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 291 of file gnunet-rest-server.c.

292 {
293  GNUNET_free (value);
294  return GNUNET_YES;
295 }
static char * value
Value of the record to add/remove.
@ GNUNET_YES
#define GNUNET_free(ptr)
Wrapper around free.

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 298 of file gnunet-rest-server.c.

299 {
300  if (NULL != handle->response)
301  MHD_destroy_response (handle->response);
302  if (NULL != handle->data_handle)
303  {
304  if (NULL != handle->data_handle->header_param_map)
305  {
307  ->header_param_map,
309  NULL);
311  handle->data_handle->header_param_map);
312  }
313  if (NULL != handle->data_handle->url_param_map)
314  {
315  GNUNET_CONTAINER_multihashmap_iterate (handle->data_handle->url_param_map,
317  NULL);
319  handle->data_handle->url_param_map);
320  }
321  GNUNET_free (handle->data_handle);
322  }
324 }
static int cleanup_url_map(void *cls, const struct GNUNET_HashCode *key, void *value)
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_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.

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 327 of file gnunet-rest-server.c.

328 {
329  if (NULL != ar->con_handle)
330  {
332  }
333  if (GNUNET_YES == ar->socket_with_mhd)
334  {
336  }
337  else {
339  }
340  ar->sock = NULL;
343  ar);
344  GNUNET_free (ar);
345 }
static struct AcceptedRequest * req_list_head
AcceptedRequest list head.
static struct AcceptedRequest * req_list_tail
AcceptedRequest list tail.
static void cleanup_handle(struct MhdConnectionHandle *handle)
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_close(struct GNUNET_NETWORK_Handle *desc)
Close a socket.
Definition: network.c:508
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:565
struct MhdConnectionHandle * con_handle
Connection.
struct GNUNET_NETWORK_Handle * sock
Socket.

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 348 of file gnunet-rest-server.c.

352 {
353  struct GNUNET_REST_RequestHandle *handle = cls;
354  struct GNUNET_HashCode hkey;
355  char *val;
356  char *lowerkey;
357 
358  lowerkey = GNUNET_strdup (key);
359  GNUNET_STRINGS_utf8_tolower (key, lowerkey);
360  GNUNET_CRYPTO_hash (lowerkey, strlen (lowerkey), &hkey);
361  GNUNET_asprintf (&val, "%s", value);
363  handle->header_param_map,
364  &hkey,
365  val,
367  {
369  "Could not load add header `%s'=%s\n",
370  lowerkey,
371  value);
372  }
373  GNUNET_free (lowerkey);
374  return MHD_YES;
375 }
struct GNUNET_HashCode key
The key used in the DHT.
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
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.
@ 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_OK
@ GNUNET_ERROR_TYPE_ERROR
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
enum GNUNET_GenericReturnValue GNUNET_STRINGS_utf8_tolower(const char *input, char *output)
Convert the utf-8 input string to lower case.
Definition: strings.c:449
A 512-bit hashcode.

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_strdup, 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 379 of file gnunet-rest-server.c.

383 {
384  struct GNUNET_REST_RequestHandle *handle = cls;
385  struct GNUNET_HashCode hkey;
386  char *val;
387 
388  GNUNET_CRYPTO_hash (key, strlen (key), &hkey);
389  GNUNET_asprintf (&val, "%s", value);
391  handle->url_param_map,
392  &hkey,
393  val,
395  {
397  "Could not load add url param `%s'=%s\n",
398  key,
399  value);
400  }
401  return MHD_YES;
402 }

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 406 of file gnunet-rest-server.c.

415 {
416  struct GNUNET_REST_RequestHandle *handle = cls;
417  struct GNUNET_HashCode hkey;
418  char *val;
419 
420  if (MHD_POSTDATA_KIND != kind)
421  return MHD_YES;
422 
423  GNUNET_CRYPTO_hash (key, strlen (key), &hkey);
424  val = GNUNET_CONTAINER_multihashmap_get (handle->url_param_map,
425  &hkey);
426  if (NULL == val)
427  {
428  val = GNUNET_malloc (65536);
430  handle->url_param_map,
431  &hkey,
432  val,
434  {
436  "Could not add url param '%s'\n",
437  key);
438  GNUNET_free (val);
439  }
440  }
441  memcpy (val + off, data, size);
442  return MHD_YES;
443 }
uint32_t data
The data value.
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.
#define GNUNET_malloc(size)
Wrapper around malloc.
static unsigned int size
Size of the "table".
Definition: peer.c:68

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 472 of file gnunet-rest-server.c.

480 {
481  char *origin;
482  char *pw;
483  char *user;
484  struct AcceptedRequest *ar;
485  struct GNUNET_HashCode key;
486  struct MhdConnectionHandle *con_handle;
487  struct GNUNET_REST_RequestHandle *rest_conndata_handle;
488  struct PluginListEntry *ple;
489 
490  ar = *con_cls;
491  if (NULL == ar)
492  {
493  GNUNET_break (0);
494  return MHD_NO;
495  }
496 
497  if (NULL == ar->con_handle)
498  {
499  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "New connection %s\n", url);
500  con_handle = GNUNET_new (struct MhdConnectionHandle);
501  con_handle->con = con;
502  con_handle->state = GN_REST_STATE_INIT;
503  ar->con_handle = con_handle;
504  return MHD_YES;
505  }
506  con_handle = ar->con_handle;
507  if (GN_REST_STATE_INIT == con_handle->state)
508  {
509  rest_conndata_handle = GNUNET_new (struct GNUNET_REST_RequestHandle);
510  rest_conndata_handle->method = meth;
511  rest_conndata_handle->url = url;
512  rest_conndata_handle->data = upload_data;
513  rest_conndata_handle->data_size = *upload_data_size;
514  rest_conndata_handle->url_param_map =
516  rest_conndata_handle->header_param_map =
518  con_handle->data_handle = rest_conndata_handle;
519  MHD_get_connection_values (con,
520  MHD_GET_ARGUMENT_KIND,
521  (MHD_KeyValueIterator) & url_iterator,
522  rest_conndata_handle);
523  MHD_get_connection_values (con,
524  MHD_HEADER_KIND,
525  (MHD_KeyValueIterator) & header_iterator,
526  rest_conndata_handle);
528  {
529  pw = NULL;
530  user = MHD_basic_auth_get_username_password (con, &pw);
531  if ((NULL == user) ||
532  (0 != strcmp (user, cuser)))
533  {
535  "Unknown user %s\n", user);
536  MHD_queue_basic_auth_fail_response (con, "gnunet", failure_response);
537  return MHD_YES;
538  }
539  if ((NULL == pw) ||
540  (0 != strcmp (pw, basic_auth_secret)))
541  {
543  "Password incorrect\n");
544  MHD_queue_basic_auth_fail_response (con, "gnunet", failure_response);
545  GNUNET_free (pw);
546  return MHD_YES;
547  }
548  GNUNET_free (pw);
549  }
550 
551  con_handle->pp = MHD_create_post_processor (con,
552  65536,
554  rest_conndata_handle);
555  if (*upload_data_size)
556  {
557  MHD_post_process (con_handle->pp, upload_data, *upload_data_size);
558  }
559  MHD_destroy_post_processor (con_handle->pp);
560 
561  con_handle->state = GN_REST_STATE_PROCESSING;
562  for (ple = plugins_head; NULL != ple; ple = ple->next)
563  {
564  if (GNUNET_YES == ple->plugin->process_request (rest_conndata_handle,
566  con_handle))
567  break; /* Request handled */
568  }
569  if (NULL == ple)
570  {
572  MHD_queue_response (con, MHD_HTTP_NOT_FOUND, failure_response);
573  }
574  *upload_data_size = 0;
575  run_mhd_now ();
576  return MHD_YES;
577  }
578  if (NULL == con_handle->response)
579  {
580  // Suspend connection until plugin is done
581  MHD_suspend_connection (con_handle->con);
582  return MHD_YES;
583  }
584  // MHD_resume_connection (con_handle->con);
586  "Queueing response from plugin with MHD\n");
587  // Handle Preflights for extensions
588  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Checking origin\n");
589  GNUNET_CRYPTO_hash ("origin", strlen ("origin"), &key);
592  &key);
593  if (NULL != origin)
594  {
595  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Origin: %s\n", origin);
596  // Only echo for browser plugins
597  if (GNUNET_YES == echo_origin)
598  {
599  if ((0 ==
600  strncmp ("moz-extension://", origin, strlen ("moz-extension://"))) ||
601  (0 == strncmp ("chrome-extension://",
602  origin,
603  strlen ("chrome-extension://"))))
604  {
605  GNUNET_assert (MHD_NO != MHD_add_response_header (con_handle->response,
606  MHD_HTTP_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN,
607  origin));
608  }
609  }
610  if (NULL != allow_origins)
611  {
612  char *tmp = GNUNET_strdup (allow_origins);
613  char *allow_origin = strtok (tmp, ",");
614  while (NULL != allow_origin)
615  {
616  if (0 == strncmp (allow_origin, origin, strlen (allow_origin)))
617  {
618  GNUNET_assert (MHD_NO != MHD_add_response_header (con_handle->response,
619  MHD_HTTP_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN,
620  allow_origin));
621  break;
622  }
623  allow_origin = strtok (NULL, ",");
624  }
625  GNUNET_free (tmp);
626  }
627  }
628  if (NULL != allow_credentials)
629  {
630  GNUNET_assert (MHD_NO != MHD_add_response_header (con_handle->response,
631  "Access-Control-Allow-Credentials",
633  }
634  if (NULL != allow_headers)
635  {
636  GNUNET_assert (MHD_NO != MHD_add_response_header (con_handle->response,
637  "Access-Control-Allow-Headers",
638  allow_headers));
639  }
640  run_mhd_now ();
641  {
642  MHD_RESULT ret = MHD_queue_response (con,
643  con_handle->status,
644  con_handle->response);
645  // cleanup_handle (con_handle);
646  return ret;
647  }
648 }
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
static char origin[GNUNET_DNSPARSER_MAX_NAME_LENGTH]
Current origin.
static char * allow_origins
Allowed Origins (CORS)
static void plugin_callback(void *cls, struct MHD_Response *resp, int status)
Plugin result callback.
static int basic_auth_enabled
Do basic auth of user.
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)
#define GN_REST_STATE_INIT
static char * allow_headers
Allowed Headers (CORS)
static char * basic_auth_secret
Basic auth secret.
#define GN_REST_STATE_PROCESSING
static int url_iterator(void *cls, enum MHD_ValueKind kind, const char *key, const char *value)
static int header_iterator(void *cls, enum MHD_ValueKind kind, const char *key, const char *value)
static int echo_origin
Echo request Origin in CORS.
static char * allow_credentials
Allowed Credentials (CORS)
static struct MHD_Response * failure_response
Response we return on failures.
static struct PluginListEntry * plugins_head
Plugin list head.
#define MHD_RESULT
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
@ GNUNET_NO
#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_DEBUG
#define GNUNET_new(type)
Allocate a struct or union of the given type.
@ MHD_HTTP_NOT_FOUND
Not Found [RFC7231, Section 6.5.4].
Accepted requests.
enum GNUNET_GenericReturnValue(* process_request)(struct GNUNET_REST_RequestHandle *handle, GNUNET_REST_ResultProcessor proc, void *proc_cls)
Function to process a REST call.
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.
struct GNUNET_REST_RequestHandle * data_handle
struct MHD_PostProcessor * pp
struct MHD_Response * response
struct MHD_Connection * con
A plugin list entry.
struct GNUNET_REST_Plugin * plugin
The plugin.
struct PluginListEntry * next

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_HTTP_NOT_FOUND, MHD_RESULT, PluginListEntry::next, origin, PluginListEntry::plugin, plugin_callback(), plugins_head, post_data_iter(), MhdConnectionHandle::pp, GNUNET_REST_Plugin::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 658 of file gnunet-rest-server.c.

659 {
660  if (NULL != httpd)
661  {
662  MHD_stop_daemon (httpd);
663  httpd = NULL;
664  }
665  if (NULL != httpd_task)
666  {
668  httpd_task = NULL;
669  }
670  if (NULL != ltask4)
671  {
673  ltask4 = NULL;
674  }
675  if (NULL != ltask6)
676  {
678  ltask6 = NULL;
679  }
680 
681  if (NULL != lsock4)
682  {
684  lsock4 = NULL;
685  }
686  if (NULL != lsock6)
687  {
689  lsock6 = NULL;
690  }
691 }
static struct GNUNET_NETWORK_Handle * lsock6
The listen socket of the service for IPv6.
static struct GNUNET_NETWORK_Handle * lsock4
The listen socket of the service for IPv4.
static struct GNUNET_SCHEDULER_Task * ltask6
The listen task ID for IPv6.
static struct GNUNET_SCHEDULER_Task * ltask4
The listen task ID for IPv4.

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

Referenced by do_shutdown(), 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 702 of file gnunet-rest-server.c.

703 {
704  fd_set rs;
705  fd_set ws;
706  fd_set es;
707  struct GNUNET_NETWORK_FDSet *wrs;
708  struct GNUNET_NETWORK_FDSet *wws;
709  int max;
710  int haveto;
711  MHD_UNSIGNED_LONG_LONG timeout;
712  struct GNUNET_TIME_Relative tv;
713 
714  FD_ZERO (&rs);
715  FD_ZERO (&ws);
716  FD_ZERO (&es);
717  max = -1;
718  if (MHD_YES != MHD_get_fdset (httpd, &rs, &ws, &es, &max))
719  {
720  kill_httpd ();
721  return;
722  }
723  haveto = MHD_get_timeout (httpd, &timeout);
724  if (MHD_YES == haveto)
725  tv.rel_value_us = (uint64_t) timeout * 1000LL;
726  else
728  if (-1 != max)
729  {
732  GNUNET_NETWORK_fdset_copy_native (wrs, &rs, max + 1);
733  GNUNET_NETWORK_fdset_copy_native (wws, &ws, max + 1);
734  }
735  else
736  {
737  wrs = NULL;
738  wws = NULL;
739  }
740  if (NULL != httpd_task)
741  {
743  httpd_task = NULL;
744  }
745  if ((MHD_YES == haveto) || (-1 != max))
746  {
748  tv,
749  wrs,
750  wws,
751  &do_httpd,
752  NULL);
753  }
754  if (NULL != wrs)
756  if (NULL != wws)
758 }
static struct GNUNET_TIME_Relative timeout
Desired timeout for the lookup (default is no timeout).
Definition: gnunet-abd.c:61
static void kill_httpd()
Kill the MHD daemon.
@ GNUNET_SCHEDULER_PRIORITY_DEFAULT
Run with the default priority (normal P2P operations).
struct GNUNET_NETWORK_FDSet * GNUNET_NETWORK_fdset_create(void)
Creates an fd set.
Definition: network.c:1170
void GNUNET_NETWORK_fdset_destroy(struct GNUNET_NETWORK_FDSet *fds)
Releases the associated memory of an fd set.
Definition: network.c:1186
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:1040
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_select(enum GNUNET_SCHEDULER_Priority prio, struct GNUNET_TIME_Relative delay, const struct GNUNET_NETWORK_FDSet *rs, const struct GNUNET_NETWORK_FDSet *ws, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay or when any of the specified file descriptor set...
Definition: scheduler.c:1830
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
#define max(x, y)
collection of IO descriptors
Time for relative time used by GNUnet, in microseconds.

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(), and do_httpd().

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 774 of file gnunet-rest-server.c.

777 {
778  struct AcceptedRequest *ar;
779  const union MHD_ConnectionInfo *ci;
780 
781  ci = MHD_get_connection_info (connection,
782  MHD_CONNECTION_INFO_SOCKET_CONTEXT);
783  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Processing %s\n", url);
784  if (NULL == ci)
785  {
786  GNUNET_break (0);
787  return NULL;
788  }
789  ar = ci->socket_context;
790  return ar;
791 }

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 805 of file gnunet-rest-server.c.

809 {
810  struct AcceptedRequest *ar = *con_cls;
811  if (MHD_REQUEST_TERMINATED_COMPLETED_OK != toe)
813  "MHD encountered error handling request: %d\n",
814  toe);
815  if (NULL == ar)
816  return;
817  if (NULL != ar->con_handle)
818  {
820  ar->con_handle = NULL;
821  }
823  *con_cls = NULL;
824 }

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 836 of file gnunet-rest-server.c.

840 {
841  struct AcceptedRequest *ar;
842  const union MHD_ConnectionInfo *ci;
843  int sock;
844 
845  switch (cnc)
846  {
847  case MHD_CONNECTION_NOTIFY_STARTED:
848  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connection started...\n");
849  ci = MHD_get_connection_info (connection,
850  MHD_CONNECTION_INFO_CONNECTION_FD);
851  if (NULL == ci)
852  {
853  GNUNET_break (0);
854  return;
855  }
856  sock = ci->connect_fd;
857  for (ar = req_list_head; NULL != ar; ar = ar->next)
858  {
859  if (GNUNET_NETWORK_get_fd (ar->sock) == sock)
860  {
862  "Context set...\n");
863  *con_cls = ar;
864  break;
865  }
866  }
867  break;
868 
869  case MHD_CONNECTION_NOTIFY_CLOSED:
871  "Connection closed... cleaning up\n");
872  ar = *con_cls;
873  if (NULL == ar)
874  {
876  "Connection stale!\n");
877  return;
878  }
879  cleanup_ar (ar);
880  *con_cls = NULL;
881  break;
882 
883  default:
884  GNUNET_break (0);
885  }
886 }
static void cleanup_ar(struct AcceptedRequest *ar)
int GNUNET_NETWORK_get_fd(const struct GNUNET_NETWORK_Handle *desc)
Return file descriptor for this network handle.
Definition: network.c:1000
struct AcceptedRequest * next
DLL.

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 910 of file gnunet-rest-server.c.

911 {
912  struct GNUNET_NETWORK_Handle *lsock = cls;
913  struct AcceptedRequest *ar;
914  int fd;
915  const struct sockaddr *addr;
916  socklen_t len;
917 
918  GNUNET_assert (NULL != lsock);
919  if (lsock == lsock4)
920  {
922  lsock,
923  &do_accept,
924  lsock);
925  }
926  else if (lsock == lsock6)
927  {
929  lsock,
930  &do_accept,
931  lsock);
932  }
933  else
934  GNUNET_assert (0);
935  ar = GNUNET_new (struct AcceptedRequest);
937  ar->sock = GNUNET_NETWORK_socket_accept (lsock, NULL, NULL);
938  if (NULL == ar->sock)
939  {
940  GNUNET_free (ar);
942  return;
943  }
945  "Got an inbound connection, waiting for data\n");
946  fd = GNUNET_NETWORK_get_fd (ar->sock);
947  addr = GNUNET_NETWORK_get_addr (ar->sock);
951  ar);
952  if (MHD_YES != MHD_add_connection (httpd, fd, addr, len))
953  {
955  GNUNET_free (ar);
957  _ ("Failed to pass client to MHD\n"));
958  return;
959  }
960  schedule_httpd ();
961 }
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...
static void do_accept(void *cls)
Accept new incoming connections.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
#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...
struct sockaddr * GNUNET_NETWORK_get_addr(const struct GNUNET_NETWORK_Handle *desc)
Return the sockaddr for this network handle.
Definition: network.c:1013
socklen_t GNUNET_NETWORK_get_addrlen(const struct GNUNET_NETWORK_Handle *desc)
Return sockaddr length for this network handle.
Definition: network.c:1026
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
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:1506
#define _(String)
GNU gettext support macro.
Definition: platform.h:177
handle to a socket
Definition: network.c:53

References _, 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, len, lsock4, lsock6, ltask4, ltask6, req_list_head, req_list_tail, schedule_httpd(), AcceptedRequest::sock, and AcceptedRequest::socket_with_mhd.

Referenced by 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 970 of file gnunet-rest-server.c.

971 {
972  struct PluginListEntry *ple;
973 
974  while (NULL != plugins_head)
975  {
976  ple = plugins_head;
978  plugins_tail,
979  ple);
980  GNUNET_PLUGIN_unload (ple->libname, ple->plugin);
981  GNUNET_free (ple->libname);
982  GNUNET_free (ple);
983  }
984  GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Shutting down...\n");
985  kill_httpd ();
988 }
static struct PluginListEntry * plugins_tail
Plugin list tail.
@ GNUNET_ERROR_TYPE_INFO
void * GNUNET_PLUGIN_unload(const char *library_name, void *arg)
Unload plugin (runs the "done" callback and returns whatever "done" returned).
Definition: plugin.c:242
char * libname
libname (to cleanup)

References allow_credentials, allow_headers, GNUNET_CONTAINER_DLL_remove, GNUNET_ERROR_TYPE_INFO, GNUNET_free, GNUNET_log, GNUNET_PLUGIN_unload(), kill_httpd(), PluginListEntry::libname, PluginListEntry::plugin, plugins_head, and plugins_tail.

Referenced by run().

Here is the call graph for this function:
Here is the caller 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 997 of file gnunet-rest-server.c.

998 {
999  struct GNUNET_NETWORK_Handle *ls;
1000  struct sockaddr_in sa4;
1001  int eno;
1002 
1003  memset (&sa4, 0, sizeof(sa4));
1004  sa4.sin_family = AF_INET;
1005  sa4.sin_port = htons (port);
1006  sa4.sin_addr.s_addr = address;
1007 #if HAVE_SOCKADDR_IN_SIN_LEN
1008  sa4.sin_len = sizeof(sa4);
1009 #endif
1010  ls = GNUNET_NETWORK_socket_create (AF_INET, SOCK_STREAM, 0);
1011  if (NULL == ls)
1012  return NULL;
1014  (const struct sockaddr *) &sa4,
1015  sizeof(sa4)))
1016  {
1017  eno = errno;
1019  errno = eno;
1020  return NULL;
1021  }
1022  return ls;
1023 }
static struct GNUNET_NETWORK_Handle * ls
Listen socket for STUN processing.
Definition: gnunet-nat.c:85
static unsigned long long port
The port the service is running on (default 7776)
static in_addr_t address
The address to bind to.
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_create(int domain, int type, int protocol)
Create a new socket.
Definition: network.c:832
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

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 1032 of file gnunet-rest-server.c.

1033 {
1034  struct GNUNET_NETWORK_Handle *ls;
1035  struct sockaddr_in6 sa6;
1036  int eno;
1037 
1038  memset (&sa6, 0, sizeof(sa6));
1039  sa6.sin6_family = AF_INET6;
1040  sa6.sin6_port = htons (port);
1041  sa6.sin6_addr = address6;
1042 #if HAVE_SOCKADDR_IN_SIN_LEN
1043  sa6.sin6_len = sizeof(sa6);
1044 #endif
1045  ls = GNUNET_NETWORK_socket_create (AF_INET6, SOCK_STREAM, 0);
1046  if (NULL == ls)
1047  return NULL;
1049  (const struct sockaddr *) &sa6,
1050  sizeof(sa6)))
1051  {
1052  eno = errno;
1054  errno = eno;
1055  return NULL;
1056  }
1057  return ls;
1058 }
static struct in6_addr address6
The IPv6 address to bind to.

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:

◆ load_plugin()

static void load_plugin ( void *  cls,
const char *  libname,
void *  lib_ret 
)
static

Callback for plugin load.

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

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

1070 {
1071  struct GNUNET_REST_Plugin *plugin = lib_ret;
1072  struct PluginListEntry *ple;
1073 
1074  if (NULL == lib_ret)
1075  {
1077  "Could not load plugin `%s'\n",
1078  libname);
1079  return;
1080  }
1081  GNUNET_assert (1 < strlen (plugin->name));
1082  GNUNET_assert ('/' == *plugin->name);
1083  ple = GNUNET_new (struct PluginListEntry);
1084  ple->libname = GNUNET_strdup (libname);
1085  ple->plugin = plugin;
1087  plugins_tail,
1088  ple);
1089  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Loaded plugin `%s'\n", libname);
1090 }
struct TestcasePlugin * plugin
The process handle to the testbed service.
struct returned by the initialization function of the plugin

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

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 1102 of file gnunet-rest-server.c.

1106 {
1107  char *addr_str;
1108  char *basic_auth_file;
1109  uint64_t secret;
1110 
1111  cfg = c;
1112  plugins_head = NULL;
1113  plugins_tail = NULL;
1114  /* Get port to bind to */
1115  if (GNUNET_OK !=
1116  GNUNET_CONFIGURATION_get_value_number (cfg, "rest", "HTTP_PORT", &port))
1117  {
1118  // No address specified
1119  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Using default port...\n");
1121  }
1122 
1123  /* Get address to bind to */
1124  if (GNUNET_OK !=
1125  GNUNET_CONFIGURATION_get_value_string (cfg, "rest", "BIND_TO", &addr_str))
1126  {
1127  // No address specified
1128  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Don't know what to bind to...\n");
1130  return;
1131  }
1132  if (1 != inet_pton (AF_INET, addr_str, &address))
1133  {
1135  "Unable to parse address %s\n",
1136  addr_str);
1137  GNUNET_free (addr_str);
1139  return;
1140  }
1141  GNUNET_free (addr_str);
1142  /* Get address to bind to */
1144  "rest",
1145  "BIND_TO6",
1146  &addr_str))
1147  {
1148  // No address specified
1149  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Don't know what to bind6 to...\n");
1151  return;
1152  }
1153  if (1 != inet_pton (AF_INET6, addr_str, &address6))
1154  {
1156  "Unable to parse IPv6 address %s\n",
1157  addr_str);
1158  GNUNET_free (addr_str);
1160  return;
1161  }
1162  GNUNET_free (addr_str);
1163 
1165  "rest",
1166  "BASIC_AUTH_ENABLED");
1167  if (basic_auth_enabled)
1168  {
1170  "rest",
1171  "BASIC_AUTH_SECRET_FILE",
1172  &basic_auth_file))
1173  {
1175  "No basic auth secret file location set...\n");
1177  return;
1178  }
1179  if (GNUNET_YES != GNUNET_DISK_file_test (basic_auth_file))
1180  {
1182  "No basic auth secret found... generating\n");
1184  UINT64_MAX);
1186  sizeof(secret));
1187  if (GNUNET_OK !=
1188  GNUNET_DISK_fn_write (basic_auth_file,
1190  strlen (basic_auth_secret),
1194  "write",
1195  basic_auth_file);
1196  GNUNET_free (basic_auth_file);
1197  }
1198  else
1199  {
1200  char basic_auth_secret_tmp[16]; // Should be more than enough
1201  memset (basic_auth_secret_tmp, 0, 16);
1202  if (GNUNET_SYSERR == GNUNET_DISK_fn_read (basic_auth_file,
1203  basic_auth_secret_tmp,
1204  sizeof (basic_auth_secret_tmp) - 1))
1205  {
1207  "Unable to read basic auth secret file.\n");
1209  GNUNET_free (basic_auth_file);
1210  return;
1211  }
1212  GNUNET_free (basic_auth_file);
1213  if (0 != getlogin_r (cuser, _POSIX_LOGIN_NAME_MAX))
1214  {
1216  "Unable to get user.\n");
1218  return;
1219  }
1220  basic_auth_secret = GNUNET_strdup (basic_auth_secret_tmp);
1221  }
1222  }
1223 
1224  /* Get CORS data from cfg */
1225  echo_origin =
1227  "rest",
1228  "REST_ECHO_ORIGIN_WEBEXT");
1229  allow_origins = NULL;
1231  "rest",
1232  "REST_ALLOW_ORIGIN",
1233  &allow_origins))
1234  {
1236  "No CORS Access-Control-Allow-Origin header will be sent...\n");
1237  }
1238  if (GNUNET_OK !=
1240  "rest",
1241  "REST_ALLOW_CREDENTIALS",
1243  {
1244  // No origin specified
1246  "No CORS Credential Header will be sent...\n");
1247  }
1248 
1250  "rest",
1251  "REST_ALLOW_HEADERS",
1252  &allow_headers))
1253  {
1254  // No origin specified
1256  "No CORS Access-Control-Allow-Headers Header will be sent...\n");
1257  }
1258 
1259 /* Open listen socket proxy */
1260  lsock6 = bind_v6 ();
1261  if (NULL == lsock6)
1262  {
1264  }
1265  else
1266  {
1268  {
1271  lsock6 = NULL;
1272  }
1273  else
1274  {
1276  lsock6,
1277  &do_accept,
1278  lsock6);
1279  }
1280  }
1281  lsock4 = bind_v4 ();
1282  if (NULL == lsock4)
1283  {
1285  }
1286  else
1287  {
1289  {
1292  lsock4 = NULL;
1293  }
1294  else
1295  {
1297  lsock4,
1298  &do_accept,
1299  lsock4);
1300  }
1301  }
1302  if ((NULL == lsock4) && (NULL == lsock6))
1303  {
1305  return;
1306  }
1307  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Service listens on port %llu\n",
1308  port);
1309  httpd = MHD_start_daemon (MHD_USE_DEBUG | MHD_USE_NO_LISTEN_SOCKET
1310  | MHD_ALLOW_SUSPEND_RESUME,
1311  0,
1312  NULL,
1313  NULL,
1314  &create_response,
1315  NULL,
1316  MHD_OPTION_CONNECTION_TIMEOUT,
1317  (unsigned int) 16,
1318  MHD_OPTION_NOTIFY_CONNECTION,
1320  NULL,
1321  MHD_OPTION_URI_LOG_CALLBACK,
1323  NULL,
1324  MHD_OPTION_NOTIFY_COMPLETED,
1326  NULL,
1327  MHD_OPTION_END);
1328  if (NULL == httpd)
1329  {
1331  return;
1332  }
1333 /* Load plugins */
1335  "libgnunet_plugin_rest",
1336  (void *) cfg,
1337  &load_plugin,
1338  NULL);
1340 }
#define GNUNET_REST_SERVICE_PORT
Default Socks5 listen port.
static void * mhd_log_callback(void *cls, const char *url, struct MHD_Connection *connection)
Function called when MHD first processes an incoming connection.
static struct GNUNET_NETWORK_Handle * bind_v6()
Create an IPv6 listen socket bound to our port.
static const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
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 do_shutdown(void *cls)
Task run on shutdown.
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 load_plugin(void *cls, const char *libname, void *lib_ret)
Callback for plugin load.
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 GNUNET_NETWORK_Handle * bind_v4()
Create an IPv4 listen socket bound to our port.
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:482
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:725
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:664
@ GNUNET_DISK_PERM_USER_READ
Owner can read.
@ GNUNET_DISK_PERM_USER_WRITE
Owner can write.
@ GNUNET_SYSERR
#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...
enum GNUNET_GenericReturnValue GNUNET_NETWORK_socket_listen(const struct GNUNET_NETWORK_Handle *desc, int backlog)
Listen on a socket.
Definition: network.c:651
const struct GNUNET_OS_ProjectData * GNUNET_OS_project_data_default(void)
Return default project data used by 'libgnunetutil' for GNUnet.
void GNUNET_PLUGIN_load_all_in_context(const struct GNUNET_OS_ProjectData *ctx, const char *basename, void *arg, GNUNET_PLUGIN_LoaderCallback cb, void *cb_cls)
Load all compatible plugins with the given base name while inside the given context (i....
Definition: plugin.c:386
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:562
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:1334
char * GNUNET_STRINGS_data_to_string_alloc(const void *buf, size_t size)
Return the base32crockford encoding of the given buffer.
Definition: strings.c:763

References address, address6, allow_credentials, allow_headers, allow_origins, basic_auth_enabled, basic_auth_secret, bind_v4(), bind_v6(), cfg, create_response(), cuser, do_accept(), do_shutdown(), echo_origin, 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_OS_project_data_default(), GNUNET_PLUGIN_load_all_in_context(), 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, load_plugin(), lsock4, lsock6, ltask4, ltask6, mhd_completed_cb(), mhd_connection_cb(), mhd_log_callback(), plugins_head, plugins_tail, and port.

Referenced by main().

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

◆ main()

int main ( int  argc,
char *const *  argv 
)

The main function for gnunet-rest-service.

Parameters
argcnumber of arguments from the cli
argvcommand line arguments
Returns
0 ok, 1 on error

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

1354 {
1357  static const char *err_page = "{}";
1358  int ret;
1359 
1360  if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
1361  return 2;
1362  GNUNET_log_setup ("gnunet-rest-server", "WARNING", NULL);
1363  failure_response = MHD_create_response_from_buffer (strlen (err_page),
1364  (void *) err_page,
1365  MHD_RESPMEM_PERSISTENT);
1366  ret = (GNUNET_OK == GNUNET_PROGRAM_run (argc,
1367  argv,
1368  "gnunet-rest-server",
1369  _ ("GNUnet REST server"),
1370  options,
1371  &run,
1372  NULL))
1373  ? 0
1374  : 1;
1375  MHD_destroy_response (failure_response);
1376  GNUNET_free_nz ((char *) argv);
1377  return ret;
1378 }
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_OPTION_END
Definition: 002.c:13
struct GNUNET_GETOPT_CommandLineOption options[]
Definition: 002.c:5
static void run(void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *c)
Main function that will be run.
int GNUNET_log_setup(const char *comp, const char *loglevel, const char *logfile)
Setup logging.
#define GNUNET_free_nz(ptr)
Wrapper around free.
enum GNUNET_GenericReturnValue GNUNET_PROGRAM_run(int argc, char *const *argv, const char *binaryName, const char *binaryHelp, const struct GNUNET_GETOPT_CommandLineOption *options, GNUNET_PROGRAM_Main task, void *task_cls)
Run a standard GNUnet command startup sequence (initialize loggers and configuration,...
Definition: program.c:400
enum GNUNET_GenericReturnValue GNUNET_STRINGS_get_utf8_args(int argc, char *const *argv, int *u8argc, char *const **u8argv)
Returns utf-8 encoded arguments.
Definition: strings.c:1222
Definition of a command line option.

References _, failure_response, GNUNET_free_nz, GNUNET_GETOPT_OPTION_END, GNUNET_log_setup(), GNUNET_OK, GNUNET_PROGRAM_run(), GNUNET_STRINGS_get_utf8_args(), options, ret, and run().

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 65 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 70 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 70 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 80 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 85 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 90 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 95 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 100 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 105 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 110 of file gnunet-rest-server.c.

Referenced by create_response(), and main().

◆ cfg

const struct GNUNET_CONFIGURATION_Handle* cfg
static

Our configuration.

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

Referenced by run().

◆ echo_origin

int echo_origin
static

Echo request Origin in CORS.

Definition at line 120 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 125 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 130 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 135 of file gnunet-rest-server.c.

Referenced by create_response(), and run().

◆ allow_origins

char* allow_origins
static

Allowed Origins (CORS)

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

Referenced by create_response(), and run().

◆ allow_headers

char* allow_headers
static

Allowed Headers (CORS)

Definition at line 145 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 150 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 155 of file gnunet-rest-server.c.

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

◆ plugins_tail

struct PluginListEntry* plugins_tail
static

Plugin list tail.

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

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

◆ req_list_head

struct AcceptedRequest* req_list_head
static

AcceptedRequest list head.

Definition at line 236 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 241 of file gnunet-rest-server.c.

Referenced by cleanup_ar(), and do_accept().