From df2725fc53449fb9cbc61e402d5124f5266743dc Mon Sep 17 00:00:00 2001 From: Matthias Wachs Date: Tue, 21 Feb 2012 12:39:02 +0000 Subject: [PATCH] - basics for the api --- src/namestore/namestore_api.c | 211 +++++++++++++++++++++++++++++++--- 1 file changed, 198 insertions(+), 13 deletions(-) diff --git a/src/namestore/namestore_api.c b/src/namestore/namestore_api.c index e0223589a..53235de6a 100644 --- a/src/namestore/namestore_api.c +++ b/src/namestore/namestore_api.c @@ -30,7 +30,7 @@ #include "gnunet_constants.h" #include "gnunet_arm_service.h" #include "gnunet_namestore_service.h" - +#include "namestore.h" #define DEBUG_GNS_API GNUNET_EXTRA_LOGGING #define LOG(kind,...) GNUNET_log_from (kind, "gns-api",__VA_ARGS__) @@ -43,6 +43,36 @@ struct GNUNET_NAMESTORE_QueueEntry char *data; /*stub data pointer*/ }; + +/** + * Message in linked list we should send to the service. The + * actual binary message follows this struct. + */ +struct PendingMessage +{ + + /** + * Kept in a DLL. + */ + struct PendingMessage *next; + + /** + * Kept in a DLL. + */ + struct PendingMessage *prev; + + /** + * Size of the message. + */ + size_t size; + + /** + * Is this the 'START' message? + */ + int is_init; +}; + + /** * Connection to the NAMESTORE service. */ @@ -64,10 +94,18 @@ struct GNUNET_NAMESTORE_Handle */ struct GNUNET_CLIENT_TransmitHandle *th; - /* dll to use for records */ - struct GNUNET_NAMESTORE_SimpleRecord * records_head; - struct GNUNET_NAMESTORE_SimpleRecord * records_tail; + /** + * Reconnect task + */ + GNUNET_SCHEDULER_TaskIdentifier reconnect_task; + + struct PendingMessage * pending_head; + struct PendingMessage * pending_tail; + /** + * Should we reconnect to service due to some serious error? + */ + int reconnect; }; struct GNUNET_NAMESTORE_SimpleRecord @@ -91,6 +129,151 @@ struct GNUNET_NAMESTORE_SimpleRecord const void *data; }; +/** + * Disconnect from service and then reconnect. + * + * @param nsh our handle + */ +static void +force_reconnect (struct GNUNET_NAMESTORE_Handle *nsh); + +/** + * Transmit messages from the message queue to the service + * (if there are any, and if we are not already trying). + * + * @param nsh handle to use + */ +static void +do_transmit (struct GNUNET_NAMESTORE_Handle *nsh); + +/** + * We can now transmit a message to NAMESTORE. Do it. + * + * @param cls the 'struct GNUNET_NAMESTORE_Handle' + * @param size number of bytes we can transmit + * @param buf where to copy the messages + * @return number of bytes copied into buf + */ +static size_t +transmit_message_to_namestore (void *cls, size_t size, void *buf) +{ + struct GNUNET_NAMESTORE_Handle *nsh = cls; + struct PendingMessage *p; + size_t ret; + char *cbuf; + + nsh->th = NULL; + if ((size == 0) || (buf == NULL)) + { + force_reconnect (nsh); + return 0; + } + ret = 0; + cbuf = buf; + while ((NULL != (p = nsh->pending_head)) && (p->size <= size)) + { + memcpy (&cbuf[ret], &p[1], p->size); + ret += p->size; + size -= p->size; + GNUNET_CONTAINER_DLL_remove (nsh->pending_head, nsh->pending_tail, p); + if (GNUNET_YES == p->is_init) + GNUNET_CLIENT_receive (nsh->client,/* &process_namestore_message*/ NULL, nsh, + GNUNET_TIME_UNIT_FOREVER_REL); + GNUNET_free (p); + } + do_transmit (nsh); + return ret; +} + + +/** + * Transmit messages from the message queue to the service + * (if there are any, and if we are not already trying). + * + * @param nsh handle to use + */ +static void +do_transmit (struct GNUNET_NAMESTORE_Handle *nsh) +{ + struct PendingMessage *p; + + if (NULL != nsh->th) + return; + if (NULL == (p = nsh->pending_head)) + return; + if (NULL == nsh->client) + return; /* currently reconnecting */ + nsh->th = GNUNET_CLIENT_notify_transmit_ready (nsh->client, p->size, + GNUNET_TIME_UNIT_FOREVER_REL, + GNUNET_NO, &transmit_message_to_namestore, + nsh); +} + + +/** + * Try again to connect to namestore service. + * + * @param cls the handle to the namestore service + * @param tc scheduler context + */ +static void +reconnect (struct GNUNET_NAMESTORE_Handle *nsh) +{ + struct PendingMessage *p; + struct StartMessage *init; + + GNUNET_assert (NULL == nsh->client); + nsh->client = GNUNET_CLIENT_connect ("namestore", nsh->cfg); + GNUNET_assert (NULL != nsh->client); + + if ((NULL == (p = nsh->pending_head)) || (GNUNET_YES != p->is_init)) + { + p = GNUNET_malloc (sizeof (struct PendingMessage) + + sizeof (struct StartMessage)); + p->size = sizeof (struct StartMessage); + p->is_init = GNUNET_YES; + init = (struct StartMessage *) &p[1]; + init->header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_START); + init->header.size = htons (sizeof (struct StartMessage)); + GNUNET_CONTAINER_DLL_insert (nsh->pending_head, nsh->pending_tail, p); + } + do_transmit (nsh); +} + +/** + * Re-establish the connection to the service. + * + * @param cls handle to use to re-connect. + * @param tc scheduler context + */ +static void +reconnect_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct GNUNET_NAMESTORE_Handle *nsh = cls; + + nsh->reconnect_task = GNUNET_SCHEDULER_NO_TASK; + reconnect (nsh); +} + + +/** + * Disconnect from service and then reconnect. + * + * @param nsh our handle + */ +static void +force_reconnect (struct GNUNET_NAMESTORE_Handle *nsh) +{ + nsh->reconnect = GNUNET_NO; + GNUNET_CLIENT_disconnect (nsh->client, GNUNET_NO); + nsh->client = NULL; + nsh->reconnect_task = + GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, &reconnect_task, + nsh); +} + + + /** * Initialize the connection with the NAMESTORE service. * @@ -100,11 +283,12 @@ struct GNUNET_NAMESTORE_SimpleRecord struct GNUNET_NAMESTORE_Handle * GNUNET_NAMESTORE_connect (const struct GNUNET_CONFIGURATION_Handle *cfg) { - struct GNUNET_NAMESTORE_Handle *handle; + struct GNUNET_NAMESTORE_Handle *nsh; - handle = GNUNET_malloc (sizeof (struct GNUNET_NAMESTORE_Handle)); - handle->cfg = cfg; - return handle; + nsh = GNUNET_malloc (sizeof (struct GNUNET_NAMESTORE_Handle)); + nsh->cfg = cfg; + nsh->reconnect_task = GNUNET_SCHEDULER_add_now (&reconnect, nsh); + return nsh; } @@ -260,7 +444,7 @@ GNUNET_NAMESTORE_record_put (struct GNUNET_NAMESTORE_Handle *h, { struct GNUNET_NAMESTORE_QueueEntry *qe; qe = GNUNET_malloc(sizeof (struct GNUNET_NAMESTORE_QueueEntry)); - +#if 0 struct GNUNET_NAMESTORE_SimpleRecord *sr; sr = GNUNET_malloc(sizeof(struct GNUNET_NAMESTORE_SimpleRecord)); sr->name = name; @@ -270,6 +454,7 @@ GNUNET_NAMESTORE_record_put (struct GNUNET_NAMESTORE_Handle *h, sr->data_size = data_size; sr->data = data; GNUNET_CONTAINER_DLL_insert(h->records_head, h->records_tail, sr); +#endif return qe; } @@ -301,7 +486,7 @@ GNUNET_NAMESTORE_record_remove (struct GNUNET_NAMESTORE_Handle *h, { struct GNUNET_NAMESTORE_QueueEntry *qe; qe = GNUNET_malloc(sizeof (struct GNUNET_NAMESTORE_QueueEntry)); - +#if 0 struct GNUNET_NAMESTORE_SimpleRecord *iter; for (iter=h->records_head; iter != NULL; iter=iter->next) { @@ -314,7 +499,7 @@ GNUNET_NAMESTORE_record_remove (struct GNUNET_NAMESTORE_Handle *h, GNUNET_CONTAINER_DLL_remove(h->records_head, h->records_tail, iter); - +#endif return qe; } @@ -341,7 +526,7 @@ GNUNET_NAMESTORE_lookup_name (struct GNUNET_NAMESTORE_Handle *h, { struct GNUNET_NAMESTORE_QueueEntry *qe; qe = GNUNET_malloc(sizeof (struct GNUNET_NAMESTORE_QueueEntry)); - +#if 0 struct GNUNET_NAMESTORE_SimpleRecord *iter; for (iter=h->records_head; iter != NULL; iter=iter->next) { @@ -354,7 +539,7 @@ GNUNET_NAMESTORE_lookup_name (struct GNUNET_NAMESTORE_Handle *h, } proc(proc_cls, zone, name, record_type, GNUNET_TIME_absolute_get_forever(), 0, NULL, 0, NULL); /*TERMINATE*/ - +#endif return qe; } -- 2.25.1