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 dependency graph for gnunet-rest-server.c:

Go to the source code of this file.

Data Structures

struct  MhdConnectionHandle
 MHD Connection handle. 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 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 int 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 int 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 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 kill_httpd ()
 Kill the MHD daemon. More...
 
static void schedule_httpd ()
 Schedule MHD. 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 struct GNUNET_CONTAINER_MultiHashMapplugin_map
 Map of loaded plugins. 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...
 

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

References httpd, and schedule_httpd().

Referenced by run_mhd_now(), and schedule_httpd().

656 {
657  httpd_task = NULL;
658  MHD_run (httpd);
659  schedule_httpd ();
660 }
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 178 of file gnunet-rest-server.c.

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

Referenced by create_response(), and plugin_callback().

179 {
180  if (NULL != httpd_task)
181  {
183  httpd_task = NULL;
184  }
186 }
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:1280
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:966
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 198 of file gnunet-rest-server.c.

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

Referenced by create_response().

199 {
200  struct MhdConnectionHandle *handle = cls;
201 
202  handle->status = status;
203  handle->response = resp;
204  MHD_resume_connection (handle->con);
205  run_mhd_now ();
206 }
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 210 of file gnunet-rest-server.c.

References GNUNET_free_non_null, and GNUNET_YES.

Referenced by cleanup_handle().

211 {
213  return GNUNET_YES;
214 }
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
static char * value
Value of the record to add/remove.
#define GNUNET_YES
Definition: gnunet_common.h:77
Here is the caller graph for this function:

◆ cleanup_handle()

static void cleanup_handle ( struct MhdConnectionHandle handle)
static

Definition at line 218 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 create_response().

219 {
220  if (NULL != handle->response)
221  MHD_destroy_response (handle->response);
222  if (NULL != handle->data_handle)
223  {
224  if (NULL != handle->data_handle->header_param_map)
225  {
229  NULL);
231  handle->data_handle->header_param_map);
232  }
233  if (NULL != handle->data_handle->url_param_map)
234  {
237  NULL);
239  handle->data_handle->url_param_map);
240  }
241  GNUNET_free (handle->data_handle);
242  }
243  GNUNET_free (handle);
244 }
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:

◆ header_iterator()

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

Definition at line 248 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().

252 {
253  struct GNUNET_REST_RequestHandle *handle = cls;
254  struct GNUNET_HashCode hkey;
255  char *val;
256  char *lowerkey;
257 
258  lowerkey = GNUNET_strdup (key);
259  GNUNET_STRINGS_utf8_tolower (key, lowerkey);
260  GNUNET_CRYPTO_hash (lowerkey, strlen (lowerkey), &hkey);
261  GNUNET_asprintf (&val, "%s", value);
263  handle->header_param_map,
264  &hkey,
265  val,
267  {
269  "Could not load add header `%s'=%s\n",
270  lowerkey,
271  value);
272  }
273  GNUNET_free (lowerkey);
274  return MHD_YES;
275 }
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
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.
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:553
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 279 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, and GNUNET_REST_RequestHandle::url_param_map.

Referenced by create_response().

283 {
284  struct GNUNET_REST_RequestHandle *handle = cls;
285  struct GNUNET_HashCode hkey;
286  char *val;
287 
288  GNUNET_CRYPTO_hash (key, strlen (key), &hkey);
289  GNUNET_asprintf (&val, "%s", value);
291  handle->url_param_map,
292  &hkey,
293  val,
295  {
297  "Could not load add url param `%s'=%s\n",
298  key,
299  value);
300  }
301  return MHD_YES;
302 }
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
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.
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 int 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 306 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, handle, and GNUNET_REST_RequestHandle::url_param_map.

Referenced by create_response().

315 {
316  struct GNUNET_REST_RequestHandle *handle = cls;
317  struct GNUNET_HashCode hkey;
318  char *val;
319 
320  if (MHD_POSTDATA_KIND != kind)
321  return MHD_YES;
322 
323  GNUNET_CRYPTO_hash (key, strlen (key), &hkey);
324  GNUNET_asprintf (&val, "%s", data);
326  handle->url_param_map,
327  &hkey,
328  val,
330  {
332  "Could not load add url param '%s'=%s\n",
333  key,
334  data);
335  GNUNET_free (val);
336  }
337  return MHD_YES;
338 }
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
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.
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_free(ptr)
Wrapper around free.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ create_response()

