GNUnet  0.20.0
plugin_rest_gns.c File Reference

GNUnet Gns REST plugin. More...

#include "platform.h"
#include "gnunet_rest_plugin.h"
#include "gnunet_rest_lib.h"
#include "gnunet_json_lib.h"
#include "gnunet_gnsrecord_lib.h"
#include "gnunet_gnsrecord_json_lib.h"
#include "gnunet_gns_service.h"
#include "microhttpd.h"
#include <jansson.h>
Include dependency graph for plugin_rest_gns.c:

Go to the source code of this file.

Data Structures

struct  Plugin
 Handle for a plugin. More...
struct  RequestHandle
 The request handle. More...


#define GNUNET_REST_API_NS_GNS   "/gns"
 Rest API GNS Namespace. More...
#define GNUNET_REST_GNS_PARAM_RECORD_TYPE   "record_type"
 Rest API GNS Parameter record_type. More...
#define GNUNET_REST_GNS_ERROR_UNKNOWN   "Unknown Error"
 Rest API GNS ERROR Unknown Error. More...
#define GNUNET_REST_GNS_NOT_FOUND   "Record not found"
 Rest API GNS ERROR Record not found. More...


static void cleanup_handle (void *cls)
 Cleanup lookup handle. More...
static void do_error (void *cls)
 Task run on errors. More...
static void do_timeout (void *cls)
static void handle_gns_response (void *cls, int was_gns, uint32_t rd_count, const struct GNUNET_GNSRECORD_Data *rd)
 Iterator called on obtained result for a GNS lookup. More...
