GNUnet  0.11.x
Data Structures | Macros | Functions | Variables
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 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.

Referenced by run().

◆ 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.

Referenced by create_response().

◆ GN_REST_STATE_PROCESSING

#define GN_REST_STATE_PROCESSING   1

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

Referenced by create_response().

Function Documentation

◆ do_httpd()

static void do_httpd ( void *  cls)
static

Task run whenever HTTP server operations are pending.

Parameters
clsNULL

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

References httpd, and schedule_httpd().

Referenced by run_mhd_now(), and schedule_httpd().

856 {
857  httpd_task = NULL;
858  MHD_run (httpd);
859  schedule_httpd ();
860 }
static struct GNUNET_SCHEDULER_Task * httpd_task
The task ID.
static void schedule_httpd()
Schedule MHD.
static struct MHD_Daemon * httpd
Daemon for HTTP.
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 244 of file gnunet-rest-server.c.

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

Referenced by create_response(), and plugin_callback().

245 {
246  if (NULL != httpd_task)
247  {
249  httpd_task = NULL;
250  }
252 }
static struct GNUNET_SCHEDULER_Task * httpd_task
The task ID.
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:1296
static void do_httpd(void *cls)
Task run whenever HTTP server operations are pending.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:972
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 264 of file gnunet-rest-server.c.

References MhdConnectionHandle::con, handle, MhdConnectionHandle::response, run_mhd_now(), status, and MhdConnectionHandle::status.

Referenced by create_response().

265 {
266  struct MhdConnectionHandle *handle = cls;
267 
268  handle->status = status;
269  handle->response = resp;
270  MHD_resume_connection (handle->con);
271  run_mhd_now ();
272 }
MHD Connection handle.
uint16_t status
See PRISM_STATUS_*-constants.
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
struct MHD_Connection * con
struct MHD_Response * response
static void run_mhd_now()
Run MHD now, we have extra data ready for the callback.
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 276 of file gnunet-rest-server.c.

References GNUNET_free, and GNUNET_YES.

Referenced by cleanup_handle().

277 {
278  GNUNET_free (value);
279  return GNUNET_YES;
280 }
static char * value
Value of the record to add/remove.
#define GNUNET_free(ptr)
Wrapper around free.
Here is the caller graph for this function:

◆ cleanup_handle()

static void cleanup_handle ( struct MhdConnectionHandle handle)
static

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

References cleanup_url_map(), MhdConnectionHandle::data_handle, GNUNET_CONTAINER_multihashmap_destroy(), GNUNET_CONTAINER_multihashmap_iterate(), GNUNET_free, GNUNET_REST_RequestHandle::header_param_map, MhdConnectionHandle::response, and GNUNET_REST_RequestHandle::url_param_map.

Referenced by cleanup_ar(), and mhd_completed_cb().

284 {
285  if (NULL != handle->response)
286  MHD_destroy_response (handle->response);
287  if (NULL != handle->data_handle)
288  {
289  if (NULL != handle->data_handle->header_param_map)
290  {
294  NULL);
296  handle->data_handle->header_param_map);
297  }
298  if (NULL != handle->data_handle->url_param_map)
299  {
302  NULL);
304  handle->data_handle->url_param_map);
305  }
306  GNUNET_free (handle->data_handle);
307  }
308  GNUNET_free (handle);
309 }
struct GNUNET_REST_RequestHandle * data_handle
struct GNUNET_CONTAINER_MultiHashMap * url_param_map
Map of url parameters.
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
static int cleanup_url_map(void *cls, const struct GNUNET_HashCode *key, void *value)
struct GNUNET_CONTAINER_MultiHashMap * header_param_map
Map of headers.
int GNUNET_CONTAINER_multihashmap_iterate(struct GNUNET_CONTAINER_MultiHashMap *map, GNUNET_CONTAINER_MulitHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map.
struct MHD_Response * response
#define GNUNET_free(ptr)
Wrapper around free.
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 312 of file gnunet-rest-server.c.

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

Referenced by mhd_connection_cb().

313 {
314  if (NULL != ar->con_handle)
315  {
317  }
318  if (GNUNET_YES == ar->socket_with_mhd)
319  {
321  } else {
323  }
324  ar->sock = NULL;
327  ar);
328  GNUNET_free (ar);
329 }
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
int socket_with_mhd
State.
static void cleanup_handle(struct MhdConnectionHandle *handle)
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:622
struct MhdConnectionHandle * con_handle
Connection.
static struct AcceptedRequest * req_list_head
AcceptedRequest list head.
struct GNUNET_NETWORK_Handle * sock
Socket.
static struct AcceptedRequest * req_list_tail
AcceptedRequest list tail.
int GNUNET_NETWORK_socket_close(struct GNUNET_NETWORK_Handle *desc)
Close a socket.
Definition: network.c:560
#define GNUNET_free(ptr)
Wrapper around free.
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 332 of file gnunet-rest-server.c.

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, and GNUNET_REST_RequestHandle::header_param_map.

Referenced by create_response().

