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 static struct EgoEntry *ego_head;
91 
95 static struct EgoEntry *ego_tail;
96 
100 static int state;
101 
106 
111 
115 struct Plugin
116 {
117  const struct GNUNET_CONFIGURATION_Handle *cfg;
118 };
119 
123 struct EgoEntry
124 {
128  struct EgoEntry *next;
129 
133  struct EgoEntry *prev;
134 
138  char *identifier;
139 
143  char *keystring;
144 
148  struct GNUNET_IDENTITY_Ego *ego;
149 };
150 
151 
153 {
156 };
157 
161 struct RequestHandle
162 {
166  struct RequestHandle *next;
167 
171  struct RequestHandle *prev;
172 
176  char *record_name;
177 
181  uint32_t record_type;
182 
187 
192 
196  unsigned int rd_count;
197 
202 
206  json_t *resp_object;
207 
208 
213 
218 
223 
228 
232  struct GNUNET_REST_RequestHandle *rest_handle;
233 
238 
243 
248 
252  void *proc_cls;
253 
257  char *url;
258 
262  char *emsg;
263 
267  int response_code;
268 };
269 
274 
279 
280 
285 static void
286 cleanup_handle (void *cls)
287 {
288  struct RequestHandle *handle = cls;
289 
290  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n");
291  if (NULL != handle->timeout_task)
292  {
294  handle->timeout_task = NULL;
295  }
296  if (NULL != handle->record_name)
297  GNUNET_free (handle->record_name);
298  if (NULL != handle->url)
299  GNUNET_free (handle->url);
300  if (NULL != handle->emsg)
301  GNUNET_free (handle->emsg);
302  if (NULL != handle->rd)
303  {
304  for (int i = 0; i < handle->rd_count; i++)
305  {
306  if (NULL != handle->rd[i].data)
307  GNUNET_free_nz ((void *) handle->rd[i].data);
308  }
309  GNUNET_free (handle->rd);
310  }
311  if (NULL != handle->timeout_task)
313  if (NULL != handle->list_it)
315  if (NULL != handle->ns_qe)
316  GNUNET_NAMESTORE_cancel (handle->ns_qe);
317 
318  if (NULL != handle->resp_object)
319  {
320  json_decref (handle->resp_object);
321  }
322  GNUNET_CONTAINER_DLL_remove (requests_head,
323  requests_tail,
324  handle);
325  GNUNET_free (handle);
326 }
327 
328 
334 static void
335 do_error (void *cls)
336 {
337  struct RequestHandle *handle = cls;
338  struct MHD_Response *resp;
339  json_t *json_error = json_object ();
340  char *response;
341 
342  if (NULL == handle->emsg)
344 
345  json_object_set_new (json_error, "error", json_string (handle->emsg));
346 
347  if (0 == handle->response_code)
348  handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
349  response = json_dumps (json_error, 0);
350  resp = GNUNET_REST_create_response (response);
351  MHD_add_response_header (resp, "Content-Type", "application/json");
352  handle->proc (handle->proc_cls, resp, handle->response_code);
353  json_decref (json_error);
354  GNUNET_free (response);
355  cleanup_handle (handle);
356 }
357 
358 
368 struct EgoEntry *
370 {
371  struct EgoEntry *ego_entry;
372  char *copy = GNUNET_strdup (name);
373  char *tmp;
374 
375  if (NULL == name)
376  return NULL;
377  tmp = strtok (copy, "/");
378  for (ego_entry = ego_head; NULL != ego_entry;
379  ego_entry = ego_entry->next)
380  {
381  if (0 != strcasecmp (tmp, ego_entry->identifier))
382  continue;
383  GNUNET_free (copy);
384  return ego_entry;
385  }
386  GNUNET_free (copy);
387  return NULL;
388 }
389 
390 
396 static void
398 {
399  struct RequestHandle *handle = cls;
400 
403  return;
404 }
405 
406 
414 static void
415 create_finished (void *cls, int32_t success, const char *emsg)
416 {
417  struct RequestHandle *handle = cls;
418  struct MHD_Response *resp;
419 
420  handle->ns_qe = NULL;
421  if (GNUNET_YES != success)
422  {
423  if (NULL != emsg)
424  {
425  handle->emsg = GNUNET_strdup (emsg);
427  return;
428  }
429  handle->emsg = GNUNET_strdup ("Error storing records");
431  return;
432  }
433  resp = GNUNET_REST_create_response (NULL);
434  handle->proc (handle->proc_cls, resp, MHD_HTTP_NO_CONTENT);
436 }
437 
438 
446 static void
447 del_finished (void *cls, int32_t success, const char *emsg)
448 {
449  struct RequestHandle *handle = cls;
450 
451  handle->ns_qe = NULL;
452  if (GNUNET_NO == success)
453  {
454  handle->response_code = MHD_HTTP_NOT_FOUND;
455  handle->emsg = GNUNET_strdup ("No record found");
457  return;
458  }
459  if (GNUNET_SYSERR == success)
460  {
461  if (NULL != emsg)
462  {
463  handle->emsg = GNUNET_strdup (emsg);
465  return;
466  }
467  handle->emsg = GNUNET_strdup ("Deleting record failed");
469  return;
470  }
471  handle->proc (handle->proc_cls,
473  MHD_HTTP_NO_CONTENT);
475 }
476 
477 
484 static void
486 {
487  struct RequestHandle *handle = cls;
488  char *result_str;
489  struct MHD_Response *resp;
490 
491  handle->list_it = NULL;
492 
493  if (NULL == handle->resp_object)
494  handle->resp_object = json_array ();
495 
496  result_str = json_dumps (handle->resp_object, 0);
497  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result_str);
498  resp = GNUNET_REST_create_response (result_str);
499  MHD_add_response_header (resp, "Content-Type", "application/json");
500  handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
501  GNUNET_free (result_str);
503 }
504 
505 
511 static void
513  const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key,
514  const char *rname,
515  unsigned int rd_len,
516  const struct GNUNET_GNSRECORD_Data *rd)
517 {
518  struct RequestHandle *handle = cls;
519  struct GNUNET_GNSRECORD_Data rd_filtered[rd_len];
520  json_t *record_obj;
521  int i = 0;
522  int j = 0;
523 
524  if (NULL == handle->resp_object)
525  handle->resp_object = json_array ();
526  for (i = 0; i < rd_len; i++)
527  {
528  if ((GNUNET_GNSRECORD_TYPE_ANY != handle->record_type) &&
529  (rd[i].record_type != handle->record_type))
530  continue; /* Apply filter */
531  rd_filtered[j] = rd[i];
532  rd_filtered[j].data = rd[i].data;
533  j++;
534  }
536  if (j > 0)
537  {
538  record_obj = GNUNET_JSON_from_gnsrecord (rname,
539  rd_filtered,
540  j);
541  json_array_append_new (handle->resp_object, record_obj);
542  }
544 }
545 
546 
552 static void
554 {
555  struct RequestHandle *handle = cls;
556 
559 }
560 
561 
562 static void
563 ns_get_lookup_cb (void *cls,
564  const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
565  const char *label,
566  unsigned int rd_len,
567  const struct GNUNET_GNSRECORD_Data *rd)
568 {
569  struct RequestHandle *handle = cls;
570  struct GNUNET_GNSRECORD_Data rd_filtered[rd_len];
571  json_t *record_obj;
572  int i = 0;
573  int j = 0;
574 
575  handle->ns_qe = NULL;
576  if (NULL == handle->resp_object)
577  handle->resp_object = json_array ();
578  for (i = 0; i < rd_len; i++)
579  {
580  if ((GNUNET_GNSRECORD_TYPE_ANY != handle->record_type) &&
581  (rd[i].record_type != handle->record_type))
582  continue; /* Apply filter */
583  rd_filtered[j] = rd[i];
584  rd_filtered[j].data = rd[i].data;
585  j++;
586  }
588  if (j > 0)
589  {
590  record_obj = GNUNET_JSON_from_gnsrecord (label,
591  rd_filtered,
592  j);
593  json_array_append_new (handle->resp_object, record_obj);
594  }
596 }
597 
598 
606 void
608  const char *url,
609  void *cls)
610 {
611  struct RequestHandle *handle = cls;
612  struct EgoEntry *ego_entry;
613  struct GNUNET_HashCode key;
614  char *egoname;
615  char *labelname;
616  char *typename;
617 
618  egoname = NULL;
619  ego_entry = NULL;
620 
621  // set zone to name if given
622  if (strlen (GNUNET_REST_API_NS_NAMESTORE) + 1 >= strlen (handle->url))
623  {
624  handle->response_code = MHD_HTTP_NOT_FOUND;
627  return;
628  }
629  egoname = &handle->url[strlen (GNUNET_REST_API_NS_NAMESTORE) + 1];
630  ego_entry = get_egoentry_namestore (handle, egoname);
631  if (NULL == ego_entry)
632  {
633  handle->response_code = MHD_HTTP_NOT_FOUND;
636  return;
637  }
638  handle->zone_pkey = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
639 
640  GNUNET_CRYPTO_hash ("record_type", strlen ("record_type"), &key);
641  if (GNUNET_NO ==
643  {
645  }
646  else
647  {
648  typename = GNUNET_CONTAINER_multihashmap_get (con_handle->url_param_map,
649  &key);
651  }
652  labelname = &egoname[strlen (ego_entry->identifier)];
653  // set zone to name if given
654  if (1 >= strlen (labelname))
655  {
656  handle->list_it =
658  handle->zone_pkey,
660  handle,
662  handle,
664  handle);
665  if (NULL == handle->list_it)
666  {
669  return;
670  }
671  return;
672  }
673  handle->record_name = GNUNET_strdup (labelname + 1);
674  handle->ns_qe = GNUNET_NAMESTORE_records_lookup (ns_handle,
675  handle->zone_pkey,
676  handle->record_name,
678  handle,
680  handle);
681  if (NULL == handle->ns_qe)
682  {
685  return;
686  }
687 }
688 
689 
690 static void
691 ns_lookup_cb (void *cls,
692  const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
693  const char *label,
694  unsigned int rd_count,
695  const struct GNUNET_GNSRECORD_Data *rd)
696 {
697  struct RequestHandle *handle = cls;
698  struct GNUNET_GNSRECORD_Data rd_new[rd_count + handle->rd_count];
699  int i = 0;
700  int j = 0;
701 
702  if (UPDATE_STRATEGY_APPEND == handle->update_strategy)
703  {
704  for (i = 0; i < rd_count; i++)
705  rd_new[i] = rd[i];
706  }
707  for (j = 0; j < handle->rd_count; j++)
708  rd_new[i + j] = handle->rd[j];
709  handle->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
710  handle->zone_pkey,
711  handle->record_name,
712  i + j,
713  rd_new,
715  handle);
716  if (NULL == handle->ns_qe)
717  {
720  return;
721  }
722 }
723 
724 
732 void
734  const char *url,
735  void *cls)
736 {
737  struct RequestHandle *handle = cls;
738  struct EgoEntry *ego_entry;
739  char *egoname;
740  json_t *data_js;
741  json_error_t err;
742 
743  char term_data[handle->rest_handle->data_size + 1];
744 
745  if (0 >= handle->rest_handle->data_size)
746  {
747  handle->response_code = MHD_HTTP_BAD_REQUEST;
750  return;
751  }
752  term_data[handle->rest_handle->data_size] = '\0';
753  GNUNET_memcpy (term_data,
754  handle->rest_handle->data,
755  handle->rest_handle->data_size);
756  data_js = json_loads (term_data, JSON_DECODE_ANY, &err);
757  struct GNUNET_JSON_Specification gnsspec[] =
758  { GNUNET_JSON_spec_gnsrecord (&handle->rd, &handle->rd_count,
759  &handle->record_name),
761  if (GNUNET_OK != GNUNET_JSON_parse (data_js, gnsspec, NULL, NULL))
762  {
765  json_decref (data_js);
766  return;
767  }
768  GNUNET_JSON_parse_free (gnsspec);
769  if (0 >= strlen (handle->record_name))
770  {
771  handle->response_code = MHD_HTTP_BAD_REQUEST;
774  json_decref (data_js);
775  return;
776  }
777  json_decref (data_js);
778 
779  egoname = NULL;
780  ego_entry = NULL;
781 
782  // set zone to name if given
783  if (strlen (GNUNET_REST_API_NS_NAMESTORE) + 1 >= strlen (handle->url))
784  {
785  handle->response_code = MHD_HTTP_NOT_FOUND;
788  return;
789  }
790  egoname = &handle->url[strlen (GNUNET_REST_API_NS_NAMESTORE) + 1];
791  ego_entry = get_egoentry_namestore (handle, egoname);
792 
793  if (NULL == ego_entry)
794  {
795  handle->response_code = MHD_HTTP_NOT_FOUND;
798  return;
799  }
800  handle->zone_pkey = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
801  handle->ns_qe = GNUNET_NAMESTORE_records_lookup (ns_handle,
802  handle->zone_pkey,
803  handle->record_name,
805  handle,
806  &ns_lookup_cb,
807  handle);
808  if (NULL == handle->ns_qe)
809  {
812  return;
813  }
814 }
815 
816 
824 void
826  const char *url,
827  void *cls)
828 {
829  struct RequestHandle *handle = cls;
831  namestore_add_or_update (con_handle, url, cls);
832 }
833 
834 
842 void
844  const char *url,
845  void *cls)
846 {
847  struct RequestHandle *handle = cls;
849  namestore_add_or_update (con_handle, url, cls);
850 }
851 
852 
860 void
862  const char *url,
863  void *cls)
864 {
865  struct RequestHandle *handle = cls;
866  struct EgoEntry *ego_entry;
867  char *egoname;
868  char *labelname;
869 
870  egoname = NULL;
871  ego_entry = NULL;
872 
873  // set zone to name if given
874  if (strlen (GNUNET_REST_API_NS_NAMESTORE) + 1 >= strlen (handle->url))
875  {
876  handle->response_code = MHD_HTTP_NOT_FOUND;
879  return;
880  }
881  egoname = &handle->url[strlen (GNUNET_REST_API_NS_NAMESTORE) + 1];
882  ego_entry = get_egoentry_namestore (handle, egoname);
883  if (NULL == ego_entry)
884  {
885  handle->response_code = MHD_HTTP_NOT_FOUND;
888  return;
889  }
890  handle->zone_pkey = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
891  labelname = &egoname[strlen (ego_entry->identifier)];
892  // set zone to name if given
893  if (1 >= strlen (labelname))
894  {
895  /* label is only "/" */
896  handle->response_code = MHD_HTTP_BAD_REQUEST;
897  handle->emsg = GNUNET_strdup ("Label missing");
899  }
900 
901  handle->record_name = GNUNET_strdup (labelname + 1);
902  handle->ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
903  handle->zone_pkey,
904  handle->record_name,
905  0,
906  NULL,
907  &del_finished,
908  handle);
909  if (NULL == handle->ns_qe)
910  {
913  return;
914  }
915 }
916 
917 
925 static void
927  const char *url,
928  void *cls)
929 {
930  struct MHD_Response *resp;
931  struct RequestHandle *handle = cls;
932 
933  // independent of path return all options
934  resp = GNUNET_REST_create_response (NULL);
935  MHD_add_response_header (resp, "Access-Control-Allow-Methods", allow_methods);
936  handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
938  return;
939 }
940 
941 
942 static void
943 list_ego (void *cls,
944  struct GNUNET_IDENTITY_Ego *ego,
945  void **ctx,
946  const char *identifier)
947 {
948  struct EgoEntry *ego_entry;
950 
951  if ((NULL == ego) && (ID_REST_STATE_INIT == state))
952  {
954  return;
955  }
956  if (ID_REST_STATE_INIT == state)
957  {
958  ego_entry = GNUNET_new (struct EgoEntry);
961  ego_entry->ego = ego;
962  ego_entry->identifier = GNUNET_strdup (identifier);
964  ego_tail,
965  ego_entry);
966  }
967  /* Ego renamed or added */
968  if (identifier != NULL)
969  {
970  for (ego_entry = ego_head; NULL != ego_entry;
971  ego_entry = ego_entry->next)
972  {
973  if (ego_entry->ego == ego)
974  {
975  /* Rename */
976  GNUNET_free (ego_entry->identifier);
977  ego_entry->identifier = GNUNET_strdup (identifier);
978  break;
979  }
980  }
981  if (NULL == ego_entry)
982  {
983  /* Add */
984  ego_entry = GNUNET_new (struct EgoEntry);
987  ego_entry->ego = ego;
988  ego_entry->identifier = GNUNET_strdup (identifier);
990  ego_tail,
991  ego_entry);
992  }
993  }
994  else
995  {
996  /* Delete */
997  for (ego_entry = ego_head; NULL != ego_entry;
998  ego_entry = ego_entry->next)
999  {
1000  if (ego_entry->ego == ego)
1001  break;
1002  }
1003  if (NULL == ego_entry)
1004  return; /* Not found */
1005 
1006  GNUNET_CONTAINER_DLL_remove (ego_head,
1007  ego_tail,
1008  ego_entry);
1009  GNUNET_free (ego_entry->identifier);
1010  GNUNET_free (ego_entry->keystring);
1011  GNUNET_free (ego_entry);
1012  return;
1013  }
1014 
1015 }
1016 
1017 
1029 static enum GNUNET_GenericReturnValue
1032  void *proc_cls)
1033 {
1034  struct RequestHandle *handle = GNUNET_new (struct RequestHandle);
1036  static const struct GNUNET_REST_RequestHandler handlers[] =
1037  { { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_NAMESTORE, &namestore_get },
1038  { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_NAMESTORE, &namestore_add },
1039  { MHD_HTTP_METHOD_PUT, GNUNET_REST_API_NS_NAMESTORE, &namestore_update },
1040  { MHD_HTTP_METHOD_DELETE, GNUNET_REST_API_NS_NAMESTORE, &namestore_delete },
1041  { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_NAMESTORE, &options_cont },
1043 
1044  handle->response_code = 0;
1046  handle->proc_cls = proc_cls;
1047  handle->proc = proc;
1048  handle->rest_handle = rest_handle;
1049  handle->zone_pkey = NULL;
1050  handle->timeout_task =
1051  GNUNET_SCHEDULER_add_delayed (handle->timeout, &do_error, handle);
1052  handle->url = GNUNET_strdup (rest_handle->url);
1053  if (handle->url[strlen (handle->url) - 1] == '/')
1054  handle->url[strlen (handle->url) - 1] = '\0';
1055  GNUNET_CONTAINER_DLL_insert (requests_head,
1056  requests_tail,
1057  handle);
1058  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting...\n");
1059  if (GNUNET_NO ==
1060  GNUNET_REST_handle_request (handle->rest_handle, handlers, &err, handle))
1061  {
1062  cleanup_handle (handle);
1063  return GNUNET_NO;
1064  }
1065 
1066  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connected\n");
1067  return GNUNET_YES;
1068 }
1069 
1070 
1077 void *
1079 {
1080  static struct Plugin plugin;
1081  struct GNUNET_REST_Plugin *api;
1082 
1083  cfg = cls;
1084  if (NULL != plugin.cfg)
1085  return NULL; /* can only initialize once! */
1086  memset (&plugin, 0, sizeof(struct Plugin));
1087  plugin.cfg = cfg;
1088  api = GNUNET_new (struct GNUNET_REST_Plugin);
1089  api->cls = &plugin;
1094  "%s, %s, %s, %s, %s",
1095  MHD_HTTP_METHOD_GET,
1096  MHD_HTTP_METHOD_POST,
1097  MHD_HTTP_METHOD_PUT,
1098  MHD_HTTP_METHOD_DELETE,
1099  MHD_HTTP_METHOD_OPTIONS);
1100  ns_handle = GNUNET_NAMESTORE_connect (cfg);
1101  identity_handle = GNUNET_IDENTITY_connect (cfg, &list_ego, NULL);
1102 
1103  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _ ("Namestore REST API initialized\n"));
1104  return api;
1105 }
1106 
1107 
1114 void *
1116 {
1117  struct GNUNET_REST_Plugin *api = cls;
1118  struct Plugin *plugin = api->cls;
1119  struct RequestHandle *request;
1120  struct EgoEntry *ego_entry;
1121  struct EgoEntry *ego_tmp;
1122 
1123  plugin->cfg = NULL;
1124  while (NULL != (request = requests_head))
1125  do_error (request);
1126  if (NULL != identity_handle)
1127  GNUNET_IDENTITY_disconnect (identity_handle);
1128  if (NULL != ns_handle)
1129  GNUNET_NAMESTORE_disconnect (ns_handle);
1130 
1131  for (ego_entry = ego_head; NULL != ego_entry;)
1132  {
1133  ego_tmp = ego_entry;
1134  ego_entry = ego_entry->next;
1135  GNUNET_free (ego_tmp->identifier);
1136  GNUNET_free (ego_tmp->keystring);
1137  GNUNET_free (ego_tmp);
1138  }
1139 
1141  GNUNET_free (api);
1142  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Namestore REST plugin is finished\n");
1143  return NULL;
1144 }
1145 
1146 
1147 /* 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.
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
static struct GNUNET_NAMESTORE_Handle * ns_handle
Handle to NAMESTORE.
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.
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.
static struct GNUNET_VPN_RedirectionRequest * request
Opaque redirection request handle.
Definition: gnunet-vpn.c:41
#define GNUNET_REST_NAMESTORE_ERROR_UNKNOWN
Error message Unknown Error.
const struct GNUNET_CONFIGURATION_Handle * cfg
The configuration handle.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
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...
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.
Definition: json.c:45
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:220
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;.
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
GNUNET_GenericReturnValue
Named constants for return values.
Definition: gnunet_common.h:83
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.
void(* proc)(struct GNUNET_REST_RequestHandle *handle, const char *url, void *cls)
Namespace to handle.
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)...
#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 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.
static struct RequestHandle * requests_head
DLL.
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
static struct EgoEntry * ego_tail
Ego list.
char * record_name
Records to store.
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.
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.
static int state
The processing state.
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.
static struct EgoEntry * ego_head
Ego list.
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_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.
#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.
struct RequestHandle * next
DLL.
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.
struct RequestHandle * prev
DLL.
#define GNUNET_CONTAINER_DLL_insert_tail(head, tail, element)
Insert an element at the tail of a DLL.
static struct GNUNET_IDENTITY_Handle * identity_handle
Handle to Identity service.
static struct GNUNET_SCHEDULER_Task * timeout_task
Task to be run on timeout.
Definition: gnunet-arm.c:124
#define GNUNET_REST_NAMESTORE_INVALID_DATA
Error message invalid data.
struct GNUNET_NAMESTORE_QueueEntry * ns_qe
NAMESTORE Operation.
static void list_ego(void *cls, struct GNUNET_IDENTITY_Ego *ego, void **ctx, const char *identifier)
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.
uint32_t record_type
Type of the GNS/DNS record.
configuration data
Definition: configuration.c:84
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 struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
struct EgoEntry * ego_entry
IDENTITY Operation.
enum GNUNET_GenericReturnValue(* process_request)(struct GNUNET_REST_RequestHandle *handle, GNUNET_REST_ResultProcessor proc, void *proc_cls)
Function to process a REST call.
static struct RequestHandle * requests_tail
DLL.
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.
#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.