static int 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

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

References allow_credentials, allow_headers, allow_origins, cleanup_handle(), MhdConnectionHandle::con, 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_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, MhdConnectionHandle::plugin, plugin_callback(), plugin_name, 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().

375 {
376  char *plugin_name;
377  char *origin;
378  struct GNUNET_HashCode key;
379  struct MhdConnectionHandle *con_handle;
380  struct GNUNET_REST_RequestHandle *rest_conndata_handle;
381 
382  con_handle = *con_cls;
383 
384  if (NULL == *con_cls)
385  {
386  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "New connection %s\n", url);
387  char tmp_url[strlen (url) + 1];
388  strcpy (tmp_url, url);
389  con_handle = GNUNET_new (struct MhdConnectionHandle);
390  con_handle->con = con;
391  con_handle->state = GN_REST_STATE_INIT;
392  *con_cls = con_handle;
393 
394  plugin_name = strtok (tmp_url, "/");
395 
396  if (NULL != plugin_name)
397  {
398  GNUNET_CRYPTO_hash (plugin_name, strlen (plugin_name), &key);
399 
401  }
402  if (NULL == con_handle->plugin)
403  {
404  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Queueing response with MHD\n");
405  GNUNET_free (con_handle);
406  return MHD_queue_response (con, MHD_HTTP_NOT_FOUND, failure_response);
407  }
408 
409  return MHD_YES;
410  }
411  if (GN_REST_STATE_INIT == con_handle->state)
412  {
413  rest_conndata_handle = GNUNET_new (struct GNUNET_REST_RequestHandle);
414  rest_conndata_handle->method = meth;
415  rest_conndata_handle->url = url;
416  rest_conndata_handle->data = upload_data;
417  rest_conndata_handle->data_size = *upload_data_size;
418  rest_conndata_handle->url_param_map =
420  rest_conndata_handle->header_param_map =
422  con_handle->data_handle = rest_conndata_handle;
423  MHD_get_connection_values (con,
424  MHD_GET_ARGUMENT_KIND,
425  (MHD_KeyValueIterator) & url_iterator,
426  rest_conndata_handle);
427  MHD_get_connection_values (con,
428  MHD_HEADER_KIND,
429  (MHD_KeyValueIterator) & header_iterator,
430  rest_conndata_handle);
431  con_handle->pp = MHD_create_post_processor (con,
432  65536,
434  rest_conndata_handle);
435  if (*upload_data_size)
436  {
437  MHD_post_process (con_handle->pp, upload_data, *upload_data_size);
438  }
439  MHD_destroy_post_processor (con_handle->pp);
440 
441  con_handle->state = GN_REST_STATE_PROCESSING;
442  con_handle->plugin->process_request (rest_conndata_handle,
444  con_handle);
445  *upload_data_size = 0;
446  run_mhd_now ();
447  return MHD_YES;
448  }
449  if (NULL == con_handle->response)
450  {
451  // Suspend connection until plugin is done
452  MHD_suspend_connection (con_handle->con);
453  return MHD_YES;
454  }
455  MHD_resume_connection (con_handle->con);
457  "Queueing response from plugin with MHD\n");
458  // Handle Preflights for extensions
459  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Checking origin\n");
460  GNUNET_CRYPTO_hash ("origin", strlen ("origin"), &key);
461  origin = GNUNET_CONTAINER_multihashmap_get (con_handle->data_handle
463  &key);
464  if (NULL != origin)
465  {
466  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Origin: %s\n", origin);
467  // Only echo for browser plugins
468  if (GNUNET_YES == echo_origin)
469  {
470  if ((0 ==
471  strncmp ("moz-extension://", origin, strlen ("moz-extension://"))) ||
472  (0 == strncmp ("chrome-extension://",
473  origin,
474  strlen ("chrome-extension://"))))
475  {
476  MHD_add_response_header (con_handle->response,
477  MHD_HTTP_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN,
478  origin);
479  }
480  }
481  if (NULL != allow_origins)
482  {
483  char *tmp = GNUNET_strdup (allow_origins);
484  char *allow_origin = strtok (tmp, ",");
485  while (NULL != allow_origin)
486  {
487  if (0 == strncmp (allow_origin, origin, strlen (allow_origin)))
488  {
489  MHD_add_response_header (con_handle->response,
490  MHD_HTTP_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN,
491  allow_origin);
492  break;
493  }
494  allow_origin = strtok (NULL, ",");
495  }
496  GNUNET_free (tmp);
497  }
498  }
499  if (NULL != allow_credentials)
500  {
501  MHD_add_response_header (con_handle->response,
502  "Access-Control-Allow-Credentials",
504  }
505  if (NULL != allow_headers)
506  {
507  MHD_add_response_header (con_handle->response,
508  "Access-Control-Allow-Headers",
509  allow_headers);
510  }
511  run_mhd_now ();
512  int ret = MHD_queue_response (con, con_handle->status, con_handle->response);
513  cleanup_handle (con_handle);
514  return ret;
515 }
static char * allow_headers
Allowed Headers (CORS)
static struct MHD_Response * failure_response
Response we return on failures.
size_t data_size
The POST data size.
MHD Connection handle.
struct GNUNET_REST_RequestHandle * data_handle
struct GNUNET_REST_Plugin * plugin
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_new(type)
Allocate a struct or union of the given type.
void(* process_request)(struct GNUNET_REST_RequestHandle *handle, GNUNET_REST_ResultProcessor proc, void *proc_cls)
Function to process a REST call.
static void cleanup_handle(struct MhdConnectionHandle *handle)
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
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.
#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.
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 512-bit hashcode.
#define GN_REST_STATE_PROCESSING
const char * data
The POST data.
struct GNUNET_HashCode key
The key used in the DHT.
static char * allow_credentials
Allowed Credentials (CORS)
struct MHD_Connection * con
static struct GNUNET_CONTAINER_MultiHashMap * plugin_map
Map of loaded plugins.
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.
#define GNUNET_YES
Definition: gnunet_common.h:77
struct GNUNET_CONTAINER_MultiHashMap * header_param_map
Map of headers.
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.
static char * plugin_name
Name of our plugin.
#define GNUNET_free(ptr)
Wrapper around free.
static int 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:

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

