GNUnet  0.11.x
plugin_rest_namestore.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2012-2015 GNUnet e.V.
4 
5  GNUnet is free software: you can redistribute it and/or modify it
6  under the terms of the GNU Affero General Public License as published
7  by the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  GNUnet is distributed in the hope that it will be useful, but
11  WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Affero General Public License for more details.
14 
15  You should have received a copy of the GNU Affero General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 
18  SPDX-License-Identifier: AGPL3.0-or-later
19  */
27 #include "platform.h"
28 #include "gnunet_rest_plugin.h"
29 #include "gnunet_gns_service.h"
32 #include "gnunet_rest_lib.h"
33 #include "gnunet_json_lib.h"
34 #include "microhttpd.h"
35 #include <jansson.h>
36 
40 #define GNUNET_REST_API_NS_NAMESTORE "/namestore"
41 
45 #define GNUNET_REST_NAMESTORE_ERROR_UNKNOWN "Unknown Error"
46 
50 #define GNUNET_REST_IDENTITY_NOT_FOUND "No identity found"
51 
52 
56 #define GNUNET_REST_NAMESTORE_FAILED "Namestore action failed"
57 
61 #define GNUNET_REST_NAMESTORE_INVALID_DATA "Data invalid"
62 
66 #define GNUNET_REST_NAMESTORE_NO_DATA "No data"
67 
71 #define ID_REST_STATE_INIT 0
72 
76 #define ID_REST_STATE_POST_INIT 1
77 
81 
85 static char *allow_methods;
86 
90 struct Plugin
91 {
92  const struct GNUNET_CONFIGURATION_Handle *cfg;
93 };
94 
98 struct EgoEntry
99 {
103  struct EgoEntry *next;
104 
108  struct EgoEntry *prev;
109 
113  char *identifier;
114 
118  char *keystring;
119 
123  struct GNUNET_IDENTITY_Ego *ego;
124 };
125 
126 
128 {
131 };
132 
136 struct RequestHandle
137 {
141  char *record_name;
142 
146  uint32_t record_type;
147 
151  enum UpdateStrategy update_strategy;
152 
157 
161  unsigned int rd_count;
162 
167 
171  json_t *resp_object;
172 
176  int state;
177 
182 
187 
192 
197 
201  struct EgoEntry *ego_head;
202 
206  struct EgoEntry *ego_tail;
207 
212 
217 
221  struct GNUNET_REST_RequestHandle *rest_handle;
222 
227 
232 
237 
241  void *proc_cls;
242 
246  char *url;
247 
251  char *emsg;
252 
256  int response_code;
257 };
258 
263 static void
264 cleanup_handle (void *cls)
265 {
266  struct RequestHandle *handle = cls;
267  struct EgoEntry *ego_entry;
268  struct EgoEntry *ego_tmp;
269 
270  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n");
271  if (NULL != handle->timeout_task)
272  {
274  handle->timeout_task = NULL;
275  }
276  if (NULL != handle->record_name)
277  GNUNET_free (handle->record_name);
278  if (NULL != handle->url)
279  GNUNET_free (handle->url);
280  if (NULL != handle->emsg)
281  GNUNET_free (handle->emsg);
282  if (NULL != handle->rd)
283  {
284  for (int i = 0; i < handle->rd_count; i++)
285  {
286  if (NULL != handle->rd[i].data)
287  GNUNET_free_nz ((void *) handle->rd[i].data);
288  }
289  GNUNET_free (handle->rd);
290  }
291  if (NULL != handle->timeout_task)
293  if (NULL != handle->list_it)
295  if (NULL != handle->ns_qe)
296  GNUNET_NAMESTORE_cancel (handle->ns_qe);
297  if (NULL != handle->identity_handle)
299  if (NULL != handle->ns_handle)
300  {
302  }
303 
304  for (ego_entry = handle->ego_head; NULL != ego_entry;)
305  {
306  ego_tmp = ego_entry;
307  ego_entry = ego_entry->next;
308  GNUNET_free (ego_tmp->identifier);
309  GNUNET_free (ego_tmp->keystring);
310  GNUNET_free (ego_tmp);
311  }
312 
313  if (NULL != handle->resp_object)
314  {
315  json_decref (handle->resp_object);
316  }
317 
318  GNUNET_free (handle);
319 }
320 
321 
327 static void
328 do_error (void *cls)
329 {
330  struct RequestHandle *handle = cls;
331  struct MHD_Response *resp;
332  json_t *json_error = json_object ();
333  char *response;
334 
335  if (NULL == handle->emsg)
337 
338  json_object_set_new (json_error, "error", json_string (handle->emsg));
339 
340  if (0 == handle->response_code)
341  handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
342  response = json_dumps (json_error, 0);
343  resp = GNUNET_REST_create_response (response);
344  MHD_add_response_header (resp, "Content-Type", "application/json");
345  handle->proc (handle->proc_cls, resp, handle->response_code);
346  json_decref (json_error);
347  GNUNET_free (response);
349 }
350 
351 
361 struct EgoEntry *
363 {
364  struct EgoEntry *ego_entry;
365  char *copy = GNUNET_strdup (name);
366  char *tmp;
367 
368  if (NULL == name)
369  return NULL;
370  tmp = strtok (copy, "/");
371  for (ego_entry = handle->ego_head; NULL != ego_entry;
372  ego_entry = ego_entry->next)
373  {
374  if (0 != strcasecmp (tmp, ego_entry->identifier))
375  continue;
376  GNUNET_free (copy);
377  return ego_entry;
378  }
379  GNUNET_free (copy);
380  return NULL;
381 }
382 
383 
389 static void
391 {
392  struct RequestHandle *handle = cls;
393 
396  return;
397 }
398 
399 
407 static void
408 create_finished (void *cls, int32_t success, const char *emsg)
409 {
410  struct RequestHandle *handle = cls;
411  struct MHD_Response *resp;
412 
413  handle->ns_qe = NULL;
414  if (GNUNET_YES != success)
415  {
416  if (NULL != emsg)
417  {
418  handle->emsg = GNUNET_strdup (emsg);
420  return;
421  }
422  handle->emsg = GNUNET_strdup ("Error storing records");
424  return;
425  }
426  resp = GNUNET_REST_create_response (NULL);
427  handle->proc (handle->proc_cls, resp, MHD_HTTP_NO_CONTENT);
429 }
430 
431 
439 static void
440 del_finished (void *cls, int32_t success, const char *emsg)
441 {
442  struct RequestHandle *handle = cls;
443 
444  handle->ns_qe = NULL;
445  if (GNUNET_NO == success)
446  {
447  handle->response_code = MHD_HTTP_NOT_FOUND;
448  handle->emsg = GNUNET_strdup ("No record found");
450  return;
451  }
452  if (GNUNET_SYSERR == success)
453  {
454  if (NULL != emsg)
455  {
456  handle->emsg = GNUNET_strdup (emsg);
458  return;
459  }
460  handle->emsg = GNUNET_strdup ("Deleting record failed");
462  return;
463  }
464  handle->proc (handle->proc_cls,
466  MHD_HTTP_NO_CONTENT);
468 }
469 
470 
477 static void
479 {
480  struct RequestHandle *handle = cls;
481  char *result_str;
482  struct MHD_Response *resp;
483 
484  handle->list_it = NULL;
485 
486  if (NULL == handle->resp_object)
487  handle->resp_object = json_array ();
488 
489  result_str = json_dumps (handle->resp_object, 0);
490  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result_str);
491  resp = GNUNET_REST_create_response (result_str);
492  MHD_add_response_header (resp, "Content-Type", "application/json");
493  handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
494  GNUNET_free (result_str);
496 }
497 
498 
504 static void
506  const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key,
507  const char *rname,
508  unsigned int rd_len,
509  const struct GNUNET_GNSRECORD_Data *rd)
510 {
511  struct RequestHandle *handle = cls;
512  struct GNUNET_GNSRECORD_Data rd_filtered[rd_len];
513  json_t *record_obj;
514  int i = 0;
515  int j = 0;
516 
517  if (NULL == handle->resp_object)
518  handle->resp_object = json_array ();
519  for (i = 0; i < rd_len; i++)
520  {
521  if ((GNUNET_GNSRECORD_TYPE_ANY != handle->record_type) &&
522  (rd[i].record_type != handle->record_type))
523  continue; /* Apply filter */
524  rd_filtered[j] = rd[i];
525  rd_filtered[j].data = rd[i].data;
526  j++;
527  }
529  if (j > 0)
530  {
531  record_obj = GNUNET_JSON_from_gnsrecord (rname,
532  rd_filtered,
533  j);
534  json_array_append_new (handle->resp_object, record_obj);
535  }
537 }
538 
544 static void
546 {
547  struct RequestHandle *handle = cls;
548 
551 }
552 
553 
554 static void
555 ns_get_lookup_cb (void *cls,
556  const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
557  const char *label,
558  unsigned int rd_len,
559  const struct GNUNET_GNSRECORD_Data *rd)
560 {
561  struct RequestHandle *handle = cls;
562  struct GNUNET_GNSRECORD_Data rd_filtered[rd_len];
563  json_t *record_obj;
564  int i = 0;
565  int j = 0;
566 
567  handle->ns_qe = NULL;
568  if (NULL == handle->resp_object)
569  handle->resp_object = json_array ();
570  for (i = 0; i < rd_len; i++)
571  {
572  if ((GNUNET_GNSRECORD_TYPE_ANY != handle->record_type) &&
573  (rd[i].record_type != handle->record_type))
574  continue; /* Apply filter */
575  rd_filtered[j] = rd[i];
576  rd_filtered[j].data = rd[i].data;
577  j++;
578  }
580  if (j > 0)
581  {
582  record_obj = GNUNET_JSON_from_gnsrecord (label,
583  rd_filtered,
584  j);
585  json_array_append_new (handle->resp_object, record_obj);
586  }
588 }
589 
590 
591 
592 
600 void
602  const char *url,
603  void *cls)
604 {
605  struct RequestHandle *handle = cls;
606  struct EgoEntry *ego_entry;
607  struct GNUNET_HashCode key;
608  char *egoname;
609  char *labelname;
610  char *typename;
611 
612  egoname = NULL;
613  ego_entry = NULL;
614 
615  // set zone to name if given
616  if (strlen (GNUNET_REST_API_NS_NAMESTORE) + 1 >= strlen (handle->url))
617  {
618  handle->response_code = MHD_HTTP_NOT_FOUND;
621  return;
622  }
623  egoname = &handle->url[strlen (GNUNET_REST_API_NS_NAMESTORE) + 1];
624  ego_entry = get_egoentry_namestore (handle, egoname);
625  if (NULL == ego_entry)
626  {
627  handle->response_code = MHD_HTTP_NOT_FOUND;
630  return;
631  }
632  handle->zone_pkey = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
633 
634  GNUNET_CRYPTO_hash ("record_type", strlen ("record_type"), &key);
635  if (GNUNET_NO ==
637  {
639  }
640  else
641  {
642  typename = GNUNET_CONTAINER_multihashmap_get (con_handle->url_param_map,
643  &key);
645  }
646  labelname = &egoname[strlen (ego_entry->identifier)];
647  // set zone to name if given
648  if (1 >= strlen (labelname))
649  {
650  handle->list_it =
652  handle->zone_pkey,
654  handle,
656  handle,
658  handle);
659  if (NULL == handle->list_it)
660  {
663  return;
664  }
665  return;
666  }
667  handle->record_name = GNUNET_strdup (labelname + 1);
669  handle->zone_pkey,
670  handle->record_name,
672  handle,
674  handle);
675  if (NULL == handle->ns_qe)
676  {
679  return;
680  }
681 }
682 
683 
684 
685 static void
686 ns_lookup_cb (void *cls,
687  const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
688  const char *label,
689  unsigned int rd_count,
690  const struct GNUNET_GNSRECORD_Data *rd)
691 {
692  struct RequestHandle *handle = cls;
693  struct GNUNET_GNSRECORD_Data rd_new[rd_count + handle->rd_count];
694  int i = 0;
695  int j = 0;
696 
697  if (UPDATE_STRATEGY_APPEND == handle->update_strategy)
698  {
699  for (i = 0; i < rd_count; i++)
700  rd_new[i] = rd[i];
701  }
702  for (j = 0; j < handle->rd_count; j++)
703  rd_new[i + j] = handle->rd[j];
704  handle->ns_qe = GNUNET_NAMESTORE_records_store (handle->ns_handle,
705  handle->zone_pkey,
706  handle->record_name,
707  i + j,
708  rd_new,
710  handle);
711  if (NULL == handle->ns_qe)
712  {
715  return;
716  }
717 }
718 
719 
727 void
729  const char *url,
730  void *cls)
731 {
732  struct RequestHandle *handle = cls;
733  struct EgoEntry *ego_entry;
734  char *egoname;
735  json_t *data_js;
736  json_error_t err;
737 
738  char term_data[handle->rest_handle->data_size + 1];
739 
740  if (0 >= handle->rest_handle->data_size)
741  {
742  handle->response_code = MHD_HTTP_BAD_REQUEST;
745  return;
746  }
747  term_data[handle->rest_handle->data_size] = '\0';
748  GNUNET_memcpy (term_data,
749  handle->rest_handle->data,
750  handle->rest_handle->data_size);
751  data_js = json_loads (term_data, JSON_DECODE_ANY, &err);
752  struct GNUNET_JSON_Specification gnsspec[] =
753  { GNUNET_JSON_spec_gnsrecord (&handle->rd, &handle->rd_count,
754  &handle->record_name),
756  if (GNUNET_OK != GNUNET_JSON_parse (data_js, gnsspec, NULL, NULL))
757  {
760  json_decref (data_js);
761  return;
762  }
763  GNUNET_JSON_parse_free (gnsspec);
764  if (0 >= strlen (handle->record_name))
765  {
766  handle->response_code = MHD_HTTP_BAD_REQUEST;
769  json_decref (data_js);
770  return;
771  }
772  json_decref (data_js);
773 
774  egoname = NULL;
775  ego_entry = NULL;
776 
777  // set zone to name if given
778  if (strlen (GNUNET_REST_API_NS_NAMESTORE) + 1 >= strlen (handle->url))
779  {
780  handle->response_code = MHD_HTTP_NOT_FOUND;
783  return;
784  }
785  egoname = &handle->url[strlen (GNUNET_REST_API_NS_NAMESTORE) + 1];
786  ego_entry = get_egoentry_namestore (handle, egoname);
787 
788  if (NULL == ego_entry)
789  {
790  handle->response_code = MHD_HTTP_NOT_FOUND;
793  return;
794  }
795  handle->zone_pkey = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
797  handle->zone_pkey,
798  handle->record_name,
800  handle,
801  &ns_lookup_cb,
802  handle);
803  if (NULL == handle->ns_qe)
804  {
807  return;
808  }
809 }
810 
811 
819 void
821  const char *url,
822  void *cls)
823 {
824  struct RequestHandle *handle = cls;
826  namestore_add_or_update (con_handle, url, cls);
827 }
828 
829 
837 void
839  const char *url,
840  void *cls)
841 {
842  struct RequestHandle *handle = cls;
844  namestore_add_or_update (con_handle, url, cls);
845 }
846 
847 
855 void
857  const char *url,
858  void *cls)
859 {
860  struct RequestHandle *handle = cls;
861  struct EgoEntry *ego_entry;
862  char *egoname;
863  char *labelname;
864 
865  egoname = NULL;
866  ego_entry = NULL;
867 
868  // set zone to name if given
869  if (strlen (GNUNET_REST_API_NS_NAMESTORE) + 1 >= strlen (handle->url))
870  {
871  handle->response_code = MHD_HTTP_NOT_FOUND;
874  return;
875  }
876  egoname = &handle->url[strlen (GNUNET_REST_API_NS_NAMESTORE) + 1];
877  ego_entry = get_egoentry_namestore (handle, egoname);
878  if (NULL == ego_entry)
879  {
880  handle->response_code = MHD_HTTP_NOT_FOUND;
883  return;
884  }
885  handle->zone_pkey = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
886  labelname = &egoname[strlen (ego_entry->identifier)];
887  // set zone to name if given
888  if (1 >= strlen (labelname))
889  {
890  /* label is only "/" */
891  handle->response_code = MHD_HTTP_BAD_REQUEST;
892  handle->emsg = GNUNET_strdup ("Label missing");
894  }
895 
896  handle->record_name = GNUNET_strdup (labelname + 1);
898  handle->zone_pkey,
899  handle->record_name,
900  0,
901  NULL,
902  &del_finished,
903  handle);
904  if (NULL == handle->ns_qe)
905  {
908  return;
909  }
910 }
911 
912 
920 static void
922  const char *url,
923  void *cls)
924 {
925  struct MHD_Response *resp;
926  struct RequestHandle *handle = cls;
927 
928  // independent of path return all options
929  resp = GNUNET_REST_create_response (NULL);
930  MHD_add_response_header (resp, "Access-Control-Allow-Methods", allow_methods);
931  handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
933  return;
934 }
935 
936 
942 static void
944 {
946  static const struct GNUNET_REST_RequestHandler handlers[] =
947  { { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_NAMESTORE, &namestore_get },
948  { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_NAMESTORE, &namestore_add },
949  { MHD_HTTP_METHOD_PUT, GNUNET_REST_API_NS_NAMESTORE, &namestore_update },
950  { MHD_HTTP_METHOD_DELETE, GNUNET_REST_API_NS_NAMESTORE, &namestore_delete },
951  { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_NAMESTORE, &options_cont },
953 
954  if (GNUNET_NO ==
955  GNUNET_REST_handle_request (handle->rest_handle, handlers, &err, handle))
956  {
957  handle->response_code = err.error_code;
959  }
960 }
961 
962 
994 static void
995 id_connect_cb (void *cls,
996  struct GNUNET_IDENTITY_Ego *ego,
997  void **ctx,
998  const char *name)
999 {
1000  struct RequestHandle *handle = cls;
1001  struct EgoEntry *ego_entry;
1002  struct GNUNET_CRYPTO_EcdsaPublicKey pk;
1003 
1004  if ((NULL == ego) && (ID_REST_STATE_INIT == handle->state))
1005  {
1006  handle->state = ID_REST_STATE_POST_INIT;
1007  init_cont (handle);
1008  return;
1009  }
1010  if (ID_REST_STATE_INIT == handle->state)
1011  {
1012  ego_entry = GNUNET_new (struct EgoEntry);
1015  ego_entry->ego = ego;
1016  GNUNET_asprintf (&ego_entry->identifier, "%s", name);
1018  handle->ego_tail,
1019  ego_entry);
1020  }
1021 }
1022 
1023 
1035 static void
1038  void *proc_cls)
1039 {
1040  struct RequestHandle *handle = GNUNET_new (struct RequestHandle);
1041 
1042  handle->response_code = 0;
1044  handle->proc_cls = proc_cls;
1045  handle->proc = proc;
1046  handle->rest_handle = rest_handle;
1047  handle->zone_pkey = NULL;
1048 
1049  handle->url = GNUNET_strdup (rest_handle->url);
1050  if (handle->url[strlen (handle->url) - 1] == '/')
1051  handle->url[strlen (handle->url) - 1] = '\0';
1052  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting...\n");
1053 
1054  handle->ns_handle = GNUNET_NAMESTORE_connect (cfg);
1055  handle->identity_handle =
1056  GNUNET_IDENTITY_connect (cfg, &id_connect_cb, handle);
1057  handle->timeout_task =
1058  GNUNET_SCHEDULER_add_delayed (handle->timeout, &do_error, handle);
1059 
1060  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connected\n");
1061 }
1062 
1063 
1070 void *
1072 {
1073  static struct Plugin plugin;
1074  struct GNUNET_REST_Plugin *api;
1075 
1076  cfg = cls;
1077  if (NULL != plugin.cfg)
1078  return NULL; /* can only initialize once! */
1079  memset (&plugin, 0, sizeof(struct Plugin));
1080  plugin.cfg = cfg;
1081  api = GNUNET_new (struct GNUNET_REST_Plugin);
1082  api->cls = &plugin;
1086  "%s, %s, %s, %s, %s",
1087  MHD_HTTP_METHOD_GET,
1088  MHD_HTTP_METHOD_POST,
1089  MHD_HTTP_METHOD_PUT,
1090  MHD_HTTP_METHOD_DELETE,
1091  MHD_HTTP_METHOD_OPTIONS);
1092 
1093  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _ ("Namestore REST API initialized\n"));
1094  return api;
1095 }
1096 
1097 
1104 void *
1106 {
1107  struct GNUNET_REST_Plugin *api = cls;
1108  struct Plugin *plugin = api->cls;
1109 
1110  plugin->cfg = NULL;
1111 
1113  GNUNET_free (api);
1114  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Namestore REST plugin is finished\n");
1115  return NULL;
1116 }
1117 
1118 
1119 /* end of plugin_rest_namestore.c */
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.
Definition: identity_api.c:566
void * cls
Closure for parser and cleaner.
char * name
Plugin name.
void namestore_update(struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
Handle namestore PUT request.
void(* GNUNET_REST_ResultProcessor)(void *cls, struct MHD_Response *resp, int status)
Iterator called on obtained result for a REST result.
#define GNUNET_REST_NAMESTORE_FAILED
Error message Failed request.
int record_type
Record type to look up.
#define GNUNET_REST_NAMESTORE_ERROR_UNKNOWN
Error message Unknown Error.
struct EgoEntry * ego_tail
Ego list.
const struct GNUNET_CONFIGURATION_Handle * cfg
The configuration handle.
functions to parse JSON objects into GNUnet objects
static void namestore_iteration_error(void *cls)
Does internal server error when iteration failed.
void namestore_delete(struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
Handle namestore DELETE request.
void * cls
The closure of the plugin.
void * libgnunet_plugin_rest_namestore_done(void *cls)
Exit point from the plugin.
size_t data_size
The POST data size.
struct GNUNET_NAMESTORE_QueueEntry * GNUNET_NAMESTORE_records_lookup(struct GNUNET_NAMESTORE_Handle *h, const struct GNUNET_CRYPTO_EcdsaPrivateKey *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_ZoneIterator * GNUNET_NAMESTORE_zone_iteration_start(struct GNUNET_NAMESTORE_Handle *h, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, GNUNET_SCHEDULER_TaskCallback error_cb, void *error_cb_cls, GNUNET_NAMESTORE_RecordMonitor proc, void *proc_cls, GNUNET_SCHEDULER_TaskCallback finish_cb, void *finish_cb_cls)
Starts a new zone iteration (used to periodically PUT all of our records into our DHT)...
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...
GNUNET_REST_ResultProcessor proc
The plugin result processor.
void * libgnunet_plugin_rest_namestore_init(void *cls)
Entry point for the plugin.
uint32_t GNUNET_GNSRECORD_typename_to_number(const char *dns_typename)
Convert a type name (i.e.
Definition: gnsrecord.c:204
void GNUNET_JSON_parse_free(struct GNUNET_JSON_Specification *spec)
Frees all elements allocated during a GNUNET_JSON_parse() operation.
Definition: json.c:100
#define GNUNET_GNSRECORD_TYPE_ANY
Record type indicating any record/&#39;*&#39;.
static void id_connect_cb(void *cls, struct GNUNET_IDENTITY_Ego *ego, void **ctx, const char *name)
This function is initially called for all egos and then again whenever a ego&#39;s identifier changes or ...
const struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
const struct GNUNET_CRYPTO_EcdsaPrivateKey * GNUNET_IDENTITY_ego_get_private_key(const struct GNUNET_IDENTITY_Ego *ego)
Obtain the ECC key associated with a ego.
Definition: identity_api.c:595
static void create_finished(void *cls, int32_t success, const char *emsg)
Create finished callback.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
struct returned by the initialization function of the plugin
uint32_t record_type
Record type filter.
Entry in parser specification for GNUNET_JSON_parse().
static void ns_lookup_error_cb(void *cls)
Handle lookup error.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
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...
Private ECC key encoded for transmission.
int 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(* process_request)(struct GNUNET_REST_RequestHandle *handle, GNUNET_REST_ResultProcessor proc, void *proc_cls)
Function to process a REST call.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
void * proc_cls
The closure of the result processor.
static void namestore_list_iteration(void *cls, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key, const char *rname, unsigned int rd_len, const struct GNUNET_GNSRECORD_Data *rd)
Create a response with requested records.
Handle for an operation with the identity service.
Definition: identity_api.c:39
#define GNUNET_REST_HANDLER_END
static void rest_process_request(struct GNUNET_REST_RequestHandle *rest_handle, GNUNET_REST_ResultProcessor proc, void *proc_cls)
Function processing the REST call.
static struct GNUNET_DNSSTUB_Context * ctx
Context for DNS resolution.
struct GNUNET_BLOCK_PluginFunctions * api
Plugin API.
Definition: block.c:47
The request handle.
void GNUNET_NAMESTORE_cancel(struct GNUNET_NAMESTORE_QueueEntry *qe)
Cancel a namestore operation.
void * GNUNET_CONTAINER_multihashmap_get(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Given a key find a value in the map matching the key.
#define _(String)
GNU gettext support macro.
Definition: platform.h:184
struct GNUNET_NAMESTORE_QueueEntry * GNUNET_NAMESTORE_records_store(struct GNUNET_NAMESTORE_Handle *h, const struct GNUNET_CRYPTO_EcdsaPrivateKey *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.
The ego list.
static char * zone
Name of the zone we manage.
void namestore_add(struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
Handle namestore POST request.
struct GNUNET_IDENTITY_Ego * ego
The Ego.
void GNUNET_NAMESTORE_disconnect(struct GNUNET_NAMESTORE_Handle *h)
Disconnect from the namestore service (and free associated resources).
struct GNUNET_NAMESTORE_ZoneIterator * list_it
Handle to NAMESTORE it.
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
Handle for a zone iterator operation.
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:1269
Handle for an ego.
Definition: identity.h:245
char * record_name
Records to store.
enum State state
current state of profiling
json_t * resp_object
Response object.
static struct GNUNET_TIME_Relative timeout
Desired timeout for the lookup (default is no timeout).
Definition: gnunet-abd.c:61
const void * data
Binary value stored in the DNS record.
static void ns_lookup_cb(void *cls, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
char * emsg
Error response message.
int 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.
Definition: json.c:45
void namestore_add_or_update(struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
Handle namestore POST/PUT request.
struct GNUNET_CONTAINER_MultiHashMap * url_param_map
Map of url parameters.
#define GNUNET_REST_IDENTITY_NOT_FOUND
Error message No identity found.
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.
Connection to the NAMESTORE service.
Handle for the service.
Definition: identity_api.c:95
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1296
char * name
Plugin name.
struct GNUNET_TIME_Relative timeout
Desired timeout for the lookup (default is no timeout).
unsigned int rd_count
Number of records in rd.
static struct GNUNET_IDENTITY_Handle * identity_handle
Identity handle.
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
void GNUNET_IDENTITY_disconnect(struct GNUNET_IDENTITY_Handle *h)
Disconnect from identity service.
Definition: identity_api.c:884
enum UpdateStrategy update_strategy
How to update the record set.
static void options_cont(struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
Respond to OPTIONS request.
static void namestore_list_finished(void *cls)
Iteration over all results finished, build final response.
json_t * GNUNET_JSON_from_gnsrecord(const char *rname, const struct GNUNET_GNSRECORD_Data *rd, unsigned int rd_count)
Convert Gns record to JSON.
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:77
void GNUNET_NAMESTORE_zone_iteration_stop(struct GNUNET_NAMESTORE_ZoneIterator *it)
Stops iteration and releases the namestore handle for further calls.
struct GNUNET_REST_RequestHandle * rest_handle
Rest connection.
A 512-bit hashcode.
int response_code
Response code.
int state
The processing state.
#define GNUNET_REST_NAMESTORE_NO_DATA
Error message No data.
static char * plugin
Solver plugin name as string.
char * GNUNET_CRYPTO_ecdsa_public_key_to_string(const struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
Convert a public key to a string.
Definition: crypto_ecc.c:232
const char * data
The POST data.
char * keystring
Public key string.
#define GNUNET_free_nz(ptr)
Wrapper around free.
An QueueEntry used to store information for a pending NAMESTORE record operation. ...
Definition: namestore_api.c:53
static char * allow_methods
HTTP methods allows for this plugin.
static void cleanup_handle(void *cls)
Cleanup lookup handle.
#define ID_REST_STATE_INIT
State while collecting all egos.
const struct GNUNET_CRYPTO_EcdsaPrivateKey * zone_pkey
Private key for the zone.
struct GNUNET_JSON_Specification GNUNET_JSON_spec_gnsrecord(struct GNUNET_GNSRECORD_Data **rd, unsigned int *rd_count, char **name)
JSON Specification for GNS Records.
static void do_error(void *cls)
Task run on errors.
struct GNUNET_NAMESTORE_Handle * GNUNET_NAMESTORE_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the namestore service.
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
static struct GNUNET_SCHEDULER_Task * timeout_task
Task to be run on timeout.
Definition: gnunet-arm.c:124
static struct Ego * ego_head
Head of DLL of all egos.
#define GNUNET_REST_NAMESTORE_INVALID_DATA
Error message invalid data.
struct GNUNET_NAMESTORE_QueueEntry * ns_qe
NAMESTORE Operation.
char * identifier
Ego Identifier.
#define ID_REST_STATE_POST_INIT
Done collecting egos.
void namestore_get(struct GNUNET_REST_RequestHandle *con_handle, const char *url, void *cls)
Handle namestore GET request.
struct GNUNET_NAMESTORE_Handle * ns_handle
Handle to NAMESTORE.
uint32_t record_type
Type of the GNS/DNS record.
configuration data
Definition: configuration.c:84
struct EgoEntry * ego_head
Ego list.
Handle for a plugin.
Definition: block.c:37
struct GNUNET_SCHEDULER_Task * timeout_task
ID of a task associated with the resolution process.
struct MHD_Response * GNUNET_REST_create_response(const char *data)
Create REST MHD response.
Definition: rest.c:57
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and ECDS...
#define GNUNET_REST_API_NS_NAMESTORE
Namestore Namespace.
#define GNUNET_log(kind,...)
Entry in list of pending tasks.
Definition: scheduler.c:134
static void ns_get_lookup_cb(void *cls, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, const char *label, unsigned int rd_len, const struct GNUNET_GNSRECORD_Data *rd)
static struct MHD_Response * response
Our canonical response.
struct GNUNET_GNSRECORD_Data * rd
Records to store.
static void del_finished(void *cls, int32_t success, const char *emsg)
Delete finished callback.
struct EgoEntry * prev
DLL.
struct GNUNET_JSON_Specification GNUNET_JSON_spec_end(void)
End of a parser specification.
Definition: json_helper.c:35
static void init_cont(struct RequestHandle *handle)
Handle rest request.
static struct Ego * ego_tail
Tail of DLL of all egos.
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
struct EgoEntry * ego_entry
IDENTITY Operation.
void GNUNET_IDENTITY_ego_get_public_key(struct GNUNET_IDENTITY_Ego *ego, struct GNUNET_CRYPTO_EcdsaPublicKey *pk)
Get the identifier (public key) of an ego.
Definition: identity_api.c:608
struct EgoEntry * next
DLL.
struct GNUNET_IDENTITY_Handle * identity_handle
Handle to Identity service.
#define GNUNET_free(ptr)
Wrapper around free.
Time for relative time used by GNUnet, in microseconds.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:972
char * url
The url.