336 {
337  struct GNUNET_REST_RequestHandle *handle = cls;
338  struct GNUNET_HashCode hkey;
339  char *val;
340  char *lowerkey;
341 
342  lowerkey = GNUNET_strdup (key);
343  GNUNET_STRINGS_utf8_tolower (key, lowerkey);
344  GNUNET_CRYPTO_hash (lowerkey, strlen (lowerkey), &hkey);
345  GNUNET_asprintf (&val, "%s", value);
347  handle->header_param_map,
348  &hkey,
349  val,
351  {
353  "Could not load add header `%s'=%s\n",
354  lowerkey,
355  value);
356  }
357  GNUNET_free (lowerkey);
358  return MHD_YES;
359 }
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
static char * value
Value of the record to add/remove.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:48
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
A 512-bit hashcode.
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
There must only be one value per key; storing a value should fail if a value under the same key alrea...
struct GNUNET_HashCode key
The key used in the DHT.
int 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.
#define GNUNET_log(kind,...)
struct GNUNET_CONTAINER_MultiHashMap * header_param_map
Map of headers.
#define GNUNET_free(ptr)
Wrapper around free.
void GNUNET_STRINGS_utf8_tolower(const char *input, char *output)
Convert the utf-8 input string to lower case.
Definition: strings.c:568
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 363 of file gnunet-rest-server.c.

References GNUNET_asprintf(), GNUNET_CONTAINER_multihashmap_put(), GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY, GNUNET_CRYPTO_hash(), GNUNET_ERROR_TYPE_ERROR, GNUNET_log, GNUNET_OK, handle, MHD_RESULT, and GNUNET_REST_RequestHandle::url_param_map.

Referenced by create_response().

367 {
368  struct GNUNET_REST_RequestHandle *handle = cls;
369  struct GNUNET_HashCode hkey;
370  char *val;
371 
372  GNUNET_CRYPTO_hash (key, strlen (key), &hkey);
373  GNUNET_asprintf (&val, "%s", value);
375  handle->url_param_map,
376  &hkey,
377  val,
379  {
381  "Could not load add url param `%s'=%s\n",
382  key,
383  value);
384  }
385  return MHD_YES;
386 }
static char * value
Value of the record to add/remove.
struct GNUNET_CONTAINER_MultiHashMap * url_param_map
Map of url parameters.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:48
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
A 512-bit hashcode.
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
There must only be one value per key; storing a value should fail if a value under the same key alrea...
struct GNUNET_HashCode key
The key used in the DHT.
int 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.
#define GNUNET_log(kind,...)
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 390 of file gnunet-rest-server.c.

References 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, MHD_RESULT, and GNUNET_REST_RequestHandle::url_param_map.

Referenced by create_response().

399 {
400  struct GNUNET_REST_RequestHandle *handle = cls;
401  struct GNUNET_HashCode hkey;
402  char *val;
403 
404  if (MHD_POSTDATA_KIND != kind)
405  return MHD_YES;
406 
407  GNUNET_CRYPTO_hash (key, strlen (key), &hkey);
409  &hkey);
410  if (NULL == val)
411  {
412  val = GNUNET_malloc (65536);
414  handle->url_param_map,
415  &hkey,
416  val,
418  {
420  "Could not add url param '%s'\n",
421  key);
422  GNUNET_free (val);
423  }
424  }
425  memcpy (val + off, data, size);
426  return MHD_YES;
427 }
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.
struct GNUNET_CONTAINER_MultiHashMap * url_param_map
Map of url parameters.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:48
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
A 512-bit hashcode.
There must only be one value per key; storing a value should fail if a value under the same key alrea...
struct GNUNET_HashCode key
The key used in the DHT.
static unsigned int size
Size of the "table".
Definition: peer.c:67
int 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.
#define GNUNET_log(kind,...)
uint32_t data
The data value.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
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 (i.e. "HTTP/1.1")
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 456 of file gnunet-rest-server.c.

