GNUnet  0.11.x
gnunet-namestore-fcfsd.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2012-2021 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  */
20 
27 #include "platform.h"
28 #include <microhttpd.h>
29 #include "gnunet_util_lib.h"
31 #include "gnunet_gnsrecord_lib.h"
33 #include "gnunet_mhd_compat.h"
34 #include "gnunet_json_lib.h"
35 
42 struct StaticPage
43 {
48 
52  uint64_t size;
53 
57  struct MHD_Response *response;
58 };
59 
64 {
68  struct MHD_Connection *c;
69 
73  char *body;
74 
78  size_t body_length;
79 
83  int code;
84 
89 
94 
98  void *ptr;
99 
104 
109 
114 };
115 
119 static char *zone = NULL;
120 
124 static unsigned long long port = 18080;
125 
129 static struct GNUNET_NAMESTORE_Handle *namestore = NULL;
130 
134 static struct GNUNET_IDENTITY_Handle *identity = NULL;
135 
139 static const struct GNUNET_IDENTITY_PrivateKey *zone_key = NULL;
140 
144 static struct MHD_Daemon *httpd = NULL;
145 
149 static struct GNUNET_SCHEDULER_Task *httpd_task = NULL;
150 
154 static struct StaticPage *main_page = NULL;
155 
159 static struct StaticPage *notfound_page = NULL;
160 
165 static struct StaticPage *forbidden_page = NULL;
166 
172 static void
173 do_shutdown (void *cls)
174 {
175  /* We cheat a bit here: the file descriptor is implicitly closed by MHD, so
176  calling `GNUNET_DISK_file_close' would generate a spurious warning message
177  in the log. Since that function does nothing but close the descriptor and
178  free the allocated memory, After destroying the response all that's left to
179  do is call `GNUNET_free'. */
180  if (NULL != main_page)
181  {
182  MHD_destroy_response (main_page->response);
183  GNUNET_free (main_page->handle);
184  GNUNET_free (main_page);
185  }
186  if (NULL != notfound_page)
187  {
188  MHD_destroy_response (main_page->response);
189  GNUNET_free (main_page->handle);
190  GNUNET_free (main_page);
191  }
192  if (NULL != forbidden_page)
193  {
194  MHD_destroy_response (main_page->response);
195  GNUNET_free (main_page->handle);
196  GNUNET_free (main_page);
197  }
198 
199  if (NULL != namestore)
200  {
201  GNUNET_NAMESTORE_disconnect (namestore);
202  }
203 
204  if (NULL != identity)
205  {
206  GNUNET_IDENTITY_disconnect (identity);
207  }
208 }
209 
210 
216 static void
217 do_httpd (void *cls);
218 
222 static void
223 run_httpd (void)
224 {
225  fd_set rs;
226  fd_set ws;
227  fd_set es;
228 
232 
233  FD_ZERO (&rs);
234  FD_ZERO (&ws);
235  FD_ZERO (&es);
236 
237  int max = -1;
238  GNUNET_assert (MHD_YES == MHD_get_fdset (httpd, &rs, &ws, &es, &max));
239 
240  unsigned MHD_LONG_LONG timeout = 0;
242  if (MHD_YES == MHD_get_timeout (httpd, &timeout))
243  {
245  timeout);
246  }
247 
248  GNUNET_NETWORK_fdset_copy_native (grs, &rs, max + 1);
249  GNUNET_NETWORK_fdset_copy_native (gws, &ws, max + 1);
250  GNUNET_NETWORK_fdset_copy_native (ges, &es, max + 1);
251 
253  gtime,
254  grs,
255  gws,
256  &do_httpd,
257  NULL);
261 }
262 
263 
269 static void
270 do_httpd (void *cls)
271 {
272  httpd_task = NULL;
273  MHD_run (httpd);
274  run_httpd ();
275 }
276 
277 
278 static void
280 {
281  if (NULL != httpd_task)
282  {
283  GNUNET_SCHEDULER_cancel (httpd_task);
284  httpd_task = NULL;
285  }
286  httpd_task = GNUNET_SCHEDULER_add_now (&do_httpd, NULL);
287 }
288 
289 
298 static char *
299 make_json (const char *key, const char *value, ...)
300 {
301  va_list args;
302  va_start (args, value);
303 
304  json_t *obj = NULL;
305 
306  obj = json_object ();
307  if ((NULL == key) || (NULL == value))
308  {
309  va_end (args);
310  return json_dumps (obj, JSON_COMPACT);
311  }
312 
313  json_object_set (obj, key, json_string (value));
314 
315  char *k = va_arg (args, char *);
316  if (NULL == k)
317  {
318  va_end (args);
319  return json_dumps (obj, JSON_COMPACT);
320  }
321  char *v = va_arg (args, char *);
322  if (NULL == v)
323  {
324  va_end (args);
325  return json_dumps (obj, JSON_COMPACT);
326  }
327 
328  while (NULL != k && NULL != v)
329  {
330  json_object_set (obj, k, json_string (v));
331  k = va_arg (args, char *);
332  if (NULL != k)
333  {
334  v = va_arg (args, char *);
335  }
336  }
337 
338  va_end (args);
339 
340  char *json = json_dumps (obj, JSON_COMPACT);
341  json_decref (obj);
342 
343  return json;
344 }
345 
346 
352 static void
353 search_error_cb (void *cls)
354 {
355  struct RequestData *rd = cls;
356  MHD_resume_connection (rd->c);
357  rd->searching = NULL;
358  rd->body = make_json ("error", "true",
359  "message", _ ("can not search the namestore"),
360  NULL);
361  rd->body_length = strlen (rd->body);
362  rd->code = MHD_HTTP_INTERNAL_SERVER_ERROR;
363  run_httpd_now ();
364 }
365 
366 
376 static void
377 search_done_cb (void *cls,
378  const struct GNUNET_IDENTITY_PrivateKey *zone,
379  const char *label,
380  unsigned int count,
381  const struct GNUNET_GNSRECORD_Data *d)
382 {
383  (void) zone;
384  (void) d;
385 
386  struct RequestData *rd = cls;
387  MHD_resume_connection (rd->c);
388 
389  rd->searching = NULL;
390  rd->body = make_json ("error", "false",
391  "free", (0 == count) ? "true" : "false",
392  NULL);
393  rd->body_length = strlen (rd->body);
394  rd->code = MHD_HTTP_OK;
395 
396  run_httpd_now ();
397 }
398 
399 
405 static void
406 register_error_cb (void *cls)
407 {
408  struct RequestData *rd = cls;
409 
410  MHD_resume_connection (rd->c);
411  rd->searching = NULL;
412  rd->body = make_json ("error", "true",
413  "message", _ ("unable to scan namestore"),
414  NULL);
415  rd->body_length = strlen (rd->body);
416  rd->code = MHD_HTTP_INTERNAL_SERVER_ERROR;
417  run_httpd_now ();
418 }
419 
420 
428 static void
429 register_done_cb (void *cls,
430  int32_t status,
431  const char *emsg)
432 {
433  struct RequestData *rd = cls;
434 
435  MHD_resume_connection (rd->c);
436  rd->searching = NULL;
437 
438  if ((GNUNET_SYSERR == status) || (GNUNET_NO == status))
439  {
441  _ ("Failed to create record for `%s': %s\n"),
442  rd->register_name,
443  emsg);
444  rd->body = make_json ("error", "true",
445  "message", emsg,
446  NULL);
447  rd->body_length = strlen (rd->body);
448  rd->code = MHD_HTTP_INTERNAL_SERVER_ERROR;
449  }
450  else
451  {
452  rd->body = make_json ("error", "false",
453  "message", _ ("no errors"),
454  NULL);
455  rd->body_length = strlen (rd->body);
456  rd->code = MHD_HTTP_OK;
457  }
458 
459  run_httpd_now ();
460 }
461 
462 
472 static void
473 register_do_cb (void *cls,
474  const struct GNUNET_IDENTITY_PrivateKey *key,
475  const char *label,
476  unsigned int count,
477  const struct GNUNET_GNSRECORD_Data *d)
478 {
479  (void) key;
480  (void) d;
481 
482  struct RequestData *rd = cls;
483 
484  rd->searching = NULL;
485 
486  if (0 != count)
487  {
489  _ ("The requested key `%s' exists as `%s'\n"),
490  rd->register_key,
491  label);
492 
493  MHD_resume_connection (rd->c);
494  rd->searching = NULL;
495  rd->body = make_json ("error", "true",
496  "message", _ ("key exists"),
497  NULL);
498  rd->body_length = strlen (rd->body);
499  rd->code = MHD_HTTP_FORBIDDEN;
500  run_httpd_now ();
501  return;
502  }
503 
504  struct GNUNET_GNSRECORD_Data gd;
505  char *gdraw = NULL;
506 
508  &gdraw,
509  &(gd.data_size),
510  &(gd.record_type)))
511  {
513  _ ("Error creating record data\n"));
514  MHD_resume_connection (rd->c);
515  rd->searching = NULL;
516  rd->body = make_json ("error", "true",
517  "message", _ ("unable to store record"),
518  NULL);
519  rd->body_length = strlen (rd->body);
520  rd->code = MHD_HTTP_INTERNAL_SERVER_ERROR;
521  run_httpd_now ();
522  return;
523  }
524 
525  gd.data = gdraw;
526  gd.expiration_time = UINT64_MAX;
528 
529  rd->searching = GNUNET_NAMESTORE_records_store (namestore,
530  zone_key,
531  rd->register_name,
532  1,
533  &gd,
535  rd);
536 
537  GNUNET_free (gdraw);
538 }
539 
540 
546 static void
547 iterate_error_cb (void *cls)
548 {
549  struct RequestData *rd = cls;
550 
551  MHD_resume_connection (rd->c);
552  rd->iterating = NULL;
553  rd->body = make_json ("error", "true",
554  "message", _ ("unable to scan namestore"),
555  NULL);
556  rd->body_length = strlen (rd->body);
557  rd->code = MHD_HTTP_INTERNAL_SERVER_ERROR;
558  run_httpd_now ();
559 }
560 
561 
571 static void
572 iterate_do_cb (void *cls,
573  const struct GNUNET_IDENTITY_PrivateKey *key,
574  const char *label,
575  unsigned int count,
576  const struct GNUNET_GNSRECORD_Data *d)
577 {
578  (void) key;
579  (void) label;
580  (void) d;
581 
582  struct RequestData *rd = cls;
583 
584  if (0 == strcmp (label, rd->register_name))
585  {
586  GNUNET_break (0 != count);
588  _ ("Requested name `%s' exists with `%u' records\n"),
589  rd->register_name,
590  count);
591 
592  MHD_resume_connection (rd->c);
593  rd->body = make_json ("error", "true",
594  "message", _ ("name exists\n"),
595  NULL);
596  rd->body_length = strlen (rd->body);
597  rd->code = MHD_HTTP_FORBIDDEN;
599  run_httpd_now ();
600  return;
601  }
602 
604 }
605 
606 
612 static void
613 iterate_done_cb (void *cls)
614 {
615  struct RequestData *rd = cls;
616 
617  rd->iterating = NULL;
618 
619  /* See if the key was not registered already */
620  rd->searching = GNUNET_NAMESTORE_zone_to_name (namestore,
621  zone_key,
622  &(rd->key),
624  rd,
626  rd);
627 }
628 
629 
639 static MHD_RESULT
640 serve_json (struct MHD_Connection *c,
641  char *body,
642  size_t length,
643  int code)
644 {
645  struct MHD_Response *response =
646  MHD_create_response_from_buffer (length,
647  body,
648  MHD_RESPMEM_PERSISTENT);
649  MHD_RESULT r = MHD_queue_response (c, code, response);
650  MHD_destroy_response (response);
651  return r;
652 }
653 
654 
668 static MHD_RESULT
669 create_response (void *cls,
670  struct MHD_Connection *connection,
671  const char *url,
672  const char *method,
673  const char *version,
674  const char *upload_data,
675  size_t *upload_data_size,
676  void **ptr)
677 {
678  (void) cls;
679  (void) version;
680 
681  struct RequestData *rd = *ptr;
682 
683  if (0 == strcmp (method, MHD_HTTP_METHOD_GET))
684  {
685  /* Handle a previously suspended request */
686  if (NULL != rd)
687  {
688  return serve_json (rd->c, rd->body, rd->body_length, rd->code);
689  }
690 
691  if (0 == strcmp ("/", url))
692  {
693  return MHD_queue_response (connection,
694  MHD_HTTP_OK,
695  main_page->response);
696  }
697 
698  if (0 == strcmp ("/search", url))
699  {
700  const char *name = MHD_lookup_connection_value (connection,
701  MHD_GET_ARGUMENT_KIND,
702  "name");
703  if (NULL == name)
704  {
705  return MHD_queue_response (connection,
706  MHD_HTTP_BAD_REQUEST,
707  forbidden_page->response);
708  }
709 
710  MHD_suspend_connection (connection);
711  rd = GNUNET_new (struct RequestData);
712  rd->c = connection;
714  zone_key,
715  name,
717  rd,
719  rd);
720  *ptr = rd;
721  return MHD_YES;
722  }
723 
724  return MHD_queue_response (connection,
725  MHD_HTTP_NOT_FOUND,
726  notfound_page->response);
727  }
728 
729  if (0 == strcmp (method, MHD_HTTP_METHOD_HEAD))
730  {
731  /* We take a shortcut here by always serving the main page: starting a
732  namestore lookup, allocating the necessary resources, waiting for the
733  lookup to complete and then discard everything just because it was a HEAD
734  and thus only the headers are significative, is an unnecessary waste of
735  resources. The handling of this method could be smarter, for example by
736  sending a proper content type header based on the endpoint, but this is
737  not a service in which HEAD requests are significant, so there's no need
738  to spend too much time here. */
739  return MHD_queue_response (connection,
740  MHD_HTTP_OK,
741  main_page->response);
742  }
743 
744  if (0 == strcmp (method, MHD_HTTP_METHOD_POST))
745  {
746  if (0 == strcmp ("/register", url))
747  {
748  /* Handle a previously suspended request */
749  if ((NULL != rd) && (NULL != rd->body))
750  {
751  return serve_json (rd->c, rd->body, rd->body_length, rd->code);
752  }
753 
754  if (NULL == rd)
755  {
756  rd = GNUNET_new (struct RequestData);
757  rd->c = connection;
758  rd->body = NULL;
759  rd->ptr = NULL;
760  *ptr = rd;
761  }
762 
763  json_t *json = NULL;
765  GNUNET_JSON_post_parser (32 * 1024,
766  connection,
767  &(rd->ptr),
768  upload_data,
769  upload_data_size,
770  &json);
771 
772  switch (result)
773  {
775  /* Keep processing POST data */
776  return MHD_YES;
779  rd->body = make_json ("error", "true",
780  "message", _ ("unable to process submitted data"),
781  NULL);
782  rd->body_length = strlen (rd->body);
783  rd->code = MHD_HTTP_PAYLOAD_TOO_LARGE;
784  return MHD_YES;
786  rd->body = make_json ("error", "true",
787  "message", _ ("the submitted data is invalid"),
788  NULL);
789  rd->body_length = strlen (rd->body);
790  rd->code = MHD_HTTP_BAD_REQUEST;
791  return MHD_YES;
792  default:
793  break;
794  }
795 
796  /* POST data has been read in its entirety */
797 
798  const char *name = json_string_value (json_object_get (json, "name"));
799  const char *key = json_string_value (json_object_get (json, "key"));
800  if ((NULL == name) || (NULL == key) || (0 == strlen (name)) || (0 ==
801  strlen (
802  key)))
803  {
804  json_decref (json);
805  rd->body = make_json ("error", "true",
806  "message", _ ("invalid parameters"),
807  NULL);
808  rd->body_length = strlen (rd->body);
809  rd->code = MHD_HTTP_BAD_REQUEST;
810  return MHD_YES;
811  }
812 
813  rd->register_name = strdup (name);
814  rd->register_key = strdup (key);
815 
816  json_decref (json);
818 
819  if ((NULL != strchr (rd->register_name, '.')) ||
820  (NULL != strchr (rd->register_name, '+')))
821  {
822  rd->body = make_json ("error", "true",
823  "message", _ ("invalid name"),
824  NULL);
825  rd->body_length = strlen (rd->body);
826  rd->code = MHD_HTTP_BAD_REQUEST;
827  return MHD_YES;
828  }
829 
831  &(rd->key)))
832  {
834  _ ("Unable to parse key %s\n"),
835  rd->register_key);
836 
837  rd->body = make_json ("error", "true",
838  "message", _ ("unable to parse key"),
839  NULL);
840  rd->body_length = strlen (rd->body);
841  rd->code = MHD_HTTP_INTERNAL_SERVER_ERROR;
842  return MHD_YES;
843  }
844 
845  MHD_suspend_connection (connection);
846  /* See if the requested name is free */
847  rd->iterating =
849  zone_key,
851  rd,
852  &iterate_do_cb,
853  rd,
855  rd);
856  return MHD_YES;
857  }
858 
859  return MHD_queue_response (connection,
860  MHD_HTTP_FORBIDDEN,
861  forbidden_page->response);
862  }
863 
864  return MHD_queue_response (connection,
865  MHD_HTTP_NOT_IMPLEMENTED,
866  forbidden_page->response);
867 }
868 
869 
878 static void
879 completed_cb (void *cls,
880  struct MHD_Connection *connection,
881  void **ptr,
882  enum MHD_RequestTerminationCode status)
883 {
884  (void) cls;
885  (void) connection;
886  (void) status;
887 
888  struct RequestData *rd = *ptr;
889 
890  if (NULL == rd)
891  {
892  return;
893  }
894 
895  if (NULL == rd->body)
896  {
897  GNUNET_free (rd->body);
898  }
899 
900  if (NULL != rd->searching)
901  {
903  }
904 
905  if (NULL != rd->register_name)
906  {
908  }
909 
910  if (NULL != rd->register_key)
911  {
913  }
914 
915  if (NULL != rd->iterating)
916  {
918  }
919 
920  GNUNET_free (rd);
921 }
922 
923 
932 static void
933 identity_cb (void *cls,
934  struct GNUNET_IDENTITY_Ego *ego,
935  void **ctx,
936  const char *name)
937 {
938  (void) cls;
939  (void) ctx;
940 
941  if ((NULL == name) || (0 != strcmp (name, zone)))
942  {
943  return;
944  }
945 
946  if (NULL == ego)
947  {
949  _ ("No ego configured for `fcfsd` subsystem\n"));
951  return;
952  }
953 
954  zone_key = GNUNET_IDENTITY_ego_get_private_key (ego);
955 
956  int flags = MHD_USE_DUAL_STACK | MHD_USE_DEBUG | MHD_ALLOW_SUSPEND_RESUME;
957  do
958  {
959  httpd = MHD_start_daemon (flags,
960  (uint16_t) port,
961  NULL, NULL,
962  &create_response, NULL,
963  MHD_OPTION_CONNECTION_LIMIT, 128,
964  MHD_OPTION_PER_IP_CONNECTION_LIMIT, 1,
965  MHD_OPTION_CONNECTION_TIMEOUT, 4 * 1024,
966  MHD_OPTION_NOTIFY_COMPLETED, &completed_cb, NULL,
967  MHD_OPTION_END);
968  flags = MHD_USE_DEBUG;
969  } while (NULL == httpd && flags != MHD_USE_DEBUG);
970 
971  if (NULL == httpd)
972  {
974  _ ("Failed to start HTTP server\n"));
976  return;
977  }
978 
979  run_httpd ();
980 }
981 
982 
990 static struct StaticPage *
991 open_static_page (const char *name, const char *basedir)
992 {
993  char *fullname = NULL;
994  GNUNET_asprintf (&fullname, "%s/fcfsd-%s", basedir, name);
995 
996  struct GNUNET_DISK_FileHandle *f =
997  GNUNET_DISK_file_open (fullname,
1000  GNUNET_free (fullname);
1001 
1002  if (NULL == f)
1003  {
1004  return NULL;
1005  }
1006 
1007  off_t size = 0;
1008  if (GNUNET_SYSERR == GNUNET_DISK_file_handle_size (f, &size))
1009  {
1011  return NULL;
1012  }
1013 
1014  struct MHD_Response *response =
1015  MHD_create_response_from_fd64 (size,
1016  f->fd);
1017 
1018  if (NULL == response)
1019  {
1021  return NULL;
1022  }
1023 
1024  struct StaticPage *page = GNUNET_new (struct StaticPage);
1025  page->handle = f;
1026  page->size = (uint64_t) size;
1027  page->response = response;
1028  return page;
1029 }
1030 
1031 
1040 static void
1041 run_service (void *cls,
1042  char *const *args,
1043  const char *cfgfile,
1044  const struct GNUNET_CONFIGURATION_Handle *cfg)
1045 {
1046  (void) cls;
1047  (void) args;
1048  (void) cfgfile;
1049 
1050  GNUNET_log_setup ("fcfsd", "WARNING", NULL);
1051 
1053  "fcfsd",
1054  "HTTPPORT",
1055  &port))
1056  {
1058  _ ("No port specified, using default value\n"));
1059  }
1060 
1062 
1063  namestore = GNUNET_NAMESTORE_connect (cfg);
1064  if (NULL == namestore)
1065  {
1067  _ ("Failed to connect to namestore\n"));
1069  return;
1070  }
1071 
1072  identity = GNUNET_IDENTITY_connect (cfg, &identity_cb, NULL);
1073  if (NULL == identity)
1074  {
1076  _ ("Failed to connect to identity\n"));
1078  return;
1079  }
1080 
1081  char *basedir = NULL;
1083  "fcfsd",
1084  "HTMLDIR",
1085  &basedir))
1086  {
1088  }
1089 
1090  main_page = open_static_page ("index.html", basedir);
1091  notfound_page = open_static_page ("notfound.html", basedir);
1092  forbidden_page = open_static_page ("forbidden.html", basedir);
1093 
1094  GNUNET_free (basedir);
1095 
1096  if ((NULL == main_page) || (NULL == notfound_page) || (NULL ==
1097  forbidden_page) )
1098  {
1100  _ ("Unable to set up the daemon\n"));
1102  return;
1103  }
1104 }
1105 
1106 
1114 int
1115 main (int argc, char *const *argv)
1116 {
1117  struct GNUNET_GETOPT_CommandLineOption options[] = {
1120  "zone",
1121  "EGO",
1122  gettext_noop (
1123  "name of the zone managed by FCFSD"),
1124  &zone)),
1126  };
1127 
1128  return ((GNUNET_OK == GNUNET_PROGRAM_run (argc,
1129  argv,
1130  "gnunet-namestore-fcfsd",
1131  _ (
1132  "GNU Name System First-Come-First-Served name registration service"),
1133  options,
1134  &run_service,
1135  NULL)) ?
1136  0 :
1137  1);
1138 }
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:610
Structure representing a static page.
enum GNUNET_GenericReturnValue GNUNET_DISK_file_handle_size(struct GNUNET_DISK_FileHandle *fh, off_t *size)
Get the size of an open file.
Definition: disk.c:193
Open the file for reading.
struct GNUNET_NAMESTORE_QueueEntry * searching
Task started to search for an entry in the namestore.
Run with high priority (important requests).
JSON parsing failed.
void * ptr
Pointer used while processing POST data.
enum GNUNET_GenericReturnValue GNUNET_PROGRAM_run(int argc, char *const *argv, const char *binaryName, const char *binaryHelp, const struct GNUNET_GETOPT_CommandLineOption *options, GNUNET_PROGRAM_Main task, void *task_cls)
Run a standard GNUnet command startup sequence (initialize loggers and configuration, parse options).
Definition: program.c:360
static void register_done_cb(void *cls, int32_t status, const char *emsg)
A name/key pair has been successfully registered, or maybe not.
struct GNUNET_NAMESTORE_ZoneIterator * iterating
Task started to iterate over the namestore.
static const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration we are using.
Definition: gnunet-abd.c:36
Structure containing some request-specific data.
static void iterate_do_cb(void *cls, const struct GNUNET_IDENTITY_PrivateKey *key, const char *label, unsigned int count, const struct GNUNET_GNSRECORD_Data *d)
A block was received from the namestore.
functions to parse JSON objects into GNUnet objects
static void do_httpd(void *cls)
Called when the HTTP server has some pending operations.
static void run_httpd_now(void)
int code
Response code.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_shutdown(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run on shutdown, that is when a CTRL-C signal is received, or when GNUNET_SCHEDULER_shutdown() is being invoked.
Definition: scheduler.c:1331
static struct StaticPage * main_page
The main page, a.k.a.
static struct GNUNET_SCHEDULER_Task * httpd_task
Task executing the HTTP daemon.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static void register_error_cb(void *cls)
An error occurred while registering a name.
enum GNUNET_GenericReturnValue GNUNET_DISK_file_close(struct GNUNET_DISK_FileHandle *h)
Close an open file.
Definition: disk.c:1305
Nobody is allowed to do anything to the file.
A private key for an identity as per LSD0001.
static void iterate_done_cb(void *cls)
All entries in the namestore have been iterated over.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_number(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, unsigned long long *number)
Get a configuration value that should be a number.
size_t data_size
Number of bytes in data.
struct GNUNET_NAMESTORE_QueueEntry * GNUNET_NAMESTORE_records_store(struct GNUNET_NAMESTORE_Handle *h, const struct GNUNET_IDENTITY_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.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
Definition of a command line option.
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...
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_filename(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be the name of a file or directory.
static struct GNUNET_IDENTITY_Handle * identity
Connection with the identity service.
static void run_service(void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg)
Called after the service is up.
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:531
static void do_shutdown(void *cls)
Task ran at shutdown to clean up everything.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
static void identity_cb(void *cls, struct GNUNET_IDENTITY_Ego *ego, void **ctx, const char *name)
Called for each ego provided by the identity service.
static struct GNUNET_NAMESTORE_Handle * namestore
Connection with the namestore service.
char * register_name
Name requested to be registered.
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_OPTION_END
Definition: 002.c:13
static struct GNUNET_DNSSTUB_Context * ctx
Context for DNS resolution.
void GNUNET_NETWORK_fdset_copy_native(struct GNUNET_NETWORK_FDSet *to, const fd_set *from, int nfds)
Copy a native fd set into the GNUnet representation.
Definition: network.c:1117
static char * make_json(const char *key, const char *value,...)
Generate a JSON object.
void GNUNET_NAMESTORE_cancel(struct GNUNET_NAMESTORE_QueueEntry *qe)
Cancel a namestore operation.
static void iterate_error_cb(void *cls)
An error occurred while iterating the namestore.
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_string(char shortName, const char *name, const char *argumentHelp, const char *description, char **str)
Allow user to specify a string.
#define _(String)
GNU gettext support macro.
Definition: platform.h:178
static char * zone
Name of the zone being managed.
#define max(x, y)
void GNUNET_NETWORK_fdset_destroy(struct GNUNET_NETWORK_FDSet *fds)
Releases the associated memory of an fd set.
Definition: network.c:1263
void GNUNET_NAMESTORE_disconnect(struct GNUNET_NAMESTORE_Handle *h)
Disconnect from the namestore service (and free associated resources).
static struct StaticPage * open_static_page(const char *name, const char *basedir)
Open a file on disk and generate a response object for it.
uint64_t size
Size in bytes of the file.
Handle for a zone iterator operation.
Handle for an ego.
Definition: identity.h:36
struct GNUNET_NETWORK_FDSet * GNUNET_NETWORK_fdset_create(void)
Creates an fd set.
Definition: network.c:1247
char * register_key
Key (encoded as a string) to be associated with the requested name.
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 const struct GNUNET_IDENTITY_PrivateKey * zone_key
Private key of the zone.
static char * value
Value of the record to add/remove.
Connection to the NAMESTORE service.
Handle for the service.
Definition: identity_api.c:95
uint64_t expiration_time
Expiration time for the DNS record.
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 * GNUNET_OS_installation_get_path(enum GNUNET_OS_InstallationPathKind dirkind)
Get the path to a specific GNUnet installation directory or, with GNUNET_OS_IPK_SELF_PREFIX, the current running apps installation directory.
size_t body_length
Length in bytes of the body.
collection of IO descriptors
static void search_error_cb(void *cls)
The namestore search task failed.
uint16_t status
See PRISM_STATUS_*-constants.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_select(enum GNUNET_SCHEDULER_Priority prio, struct GNUNET_TIME_Relative delay, const struct GNUNET_NETWORK_FDSet *rs, const struct GNUNET_NETWORK_FDSet *ws, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay or when any of the specified file descriptor set...
Definition: scheduler.c:1841
struct GNUNET_NAMESTORE_QueueEntry * GNUNET_NAMESTORE_zone_to_name(struct GNUNET_NAMESTORE_Handle *h, const struct GNUNET_IDENTITY_PrivateKey *zone, const struct GNUNET_IDENTITY_PublicKey *value_zone, GNUNET_SCHEDULER_TaskCallback error_cb, void *error_cb_cls, GNUNET_NAMESTORE_RecordMonitor proc, void *proc_cls)
Look for an existing PKEY delegation record for a given public key.
static int result
Global testing status.
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:311
Sorry, memory allocation (malloc()) failed.
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_mandatory(struct GNUNET_GETOPT_CommandLineOption opt)
Make the given option mandatory.
void GNUNET_IDENTITY_disconnect(struct GNUNET_IDENTITY_Handle *h)
Disconnect from identity service.
Definition: identity_api.c:921
char * body
Body of the response object.
struct GNUNET_NAMESTORE_ZoneIterator * GNUNET_NAMESTORE_zone_iteration_start(struct GNUNET_NAMESTORE_Handle *h, const struct GNUNET_IDENTITY_PrivateKey *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)...
void GNUNET_NAMESTORE_zone_iteration_stop(struct GNUNET_NAMESTORE_ZoneIterator *it)
Stops iteration and releases the namestore handle for further calls.
Request size exceeded buffer_max argument.
#define GNUNET_TIME_UNIT_MILLISECONDS
One millisecond.
static struct StaticPage * forbidden_page
Page indicating the requested resource could not be accessed, and other errors.
static void register_do_cb(void *cls, const struct GNUNET_IDENTITY_PrivateKey *key, const char *label, unsigned int count, const struct GNUNET_GNSRECORD_Data *d)
Attempt to register the requested name.
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
enum GNUNET_GenericReturnValue GNUNET_IDENTITY_public_key_from_string(const char *str, struct GNUNET_IDENTITY_PublicKey *key)
Parses a (Base32) string representation of the public key.
struct GNUNET_HashCode key
The key used in the DHT.
An QueueEntry used to store information for a pending NAMESTORE record operation. ...
Definition: namestore_api.c:53
struct GNUNET_IDENTITY_PublicKey key
Key to be associated with the requested name.
struct GNUNET_NAMESTORE_Handle * GNUNET_NAMESTORE_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the namestore service.
#define MHD_RESULT
Data type to use for functions return an "MHD result".
struct MHD_Connection * c
The connection this request was sent in.
struct GNUNET_NAMESTORE_QueueEntry * GNUNET_NAMESTORE_records_lookup(struct GNUNET_NAMESTORE_Handle *h, const struct GNUNET_IDENTITY_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.
GNUNET_JSON_PostResult
Return codes from GNUNET_JSON_post_parser().
An identity key as per LSD0001.
static void completed_cb(void *cls, struct MHD_Connection *connection, void **ptr, enum MHD_RequestTerminationCode status)
Called when a request is completed.
uint32_t record_type
Type of the GNS/DNS record.
enum GNUNET_JSON_PostResult GNUNET_JSON_post_parser(size_t buffer_max, struct MHD_Connection *connection, void **con_cls, const char *upload_data, size_t *upload_data_size, json_t **json)
Process a POST request containing a JSON object.
Definition: json_mhd.c:265
configuration data
static void run_httpd(void)
Schedule a task to run MHD.
const char * name
void GNUNET_JSON_post_parser_cleanup(void *con_cls)
Function called whenever we are done with a request to clean up our state.
Definition: json_mhd.c:367
const struct GNUNET_IDENTITY_PrivateKey * GNUNET_IDENTITY_ego_get_private_key(const struct GNUNET_IDENTITY_Ego *ego)
Obtain the ECC key associated with a ego.
Definition: identity_api.c:639
struct MHD_Response * response
Cached response object to send to clients.
Parsing continues, call again soon!
#define GNUNET_log(kind,...)
Entry in list of pending tasks.
Definition: scheduler.c:134
static MHD_RESULT create_response(void *cls, struct MHD_Connection *connection, const char *url, const char *method, const char *version, const char *upload_data, size_t *upload_data_size, void **ptr)
Send a response back to a connected client.
static struct StaticPage * notfound_page
Page indicating the requested resource could not be found.
static struct MHD_Daemon * httpd
The HTTP daemon.
static MHD_RESULT serve_json(struct MHD_Connection *c, char *body, size_t length, int code)
Generate a response containing JSON and send it to the client.
static void search_done_cb(void *cls, const struct GNUNET_IDENTITY_PrivateKey *zone, const char *label, unsigned int count, const struct GNUNET_GNSRECORD_Data *d)
The lookup terminated with some results.
int fd
File handle on Unix-like systems.
enum GNUNET_GNSRECORD_Flags flags
Flags for the record.
int GNUNET_log_setup(const char *comp, const char *loglevel, const char *logfile)
Setup logging.
struct GNUNET_DISK_FileHandle * GNUNET_DISK_file_open(const char *fn, enum GNUNET_DISK_OpenFlags flags, enum GNUNET_DISK_AccessPermissions perm)
Open a file.
Definition: disk.c:1234
struct GNUNET_DISK_FileHandle * handle
Handle to file on disk.
Handle used to access files (and pipes).
static unsigned long long port
The port the daemon is listening to for HTTP requests.
Return the directory where data is installed (share/gnunet/)
#define GNUNET_free(ptr)
Wrapper around free.
Time for relative time used by GNUnet, in microseconds.
#define gettext_noop(String)
Definition: gettext.h:69
enum GNUNET_GenericReturnValue GNUNET_GNSRECORD_data_from_identity(const struct GNUNET_IDENTITY_PublicKey *key, char **data, size_t *data_size, uint32_t *type)
Create record data and size from an identity key.
int main(int argc, char *const *argv)
The main function of the fcfs daemon.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:972