References GNUNET_ERROR_TYPE_ERROR, and GNUNET_log.

Referenced by run().

534 {
535  if (MHD_REQUEST_TERMINATED_COMPLETED_OK != toe)
537  "MHD encountered error handling request: %d\n",
538  toe);
539 }
#define GNUNET_log(kind,...)
Here is the caller graph for this function:

◆ kill_httpd()

static void kill_httpd ( )
static

Kill the MHD daemon.

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

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

Referenced by do_shutdown(), and schedule_httpd().

547 {
548  if (NULL != httpd)
549  {
550  MHD_stop_daemon (httpd);
551  httpd = NULL;
552  }
553  if (NULL != httpd_task)
554  {
556  httpd_task = NULL;
557  }
558  if (NULL != ltask4)
559  {
561  ltask4 = NULL;
562  }
563  if (NULL != ltask6)
564  {
566  ltask6 = NULL;
567  }
568 
569  if (NULL != lsock4)
570  {
572  lsock4 = NULL;
573  }
574  if (NULL != lsock6)
575  {
577  lsock6 = NULL;
578  }
579 }
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:966
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 590 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().

591 {
592  fd_set rs;
593  fd_set ws;
594  fd_set es;
595  struct GNUNET_NETWORK_FDSet *wrs;
596  struct GNUNET_NETWORK_FDSet *wws;
597  int max;
598  int haveto;
599  MHD_UNSIGNED_LONG_LONG timeout;
600  struct GNUNET_TIME_Relative tv;
601 
602  FD_ZERO (&rs);
603  FD_ZERO (&ws);
604  FD_ZERO (&es);
605  max = -1;
606  if (MHD_YES != MHD_get_fdset (httpd, &rs, &ws, &es, &max))
607  {
608  kill_httpd ();
609  return;
610  }
611  haveto = MHD_get_timeout (httpd, &timeout);
612  if (MHD_YES == haveto)
613  tv.rel_value_us = (uint64_t) timeout * 1000LL;
614  else
616  if (-1 != max)
617  {
620  GNUNET_NETWORK_fdset_copy_native (wrs, &rs, max + 1);
621  GNUNET_NETWORK_fdset_copy_native (wws, &ws, max + 1);
622  }
623  else
624  {
625  wrs = NULL;
626  wws = NULL;
627  }
628  if (NULL != httpd_task)
629  {
631  httpd_task = NULL;
632  }
633  if ((MHD_YES == haveto) || (-1 != max))
634  {
636  tv,
637  wrs,
638  wws,
639  &do_httpd,
640  NULL);
641  }
642  if (NULL != wrs)
644  if (NULL != wws)
646 }
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:1810
#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:966
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 670 of file gnunet-rest-server.c.