References allow_credentials, allow_headers, allow_origins, MhdConnectionHandle::con, AcceptedRequest::con_handle, 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_break, GNUNET_CONTAINER_multihashmap_create(), GNUNET_CONTAINER_multihashmap_get(), GNUNET_CRYPTO_hash(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_log, GNUNET_new, GNUNET_NO, GNUNET_strdup, GNUNET_YES, header_iterator(), GNUNET_REST_RequestHandle::header_param_map, GNUNET_REST_RequestHandle::method, MHD_RESULT, PluginListEntry::next, PluginListEntry::plugin, plugin_callback(), 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().

464 {
465  char *origin;
466  struct AcceptedRequest *ar;
467  struct GNUNET_HashCode key;
468  struct MhdConnectionHandle *con_handle;
469  struct GNUNET_REST_RequestHandle *rest_conndata_handle;
470  struct PluginListEntry *ple;
471 
472  ar = *con_cls;
473  if (NULL == ar)
474  {
475  GNUNET_break (0);
476  return MHD_NO;
477  }
478 
479  if (NULL == ar->con_handle)
480  {
481  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "New connection %s\n", url);
482  con_handle = GNUNET_new (struct MhdConnectionHandle);
483  con_handle->con = con;
484  con_handle->state = GN_REST_STATE_INIT;
485  ar->con_handle = con_handle;
486  return MHD_YES;
487  }
488  con_handle = ar->con_handle;
489  if (GN_REST_STATE_INIT == con_handle->state)
490  {
491  rest_conndata_handle = GNUNET_new (struct GNUNET_REST_RequestHandle);
492  rest_conndata_handle->method = meth;
493  rest_conndata_handle->url = url;
494  rest_conndata_handle->data = upload_data;
495  rest_conndata_handle->data_size = *upload_data_size;
496  rest_conndata_handle->url_param_map =
498  rest_conndata_handle->header_param_map =
500  con_handle->data_handle = rest_conndata_handle;
501  MHD_get_connection_values (con,
502  MHD_GET_ARGUMENT_KIND,
503  (MHD_KeyValueIterator) & url_iterator,
504  rest_conndata_handle);
505  MHD_get_connection_values (con,
506  MHD_HEADER_KIND,
507  (MHD_KeyValueIterator) & header_iterator,
508  rest_conndata_handle);
509 
510  con_handle->pp = MHD_create_post_processor (con,
511  65536,
513  rest_conndata_handle);
514  if (*upload_data_size)
515  {
516  MHD_post_process (con_handle->pp, upload_data, *upload_data_size);
517  }
518  MHD_destroy_post_processor (con_handle->pp);
519 
520  con_handle->state = GN_REST_STATE_PROCESSING;
521  for (ple = plugins_head; NULL != ple; ple = ple->next)
522  {
523  if (GNUNET_YES == ple->plugin->process_request (rest_conndata_handle,
525  con_handle))
526  break; /* Request handled */
527  }
528  if (NULL == ple)
529  {
531  MHD_queue_response (con, MHD_HTTP_NOT_FOUND, failure_response);
532  }
533  *upload_data_size = 0;
534  run_mhd_now ();
535  return MHD_YES;
536  }
537  if (NULL == con_handle->response)
538  {
539  // Suspend connection until plugin is done
540  MHD_suspend_connection (con_handle->con);
541  return MHD_YES;
542  }
543  //MHD_resume_connection (con_handle->con);
545  "Queueing response from plugin with MHD\n");
546  // Handle Preflights for extensions
547  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Checking origin\n");
548  GNUNET_CRYPTO_hash ("origin", strlen ("origin"), &key);
549  origin = GNUNET_CONTAINER_multihashmap_get (con_handle->data_handle
551  &key);
552  if (NULL != origin)
553  {
554  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Origin: %s\n", origin);
555  // Only echo for browser plugins
556  if (GNUNET_YES == echo_origin)
557  {
558  if ((0 ==
559  strncmp ("moz-extension://", origin, strlen ("moz-extension://"))) ||
560  (0 == strncmp ("chrome-extension://",
561  origin,
562  strlen ("chrome-extension://"))))
563  {
564  MHD_add_response_header (con_handle->response,
565  MHD_HTTP_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN,
566  origin);
567  }
568  }
569  if (NULL != allow_origins)
570  {
571  char *tmp = GNUNET_strdup (allow_origins);
572  char *allow_origin = strtok (tmp, ",");
573  while (NULL != allow_origin)
574  {
575  if (0 == strncmp (allow_origin, origin, strlen (allow_origin)))
576  {
577  MHD_add_response_header (con_handle->response,
578  MHD_HTTP_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN,
579  allow_origin);
580  break;
581  }
582  allow_origin = strtok (NULL, ",");
583  }
584  GNUNET_free (tmp);
585  }
586  }
587  if (NULL != allow_credentials)
588  {
589  MHD_add_response_header (con_handle->response,
590  "Access-Control-Allow-Credentials",
592  }
593  if (NULL != allow_headers)
594  {
595  MHD_add_response_header (con_handle->response,
596  "Access-Control-Allow-Headers",
597  allow_headers);
598  }
599  run_mhd_now ();
600  {
601  MHD_RESULT ret = MHD_queue_response (con,
602  con_handle->status,
603  con_handle->response);
604  //cleanup_handle (con_handle);
605  return ret;
606  }
607 }
static char * allow_headers
Allowed Headers (CORS)
Accepted requests.
static struct MHD_Response * failure_response
Response we return on failures.
struct PluginListEntry * next
size_t data_size
The POST data size.
MHD Connection handle.
struct GNUNET_REST_RequestHandle * data_handle
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
static int url_iterator(void *cls, enum MHD_ValueKind kind, const char *key, const char *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.
static int echo_origin
Echo request Origin in CORS.
static struct PluginListEntry * plugins_head
Plugin list head.
#define GN_REST_STATE_INIT
struct GNUNET_CONTAINER_MultiHashMap * url_param_map
Map of url parameters.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:48
const char * url
The url as string.
struct MhdConnectionHandle * con_handle
Connection.
static char * allow_origins
Allowed Origins (CORS)
const char * method
The HTTP method as MHD value (see microhttpd.h)
static int header_iterator(void *cls, enum MHD_ValueKind kind, const char *key, const char *value)
A plugin list entry.
A 512-bit hashcode.
#define GN_REST_STATE_PROCESSING
const char * data
The POST data.
struct GNUNET_REST_Plugin * plugin
The plugin.
struct GNUNET_HashCode key
The key used in the DHT.
static char * allow_credentials
Allowed Credentials (CORS)
struct MHD_Connection * con
#define MHD_RESULT
Data type to use for functions return an "MHD result".
struct MHD_PostProcessor * pp
#define GNUNET_log(kind,...)
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
struct GNUNET_CONTAINER_MultiHashMap * header_param_map
Map of headers.
enum GNUNET_GenericReturnValue(* process_request)(struct GNUNET_REST_RequestHandle *handle, GNUNET_REST_ResultProcessor proc, void *proc_cls)
Function to process a REST call.
static void plugin_callback(void *cls, struct MHD_Response *resp, int status)
Plugin result callback.
struct MHD_Response * response
static void run_mhd_now()
Run MHD now, we have extra data ready for the callback.
#define GNUNET_free(ptr)
Wrapper around free.
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)
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 617 of file gnunet-rest-server.c.

