28 #include <microhttpd.h>
68 struct MHD_Connection *
c;
124 static unsigned long long port = 18080;
144 static struct MHD_Daemon *
httpd = NULL;
220 MHD_stop_daemon (
httpd);
254 unsigned MHD_LONG_LONG
timeout = 0;
320 obj = json_object ();
321 if ((NULL ==
key) || (NULL ==
value))
324 return json_dumps (obj, JSON_COMPACT);
327 json_object_set (obj,
key, json_string (
value));
329 char *k = va_arg (
args,
char *);
333 return json_dumps (obj, JSON_COMPACT);
335 char *v = va_arg (
args,
char *);
339 return json_dumps (obj, JSON_COMPACT);
342 while (NULL != k && NULL != v)
344 json_object_set (obj, k, json_string (v));
345 k = va_arg (
args,
char *);
348 v = va_arg (
args,
char *);
354 char *json = json_dumps (obj, JSON_COMPACT);
370 MHD_resume_connection (
rd->c);
371 rd->searching = NULL;
373 "message",
_ (
"can not search the namestore"),
375 rd->body_length = strlen (
rd->body);
401 MHD_resume_connection (
rd->c);
403 rd->searching = NULL;
405 "free", (0 == count) ?
"true" :
"false",
407 rd->body_length = strlen (
rd->body);
424 MHD_resume_connection (
rd->c);
425 rd->searching = NULL;
427 "message",
_ (
"unable to scan namestore"),
429 rd->body_length = strlen (
rd->body);
441 MHD_resume_connection (
rd->c);
442 rd->searching = NULL;
447 _ (
"Failed to create record for `%s': %s\n"),
454 rd->body_length = strlen (
rd->body);
460 "message",
_ (
"no errors"),
462 rd->body_length = strlen (
rd->body);
491 rd->searching = NULL;
496 _ (
"The requested key `%s' exists as `%s'\n"),
500 MHD_resume_connection (
rd->c);
501 rd->searching = NULL;
503 "message",
_ (
"key exists"),
505 rd->body_length = strlen (
rd->body);
520 _ (
"Error creating record data\n"));
521 MHD_resume_connection (
rd->c);
522 rd->searching = NULL;
524 "message",
_ (
"unable to store record"),
526 rd->body_length = strlen (
rd->body);
558 MHD_resume_connection (
rd->c);
559 rd->iterating = NULL;
561 "message",
_ (
"unable to scan namestore"),
563 rd->body_length = strlen (
rd->body);
591 if (0 == strcmp (label,
rd->register_name))
595 _ (
"Requested name `%s' exists with `%u' records\n"),
599 MHD_resume_connection (
rd->c);
601 "message",
_ (
"name exists\n"),
603 rd->body_length = strlen (
rd->body);
624 rd->iterating = NULL;
653 MHD_create_response_from_buffer (length,
655 MHD_RESPMEM_PERSISTENT);
677 struct MHD_Connection *connection,
681 const char *upload_data,
682 size_t *upload_data_size,
690 if (0 == strcmp (method, MHD_HTTP_METHOD_GET))
698 if (0 == strcmp (
"/", url))
700 return MHD_queue_response (connection,
705 if (0 == strcmp (
"/search", url))
707 const char *
name = MHD_lookup_connection_value (connection,
708 MHD_GET_ARGUMENT_KIND,
712 return MHD_queue_response (connection,
717 MHD_suspend_connection (connection);
731 return MHD_queue_response (connection,
736 if (0 == strcmp (method, MHD_HTTP_METHOD_HEAD))
746 return MHD_queue_response (connection,
751 if (0 == strcmp (method, MHD_HTTP_METHOD_POST))
753 if (0 == strcmp (
"/register", url))
756 if ((NULL !=
rd) && (NULL !=
rd->body))
787 "message",
_ (
"unable to process submitted data"),
789 rd->body_length = strlen (
rd->body);
790 #ifdef MHD_HTTP_CONTENT_TOO_LARGE
791 rd->code = MHD_HTTP_CONTENT_TOO_LARGE;
798 "message",
_ (
"the submitted data is invalid"),
800 rd->body_length = strlen (
rd->body);
809 const char *
name = json_string_value (json_object_get (json,
"name"));
810 const char *
key = json_string_value (json_object_get (json,
"key"));
811 if ((NULL ==
name) || (NULL ==
key) || (0 == strlen (
name)) || (0 ==
817 "message",
_ (
"invalid parameters"),
819 rd->body_length = strlen (
rd->body);
824 rd->register_name = strdup (
name);
825 rd->register_key = strdup (
key);
830 if ((NULL != strchr (
rd->register_name,
'.')) ||
831 (NULL != strchr (
rd->register_name,
'+')))
834 "message",
_ (
"invalid name"),
836 rd->body_length = strlen (
rd->body);
845 _ (
"Unable to parse key %s\n"),
849 "message",
_ (
"unable to parse key"),
851 rd->body_length = strlen (
rd->body);
856 MHD_suspend_connection (connection);
870 return MHD_queue_response (connection,
875 return MHD_queue_response (connection,
891 struct MHD_Connection *connection,
893 enum MHD_RequestTerminationCode
status)
906 if (NULL ==
rd->body)
911 if (NULL !=
rd->searching)
916 if (NULL !=
rd->register_name)
921 if (NULL !=
rd->register_key)
926 if (NULL !=
rd->iterating)
960 _ (
"No ego configured for `fcfsd` subsystem\n"));
967 int flags = MHD_USE_DUAL_STACK | MHD_USE_DEBUG | MHD_ALLOW_SUSPEND_RESUME;
970 httpd = MHD_start_daemon (flags,
974 MHD_OPTION_CONNECTION_LIMIT, 128,
975 MHD_OPTION_PER_IP_CONNECTION_LIMIT, 1,
976 MHD_OPTION_CONNECTION_TIMEOUT, 4 * 1024,
979 flags = MHD_USE_DEBUG;
980 }
while (NULL ==
httpd && flags != MHD_USE_DEBUG);
985 _ (
"Failed to start HTTP server\n"));
1004 char *fullname = NULL;
1026 MHD_create_response_from_fd64 (
size,
1054 const char *cfgfile,
1065 "RELATIVE_RECORD_EXPIRATION",
1069 _(
"No expiration specified for records.\n"));
1080 _ (
"No port specified, using default value\n"));
1089 _ (
"Failed to connect to namestore\n"));
1098 _ (
"Failed to connect to identity\n"));
1103 char *basedir = NULL;
1122 _ (
"Unable to set up the daemon\n"));
1145 "name of the zone managed by FCFSD"),
1152 "gnunet-namestore-fcfsd",
1154 "GNU Name System First-Come-First-Served name registration service"),
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_OPTION_END
struct GNUNET_GETOPT_CommandLineOption options[]
const char * GNUNET_ErrorCode_get_hint(enum GNUNET_ErrorCode ec)
Returns a hint for a given error code.
GNUNET_ErrorCode
Taler error codes.
@ GNUNET_EC_NONE
No error (success).
#define gettext_noop(String)
static const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration we are using.
static struct GNUNET_TIME_Relative timeout
Desired timeout for the lookup (default is no timeout).
static struct MHD_Response * response
Our canonical response.
struct GNUNET_HashCode key
The key used in the DHT.
uint16_t status
See PRISM_STATUS_*-constants.
static void register_error_cb(void *cls)
An error occurred while registering a name.
static void run_httpd_now(void)
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 GNUNET_TIME_Relative record_exp
The relative expiration time for added records.
static char * zone
Name of the zone being managed.
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 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.
static struct StaticPage * open_static_page(const char *name, const char *basedir)
Open a file on disk and generate a response object for it.
static void completed_cb(void *cls, struct MHD_Connection *connection, void **ptr, enum MHD_RequestTerminationCode status)
Called when a request is completed.
static unsigned long long port
The port the daemon is listening to for HTTP requests.
static void do_shutdown(void *cls)
Task ran at shutdown to clean up everything.
static void iterate_error_cb(void *cls)
An error occurred while iterating the namestore.
static void run_httpd(void)
Schedule a task to run MHD.
static void do_httpd(void *cls)
Called when the HTTP server has some pending operations.
static void run_service(void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg)
Called after the service is up.
static struct GNUNET_NAMESTORE_Handle * namestore
Connection with the namestore service.
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.
static struct StaticPage * main_page
The main page, a.k.a.
static struct StaticPage * notfound_page
Page indicating the requested resource could not be found.
static struct GNUNET_SCHEDULER_Task * httpd_task
Task executing the HTTP daemon.
static struct StaticPage * forbidden_page
Page indicating the requested resource could not be accessed, and other errors.
static struct GNUNET_IDENTITY_Handle * identity
Connection with the identity service.
static void iterate_done_cb(void *cls)
All entries in the namestore have been iterated over.
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 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.
int main(int argc, char *const *argv)
The main function of the fcfs daemon.
static void register_done_cb(void *cls, enum GNUNET_ErrorCode ec)
static void search_error_cb(void *cls)
The namestore search task failed.
static char * make_json(const char *key, const char *value,...)
Generate a JSON object.
static const struct GNUNET_IDENTITY_PrivateKey * zone_key
Private key of the zone.
static struct GNUNET_GNSRECORD_Data rd[50]
The record data under a single label.
static char * value
Value of the record to add/remove.
static int result
Global testing status.
static struct GNUNET_DNSSTUB_Context * ctx
Context for DNS resolution.
API that can be used to manipulate GNS record data.
Identity service; implements identity management for GNUnet.
functions to parse JSON objects into GNUnet objects
GNUNET_JSON_PostResult
Return codes from GNUNET_JSON_post_parser().
@ GNUNET_JSON_PR_CONTINUE
Parsing continues, call again soon!
@ GNUNET_JSON_PR_OUT_OF_MEMORY
Sorry, memory allocation (malloc()) failed.
@ GNUNET_JSON_PR_JSON_INVALID
JSON parsing failed.
@ GNUNET_JSON_PR_REQUEST_TOO_LARGE
Request size exceeded buffer_max argument.
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.
void GNUNET_JSON_post_parser_cleanup(void *con_cls)
Function called whenever we are done with a request to clean up our state.
API that can be used to store naming information on a GNUnet node;.
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.
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.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_time(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, struct GNUNET_TIME_Relative *time)
Get a configuration value that should be a relative time.
struct GNUNET_DISK_FileHandle * GNUNET_DISK_file_open(const char *fn, enum GNUNET_DISK_OpenFlags flags, enum GNUNET_DISK_AccessPermissions perm)
Open a file.
enum GNUNET_GenericReturnValue GNUNET_DISK_file_close(struct GNUNET_DISK_FileHandle *h)
Close an open file.
enum GNUNET_GenericReturnValue GNUNET_DISK_file_handle_size(struct GNUNET_DISK_FileHandle *fh, off_t *size)
Get the size of an open file.
@ GNUNET_DISK_OPEN_READ
Open the file for reading.
@ GNUNET_DISK_PERM_NONE
Nobody is allowed to do anything to the file.
struct GNUNET_GETOPT_CommandLineOption GNUNET_GETOPT_option_mandatory(struct GNUNET_GETOPT_CommandLineOption opt)
Make the given option mandatory.
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.
@ GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION
This expiration time of the record is a relative time (not an absolute time).
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.
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.
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_IDENTITY_Handle * GNUNET_IDENTITY_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_IDENTITY_Callback cb, void *cb_cls)
Connect to the identity service.
void GNUNET_IDENTITY_disconnect(struct GNUNET_IDENTITY_Handle *h)
Disconnect from identity service.
#define GNUNET_log(kind,...)
@ GNUNET_SCHEDULER_PRIORITY_HIGH
Run with high priority (important requests).
int GNUNET_log_setup(const char *comp, const char *loglevel, const char *logfile)
Setup logging.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_ERROR
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_free(ptr)
Wrapper around free.
void GNUNET_NAMESTORE_disconnect(struct GNUNET_NAMESTORE_Handle *h)
Disconnect from the namestore service (and free associated resources).
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)
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.
void GNUNET_NAMESTORE_zone_iterator_next(struct GNUNET_NAMESTORE_ZoneIterator *it, uint64_t limit)
Calls the record processor specified in GNUNET_NAMESTORE_zone_iteration_start for the next record.
void GNUNET_NAMESTORE_cancel(struct GNUNET_NAMESTORE_QueueEntry *qe)
Cancel a namestore operation.
struct GNUNET_NAMESTORE_QueueEntry * GNUNET_NAMESTORE_records_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.
struct GNUNET_NAMESTORE_Handle * GNUNET_NAMESTORE_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the namestore service.
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.
void GNUNET_NAMESTORE_zone_iteration_stop(struct GNUNET_NAMESTORE_ZoneIterator *it)
Stops iteration and releases the namestore handle for further calls.
struct GNUNET_NETWORK_FDSet * GNUNET_NETWORK_fdset_create(void)
Creates an fd set.
void GNUNET_NETWORK_fdset_destroy(struct GNUNET_NETWORK_FDSet *fds)
Releases the associated memory of an fd set.
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.
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,...
@ GNUNET_OS_IPK_DATADIR
Return the directory where data is installed (share/gnunet/)
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,...
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_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...
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,...
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
#define GNUNET_TIME_UNIT_MILLISECONDS
One millisecond.
struct GNUNET_TIME_Relative GNUNET_TIME_relative_multiply(struct GNUNET_TIME_Relative rel, unsigned long long factor)
Multiply relative time by a given factor.
@ MHD_HTTP_BAD_REQUEST
Bad Request [RFC7231, Section 6.5.1].
@ MHD_HTTP_OK
OK [RFC7231, Section 6.3.1].
@ MHD_HTTP_NOT_FOUND
Not Found [RFC7231, Section 6.5.4].
@ MHD_HTTP_PAYLOAD_TOO_LARGE
Payload Too Large [RFC7231, Section 6.5.11].
@ MHD_HTTP_INTERNAL_SERVER_ERROR
Internal Server Error [RFC7231, Section 6.6.1].
@ MHD_HTTP_FORBIDDEN
Forbidden [RFC7231, Section 6.5.3].
@ MHD_HTTP_NOT_IMPLEMENTED
Not Implemented [RFC7231, Section 6.6.2].
static unsigned int size
Size of the "table".
Handle used to access files (and pipes).
Definition of a command line option.
uint32_t record_type
Type of the GNS/DNS record.
const void * data
Binary value stored in the DNS record.
size_t data_size
Number of bytes in data.
enum GNUNET_GNSRECORD_Flags flags
Flags for the record.
uint64_t expiration_time
Expiration time for the DNS record.
A private key for an identity as per LSD0001.
An identity key as per LSD0001.
Connection to the NAMESTORE service.
An QueueEntry used to store information for a pending NAMESTORE record operation.
Handle for a zone iterator operation.
collection of IO descriptors
Entry in list of pending tasks.
Time for relative time used by GNUnet, in microseconds.
uint64_t rel_value_us
The actual value.
Structure containing some request-specific data.
size_t body_length
Length in bytes of the body.
struct GNUNET_IDENTITY_PublicKey key
Key to be associated with the requested name.
struct MHD_Connection * c
The connection this request was sent in.
struct GNUNET_NAMESTORE_ZoneIterator * iterating
Task started to iterate over the namestore.
char * body
Body of the response object.
struct GNUNET_NAMESTORE_QueueEntry * searching
Task started to search for an entry in the namestore.
void * ptr
Pointer used while processing POST data.
char * register_key
Key (encoded as a string) to be associated with the requested name.
char * register_name
Name requested to be registered.
Structure representing a static page.
struct GNUNET_DISK_FileHandle * handle
Handle to file on disk.
struct MHD_Response * response
Cached response object to send to clients.
uint64_t size
Size in bytes of the file.