References _, GNUNET_NETWORK_Handle::fd, GNUNET_assert, 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_SCHEDULER_add_read_net(), GNUNET_TIME_UNIT_FOREVER_REL, httpd, len, and schedule_httpd().

Referenced by run().

671 {
672  struct GNUNET_NETWORK_Handle *lsock = cls;
673  struct GNUNET_NETWORK_Handle *s;
674  int fd;
675  const struct sockaddr *addr;
676  socklen_t len;
677 
678  GNUNET_assert (NULL != lsock);
679  if (lsock == lsock4)
680  {
682  lsock,
683  &do_accept,
684  lsock);
685  }
686  else if (lsock == lsock6)
687  {
689  lsock,
690  &do_accept,
691  lsock);
692  }
693  else
694  GNUNET_assert (0);
695  s = GNUNET_NETWORK_socket_accept (lsock, NULL, NULL);
696  if (NULL == s)
697  {
699  return;
700  }
702  "Got an inbound connection, waiting for data\n");
703  fd = GNUNET_NETWORK_get_fd (s);
704  addr = GNUNET_NETWORK_get_addr (s);
705  len = GNUNET_NETWORK_get_addrlen (s);
706  if (MHD_YES != MHD_add_connection (httpd, fd, addr, len))
707  {
709  _ ("Failed to pass client to MHD\n"));
710  return;
711  }
712  GNUNET_free (s);
713  schedule_httpd ();
714 }
int GNUNET_NETWORK_get_fd(const struct GNUNET_NETWORK_Handle *desc)
Return file descriptor for this network handle.
Definition: network.c:1080
struct sockaddr * GNUNET_NETWORK_get_addr(const struct GNUNET_NETWORK_Handle *desc)
Return the sockaddr for this network handle.
Definition: network.c:1093
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 _(String)
GNU gettext support macro.
Definition: platform.h:181
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.
#define GNUNET_log(kind,...)
static struct MHD_Daemon * httpd
Daemon for HTTP.
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:1486
#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 723 of file gnunet-rest-server.c.

References allow_credentials, allow_headers, GNUNET_ERROR_TYPE_INFO, GNUNET_free_non_null, GNUNET_log, and kill_httpd().

Referenced by run().

724 {
725  GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Shutting down...\n");
726  kill_httpd ();
729 }
static char * allow_headers
Allowed Headers (CORS)
static void kill_httpd()
Kill the MHD daemon.
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
static char * allow_credentials
Allowed Credentials (CORS)
#define GNUNET_log(kind,...)
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 738 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().

739 {
740  struct GNUNET_NETWORK_Handle *ls;
741  struct sockaddr_in sa4;
742  int eno;
743 
744  memset (&sa4, 0, sizeof(sa4));
745  sa4.sin_family = AF_INET;
746  sa4.sin_port = htons (port);
747  sa4.sin_addr.s_addr = address;
748 #if HAVE_SOCKADDR_IN_SIN_LEN
749  sa4.sin_len = sizeof(sa4);
750 #endif
751  ls = GNUNET_NETWORK_socket_create (AF_INET, SOCK_STREAM, 0);
752  if (NULL == ls)
753  return NULL;
755  (const struct sockaddr *) &sa4,
756  sizeof(sa4)))
757  {
758  eno = errno;
760  errno = eno;
761  return NULL;
762  }
763  return ls;
764 }
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
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
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 773 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().