References GNUNET_NETWORK_socket_close(), GNUNET_SCHEDULER_cancel(), and httpd.

Referenced by do_shutdown(), and schedule_httpd().

618 {
619  if (NULL != httpd)
620  {
621  MHD_stop_daemon (httpd);
622  httpd = NULL;
623  }
624  if (NULL != httpd_task)
625  {
627  httpd_task = NULL;
628  }
629  if (NULL != ltask4)
630  {
632  ltask4 = NULL;
633  }
634  if (NULL != ltask6)
635  {
637  ltask6 = NULL;
638  }
639 
640  if (NULL != lsock4)
641  {
643  lsock4 = NULL;
644  }
645  if (NULL != lsock6)
646  {
648  lsock6 = NULL;
649  }
650 }
static struct GNUNET_SCHEDULER_Task * httpd_task
The task ID.
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_NETWORK_Handle * lsock6
The listen socket of the service for IPv6.
static struct GNUNET_SCHEDULER_Task * ltask4
The listen task ID for IPv4.
static struct MHD_Daemon * httpd
Daemon for HTTP.
int GNUNET_NETWORK_socket_close(struct GNUNET_NETWORK_Handle *desc)
Close a socket.
Definition: network.c:560
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:972
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 661 of file gnunet-rest-server.c.

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, kill_httpd(), GNUNET_TIME_Relative::rel_value_us, and timeout.

Referenced by do_accept(), and do_httpd().

662 {
663  fd_set rs;
664  fd_set ws;
665  fd_set es;
666  struct GNUNET_NETWORK_FDSet *wrs;
667  struct GNUNET_NETWORK_FDSet *wws;
668  int max;
669  int haveto;
670  MHD_UNSIGNED_LONG_LONG timeout;
671  struct GNUNET_TIME_Relative tv;
672 
673  FD_ZERO (&rs);
674  FD_ZERO (&ws);
675  FD_ZERO (&es);
676  max = -1;
677  if (MHD_YES != MHD_get_fdset (httpd, &rs, &ws, &es, &max))
678  {
679  kill_httpd ();
680  return;
681  }
682  haveto = MHD_get_timeout (httpd, &timeout);
683  if (MHD_YES == haveto)
684  tv.rel_value_us = (uint64_t) timeout * 1000LL;
685  else
687  if (-1 != max)
688  {
691  GNUNET_NETWORK_fdset_copy_native (wrs, &rs, max + 1);
692  GNUNET_NETWORK_fdset_copy_native (wws, &ws, max + 1);
693  }
694  else
695  {
696  wrs = NULL;
697  wws = NULL;
698  }
699  if (NULL != httpd_task)
700  {
702  httpd_task = NULL;
703  }
704  if ((MHD_YES == haveto) || (-1 != max))
705  {
707  tv,
708  wrs,
709  wws,
710  &do_httpd,
711  NULL);
712  }
713  if (NULL != wrs)
715  if (NULL != wws)
717 }
static struct GNUNET_SCHEDULER_Task * httpd_task
The task ID.
static void kill_httpd()
Kill the MHD daemon.
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:1120
void GNUNET_NETWORK_fdset_destroy(struct GNUNET_NETWORK_FDSet *fds)
Releases the associated memory of an fd set.
Definition: network.c:1266
struct GNUNET_NETWORK_FDSet * GNUNET_NETWORK_fdset_create(void)
Creates an fd set.
Definition: network.c:1250
static struct GNUNET_TIME_Relative timeout
Desired timeout for the lookup (default is no timeout).
Definition: gnunet-abd.c:61
collection of IO descriptors
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:1841
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
static void do_httpd(void *cls)
Task run whenever HTTP server operations are pending.
static struct MHD_Daemon * httpd
Daemon for HTTP.
Run with the default priority (normal P2P operations).
Time for relative time used by GNUnet, in microseconds.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:972
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 733 of file gnunet-rest-server.c.

References GNUNET_break, GNUNET_ERROR_TYPE_DEBUG, and GNUNET_log.

Referenced by run().

736 {
737  struct AcceptedRequest *ar;
738  const union MHD_ConnectionInfo *ci;
739 
740  ci = MHD_get_connection_info (connection,
741  MHD_CONNECTION_INFO_SOCKET_CONTEXT);
742  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Processing %s\n", url);
743  if (NULL == ci)
744  {
745  GNUNET_break (0);
746  return NULL;
747  }
748  ar = ci->socket_context;
749  return ar;
750 }
Accepted requests.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
#define GNUNET_log(kind,...)
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 764 of file gnunet-rest-server.c.

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

Referenced by run().

