gnunet

Main GNUnet Logic
Log | Files | Refs | Submodules | README | LICENSE

commit ebfff277d665c418845f138aaf2b597ef29624ae
parent c332f5fe5ecbf213955580b0368de1e6c281c19b
Author: Matthias Wachs <wachs@net.in.tum.de>
Date:   Thu,  1 Aug 2013 09:55:19 +0000

message parsing on receive


Diffstat:
Msrc/experimentation/gnunet-daemon-experimentation.h | 74++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/experimentation/gnunet-daemon-experimentation_experiments.c | 57++++++++++++++++++++++++++++++++++++++++++++++++++++-----
Msrc/experimentation/gnunet-daemon-experimentation_nodes.c | 248+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------
3 files changed, 357 insertions(+), 22 deletions(-)

diff --git a/src/experimentation/gnunet-daemon-experimentation.h b/src/experimentation/gnunet-daemon-experimentation.h @@ -175,6 +175,8 @@ struct Experimentation_Issuer struct GNUNET_PeerIdentity issuer_id; }; +GNUNET_NETWORK_STRUCT_BEGIN + /** * Experimentation request message * Used to detect experimentation capability @@ -208,6 +210,63 @@ struct Experimentation_Response uint32_t issuer_count; }; + +/** + * Experiment start message + * + * struct is followed by string with length len_name + */ +struct GED_start_message +{ + struct GNUNET_MessageHeader header; + + /** + * String length of experiment name following the struct + */ + uint32_t len_name; + + /* Experiment issuer */ + struct GNUNET_PeerIdentity issuer; + + /* Experiment version as timestamp of creation */ + struct GNUNET_TIME_AbsoluteNBO version_nbo; +}; + +struct GED_start_ack_message +{ + struct GNUNET_MessageHeader header; + + /** + * String length of experiment name following the struct + */ + uint32_t len_name; + + /* Experiment issuer */ + struct GNUNET_PeerIdentity issuer; + + /* Experiment version as timestamp of creation */ + struct GNUNET_TIME_AbsoluteNBO version_nbo; +}; + +struct GED_stop_message +{ + struct GNUNET_MessageHeader header; + + /** + * String length of experiment name following the struct + */ + uint32_t len_name; + + /* Experiment issuer */ + struct GNUNET_PeerIdentity issuer; + + /* Experiment version as timestamp of creation */ + struct GNUNET_TIME_AbsoluteNBO version_nbo; +}; + +GNUNET_NETWORK_STRUCT_END + + int GED_nodes_rts (struct Node *n); @@ -273,8 +332,23 @@ int GED_experiments_issuer_accepted (struct GNUNET_PeerIdentity *issuer_ID); +/* + * Find an experiment based on issuer name and version + * + * @param issuer the issuer + * @param name experiment name + * @param version experiment version + * @return the experiment or NULL if not found + */ +struct Experiment * +GED_experiments_find (const struct GNUNET_PeerIdentity *issuer, + const char *name, + const struct GNUNET_TIME_Absolute version); + + typedef void (*GNUNET_EXPERIMENTATION_experiments_get_cb) (struct Node *n, struct Experiment *e); + void GED_experiments_get (struct Node *n, struct GNUNET_PeerIdentity *issuer, diff --git a/src/experimentation/gnunet-daemon-experimentation_experiments.c b/src/experimentation/gnunet-daemon-experimentation_experiments.c @@ -141,12 +141,62 @@ GED_experiments_issuer_accepted (struct GNUNET_PeerIdentity *issuer_ID) return GNUNET_NO; } +struct FindCtx +{ + const char *name; + struct GNUNET_TIME_Absolute version; + struct Experiment *res; +}; + +static int +find_it (void *cls, + const struct GNUNET_HashCode * key, + void *value) +{ + struct FindCtx *find_ctx = cls; + struct Experiment *e = (struct Experiment *) value; + + if (0 != strcmp(e->name, find_ctx->name)) + return GNUNET_OK; + if (e->version.abs_value != find_ctx->version.abs_value) + return GNUNET_OK; + + find_ctx->res = e; + return GNUNET_NO; +} + + +/* + * Find an experiment based on issuer name and version + * + * @param issuer the issuer + * @param name experiment name + * @param version experiment version + * @return the experiment or NULL if not found + */ +struct Experiment * +GED_experiments_find (const struct GNUNET_PeerIdentity *issuer, + const char *name, + const struct GNUNET_TIME_Absolute version) +{ + struct FindCtx find_ctx; + + find_ctx.name = name; + find_ctx.version = version; + find_ctx.res = NULL; + + GNUNET_CONTAINER_multihashmap_get_multiple (experiments, + &issuer->hashPubKey, &find_it, &find_ctx); + return find_ctx.res; +} + struct GetCtx { struct Node *n; GNUNET_EXPERIMENTATION_experiments_get_cb get_cb; }; + static int get_it (void *cls, const struct GNUNET_HashCode * key, @@ -160,13 +210,10 @@ get_it (void *cls, return GNUNET_OK; } - - - void GED_experiments_get (struct Node *n, - struct GNUNET_PeerIdentity *issuer, - GNUNET_EXPERIMENTATION_experiments_get_cb get_cb) + struct GNUNET_PeerIdentity *issuer, + GNUNET_EXPERIMENTATION_experiments_get_cb get_cb) { struct GetCtx get_ctx; diff --git a/src/experimentation/gnunet-daemon-experimentation_nodes.c b/src/experimentation/gnunet-daemon-experimentation_nodes.c @@ -32,6 +32,7 @@ #include "gnunet-daemon-experimentation.h" +#define FAST_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5) /** * Core handle */ @@ -320,6 +321,34 @@ get_experiments_cb (struct Node *n, struct Experiment *e) counter ++; } +struct Node * +get_node (const struct GNUNET_PeerIdentity *id) +{ + struct Node * res; + struct Node * tmp; + + res = NULL; + tmp = NULL; + tmp = GNUNET_CONTAINER_multihashmap_get (nodes_active, &id->hashPubKey); + if (res == NULL) + res = tmp; + + tmp = GNUNET_CONTAINER_multihashmap_get (nodes_inactive, &id->hashPubKey); + if (res == NULL) + res = tmp; + else + GNUNET_break (0); /* Multiple instances */ + + tmp = GNUNET_CONTAINER_multihashmap_get (nodes_requested, &id->hashPubKey); + if (res == NULL) + res = tmp; + else + GNUNET_break (0); /* Multiple instances */ + + return res; +} + + /** * Set a specific node as active * @@ -555,7 +584,68 @@ static void handle_response (const struct GNUNET_PeerIdentity *peer, static void handle_start (const struct GNUNET_PeerIdentity *peer, const struct GNUNET_MessageHeader *message) { - GED_scheduler_handle_start (NULL, NULL); + uint16_t size; + uint32_t name_len; + const struct GED_start_message *msg; + const char *name; + struct Node *n; + struct Experiment *e; + + if (NULL == peer) + { + GNUNET_break (0); + return; + } + if (NULL == message) + { + GNUNET_break (0); + return; + } + + size = ntohs (message->size); + if (size < sizeof (struct GED_start_message)) + { + GNUNET_break (0); + return; + } + msg = (const struct GED_start_message *) message; + name_len = ntohl (msg->len_name); + if (size != sizeof (struct GED_start_message) + name_len) + { + GNUNET_break (0); + return; + } + + n = get_node (peer); + if (NULL == n) + { + GNUNET_break (0); + return; + } + name = (const char *) &msg[1]; + if (name[name_len-1] != '\0') + { + GNUNET_break (0); + return; + } + + if (name_len != strlen (name) + 1) + { + GNUNET_break (0); + return; + } + + e = GED_experiments_find (&msg->issuer, name, GNUNET_TIME_absolute_ntoh(msg->version_nbo)); + if (NULL == e) + { + GNUNET_break (0); + return; + } + + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Received %s message from peer %s for experiment `%s'\n"), + "START", GNUNET_i2s (peer), name); + + GED_scheduler_handle_start (n, e); } /** @@ -567,7 +657,67 @@ static void handle_start (const struct GNUNET_PeerIdentity *peer, static void handle_start_ack (const struct GNUNET_PeerIdentity *peer, const struct GNUNET_MessageHeader *message) { - GED_scheduler_handle_start_ack (NULL, NULL); + uint16_t size; + uint32_t name_len; + const struct GED_start_ack_message *msg; + const char *name; + struct Node *n; + struct Experiment *e; + + if (NULL == peer) + { + GNUNET_break (0); + return; + } + if (NULL == message) + { + GNUNET_break (0); + return; + } + + size = ntohs (message->size); + if (size < sizeof (struct GED_start_ack_message)) + { + GNUNET_break (0); + return; + } + msg = (const struct GED_start_ack_message *) message; + name_len = ntohl (msg->len_name); + if (size != sizeof (struct GED_start_message) + name_len) + { + GNUNET_break (0); + return; + } + + n = get_node (peer); + if (NULL == n) + { + GNUNET_break (0); + return; + } + name = (const char *) &msg[1]; + if (name[name_len-1] != '\0') + { + GNUNET_break (0); + return; + } + + if (name_len != strlen (name) + 1) + { + GNUNET_break (0); + return; + } + + e = GED_experiments_find (&msg->issuer, name, GNUNET_TIME_absolute_ntoh(msg->version_nbo)); + if (NULL == e) + { + GNUNET_break (0); + return; + } + + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Received %s message from peer %s for experiment `%s'\n"), + "START_ACK", GNUNET_i2s (peer), name); + GED_scheduler_handle_start_ack (n, e); } /** @@ -577,9 +727,69 @@ static void handle_start_ack (const struct GNUNET_PeerIdentity *peer, * @param message the message */ static void handle_stop (const struct GNUNET_PeerIdentity *peer, - const struct GNUNET_MessageHeader *message) + const struct GNUNET_MessageHeader *message) { - GED_scheduler_handle_stop (NULL, NULL); + uint16_t size; + uint32_t name_len; + const struct GED_stop_message *msg; + const char *name; + struct Node *n; + struct Experiment *e; + + if (NULL == peer) + { + GNUNET_break (0); + return; + } + if (NULL == message) + { + GNUNET_break (0); + return; + } + + size = ntohs (message->size); + if (size < sizeof (struct GED_stop_message)) + { + GNUNET_break (0); + return; + } + msg = (const struct GED_stop_message *) message; + name_len = ntohl (msg->len_name); + if (size != sizeof (struct GED_start_message) + name_len) + { + GNUNET_break (0); + return; + } + + n = get_node (peer); + if (NULL == n) + { + GNUNET_break (0); + return; + } + name = (const char *) &msg[1]; + if (name[name_len-1] != '\0') + { + GNUNET_break (0); + return; + } + + if (name_len != strlen (name) + 1) + { + GNUNET_break (0); + return; + } + + e = GED_experiments_find (&msg->issuer, name, GNUNET_TIME_absolute_ntoh(msg->version_nbo)); + if (NULL == e) + { + GNUNET_break (0); + return; + } + + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Received %s message from peer %s for experiment `%s'\n"), + "STOP", GNUNET_i2s (peer), name); + GED_scheduler_handle_stop (n, e); } /** @@ -671,13 +881,6 @@ core_receive_handler (void *cls, return GNUNET_OK; } -#define FAST_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5) - -struct GNUNET_EXPERIMENTATION_start_message -{ - struct GNUNET_MessageHeader header; -}; - struct ExperimentStartCtx { struct ExperimentStartCtx *prev; @@ -690,7 +893,9 @@ struct ExperimentStartCtx size_t node_experiment_start_cb (void *cls, size_t bufsize, void *buf) { struct ExperimentStartCtx *e_ctx = cls; - struct GNUNET_EXPERIMENTATION_start_message msg; + struct GED_start_message *msg; + size_t name_len; + size_t size; GNUNET_CONTAINER_DLL_remove (e_ctx->n->e_req_head, e_ctx->n->e_req_tail, e_ctx); e_ctx->n->cth = NULL; @@ -700,15 +905,24 @@ size_t node_experiment_start_cb (void *cls, size_t bufsize, void *buf) return 0; } - size_t size = sizeof (struct GNUNET_EXPERIMENTATION_start_message); - msg.header.size = htons (size); - msg.header.type = htons (GNUNET_MESSAGE_TYPE_EXPERIMENTATION_START); + name_len = strlen(e_ctx->e->name) + 1; + size = sizeof (struct GED_start_message) + name_len; - memcpy (buf, &msg, size); + msg = GNUNET_malloc (size); + msg->header.size = htons (size); + msg->header.type = htons (GNUNET_MESSAGE_TYPE_EXPERIMENTATION_START); + msg->issuer = e_ctx->e->issuer; + msg->version_nbo = GNUNET_TIME_absolute_hton(e_ctx->e->version); + msg->len_name = htonl (name_len); + memcpy (&msg[1], e_ctx->e->name, name_len); + + memcpy (buf, msg, size); + GNUNET_free (msg); GNUNET_free (e_ctx); return size; } + int GED_nodes_rts (struct Node *n) { @@ -742,7 +956,7 @@ GED_nodes_request_start (struct Node *n, struct Experiment *e) e_ctx->n = n; e_ctx->e = e; n->cth = GNUNET_CORE_notify_transmit_ready (ch, GNUNET_NO, 0, FAST_TIMEOUT, &n->id, - sizeof (struct GNUNET_EXPERIMENTATION_start_message), + sizeof (struct GED_start_message) + strlen (e->name) + 1, &node_experiment_start_cb, e_ctx); if (NULL == n->cth) {