28#include "gnunet_error_codes.h"
34#include "microhttpd.h"
40#define GNUNET_REST_API_NS_NAMESTORE "/namestore"
45#define GNUNET_REST_API_NS_NAMESTORE_IMPORT "/namestore/import"
50#define ID_REST_STATE_INIT 0
55#define ID_REST_STATE_POST_INIT 1
286 if (NULL !=
handle->timeout_task)
289 handle->timeout_task = NULL;
291 if (NULL !=
handle->record_name)
297 for (
int i = 0; i <
handle->rd_count; i++)
299 if (NULL !=
handle->rd[i].data)
304 if (NULL !=
handle->timeout_task)
306 if (NULL !=
handle->list_it)
308 if (NULL !=
handle->ns_qe)
312 if (NULL !=
handle->resp_object)
314 json_decref (
handle->resp_object);
332 struct MHD_Response *resp;
333 json_t *json_error = json_object ();
339 json_object_set_new (json_error,
"error", json_string (emsg));
340 json_object_set_new (json_error,
"error_code", json_integer (
handle->ec));
342 if (0 == response_code)
344 response = json_dumps (json_error, 0);
347 MHD_add_response_header (resp,
"Content-Type",
348 "application/json"));
350 json_decref (json_error);
374 tmp = strtok (copy,
"/");
377 for (ego_entry =
ego_head; NULL != ego_entry;
378 ego_entry = ego_entry->
next)
380 if (0 != strcasecmp (tmp, ego_entry->
identifier))
410 struct MHD_Response *resp;
455 struct MHD_Response *resp;
459 if (NULL ==
handle->resp_object)
465 result_str = json_dumps (
handle->resp_object, 0);
469 MHD_add_response_header (resp,
"Content-Type",
470 "application/json"));
503 for (i = 0; i < rd_len; i++)
508 rd_filtered[j] =
rd[i];
515 if (NULL ==
handle->resp_object)
516 handle->resp_object = json_array ();
520 json_array_append_new (
handle->resp_object, record_obj);
554 for (i = 0; i < rd_len; i++)
559 rd_filtered[j] =
rd[i];
610 if (NULL == ego_entry)
625 if (NULL !=
typename)
635 if ((0 == strcmp (boolstring,
"1")) ||
636 (0 == strcmp (boolstring,
"yes")) ||
637 (0 == strcmp (boolstring,
"true")))
647 if ((0 == strcmp (boolstring,
"1")) ||
648 (0 == strcmp (boolstring,
"yes")) ||
649 (0 == strcmp (boolstring,
"true")))
653 if (1 >= strlen (labelname))
666 if (NULL ==
handle->list_it)
683 if (NULL ==
handle->ns_qe)
709 for (j = 0; j <
handle->rd_count; j++)
710 rd_new[i + j] =
handle->rd[j];
718 if (NULL ==
handle->ns_qe)
733 "Import finished (%d)\n",
ec);
741 unsigned int remaining =
handle->rd_set_count -
handle->rd_set_pos;
744 struct MHD_Response *resp;
748 "Commit finished (%d)\n", ec);
760 unsigned int sent_rds = 0;
771 if ((NULL ==
handle->ns_qe) && (0 == sent_rds))
777 handle->rd_set_pos += sent_rds;
788 "Transaction started...\n");
789 if (0 >=
handle->rest_handle->data_size)
795 char term_data[
handle->rest_handle->data_size + 1];
796 term_data[
handle->rest_handle->data_size] =
'\0';
798 handle->rest_handle->data,
799 handle->rest_handle->data_size);
800 data_js = json_loads (term_data, JSON_DECODE_ANY, &err);
805 "Error parsing data: %s", err.text);
809 if (! json_is_array (data_js))
813 json_decref (data_js);
816 handle->rd_set_count = json_array_size (data_js);
820 "Got record set of size %d\n",
handle->rd_set_count);
824 json_array_foreach (data_js, index,
value) {
829 &
handle->ri[index].a_rd_count,
836 json_decref (data_js);
840 handle->ri[index].a_label = albl;
842 "Parsed record set for name %s\n",
843 handle->ri[index].a_label);
848 unsigned int sent_rds = 0;
858 if ((NULL ==
handle->ns_qe) && (0 == sent_rds))
864 handle->rd_set_pos += sent_rds;
897 if (NULL == ego_entry)
935 char term_data[
handle->rest_handle->data_size + 1];
937 if (0 >=
handle->rest_handle->data_size)
943 term_data[
handle->rest_handle->data_size] =
'\0';
945 handle->rest_handle->data,
946 handle->rest_handle->data_size);
947 data_js = json_loads (term_data, JSON_DECODE_ANY, &err);
956 json_decref (data_js);
960 if (0 >= strlen (
handle->record_name))
964 json_decref (data_js);
967 json_decref (data_js);
982 if (NULL == ego_entry)
996 if (NULL ==
handle->ns_qe)
1070 if (NULL == ego_entry)
1079 if (1 >= strlen (labelname))
1094 if (NULL ==
handle->ns_qe)
1115 struct MHD_Response *resp;
1121 MHD_add_response_header (resp,
1122 "Access-Control-Allow-Methods",
1134 const char *identifier)
1147 "Called with NULL ego\n");
1155 ego_entry->
ego = ego;
1162 if (identifier != NULL)
1164 for (ego_entry =
ego_head; NULL != ego_entry;
1165 ego_entry = ego_entry->
next)
1167 if (ego_entry->
ego == ego)
1175 if (NULL == ego_entry)
1181 ego_entry->
ego = ego;
1191 for (ego_entry =
ego_head; NULL != ego_entry;
1192 ego_entry = ego_entry->
next)
1194 if (ego_entry->
ego == ego)
1197 if (NULL == ego_entry)
1244 handle->proc_cls = proc_cls;
1246 handle->rest_handle = rest_handle;
1247 handle->zone_pkey = NULL;
1292 "%s, %s, %s, %s, %s",
1293 MHD_HTTP_METHOD_GET,
1294 MHD_HTTP_METHOD_POST,
1295 MHD_HTTP_METHOD_PUT,
1296 MHD_HTTP_METHOD_DELETE,
1297 MHD_HTTP_METHOD_OPTIONS);
1302 "Namestore REST API initialized\n"));
1329 for (ego_entry =
ego_head; NULL != ego_entry;)
1331 ego_tmp = ego_entry;
1332 ego_entry = ego_entry->
next;
struct GNUNET_MQ_MessageHandlers handlers[]
struct TestcasePlugin * plugin
The process handle to the testbed service.
static struct MHD_Response * response
Our canonical response.
struct GNUNET_HashCode key
The key used in the DHT.
static char * egoname
Ego Attribut String.
static struct GNUNET_FS_Handle * ctx
struct GNUNET_CRYPTO_PrivateKey pk
Private key from command line option, or NULL.
static char * name
Name (label) of the records to list.
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 char * value
Value of the record to add/remove.
static struct GNUNET_VPN_RedirectionRequest * request
Opaque redirection request handle.
static struct GNUNET_VPN_Handle * handle
Handle to vpn service.
API that can be used to manipulate JSON GNS record data.
Identity service; implements identity management for GNUnet.
void GNUNET_JSON_parse_free(struct GNUNET_JSON_Specification *spec)
Frees all elements allocated during a GNUNET_JSON_parse() operation.
enum GNUNET_GenericReturnValue GNUNET_JSON_parse(const json_t *root, struct GNUNET_JSON_Specification *spec, const char **error_json_name, unsigned int *error_line)
Navigate and parse data in a JSON tree.
struct GNUNET_JSON_Specification GNUNET_JSON_spec_end(void)
End of a parser specification.
API that can be used to store naming information on a GNUnet node;.
API for helper library to parse/create REST.
GNUnet service REST plugin header.
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
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.
uint32_t GNUNET_GNSRECORD_typename_to_number(const char *dns_typename)
Convert a type name (e.g.
struct GNUNET_JSON_Specification GNUNET_GNSRECORD_JSON_spec_gnsrecord(struct GNUNET_GNSRECORD_Data **rd, unsigned int *rd_count, char **name)
JSON Specification for GNS Records.
GNUNET_GNSRECORD_Filter
Filter for GNUNET_GNSRECORD_normalize_record_set().
#define GNUNET_GNSRECORD_TYPE_ANY
Record type indicating any record/'*'.
@ GNUNET_GNSRECORD_FILTER_NONE
No filter flags set.
@ GNUNET_GNSRECORD_FILTER_INCLUDE_MAINTENANCE
Include maintenance records (TOMBSTONE etc).
@ GNUNET_GNSRECORD_FILTER_OMIT_PRIVATE
Filter private records.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
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 struct GNUNET_CRYPTO_PrivateKey * GNUNET_IDENTITY_ego_get_private_key(const struct GNUNET_IDENTITY_Ego *ego)
Obtain the ECC key associated with a ego.
struct GNUNET_IDENTITY_Handle * GNUNET_IDENTITY_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_IDENTITY_Callback cb, void *cb_cls)
Connect to the identity service.
void GNUNET_IDENTITY_disconnect(struct GNUNET_IDENTITY_Handle *h)
Disconnect from identity service.
void GNUNET_IDENTITY_ego_get_public_key(struct GNUNET_IDENTITY_Ego *ego, struct GNUNET_CRYPTO_PublicKey *pk)
Get the identifier (public key) of an ego.
#define GNUNET_log(kind,...)
char * GNUNET_CRYPTO_public_key_to_string(const struct GNUNET_CRYPTO_PublicKey *key)
Creates a (Base32) string representation of the public key.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
GNUNET_GenericReturnValue
Named constants for return values.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_DEBUG
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
#define GNUNET_free_nz(ptr)
Wrapper around free.
struct GNUNET_NAMESTORE_ZoneIterator * GNUNET_NAMESTORE_zone_iteration_start2(struct GNUNET_NAMESTORE_Handle *h, const struct GNUNET_CRYPTO_PrivateKey *zone, GNUNET_SCHEDULER_TaskCallback error_cb, void *error_cb_cls, GNUNET_NAMESTORE_RecordSetMonitor proc, void *proc_cls, GNUNET_SCHEDULER_TaskCallback finish_cb, void *finish_cb_cls, enum GNUNET_GNSRECORD_Filter filter)
Starts a new zone iteration (used to periodically PUT all of our records into our DHT).
struct GNUNET_NAMESTORE_QueueEntry * GNUNET_NAMESTORE_records_lookup(struct GNUNET_NAMESTORE_Handle *h, const struct GNUNET_CRYPTO_PrivateKey *pkey, const char *label, GNUNET_SCHEDULER_TaskCallback error_cb, void *error_cb_cls, GNUNET_NAMESTORE_RecordMonitor rm, void *rm_cls)
Lookup an item in the namestore.
struct GNUNET_NAMESTORE_QueueEntry * GNUNET_NAMESTORE_record_set_store(struct GNUNET_NAMESTORE_Handle *h, const struct GNUNET_CRYPTO_PrivateKey *pkey, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd, GNUNET_NAMESTORE_ContinuationWithStatus cont, void *cont_cls)
Store an item in the namestore.
void GNUNET_NAMESTORE_disconnect(struct GNUNET_NAMESTORE_Handle *h)
Disconnect from the namestore service (and free associated resources).
void GNUNET_NAMESTORE_zone_iterator_next(struct GNUNET_NAMESTORE_ZoneIterator *it, uint64_t limit)
Calls the record processor specified in GNUNET_NAMESTORE_zone_iteration_start for the next record.
void GNUNET_NAMESTORE_cancel(struct GNUNET_NAMESTORE_QueueEntry *qe)
Cancel a namestore operation.
struct GNUNET_NAMESTORE_QueueEntry * GNUNET_NAMESTORE_records_lookup2(struct GNUNET_NAMESTORE_Handle *h, const struct GNUNET_CRYPTO_PrivateKey *pkey, const char *label, GNUNET_SCHEDULER_TaskCallback error_cb, void *error_cb_cls, GNUNET_NAMESTORE_RecordMonitor rm, void *rm_cls, enum GNUNET_GNSRECORD_Filter filter)
Lookup an item in the namestore with GNSRECORD filter.
struct GNUNET_NAMESTORE_QueueEntry * GNUNET_NAMESTORE_records_store(struct GNUNET_NAMESTORE_Handle *h, const struct GNUNET_CRYPTO_PrivateKey *pkey, unsigned int rd_set_count, const struct GNUNET_NAMESTORE_RecordInfo *record_info, unsigned int *rds_sent, GNUNET_NAMESTORE_ContinuationWithStatus cont, void *cont_cls)
Store one or more record sets in the namestore.
struct GNUNET_NAMESTORE_Handle * GNUNET_NAMESTORE_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the namestore service.
void GNUNET_NAMESTORE_zone_iteration_stop(struct GNUNET_NAMESTORE_ZoneIterator *it)
Stops iteration and releases the namestore handle for further calls.
int GNUNET_REST_handle_request(struct GNUNET_REST_RequestHandle *conn, const struct GNUNET_REST_RequestHandler *handlers, struct GNUNET_REST_RequestHandlerError *err, void *cls)
void(* GNUNET_REST_ResultProcessor)(void *cls, struct MHD_Response *resp, int status)
Iterator called on obtained result for a REST result.
#define GNUNET_REST_HANDLER_END
struct MHD_Response * GNUNET_REST_create_response(const char *data)
Create REST MHD response.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
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.
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.
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
@ MHD_HTTP_OK
OK [RFC7231, Section 6.3.1].
@ MHD_HTTP_NO_CONTENT
No Content [RFC7231, Section 6.3.5].
@ MHD_HTTP_INTERNAL_SERVER_ERROR
Internal Server Error [RFC7231, Section 6.6.1].
static struct EgoEntry * ego_tail
Ego list.
#define GNUNET_REST_API_NS_NAMESTORE
Namestore namespace.
void namestore_import(struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
Handle namestore POST import.
@ UPDATE_STRATEGY_REPLACE
static void ns_get_lookup_cb(void *cls, const struct GNUNET_CRYPTO_PrivateKey *zone, const char *label, unsigned int rd_len, const struct GNUNET_GNSRECORD_Data *rd)
static void import_next_cb(void *cls, enum GNUNET_ErrorCode ec)
static void del_finished(void *cls, enum GNUNET_ErrorCode ec)
static void ns_lookup_cb(void *cls, const struct GNUNET_CRYPTO_PrivateKey *zone, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
static struct GNUNET_NAMESTORE_Handle * ns_handle
Handle to NAMESTORE.
static void namestore_iteration_error(void *cls)
Does internal server error when iteration failed.
static void namestore_list_finished(void *cls)
Iteration over all results finished, build final response.
#define ID_REST_STATE_INIT
State while collecting all egos.
static struct RequestHandle * requests_head
DLL.
static void options_cont(struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
Respond to OPTIONS request.
void REST_namestore_done(struct GNUNET_REST_Plugin *api)
Exit point from the plugin.
void * REST_namestore_init(const struct GNUNET_CONFIGURATION_Handle *c)
Entry point for the plugin.
static int state
The processing state.
static void namestore_list_iteration(void *cls, const struct GNUNET_CRYPTO_PrivateKey *zone_key, const char *rname, unsigned int rd_len, const struct GNUNET_GNSRECORD_Data *rd, struct GNUNET_TIME_Absolute expiry)
Create a response with requested records.
static struct EgoEntry * ego_head
Ego list.
static void list_ego(void *cls, struct GNUNET_IDENTITY_Ego *ego, void **ctx, const char *identifier)
void namestore_delete(struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
Handle namestore DELETE request.
static char * allow_methods
HTTP methods allows for this plugin.
void namestore_add(struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
Handle namestore POST request.
static void create_finished(void *cls, enum GNUNET_ErrorCode ec)
static void bulk_tx_start(struct RequestHandle *handle)
static struct RequestHandle * requests_tail
DLL.
enum GNUNET_GenericReturnValue REST_namestore_process_request(void *plugin, struct GNUNET_REST_RequestHandle *rest_handle, GNUNET_REST_ResultProcessor proc, void *proc_cls)
Function processing the REST call.
static struct GNUNET_IDENTITY_Handle * identity_handle
Handle to Identity service.
const struct GNUNET_CONFIGURATION_Handle * ns_cfg
The configuration handle.
static void ns_lookup_error_cb(void *cls)
Handle lookup error.
void namestore_add_or_update(struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
Handle namestore POST/PUT request.
#define GNUNET_REST_API_NS_NAMESTORE_IMPORT
Namestore import API namespace.
void namestore_update(struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
Handle namestore PUT request.
#define ID_REST_STATE_POST_INIT
Done collecting egos.
struct EgoEntry * get_egoentry_namestore(struct RequestHandle *handle, char *name)
Get EgoEntry from list with either a public key or a name If public key and name are not NULL,...
static void do_error(void *cls)
Task run on errors.
void namestore_get(struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
Handle namestore GET request.
static void cleanup_handle(void *cls)
Cleanup lookup handle.
const char * GNUNET_ErrorCode_get_hint(enum GNUNET_ErrorCode ec)
Returns a hint for a given error code.
unsigned int GNUNET_ErrorCode_get_http_status(enum GNUNET_ErrorCode ec)
Return HTTP status for a given error code.
GNUNET_ErrorCode
Taler error codes.
@ GNUNET_EC_NAMESTORE_LOOKUP_ERROR
Failed to lookup record.
@ GNUNET_EC_NAMESTORE_ITERATION_FAILED
Zone iteration failed.
@ GNUNET_EC_NAMESTORE_ZONE_EMPTY
Zone does not contain any records.
@ GNUNET_EC_NAMESTORE_NO_LABEL_GIVEN
No label given.
@ GNUNET_EC_NAMESTORE_RECORD_DATA_INVALID
Record data invalid.
@ GNUNET_EC_NAMESTORE_NO_RECORDS_GIVEN
No records given.
@ GNUNET_EC_NAMESTORE_ZONE_NOT_FOUND
Zone not found.
@ GNUNET_EC_NONE
No error (success).
@ GNUNET_EC_NAMESTORE_UNKNOWN
Unknown namestore error.
@ GNUNET_EC_NAMESTORE_RECORD_NOT_FOUND
Record not found.
The default namestore ego.
char * identifier
Ego Identifier.
struct EgoEntry * prev
DLL.
char * keystring
Public key string.
struct EgoEntry * next
DLL.
struct GNUNET_IDENTITY_Ego * ego
The Ego.
void * cls
Closure for all of the callbacks.
A private key for an identity as per LSD0001.
An identity key as per LSD0001.
uint32_t record_type
Type of the GNS/DNS record.
const void * data
Binary value stored in the DNS record.
Handle for an operation with the identity service.
Entry in parser specification for GNUNET_JSON_parse().
void * cls
Closure for parser and cleaner.
Connection to the NAMESTORE service.
An QueueEntry used to store information for a pending NAMESTORE record operation.
A struct for record bulk import.
Handle for a zone iterator operation.
struct returned by the initialization function of the plugin
void * cls
The closure of the plugin.
const char * url
The url as string.
struct GNUNET_CONTAINER_MultiHashMap * url_param_map
Map of url parameters.
void(* proc)(struct GNUNET_REST_RequestHandle *handle, const char *url, void *cls)
Namespace to handle.
Entry in list of pending tasks.
Time for absolute times used by GNUnet, in microseconds.
Time for relative time used by GNUnet, in microseconds.
struct GNUNET_BLOCK_PluginFunctions * api
Plugin API.
const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
char * record_name
Records to store.
unsigned int rd_count
Number of records in rd.
enum GNUNET_ErrorCode ec
Error code.
struct GNUNET_IDENTITY_Operation * op
IDENTITY Operation.
struct RequestHandle * prev
DLL.
const struct GNUNET_CRYPTO_PrivateKey * zone_pkey
Private key for the zone.
struct GNUNET_NAMESTORE_RecordInfo * ri
RecordInfo array.
struct EgoEntry * ego_entry
IDENTITY Operation.
struct GNUNET_SCHEDULER_Task * timeout_task
ID of a task associated with the resolution process.
void * proc_cls
The closure of the result processor.
struct GNUNET_GNSRECORD_Data * rd
Records to store.
GNUNET_REST_ResultProcessor proc
The plugin result processor.
unsigned int rd_set_pos
Position of record info.
struct RequestHandle * next
DLL.
enum UpdateStrategy update_strategy
How to update the record set.
uint32_t record_type
Record type filter.
json_t * resp_object
Response object.
struct GNUNET_REST_RequestHandle * rest_handle
Handle to rest request.
struct GNUNET_NAMESTORE_ZoneIterator * list_it
Handle to NAMESTORE it.
struct GNUNET_NAMESTORE_Handle * nc
For bulk import, we need a dedicated Namestore handle.
struct GNUNET_NAMESTORE_QueueEntry * ns_qe
NAMESTORE Operation.
unsigned int rd_set_count
Size of record info.
struct GNUNET_TIME_Relative timeout
Desired timeout for the lookup (default is no timeout).