void get_gns_cont (struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
 Handle gns GET request. More...
static void options_cont (struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
 Respond to OPTIONS request. More...
static enum GNUNET_GenericReturnValue rest_process_request (struct GNUNET_REST_RequestHandle *rest_handle, GNUNET_REST_ResultProcessor proc, void *proc_cls)
 Function processing the REST call. More...
void * libgnunet_plugin_rest_gns_init (void *cls)
 Entry point for the plugin. More...
void * libgnunet_plugin_rest_gns_done (void *cls)
 Exit point from the plugin. More...


const struct GNUNET_CONFIGURATION_Handlecfg
 The configuration handle. More...
static char * allow_methods
 HTTP methods allows for this plugin. More...
static struct GNUNET_GNS_Handlegns
 Connection to GNS. More...
static struct RequestHandlerequests_head
 DLL. More...
static struct RequestHandlerequests_tail
 DLL. More...

Detailed Description

GNUnet Gns REST plugin.

Philippe Buschmann

Definition in file plugin_rest_gns.c.

Macro Definition Documentation


#define GNUNET_REST_API_NS_GNS   "/gns"

Rest API GNS Namespace.

Definition at line 39 of file plugin_rest_gns.c.


#define GNUNET_REST_GNS_PARAM_RECORD_TYPE   "record_type"

Rest API GNS Parameter record_type.

Definition at line 44 of file plugin_rest_gns.c.


#define GNUNET_REST_GNS_ERROR_UNKNOWN   "Unknown Error"

Rest API GNS ERROR Unknown Error.

Definition at line 49 of file plugin_rest_gns.c.


#define GNUNET_REST_GNS_NOT_FOUND   "Record not found"

Rest API GNS ERROR Record not found.

Definition at line 54 of file plugin_rest_gns.c.

Function Documentation

◆ cleanup_handle()

static void cleanup_handle ( void *  cls)

Cleanup lookup handle.

clsstruct RequestHandle to clean up

Definition at line 165 of file plugin_rest_gns.c.

166 {
167  struct RequestHandle *handle = cls;
169  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n");
171  if (NULL != handle->gns_lookup)
172  {
174  handle->gns_lookup = NULL;
175  }
176  if (NULL != handle->timeout_task)
177  {
178  GNUNET_SCHEDULER_cancel (handle->timeout_task);
179  handle->timeout_task = NULL;
180  }
181  if (NULL != handle->url)
182  GNUNET_free (handle->url);
183  if (NULL != handle->name)
184  GNUNET_free (handle->name);
185  if (NULL != handle->emsg)
186  GNUNET_free (handle->emsg);
190  handle);
192 }
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
void * GNUNET_GNS_lookup_with_tld_cancel(struct GNUNET_GNS_LookupWithTldRequest *ltr)
Cancel pending lookup request.
Definition: gns_tld_api.c:332
#define GNUNET_log(kind,...)
#define GNUNET_free(ptr)
Wrapper around free.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:975
static struct RequestHandle * requests_head
static struct RequestHandle * requests_tail
The request handle.

References GNUNET_CONTAINER_DLL_remove, GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_GNS_lookup_with_tld_cancel(), GNUNET_log, GNUNET_SCHEDULER_cancel(), handle, requests_head, and requests_tail.

Referenced by do_error(), handle_gns_response(), and options_cont().

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

◆ do_error()

static void do_error ( void *  cls)

Task run on errors.

Reports an error and cleans up everything.

clsthe struct RequestHandle

Definition at line 201 of file plugin_rest_gns.c.

202 {
203  struct RequestHandle *handle = cls;
204  struct MHD_Response *resp;
205  json_t *json_error = json_object ();
206  char *response;
208  if (NULL != handle->timeout_task)
209  GNUNET_SCHEDULER_cancel (handle->timeout_task);
210  handle->timeout_task = NULL;
211  if (NULL == handle->emsg)
214  json_object_set_new (json_error, "error", json_string (handle->emsg));
216  if (0 == handle->response_code)
217  handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
218  response = json_dumps (json_error, 0);
220  MHD_add_response_header (resp, "Content-Type", "application/json");
221  handle->proc (handle->proc_cls, resp, handle->response_code);
222  json_decref (json_error);
225 }
static struct MHD_Response * response
Our canonical response.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
struct MHD_Response * GNUNET_REST_create_response(const char *data)
Create REST MHD response.
Definition: rest.c:44
Internal Server Error [RFC7231, Section 6.6.1].
Rest API GNS ERROR Unknown Error.
static void cleanup_handle(void *cls)
Cleanup lookup handle.

References cleanup_handle(), GNUNET_free, GNUNET_REST_create_response(), GNUNET_REST_GNS_ERROR_UNKNOWN, GNUNET_SCHEDULER_cancel(), GNUNET_strdup, handle, MHD_HTTP_INTERNAL_SERVER_ERROR, and response.

Referenced by do_timeout(), get_gns_cont(), handle_gns_response(), and libgnunet_plugin_rest_gns_done().

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

◆ do_timeout()

static void do_timeout ( void *  cls)

Definition at line 229 of file plugin_rest_gns.c.

230 {
231  struct RequestHandle *handle = cls;
233  handle->timeout_task = NULL;
234  handle->response_code = MHD_HTTP_REQUEST_TIMEOUT;
235  do_error (handle);
236 }
Request Timeout [RFC7231, Section 6.5.7].
static void do_error(void *cls)
Task run on errors.

References do_error(), handle, and MHD_HTTP_REQUEST_TIMEOUT.

Here is the call graph for this function:

◆ handle_gns_response()

static void handle_gns_response ( void *  cls,
int  was_gns,
uint32_t  rd_count,
const struct GNUNET_GNSRECORD_Data rd 

Iterator called on obtained result for a GNS lookup.

clsclosure with the object
was_gnsGNUNET_NO if name was not a GNS name
rd_countnumber of records in rd
rdthe records in reply

Definition at line 248 of file plugin_rest_gns.c.

252 {
253  struct RequestHandle *handle = cls;
254  struct MHD_Response *resp;
255  json_t *result_obj;
256  char *result;
258  handle->gns_lookup = NULL;
260  if (GNUNET_NO == was_gns)
261  {
262  handle->response_code = MHD_HTTP_NOT_FOUND;
265  return;
266  }
270  result = json_dumps (result_obj, 0);
271  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result);
273  GNUNET_assert (MHD_NO != MHD_add_response_header (resp,
274  "Content-Type",
275  "application/json"));
276  handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
278  json_decref (result_obj);
280 }
static unsigned int rd_count
Number of records for currently parsed set.
static struct GNUNET_GNSRECORD_Data rd[50]
The record data under a single label.
static int result
Global testing status.
json_t * GNUNET_GNSRECORD_JSON_from_gnsrecord(const char *rname, const struct GNUNET_GNSRECORD_Data *rd, unsigned int rd_count)
Convert GNS record to JSON.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1299
OK [RFC7231, Section 6.3.1].
Not Found [RFC7231, Section 6.5.4].
Rest API GNS ERROR Record not found.

References cleanup_handle(), do_error(), GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_GNSRECORD_JSON_from_gnsrecord(), GNUNET_log, GNUNET_NO, GNUNET_REST_create_response(), GNUNET_REST_GNS_NOT_FOUND, GNUNET_SCHEDULER_add_now(), GNUNET_strdup, handle, MHD_HTTP_NOT_FOUND, MHD_HTTP_OK, rd, rd_count, and result.

Referenced by get_gns_cont().

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

◆ get_gns_cont()

void get_gns_cont ( struct GNUNET_REST_RequestHandle con_handle,
const char *  url,
void *  cls 

Handle gns GET request.

con_handlethe connection handle
urlthe url
clsthe RequestHandle

Definition at line 291 of file plugin_rest_gns.c.

294 {
295  struct RequestHandle *handle = cls;
296  struct GNUNET_HashCode key;
297  char *record_type;
298  char *name;
300  name = NULL;
301  handle->name = NULL;
302  if (strlen (GNUNET_REST_API_NS_GNS) < strlen (handle->url))
303  {
304  name = &handle->url[strlen (GNUNET_REST_API_NS_GNS) + 1];
305  }
307  if (NULL == name)
308  {
309  handle->response_code = MHD_HTTP_NOT_FOUND;
312  return;
313  }
314  if (0 >= strlen (name))
315  {
316  handle->response_code = MHD_HTTP_NOT_FOUND;
319  return;
320  }
321  handle->name = GNUNET_strdup (name);
323  handle->record_type = UINT32_MAX;
326  &key);
327  if (GNUNET_YES ==
329  {
330  record_type =
332  handle->record_type = GNUNET_GNSRECORD_typename_to_number (record_type);
333  }
335  if (UINT32_MAX == handle->record_type)
336  {
337  handle->record_type = GNUNET_GNSRECORD_TYPE_ANY;
338  }
340  handle->gns_lookup = GNUNET_GNS_lookup_with_tld (gns,
341  handle->name,
342  handle->record_type,
345  handle);
346 }
struct GNUNET_HashCode key
The key used in the DHT.
struct GNUNET_GNS_LookupWithTldRequest * GNUNET_GNS_lookup_with_tld(struct GNUNET_GNS_Handle *handle, const char *name, uint32_t type, enum GNUNET_GNS_LocalOptions options, GNUNET_GNS_LookupResultProcessor2 proc, void *proc_cls)
Perform an asynchronous lookup operation on the GNS, determining the zone using the TLD of the given ...
Definition: gns_tld_api.c:241
Defaults, look in cache, then in DHT.
uint32_t GNUNET_GNSRECORD_typename_to_number(const char *dns_typename)
Convert a type name (e.g.
Definition: gnsrecord.c:200
Record type indicating any record/'*'.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:41
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap_contains(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Check if the map contains any value under the given key (including values that are NULL).
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.
const char * name
static struct GNUNET_GNS_Handle * gns
Connection to GNS.
static void handle_gns_response(void *cls, int was_gns, uint32_t rd_count, const struct GNUNET_GNSRECORD_Data *rd)
Iterator called on obtained result for a GNS lookup.
Rest API GNS Namespace.
Rest API GNS Parameter record_type.
A 512-bit hashcode.
struct GNUNET_CONTAINER_MultiHashMap * url_param_map
Map of url parameters.

References do_error(), gns, GNUNET_CONTAINER_multihashmap_contains(), GNUNET_CONTAINER_multihashmap_get(), GNUNET_CRYPTO_hash(), GNUNET_GNS_LO_DEFAULT, GNUNET_GNS_lookup_with_tld(), GNUNET_GNSRECORD_TYPE_ANY, GNUNET_GNSRECORD_typename_to_number(), GNUNET_REST_API_NS_GNS, GNUNET_REST_GNS_NOT_FOUND, GNUNET_REST_GNS_PARAM_RECORD_TYPE, GNUNET_SCHEDULER_add_now(), GNUNET_strdup, GNUNET_YES, handle, handle_gns_response(), key, MHD_HTTP_NOT_FOUND, name, and GNUNET_REST_RequestHandle::url_param_map.

Here is the call graph for this function:

◆ options_cont()

static void options_cont ( struct GNUNET_REST_RequestHandle con_handle,
const char *  url,
void *  cls 

Respond to OPTIONS request.

con_handlethe connection handle
urlthe url
clsthe RequestHandle

Definition at line 357 of file plugin_rest_gns.c.

360 {
361  struct MHD_Response *resp;
362  struct RequestHandle *handle = cls;
364  // independent of path return all options
365  resp = GNUNET_REST_create_response (NULL);
366  MHD_add_response_header (resp, "Access-Control-Allow-Methods", allow_methods);
367  handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
369  return;
370 }
static char * allow_methods
HTTP methods allows for this plugin.

References allow_methods, cleanup_handle(), GNUNET_REST_create_response(), GNUNET_SCHEDULER_add_now(), handle, and MHD_HTTP_OK.

Here is the call graph for this function:

◆ rest_process_request()

static enum GNUNET_GenericReturnValue rest_process_request ( struct GNUNET_REST_RequestHandle rest_handle,
GNUNET_REST_ResultProcessor  proc,
void *  proc_cls 

Function processing the REST call.

methodHTTP method
urlURL of the HTTP request
databody of the HTTP request (optional)
data_sizelength of the body
proccallback function for the result
proc_clsclosure for callback function
GNUNET_OK if request accepted

Definition at line 357 of file plugin_rest_gns.c.

388 {
389  struct RequestHandle *handle = GNUNET_new (struct RequestHandle);
391  static const struct GNUNET_REST_RequestHandler handlers[] =
392  { { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_GNS, &get_gns_cont },
396  handle->response_code = 0;
397  handle->timeout =
399  handle->proc_cls = proc_cls;
400  handle->proc = proc;
401  handle->rest_handle = rest_handle;
402  handle->url = GNUNET_strdup (rest_handle->url);
403  handle->timeout_task =
407  handle);
408  if (handle->url[strlen (handle->url) - 1] == '/')
409  handle->url[strlen (handle->url) - 1] = '\0';
410  if (GNUNET_NO ==
411  GNUNET_REST_handle_request (handle->rest_handle, handlers, &err, handle))
412  {
414  return GNUNET_NO;
415  }
418  return GNUNET_YES;
419 }
static struct GNUNET_CADET_MessageHandler handlers[]
Handlers, for diverse services.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
int GNUNET_REST_handle_request(struct GNUNET_REST_RequestHandle *conn, const struct GNUNET_REST_RequestHandler *handlers, struct GNUNET_REST_RequestHandlerError *err, void *cls)
Definition: rest.c:64
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1272
One second.
struct GNUNET_TIME_Relative GNUNET_TIME_relative_multiply(struct GNUNET_TIME_Relative rel, unsigned long long factor)
Multiply relative time by a given factor.
Definition: time.c:484
static void do_timeout(void *cls)
static void options_cont(struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
Respond to OPTIONS request.
void get_gns_cont(struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
Handle gns GET request.
const char * url
The url as string.
void(* proc)(struct GNUNET_REST_RequestHandle *handle, const char *url, void *cls)
Namespace to handle.

Referenced by libgnunet_plugin_rest_gns_init().

Here is the caller graph for this function:

◆ libgnunet_plugin_rest_gns_init()

void* libgnunet_plugin_rest_gns_init ( void *  cls)

Entry point for the plugin.

clsConfig info
NULL on error, otherwise the plugin context

Definition at line 429 of file plugin_rest_gns.c.

430 {
431  static struct Plugin plugin;
432  struct GNUNET_REST_Plugin *api;
434  cfg = cls;
435  memset (&plugin, 0, sizeof(struct Plugin));
436  plugin.cfg = cfg;
437  api = GNUNET_new (struct GNUNET_REST_Plugin);
438  api->cls = &plugin;
442  "%s, %s, %s, %s, %s",
450  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _ ("Gns REST API initialized\n"));
451  return api;
452 }
struct TestcasePlugin * plugin
The process handle to the testbed service.
struct GNUNET_GNS_Handle * GNUNET_GNS_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Initialize the connection with the GNS service.
Definition: gns_api.c:268
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
#define _(String)
GNU gettext support macro.
Definition: platform.h:178
const struct GNUNET_CONFIGURATION_Handle * cfg
The configuration handle.
static enum GNUNET_GenericReturnValue rest_process_request(struct GNUNET_REST_RequestHandle *rest_handle, GNUNET_REST_ResultProcessor proc, void *proc_cls)
Function processing the REST call.
struct returned by the initialization function of the plugin
char * name
Plugin name.
void * cls
The closure of the plugin.
enum GNUNET_GenericReturnValue(* process_request)(struct GNUNET_REST_RequestHandle *handle, GNUNET_REST_ResultProcessor proc, void *proc_cls)
Function to process a REST call.
Handle for a plugin.
Definition: block.c:38

References _, allow_methods, cfg, GNUNET_REST_Plugin::cls, gns, GNUNET_asprintf(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_GNS_connect(), GNUNET_log, GNUNET_new, GNUNET_REST_API_NS_GNS, GNUNET_REST_Plugin::name, plugin, GNUNET_REST_Plugin::process_request, and rest_process_request().

Here is the call graph for this function:

◆ libgnunet_plugin_rest_gns_done()

void* libgnunet_plugin_rest_gns_done ( void *  cls)

Exit point from the plugin.

clsthe plugin context (as returned by "init")
always NULL

Definition at line 462 of file plugin_rest_gns.c.

463 {
464  struct GNUNET_REST_Plugin *api = cls;
465  struct RequestHandle *request;
466  struct Plugin *plugin;
468  while (NULL != (request = requests_head))
469  do_error (request);
471  if (NULL != gns)
474  plugin = api->cls;
476  plugin->cfg = NULL;
479  GNUNET_free (api);
480  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Gns REST plugin is finished\n");
481  return NULL;
482 }
static struct GNUNET_VPN_RedirectionRequest * request
Opaque redirection request handle.
Definition: gnunet-vpn.c:40
void GNUNET_GNS_disconnect(struct GNUNET_GNS_Handle *handle)
Shutdown connection with the GNS service.
Definition: gns_api.c:290
void * cls
Closure for all of the callbacks.
struct GNUNET_BLOCK_PluginFunctions * api
Plugin API.
Definition: block.c:47

References allow_methods, Plugin::api, GNUNET_BLOCK_PluginFunctions::cls, GNUNET_REST_Plugin::cls, do_error(), gns, GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_GNS_disconnect(), GNUNET_log, plugin, request, and requests_head.

Here is the call graph for this function:

Variable Documentation

◆ cfg

const struct GNUNET_CONFIGURATION_Handle* cfg

The configuration handle.

Handle to our configuration.

Definition at line 59 of file plugin_rest_gns.c.

Referenced by libgnunet_plugin_rest_gns_init().

◆ allow_methods

char* allow_methods

HTTP methods allows for this plugin.

Definition at line 64 of file plugin_rest_gns.c.

Referenced by libgnunet_plugin_rest_gns_done(), libgnunet_plugin_rest_gns_init(), and options_cont().

◆ gns

struct GNUNET_GNS_Handle* gns

Connection to GNS.

Definition at line 69 of file plugin_rest_gns.c.

Referenced by get_gns_cont(), libgnunet_plugin_rest_gns_done(), and libgnunet_plugin_rest_gns_init().

◆ requests_head

struct RequestHandle* requests_head


Definition at line 153 of file plugin_rest_gns.c.

Referenced by cleanup_handle(), and libgnunet_plugin_rest_gns_done().

◆ requests_tail

struct RequestHandle* requests_tail


Definition at line 158 of file plugin_rest_gns.c.

Referenced by cleanup_handle().