774 {
775  struct GNUNET_NETWORK_Handle *ls;
776  struct sockaddr_in6 sa6;
777  int eno;
778 
779  memset (&sa6, 0, sizeof(sa6));
780  sa6.sin6_family = AF_INET6;
781  sa6.sin6_port = htons (port);
782  sa6.sin6_addr = address6;
783 #if HAVE_SOCKADDR_IN_SIN_LEN
784  sa6.sin6_len = sizeof(sa6);
785 #endif
786  ls = GNUNET_NETWORK_socket_create (AF_INET6, SOCK_STREAM, 0);
787  if (NULL == ls)
788  return NULL;
790  (const struct sockaddr *) &sa6,
791  sizeof(sa6)))
792  {
793  eno = errno;
795  errno = eno;
796  return NULL;
797  }
798  return ls;
799 }
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
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
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 810 of file gnunet-rest-server.c.

References GNUNET_assert, GNUNET_CONTAINER_multihashmap_put(), GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY, GNUNET_CRYPTO_hash(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_OK, GNUNET_REST_Plugin::name, and MhdConnectionHandle::plugin.

Referenced by run().

811 {
812  struct GNUNET_REST_Plugin *plugin = lib_ret;
813  struct GNUNET_HashCode key;
814 
815  if (NULL == lib_ret)
816  {
818  "Could not load plugin `%s'\n",
819  libname);
820  return;
821  }
822  GNUNET_assert (1 < strlen (plugin->name));
823  GNUNET_assert ('/' == *plugin->name);
824  GNUNET_CRYPTO_hash (plugin->name + 1, strlen (plugin->name + 1), &key);
826  plugin_map,
827  &key,
828  plugin,
830  {
832  "Could not load add plugin `%s'\n",
833  libname);
834  return;
835  }
836  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Loaded plugin `%s'\n", libname);
837 }
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
struct returned by the initialization function of the plugin
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
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
char * name
Plugin name.
A 512-bit hashcode.
static char * plugin
Solver plugin name as string.
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 struct GNUNET_CONTAINER_MultiHashMap * plugin_map
Map of loaded plugins.
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:

◆ 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 849 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_CONTAINER_multihashmap_create(), 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_NO, 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(), and port.

Referenced by main().

853 {
854  char *addr_str;
855 
856  cfg = c;
858 
859  /* Get port to bind to */
860  if (GNUNET_OK !=
861  GNUNET_CONFIGURATION_get_value_number (cfg, "rest", "HTTP_PORT", &port))
862  {
863  // No address specified
864  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Using default port...\n");
866  }
867 
868  /* Get address to bind to */
869  if (GNUNET_OK !=
870  GNUNET_CONFIGURATION_get_value_string (cfg, "rest", "BIND_TO", &addr_str))
871  {
872  // No address specified
873  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Don't know what to bind to...\n");
875  return;
876  }
877  if (1 != inet_pton (AF_INET, addr_str, &address))
878  {
880  "Unable to parse address %s\n",
881  addr_str);
882  GNUNET_free (addr_str);
884  return;
885  }
886  GNUNET_free (addr_str);
887  /* Get address to bind to */
889  "rest",
890  "BIND_TO6",
891  &addr_str))
892  {
893  // No address specified
894  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Don't know what to bind6 to...\n");
896  return;
897  }
898  if (1 != inet_pton (AF_INET6, addr_str, &address6))
899  {
901  "Unable to parse IPv6 address %s\n",
902  addr_str);
903  GNUNET_free (addr_str);
905  return;
906  }
907  GNUNET_free (addr_str);
908 
909 
910  /* Get CORS data from cfg */
911  echo_origin =
913  "rest",
914  "REST_ECHO_ORIGIN_WEBEXT");
915  allow_origins = NULL;
917  "rest",
918  "REST_ALLOW_ORIGIN",
919  &allow_origins))
920  {
922  "No CORS Access-Control-Allow-Origin header will be sent...\n");
923  }
924  if (GNUNET_OK !=
926  "rest",
927  "REST_ALLOW_CREDENTIALS",
929  {
930  // No origin specified
932  "No CORS Credential Header will be sent...\n");
933  }
934 
936  "rest",
937  "REST_ALLOW_HEADERS",
938  &allow_headers))
939  {
940  // No origin specified
942  "No CORS Access-Control-Allow-Headers Header will be sent...\n");
943  }
944 
945  /* Open listen socket proxy */
946  lsock6 = bind_v6 ();
947  if (NULL == lsock6)
948  {
950  }
951  else
952  {
954  {
957  lsock6 = NULL;
958  }
959  else
960  {
962  lsock6,
963  &do_accept,
964  lsock6);
965  }
966  }
967  lsock4 = bind_v4 ();
968  if (NULL == lsock4)
969  {
971  }
972  else
973  {
975  {
978  lsock4 = NULL;
979  }
980  else
981  {
983  lsock4,
984  &do_accept,
985  lsock4);
986  }
987  }
988  if ((NULL == lsock4) && (NULL == lsock6))
989  {
991  return;
992  }
993  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Service listens on port %llu\n", port);
994  httpd = MHD_start_daemon (MHD_USE_DEBUG | MHD_USE_NO_LISTEN_SOCKET
995  | MHD_ALLOW_SUSPEND_RESUME,
996  0,
997  NULL,
998  NULL,
1000  NULL,
1001  MHD_OPTION_CONNECTION_TIMEOUT,
1002  (unsigned int) 16,
1003  MHD_OPTION_NOTIFY_COMPLETED,
1005  NULL,
1006  MHD_OPTION_END);
1007  if (NULL == httpd)
1008  {
1010  return;
1011  }
1012  /* Load plugins */
1013  GNUNET_PLUGIN_load_all ("libgnunet_plugin_rest",
1014  (void *) cfg,
1015  &load_plugin,
1016  NULL);
1018 }
int GNUNET_NETWORK_socket_listen(const struct GNUNET_NETWORK_Handle *desc, int backlog)
Listen on a socket.
Definition: network.c:708
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:1300
static void do_accept(void *cls)
Accept new incoming connections.
static struct in6_addr address6
The IPv6 address to bind to.
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
static int 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.
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:526
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 int echo_origin
Echo request Origin in CORS.
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_CONTAINER_MultiHashMap * plugin_map
Map of loaded plugins.
static struct GNUNET_NETWORK_Handle * bind_v6()
Create an IPv6 listen socket bound to our port.
#define GNUNET_log(kind,...)
static struct MHD_Daemon * httpd
Daemon for HTTP.
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
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:1486
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
#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 1031 of file gnunet-rest-server.c.

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

1032 {
1035  static const char *err_page = "{}";
1036  int ret;
1037 
1038  if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
1039  return 2;
1040  GNUNET_log_setup ("gnunet-rest-server", "WARNING", NULL);
1041  failure_response = MHD_create_response_from_buffer (strlen (err_page),
1042  (void *) err_page,
1043  MHD_RESPMEM_PERSISTENT);
1044  ret = (GNUNET_OK == GNUNET_PROGRAM_run (argc,
1045  argv,
1046  "gnunet-rest-server",
1047  _ ("GNUnet REST server"),
1048  options,
1049  &run,
1050  NULL))
1051  ? 0
1052  : 1;
1053  MHD_destroy_response (failure_response);
1054  GNUNET_free_non_null ((char *) argv);
1055  return ret;
1056 }
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:1438
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
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:181
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:367
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.

◆ plugin_map

struct GNUNET_CONTAINER_MultiHashMap* plugin_map
static

Map of loaded plugins.

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

◆ echo_origin

int echo_origin
static

Echo request Origin in CORS.

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

Referenced by create_response(), and run().

◆ allow_origins

char* allow_origins
static

Allowed Origins (CORS)

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

Referenced by create_response(), and run().

◆ allow_headers

char* allow_headers
static

Allowed Headers (CORS)

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

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