768 {
769  struct AcceptedRequest *ar = *con_cls;
770  if (MHD_REQUEST_TERMINATED_COMPLETED_OK != toe)
772  "MHD encountered error handling request: %d\n",
773  toe);
774  if (NULL == ar)
775  return;
776  if (NULL != ar->con_handle)
777  {
779  ar->con_handle = NULL;
780  }
782  *con_cls = NULL;
783 }
Accepted requests.
int socket_with_mhd
State.
static void cleanup_handle(struct MhdConnectionHandle *handle)
struct MhdConnectionHandle * con_handle
Connection.
#define GNUNET_log(kind,...)
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 795 of file gnunet-rest-server.c.

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

Referenced by run().

799 {
800  struct AcceptedRequest *ar;
801  const union MHD_ConnectionInfo *ci;
802  int sock;
803 
804  switch (cnc)
805  {
806  case MHD_CONNECTION_NOTIFY_STARTED:
807  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connection started...\n");
808  ci = MHD_get_connection_info (connection,
809  MHD_CONNECTION_INFO_CONNECTION_FD);
810  if (NULL == ci)
811  {
812  GNUNET_break (0);
813  return;
814  }
815  sock = ci->connect_fd;
816  for (ar = req_list_head; NULL != ar; ar = ar->next)
817  {
818  if (GNUNET_NETWORK_get_fd (ar->sock) == sock)
819  {
821  "Context set...\n");
822  *con_cls = ar;
823  break;
824  }
825  }
826  break;
827 
828  case MHD_CONNECTION_NOTIFY_CLOSED:
830  "Connection closed... cleaning up\n");
831  ar = *con_cls;
832  if (NULL == ar)
833  {
835  "Connection stale!\n");
836  return;
837  }
838  cleanup_ar (ar);
839  *con_cls = NULL;
840  break;
841 
842  default:
843  GNUNET_break (0);
844  }
845 }
int GNUNET_NETWORK_get_fd(const struct GNUNET_NETWORK_Handle *desc)
Return file descriptor for this network handle.
Definition: network.c:1080
Accepted requests.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
static void cleanup_ar(struct AcceptedRequest *ar)
struct AcceptedRequest * next
DLL.
static struct AcceptedRequest * req_list_head
AcceptedRequest list head.
#define GNUNET_log(kind,...)
struct GNUNET_NETWORK_Handle * sock
Socket.
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
tcthe scheduler context

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

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, schedule_httpd(), AcceptedRequest::sock, and AcceptedRequest::socket_with_mhd.

Referenced by run().

871 {
872  struct GNUNET_NETWORK_Handle *lsock = cls;
873  struct AcceptedRequest *ar;
874  int fd;
875  const struct sockaddr *addr;
876  socklen_t len;
877 
878  GNUNET_assert (NULL != lsock);
879  if (lsock == lsock4)
880  {
882  lsock,
883  &do_accept,
884  lsock);
885  }
886  else if (lsock == lsock6)
887  {
889  lsock,
890  &do_accept,
891  lsock);
892  }
893  else
894  GNUNET_assert (0);
895  ar = GNUNET_new (struct AcceptedRequest);
897  ar->sock = GNUNET_NETWORK_socket_accept (lsock, NULL, NULL);
898  if (NULL == ar->sock)
899  {
900  GNUNET_free (ar);
902  return;
903  }
905  "Got an inbound connection, waiting for data\n");
906  fd = GNUNET_NETWORK_get_fd (ar->sock);
907  addr = GNUNET_NETWORK_get_addr (ar->sock);
908  len = GNUNET_NETWORK_get_addrlen (ar->sock);
911  ar);
912  if (MHD_YES != MHD_add_connection (httpd, fd, addr, len))
913  {
915  GNUNET_free (ar);
917  _ ("Failed to pass client to MHD\n"));
918  return;
919  }
920  schedule_httpd ();
921 }
int GNUNET_NETWORK_get_fd(const struct GNUNET_NETWORK_Handle *desc)
Return file descriptor for this network handle.
Definition: network.c:1080
Accepted requests.
struct sockaddr * GNUNET_NETWORK_get_addr(const struct GNUNET_NETWORK_Handle *desc)
Return the sockaddr for this network handle.
Definition: network.c:1093
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
socklen_t GNUNET_NETWORK_get_addrlen(const struct GNUNET_NETWORK_Handle *desc)
Return sockaddr length for this network handle.
Definition: network.c:1106
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static void do_accept(void *cls)
Accept new incoming connections.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
int socket_with_mhd
State.
#define _(String)
GNU gettext support macro.
Definition: platform.h:184
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:430
#define GNUNET_log_strerror(level, cmd)
Log an error message at log-level &#39;level&#39; that indicates a failure of the command &#39;cmd&#39; with the mess...
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.
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
static struct GNUNET_NETWORK_Handle * lsock6
The listen socket of the service for IPv6.
static struct GNUNET_SCHEDULER_Task * ltask4
The listen task ID for IPv4.
static void schedule_httpd()
Schedule MHD.
static struct AcceptedRequest * req_list_head
AcceptedRequest list head.
#define GNUNET_log(kind,...)
static struct MHD_Daemon * httpd
Daemon for HTTP.
struct GNUNET_NETWORK_Handle * sock
Socket.
handle to a socket
Definition: network.c:52
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:1517
static struct AcceptedRequest * req_list_tail
AcceptedRequest list tail.
int GNUNET_NETWORK_socket_close(struct GNUNET_NETWORK_Handle *desc)
Close a socket.
Definition: network.c:560
#define GNUNET_free(ptr)
Wrapper around free.
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...
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 930 of file gnunet-rest-server.c.

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, and plugins_head.

Referenced by run().

931 {
932  struct PluginListEntry *ple;
933 
934  while (NULL != plugins_head)
935  {
936  ple = plugins_head;
938  plugins_tail,
939  ple);
940  GNUNET_PLUGIN_unload (ple->libname, ple->plugin);
941  GNUNET_free (ple->libname);
942  GNUNET_free (ple);
943  }
944  GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Shutting down...\n");
945  kill_httpd ();
948 }
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
static struct PluginListEntry * plugins_tail
Plugin list tail.
static char * allow_headers
Allowed Headers (CORS)
static void kill_httpd()
Kill the MHD daemon.
void * GNUNET_PLUGIN_unload(const char *library_name, void *arg)
Unload plugin (runs the "done" callback and returns whatever "done" returned).
Definition: plugin.c:256
static struct PluginListEntry * plugins_head
Plugin list head.
char * libname
libname (to cleanup)
A plugin list entry.
struct GNUNET_REST_Plugin * plugin
The plugin.
static char * allow_credentials
Allowed Credentials (CORS)
#define GNUNET_log(kind,...)
#define GNUNET_free(ptr)
Wrapper around free.
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 957 of file gnunet-rest-server.c.

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

Referenced by run().

958 {
959  struct GNUNET_NETWORK_Handle *ls;
960  struct sockaddr_in sa4;
961  int eno;
962 
963  memset (&sa4, 0, sizeof(sa4));
964  sa4.sin_family = AF_INET;
965  sa4.sin_port = htons (port);
966  sa4.sin_addr.s_addr = address;
967 #if HAVE_SOCKADDR_IN_SIN_LEN
968  sa4.sin_len = sizeof(sa4);
969 #endif
970  ls = GNUNET_NETWORK_socket_create (AF_INET, SOCK_STREAM, 0);
971  if (NULL == ls)
972  return NULL;
974  (const struct sockaddr *) &sa4,
975  sizeof(sa4)))
976  {
977  eno = errno;
979  errno = eno;
980  return NULL;
981  }
982  return ls;
983 }
static unsigned long long port
The port the service is running on (default 7776)
int 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:485
static in_addr_t address
The address to bind to.
static struct GNUNET_NETWORK_Handle * ls
Listen socket for STUN processing.
Definition: gnunet-nat.c:85
handle to a socket
Definition: network.c:52
int GNUNET_NETWORK_socket_close(struct GNUNET_NETWORK_Handle *desc)
Close a socket.
Definition: network.c:560
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_create(int domain, int type, int protocol)
Create a new socket.
Definition: network.c:912
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 992 of file gnunet-rest-server.c.

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

Referenced by run().

993 {
994  struct GNUNET_NETWORK_Handle *ls;
995  struct sockaddr_in6 sa6;
996  int eno;
997 
998  memset (&sa6, 0, sizeof(sa6));
999  sa6.sin6_family = AF_INET6;
1000  sa6.sin6_port = htons (port);
1001  sa6.sin6_addr = address6;
1002 #if HAVE_SOCKADDR_IN_SIN_LEN
1003  sa6.sin6_len = sizeof(sa6);
1004 #endif
1005  ls = GNUNET_NETWORK_socket_create (AF_INET6, SOCK_STREAM, 0);
1006  if (NULL == ls)
1007  return NULL;
1009  (const struct sockaddr *) &sa6,
1010  sizeof(sa6)))
1011  {
1012  eno = errno;
1014  errno = eno;
1015  return NULL;
1016  }
1017  return ls;
1018 }
static unsigned long long port
The port the service is running on (default 7776)
static struct in6_addr address6
The IPv6 address to bind to.
int 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:485
static struct GNUNET_NETWORK_Handle * ls
Listen socket for STUN processing.
Definition: gnunet-nat.c:85
handle to a socket
Definition: network.c:52
int GNUNET_NETWORK_socket_close(struct GNUNET_NETWORK_Handle *desc)
Close a socket.
Definition: network.c:560
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_create(int domain, int type, int protocol)
Create a new socket.
Definition: network.c:912
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 1029 of file gnunet-rest-server.c.

References GNUNET_assert, GNUNET_CONTAINER_DLL_insert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_new, GNUNET_strdup, PluginListEntry::libname, GNUNET_REST_Plugin::name, and PluginListEntry::plugin.

Referenced by run().

1030 {
1031  struct GNUNET_REST_Plugin *plugin = lib_ret;
1032  struct PluginListEntry *ple;
1033 
1034  if (NULL == lib_ret)
1035  {
1037  "Could not load plugin `%s'\n",
1038  libname);
1039  return;
1040  }
1041  GNUNET_assert (1 < strlen (plugin->name));
1042  GNUNET_assert ('/' == *plugin->name);
1043  ple = GNUNET_new (struct PluginListEntry);
1044  ple->libname = GNUNET_strdup (libname);
1045  ple->plugin = plugin;
1047  plugins_tail,
1048  ple);
1049  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Loaded plugin `%s'\n", libname);
1050 }
static struct PluginListEntry * plugins_tail
Plugin list tail.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
struct returned by the initialization function of the plugin
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
static struct PluginListEntry * plugins_head
Plugin list head.
char * name
Plugin name.
char * libname
libname (to cleanup)
A plugin list entry.
static char * plugin
Solver plugin name as string.
struct GNUNET_REST_Plugin * plugin
The plugin.
#define GNUNET_log(kind,...)
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 1062 of file gnunet-rest-server.c.

References address, address6, allow_credentials, allow_headers, allow_origins, bind_v4(), bind_v6(), create_response(), do_accept(), do_shutdown(), echo_origin, GNUNET_CONFIGURATION_get_value_number(), GNUNET_CONFIGURATION_get_value_string(), GNUNET_CONFIGURATION_get_value_yesno(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_ERROR_TYPE_INFO, GNUNET_free, GNUNET_log, GNUNET_log_strerror, GNUNET_NETWORK_socket_close(), GNUNET_NETWORK_socket_listen(), GNUNET_OK, GNUNET_PLUGIN_load_all(), GNUNET_REST_SERVICE_PORT, GNUNET_SCHEDULER_add_read_net(), GNUNET_SCHEDULER_add_shutdown(), GNUNET_SCHEDULER_shutdown(), GNUNET_TIME_UNIT_FOREVER_REL, httpd, load_plugin(), mhd_completed_cb(), mhd_connection_cb(), mhd_log_callback(), and port.

Referenced by main().

1066 {
1067  char *addr_str;
1068 
1069  cfg = c;
1070  plugins_head = NULL;
1071  plugins_tail = NULL;
1072  /* Get port to bind to */
1073  if (GNUNET_OK !=
1074  GNUNET_CONFIGURATION_get_value_number (cfg, "rest", "HTTP_PORT", &port))
1075  {
1076  // No address specified
1077  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Using default port...\n");
1079  }
1080 
1081  /* Get address to bind to */
1082  if (GNUNET_OK !=
1083  GNUNET_CONFIGURATION_get_value_string (cfg, "rest", "BIND_TO", &addr_str))
1084  {
1085  // No address specified
1086  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Don't know what to bind to...\n");
1088  return;
1089  }
1090  if (1 != inet_pton (AF_INET, addr_str, &address))
1091  {
1093  "Unable to parse address %s\n",
1094  addr_str);
1095  GNUNET_free (addr_str);
1097  return;
1098  }
1099  GNUNET_free (addr_str);
1100  /* Get address to bind to */
1102  "rest",
1103  "BIND_TO6",
1104  &addr_str))
1105  {
1106  // No address specified
1107  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Don't know what to bind6 to...\n");
1109  return;
1110  }
1111  if (1 != inet_pton (AF_INET6, addr_str, &address6))
1112  {
1114  "Unable to parse IPv6 address %s\n",
1115  addr_str);
1116  GNUNET_free (addr_str);
1118  return;
1119  }
1120  GNUNET_free (addr_str);
1121 
1122 
1123  /* Get CORS data from cfg */
1124  echo_origin =
1126  "rest",
1127  "REST_ECHO_ORIGIN_WEBEXT");
1128  allow_origins = NULL;
1130  "rest",
1131  "REST_ALLOW_ORIGIN",
1132  &allow_origins))
1133  {
1135  "No CORS Access-Control-Allow-Origin header will be sent...\n");
1136  }
1137  if (GNUNET_OK !=
1139  "rest",
1140  "REST_ALLOW_CREDENTIALS",
1142  {
1143  // No origin specified
1145  "No CORS Credential Header will be sent...\n");
1146  }
1147 
1149  "rest",
1150  "REST_ALLOW_HEADERS",
1151  &allow_headers))
1152  {
1153  // No origin specified
1155  "No CORS Access-Control-Allow-Headers Header will be sent...\n");
1156  }
1157 
1158  /* Open listen socket proxy */
1159  lsock6 = bind_v6 ();
1160  if (NULL == lsock6)
1161  {
1163  }
1164  else
1165  {
1167  {
1170  lsock6 = NULL;
1171  }
1172  else
1173  {
1175  lsock6,
1176  &do_accept,
1177  lsock6);
1178  }
1179  }
1180  lsock4 = bind_v4 ();
1181  if (NULL == lsock4)
1182  {
1184  }
1185  else
1186  {
1188  {
1191  lsock4 = NULL;
1192  }
1193  else
1194  {
1196  lsock4,
1197  &do_accept,
1198  lsock4);
1199  }
1200  }
1201  if ((NULL == lsock4) && (NULL == lsock6))
1202  {
1204  return;
1205  }
1206  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Service listens on port %llu\n", port);
1207  httpd = MHD_start_daemon (MHD_USE_DEBUG | MHD_USE_NO_LISTEN_SOCKET
1208  | MHD_ALLOW_SUSPEND_RESUME,
1209  0,
1210  NULL,
1211  NULL,
1212  &create_response,
1213  NULL,
1214  MHD_OPTION_CONNECTION_TIMEOUT,
1215  (unsigned int) 16,
1216  MHD_OPTION_NOTIFY_CONNECTION,
1218  NULL,
1219  MHD_OPTION_URI_LOG_CALLBACK,
1221  NULL,
1222  MHD_OPTION_NOTIFY_COMPLETED,
1224  NULL,
1225  MHD_OPTION_END);
1226  if (NULL == httpd)
1227  {
1229  return;
1230  }
1231  /* Load plugins */
1232  GNUNET_PLUGIN_load_all ("libgnunet_plugin_rest",
1233  (void *) cfg,
1234  &load_plugin,
1235  NULL);
1237 }
int GNUNET_NETWORK_socket_listen(const struct GNUNET_NETWORK_Handle *desc, int backlog)
Listen on a socket.
Definition: network.c:708
static struct PluginListEntry * plugins_tail
Plugin list tail.
static char * allow_headers
Allowed Headers (CORS)
static unsigned long long port
The port the service is running on (default 7776)
int 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.
static void load_plugin(void *cls, const char *libname, void *lib_ret)
Callback for plugin load.
#define GNUNET_REST_SERVICE_PORT
Default Socks5 listen port.
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, or when GNUNET_SCHEDULER_shutdown() is being invoked.
Definition: scheduler.c:1331
static void do_accept(void *cls)
Accept new incoming connections.
static struct in6_addr address6
The IPv6 address to bind to.
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:531
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.
#define GNUNET_log_strerror(level, cmd)
Log an error message at log-level &#39;level&#39; that indicates a failure of the command &#39;cmd&#39; with the mess...
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 int echo_origin
Echo request Origin in CORS.
static struct PluginListEntry * plugins_head
Plugin list head.
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 char * allow_origins
Allowed Origins (CORS)
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
static void do_shutdown(void *cls)
Task run on shutdown.
static in_addr_t address
The address to bind to.
static struct GNUNET_NETWORK_Handle * lsock6
The listen socket of the service for IPv6.
int 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.
static struct GNUNET_SCHEDULER_Task * ltask4
The listen task ID for IPv4.
void GNUNET_PLUGIN_load_all(const char *basename, void *arg, GNUNET_PLUGIN_LoaderCallback cb, void *cb_cls)
Load all compatible plugins with the given base name.
Definition: plugin.c:372
static char * allow_credentials
Allowed Credentials (CORS)
static struct GNUNET_NETWORK_Handle * bind_v6()
Create an IPv6 listen socket bound to our port.
static void * mhd_log_callback(void *cls, const char *url, struct MHD_Connection *connection)
Function called when MHD first processes an incoming connection.
#define GNUNET_log(kind,...)
static struct MHD_Daemon * httpd
Daemon for HTTP.
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:1517
int 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".
static const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
int GNUNET_NETWORK_socket_close(struct GNUNET_NETWORK_Handle *desc)
Close a socket.
Definition: network.c:560
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.
#define GNUNET_free(ptr)
Wrapper around free.
static struct GNUNET_NETWORK_Handle * bind_v4()
Create an IPv4 listen socket bound to our port.
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 1250 of file gnunet-rest-server.c.

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

1251 {
1254  static const char *err_page = "{}";
1255  int ret;
1256 
1257  if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
1258  return 2;
1259  GNUNET_log_setup ("gnunet-rest-server", "WARNING", NULL);
1260  failure_response = MHD_create_response_from_buffer (strlen (err_page),
1261  (void *) err_page,
1262  MHD_RESPMEM_PERSISTENT);
1263  ret = (GNUNET_OK == GNUNET_PROGRAM_run (argc,
1264  argv,
1265  "gnunet-rest-server",
1266  _ ("GNUnet REST server"),
1267  options,
1268  &run,
1269  NULL))
1270  ? 0
1271  : 1;
1272  MHD_destroy_response (failure_response);
1273  GNUNET_free_nz ((char *) argv);
1274  return ret;
1275 }
static struct MHD_Response * failure_response
Response we return on failures.
struct GNUNET_GETOPT_CommandLineOption options[]
Definition: 002.c:5
int GNUNET_STRINGS_get_utf8_args(int argc, char *const *argv, int *u8argc, char *const **u8argv)
Returns utf-8 encoded arguments.
Definition: strings.c:1459
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
Definition of a command line option.
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_OPTION_END
Definition: 002.c:13
#define _(String)
GNU gettext support macro.
Definition: platform.h:184
#define GNUNET_free_nz(ptr)
Wrapper around free.
int 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, parse options).
Definition: program.c:372
int GNUNET_log_setup(const char *comp, const char *loglevel, const char *logfile)
Setup logging.
static void run(void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *c)
Main function that will be 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.

◆ 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 75 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.

◆ 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.

◆ ltask4

struct GNUNET_SCHEDULER_Task* ltask4
static

The listen task ID for IPv4.

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

◆ ltask6

struct GNUNET_SCHEDULER_Task* ltask6
static

The listen task ID for IPv6.

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

◆ 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.

◆ 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().

◆ allow_origins

char* allow_origins
static

Allowed Origins (CORS)

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

Referenced by create_response(), and run().

◆ allow_headers

char* allow_headers
static

Allowed Headers (CORS)

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

Referenced by do_shutdown().

◆ plugins_tail

struct PluginListEntry* plugins_tail
static

Plugin list tail.

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

◆ req_list_head

struct AcceptedRequest* req_list_head
static

AcceptedRequest list head.

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

◆ req_list_tail

struct AcceptedRequest* req_list_tail
static

AcceptedRequest list tail.

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