diff options
author | Matthias Wachs <wachs@net.in.tum.de> | 2013-08-01 09:55:19 +0000 |
---|---|---|
committer | Matthias Wachs <wachs@net.in.tum.de> | 2013-08-01 09:55:19 +0000 |
commit | ebfff277d665c418845f138aaf2b597ef29624ae (patch) | |
tree | 1fa7020c6ce07db88d6cfcba5ce24ba367740966 /src/experimentation | |
parent | c332f5fe5ecbf213955580b0368de1e6c281c19b (diff) | |
download | gnunet-ebfff277d665c418845f138aaf2b597ef29624ae.tar.gz gnunet-ebfff277d665c418845f138aaf2b597ef29624ae.zip |
message parsing on receive
Diffstat (limited to 'src/experimentation')
3 files changed, 357 insertions, 22 deletions
diff --git a/src/experimentation/gnunet-daemon-experimentation.h b/src/experimentation/gnunet-daemon-experimentation.h index 052005439..c6fc670f4 100644 --- a/src/experimentation/gnunet-daemon-experimentation.h +++ b/src/experimentation/gnunet-daemon-experimentation.h | |||
@@ -175,6 +175,8 @@ struct Experimentation_Issuer | |||
175 | struct GNUNET_PeerIdentity issuer_id; | 175 | struct GNUNET_PeerIdentity issuer_id; |
176 | }; | 176 | }; |
177 | 177 | ||
178 | GNUNET_NETWORK_STRUCT_BEGIN | ||
179 | |||
178 | /** | 180 | /** |
179 | * Experimentation request message | 181 | * Experimentation request message |
180 | * Used to detect experimentation capability | 182 | * Used to detect experimentation capability |
@@ -208,6 +210,63 @@ struct Experimentation_Response | |||
208 | uint32_t issuer_count; | 210 | uint32_t issuer_count; |
209 | }; | 211 | }; |
210 | 212 | ||
213 | |||
214 | /** | ||
215 | * Experiment start message | ||
216 | * | ||
217 | * struct is followed by string with length len_name | ||
218 | */ | ||
219 | struct GED_start_message | ||
220 | { | ||
221 | struct GNUNET_MessageHeader header; | ||
222 | |||
223 | /** | ||
224 | * String length of experiment name following the struct | ||
225 | */ | ||
226 | uint32_t len_name; | ||
227 | |||
228 | /* Experiment issuer */ | ||
229 | struct GNUNET_PeerIdentity issuer; | ||
230 | |||
231 | /* Experiment version as timestamp of creation */ | ||
232 | struct GNUNET_TIME_AbsoluteNBO version_nbo; | ||
233 | }; | ||
234 | |||
235 | struct GED_start_ack_message | ||
236 | { | ||
237 | struct GNUNET_MessageHeader header; | ||
238 | |||
239 | /** | ||
240 | * String length of experiment name following the struct | ||
241 | */ | ||
242 | uint32_t len_name; | ||
243 | |||
244 | /* Experiment issuer */ | ||
245 | struct GNUNET_PeerIdentity issuer; | ||
246 | |||
247 | /* Experiment version as timestamp of creation */ | ||
248 | struct GNUNET_TIME_AbsoluteNBO version_nbo; | ||
249 | }; | ||
250 | |||
251 | struct GED_stop_message | ||
252 | { | ||
253 | struct GNUNET_MessageHeader header; | ||
254 | |||
255 | /** | ||
256 | * String length of experiment name following the struct | ||
257 | */ | ||
258 | uint32_t len_name; | ||
259 | |||
260 | /* Experiment issuer */ | ||
261 | struct GNUNET_PeerIdentity issuer; | ||
262 | |||
263 | /* Experiment version as timestamp of creation */ | ||
264 | struct GNUNET_TIME_AbsoluteNBO version_nbo; | ||
265 | }; | ||
266 | |||
267 | GNUNET_NETWORK_STRUCT_END | ||
268 | |||
269 | |||
211 | int | 270 | int |
212 | GED_nodes_rts (struct Node *n); | 271 | GED_nodes_rts (struct Node *n); |
213 | 272 | ||
@@ -273,8 +332,23 @@ int | |||
273 | GED_experiments_issuer_accepted (struct GNUNET_PeerIdentity *issuer_ID); | 332 | GED_experiments_issuer_accepted (struct GNUNET_PeerIdentity *issuer_ID); |
274 | 333 | ||
275 | 334 | ||
335 | /* | ||
336 | * Find an experiment based on issuer name and version | ||
337 | * | ||
338 | * @param issuer the issuer | ||
339 | * @param name experiment name | ||
340 | * @param version experiment version | ||
341 | * @return the experiment or NULL if not found | ||
342 | */ | ||
343 | struct Experiment * | ||
344 | GED_experiments_find (const struct GNUNET_PeerIdentity *issuer, | ||
345 | const char *name, | ||
346 | const struct GNUNET_TIME_Absolute version); | ||
347 | |||
348 | |||
276 | typedef void (*GNUNET_EXPERIMENTATION_experiments_get_cb) (struct Node *n, struct Experiment *e); | 349 | typedef void (*GNUNET_EXPERIMENTATION_experiments_get_cb) (struct Node *n, struct Experiment *e); |
277 | 350 | ||
351 | |||
278 | void | 352 | void |
279 | GED_experiments_get (struct Node *n, | 353 | GED_experiments_get (struct Node *n, |
280 | struct GNUNET_PeerIdentity *issuer, | 354 | struct GNUNET_PeerIdentity *issuer, |
diff --git a/src/experimentation/gnunet-daemon-experimentation_experiments.c b/src/experimentation/gnunet-daemon-experimentation_experiments.c index 9e5cfd7e9..28becc42d 100644 --- 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) | |||
141 | return GNUNET_NO; | 141 | return GNUNET_NO; |
142 | } | 142 | } |
143 | 143 | ||
144 | struct FindCtx | ||
145 | { | ||
146 | const char *name; | ||
147 | struct GNUNET_TIME_Absolute version; | ||
148 | struct Experiment *res; | ||
149 | }; | ||
150 | |||
151 | static int | ||
152 | find_it (void *cls, | ||
153 | const struct GNUNET_HashCode * key, | ||
154 | void *value) | ||
155 | { | ||
156 | struct FindCtx *find_ctx = cls; | ||
157 | struct Experiment *e = (struct Experiment *) value; | ||
158 | |||
159 | if (0 != strcmp(e->name, find_ctx->name)) | ||
160 | return GNUNET_OK; | ||
161 | if (e->version.abs_value != find_ctx->version.abs_value) | ||
162 | return GNUNET_OK; | ||
163 | |||
164 | find_ctx->res = e; | ||
165 | return GNUNET_NO; | ||
166 | } | ||
167 | |||
168 | |||
169 | /* | ||
170 | * Find an experiment based on issuer name and version | ||
171 | * | ||
172 | * @param issuer the issuer | ||
173 | * @param name experiment name | ||
174 | * @param version experiment version | ||
175 | * @return the experiment or NULL if not found | ||
176 | */ | ||
177 | struct Experiment * | ||
178 | GED_experiments_find (const struct GNUNET_PeerIdentity *issuer, | ||
179 | const char *name, | ||
180 | const struct GNUNET_TIME_Absolute version) | ||
181 | { | ||
182 | struct FindCtx find_ctx; | ||
183 | |||
184 | find_ctx.name = name; | ||
185 | find_ctx.version = version; | ||
186 | find_ctx.res = NULL; | ||
187 | |||
188 | GNUNET_CONTAINER_multihashmap_get_multiple (experiments, | ||
189 | &issuer->hashPubKey, &find_it, &find_ctx); | ||
190 | return find_ctx.res; | ||
191 | } | ||
192 | |||
144 | struct GetCtx | 193 | struct GetCtx |
145 | { | 194 | { |
146 | struct Node *n; | 195 | struct Node *n; |
147 | GNUNET_EXPERIMENTATION_experiments_get_cb get_cb; | 196 | GNUNET_EXPERIMENTATION_experiments_get_cb get_cb; |
148 | }; | 197 | }; |
149 | 198 | ||
199 | |||
150 | static int | 200 | static int |
151 | get_it (void *cls, | 201 | get_it (void *cls, |
152 | const struct GNUNET_HashCode * key, | 202 | const struct GNUNET_HashCode * key, |
@@ -160,13 +210,10 @@ get_it (void *cls, | |||
160 | return GNUNET_OK; | 210 | return GNUNET_OK; |
161 | } | 211 | } |
162 | 212 | ||
163 | |||
164 | |||
165 | |||
166 | void | 213 | void |
167 | GED_experiments_get (struct Node *n, | 214 | GED_experiments_get (struct Node *n, |
168 | struct GNUNET_PeerIdentity *issuer, | 215 | struct GNUNET_PeerIdentity *issuer, |
169 | GNUNET_EXPERIMENTATION_experiments_get_cb get_cb) | 216 | GNUNET_EXPERIMENTATION_experiments_get_cb get_cb) |
170 | { | 217 | { |
171 | struct GetCtx get_ctx; | 218 | struct GetCtx get_ctx; |
172 | 219 | ||
diff --git a/src/experimentation/gnunet-daemon-experimentation_nodes.c b/src/experimentation/gnunet-daemon-experimentation_nodes.c index 667c9da57..58cc2e84f 100644 --- a/src/experimentation/gnunet-daemon-experimentation_nodes.c +++ b/src/experimentation/gnunet-daemon-experimentation_nodes.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include "gnunet-daemon-experimentation.h" | 32 | #include "gnunet-daemon-experimentation.h" |
33 | 33 | ||
34 | 34 | ||
35 | #define FAST_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5) | ||
35 | /** | 36 | /** |
36 | * Core handle | 37 | * Core handle |
37 | */ | 38 | */ |
@@ -320,6 +321,34 @@ get_experiments_cb (struct Node *n, struct Experiment *e) | |||
320 | counter ++; | 321 | counter ++; |
321 | } | 322 | } |
322 | 323 | ||
324 | struct Node * | ||
325 | get_node (const struct GNUNET_PeerIdentity *id) | ||
326 | { | ||
327 | struct Node * res; | ||
328 | struct Node * tmp; | ||
329 | |||
330 | res = NULL; | ||
331 | tmp = NULL; | ||
332 | tmp = GNUNET_CONTAINER_multihashmap_get (nodes_active, &id->hashPubKey); | ||
333 | if (res == NULL) | ||
334 | res = tmp; | ||
335 | |||
336 | tmp = GNUNET_CONTAINER_multihashmap_get (nodes_inactive, &id->hashPubKey); | ||
337 | if (res == NULL) | ||
338 | res = tmp; | ||
339 | else | ||
340 | GNUNET_break (0); /* Multiple instances */ | ||
341 | |||
342 | tmp = GNUNET_CONTAINER_multihashmap_get (nodes_requested, &id->hashPubKey); | ||
343 | if (res == NULL) | ||
344 | res = tmp; | ||
345 | else | ||
346 | GNUNET_break (0); /* Multiple instances */ | ||
347 | |||
348 | return res; | ||
349 | } | ||
350 | |||
351 | |||
323 | /** | 352 | /** |
324 | * Set a specific node as active | 353 | * Set a specific node as active |
325 | * | 354 | * |
@@ -555,7 +584,68 @@ static void handle_response (const struct GNUNET_PeerIdentity *peer, | |||
555 | static void handle_start (const struct GNUNET_PeerIdentity *peer, | 584 | static void handle_start (const struct GNUNET_PeerIdentity *peer, |
556 | const struct GNUNET_MessageHeader *message) | 585 | const struct GNUNET_MessageHeader *message) |
557 | { | 586 | { |
558 | GED_scheduler_handle_start (NULL, NULL); | 587 | uint16_t size; |
588 | uint32_t name_len; | ||
589 | const struct GED_start_message *msg; | ||
590 | const char *name; | ||
591 | struct Node *n; | ||
592 | struct Experiment *e; | ||
593 | |||
594 | if (NULL == peer) | ||
595 | { | ||
596 | GNUNET_break (0); | ||
597 | return; | ||
598 | } | ||
599 | if (NULL == message) | ||
600 | { | ||
601 | GNUNET_break (0); | ||
602 | return; | ||
603 | } | ||
604 | |||
605 | size = ntohs (message->size); | ||
606 | if (size < sizeof (struct GED_start_message)) | ||
607 | { | ||
608 | GNUNET_break (0); | ||
609 | return; | ||
610 | } | ||
611 | msg = (const struct GED_start_message *) message; | ||
612 | name_len = ntohl (msg->len_name); | ||
613 | if (size != sizeof (struct GED_start_message) + name_len) | ||
614 | { | ||
615 | GNUNET_break (0); | ||
616 | return; | ||
617 | } | ||
618 | |||
619 | n = get_node (peer); | ||
620 | if (NULL == n) | ||
621 | { | ||
622 | GNUNET_break (0); | ||
623 | return; | ||
624 | } | ||
625 | name = (const char *) &msg[1]; | ||
626 | if (name[name_len-1] != '\0') | ||
627 | { | ||
628 | GNUNET_break (0); | ||
629 | return; | ||
630 | } | ||
631 | |||
632 | if (name_len != strlen (name) + 1) | ||
633 | { | ||
634 | GNUNET_break (0); | ||
635 | return; | ||
636 | } | ||
637 | |||
638 | e = GED_experiments_find (&msg->issuer, name, GNUNET_TIME_absolute_ntoh(msg->version_nbo)); | ||
639 | if (NULL == e) | ||
640 | { | ||
641 | GNUNET_break (0); | ||
642 | return; | ||
643 | } | ||
644 | |||
645 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Received %s message from peer %s for experiment `%s'\n"), | ||
646 | "START", GNUNET_i2s (peer), name); | ||
647 | |||
648 | GED_scheduler_handle_start (n, e); | ||
559 | } | 649 | } |
560 | 650 | ||
561 | /** | 651 | /** |
@@ -567,7 +657,67 @@ static void handle_start (const struct GNUNET_PeerIdentity *peer, | |||
567 | static void handle_start_ack (const struct GNUNET_PeerIdentity *peer, | 657 | static void handle_start_ack (const struct GNUNET_PeerIdentity *peer, |
568 | const struct GNUNET_MessageHeader *message) | 658 | const struct GNUNET_MessageHeader *message) |
569 | { | 659 | { |
570 | GED_scheduler_handle_start_ack (NULL, NULL); | 660 | uint16_t size; |
661 | uint32_t name_len; | ||
662 | const struct GED_start_ack_message *msg; | ||
663 | const char *name; | ||
664 | struct Node *n; | ||
665 | struct Experiment *e; | ||
666 | |||
667 | if (NULL == peer) | ||
668 | { | ||
669 | GNUNET_break (0); | ||
670 | return; | ||
671 | } | ||
672 | if (NULL == message) | ||
673 | { | ||
674 | GNUNET_break (0); | ||
675 | return; | ||
676 | } | ||
677 | |||
678 | size = ntohs (message->size); | ||
679 | if (size < sizeof (struct GED_start_ack_message)) | ||
680 | { | ||
681 | GNUNET_break (0); | ||
682 | return; | ||
683 | } | ||
684 | msg = (const struct GED_start_ack_message *) message; | ||
685 | name_len = ntohl (msg->len_name); | ||
686 | if (size != sizeof (struct GED_start_message) + name_len) | ||
687 | { | ||
688 | GNUNET_break (0); | ||
689 | return; | ||
690 | } | ||
691 | |||
692 | n = get_node (peer); | ||
693 | if (NULL == n) | ||
694 | { | ||
695 | GNUNET_break (0); | ||
696 | return; | ||
697 | } | ||
698 | name = (const char *) &msg[1]; | ||
699 | if (name[name_len-1] != '\0') | ||
700 | { | ||
701 | GNUNET_break (0); | ||
702 | return; | ||
703 | } | ||
704 | |||
705 | if (name_len != strlen (name) + 1) | ||
706 | { | ||
707 | GNUNET_break (0); | ||
708 | return; | ||
709 | } | ||
710 | |||
711 | e = GED_experiments_find (&msg->issuer, name, GNUNET_TIME_absolute_ntoh(msg->version_nbo)); | ||
712 | if (NULL == e) | ||
713 | { | ||
714 | GNUNET_break (0); | ||
715 | return; | ||
716 | } | ||
717 | |||
718 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Received %s message from peer %s for experiment `%s'\n"), | ||
719 | "START_ACK", GNUNET_i2s (peer), name); | ||
720 | GED_scheduler_handle_start_ack (n, e); | ||
571 | } | 721 | } |
572 | 722 | ||
573 | /** | 723 | /** |
@@ -577,9 +727,69 @@ static void handle_start_ack (const struct GNUNET_PeerIdentity *peer, | |||
577 | * @param message the message | 727 | * @param message the message |
578 | */ | 728 | */ |
579 | static void handle_stop (const struct GNUNET_PeerIdentity *peer, | 729 | static void handle_stop (const struct GNUNET_PeerIdentity *peer, |
580 | const struct GNUNET_MessageHeader *message) | 730 | const struct GNUNET_MessageHeader *message) |
581 | { | 731 | { |
582 | GED_scheduler_handle_stop (NULL, NULL); | 732 | uint16_t size; |
733 | uint32_t name_len; | ||
734 | const struct GED_stop_message *msg; | ||
735 | const char *name; | ||
736 | struct Node *n; | ||
737 | struct Experiment *e; | ||
738 | |||
739 | if (NULL == peer) | ||
740 | { | ||
741 | GNUNET_break (0); | ||
742 | return; | ||
743 | } | ||
744 | if (NULL == message) | ||
745 | { | ||
746 | GNUNET_break (0); | ||
747 | return; | ||
748 | } | ||
749 | |||
750 | size = ntohs (message->size); | ||
751 | if (size < sizeof (struct GED_stop_message)) | ||
752 | { | ||
753 | GNUNET_break (0); | ||
754 | return; | ||
755 | } | ||
756 | msg = (const struct GED_stop_message *) message; | ||
757 | name_len = ntohl (msg->len_name); | ||
758 | if (size != sizeof (struct GED_start_message) + name_len) | ||
759 | { | ||
760 | GNUNET_break (0); | ||
761 | return; | ||
762 | } | ||
763 | |||
764 | n = get_node (peer); | ||
765 | if (NULL == n) | ||
766 | { | ||
767 | GNUNET_break (0); | ||
768 | return; | ||
769 | } | ||
770 | name = (const char *) &msg[1]; | ||
771 | if (name[name_len-1] != '\0') | ||
772 | { | ||
773 | GNUNET_break (0); | ||
774 | return; | ||
775 | } | ||
776 | |||
777 | if (name_len != strlen (name) + 1) | ||
778 | { | ||
779 | GNUNET_break (0); | ||
780 | return; | ||
781 | } | ||
782 | |||
783 | e = GED_experiments_find (&msg->issuer, name, GNUNET_TIME_absolute_ntoh(msg->version_nbo)); | ||
784 | if (NULL == e) | ||
785 | { | ||
786 | GNUNET_break (0); | ||
787 | return; | ||
788 | } | ||
789 | |||
790 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Received %s message from peer %s for experiment `%s'\n"), | ||
791 | "STOP", GNUNET_i2s (peer), name); | ||
792 | GED_scheduler_handle_stop (n, e); | ||
583 | } | 793 | } |
584 | 794 | ||
585 | /** | 795 | /** |
@@ -671,13 +881,6 @@ core_receive_handler (void *cls, | |||
671 | return GNUNET_OK; | 881 | return GNUNET_OK; |
672 | } | 882 | } |
673 | 883 | ||
674 | #define FAST_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5) | ||
675 | |||
676 | struct GNUNET_EXPERIMENTATION_start_message | ||
677 | { | ||
678 | struct GNUNET_MessageHeader header; | ||
679 | }; | ||
680 | |||
681 | struct ExperimentStartCtx | 884 | struct ExperimentStartCtx |
682 | { | 885 | { |
683 | struct ExperimentStartCtx *prev; | 886 | struct ExperimentStartCtx *prev; |
@@ -690,7 +893,9 @@ struct ExperimentStartCtx | |||
690 | size_t node_experiment_start_cb (void *cls, size_t bufsize, void *buf) | 893 | size_t node_experiment_start_cb (void *cls, size_t bufsize, void *buf) |
691 | { | 894 | { |
692 | struct ExperimentStartCtx *e_ctx = cls; | 895 | struct ExperimentStartCtx *e_ctx = cls; |
693 | struct GNUNET_EXPERIMENTATION_start_message msg; | 896 | struct GED_start_message *msg; |
897 | size_t name_len; | ||
898 | size_t size; | ||
694 | 899 | ||
695 | GNUNET_CONTAINER_DLL_remove (e_ctx->n->e_req_head, e_ctx->n->e_req_tail, e_ctx); | 900 | GNUNET_CONTAINER_DLL_remove (e_ctx->n->e_req_head, e_ctx->n->e_req_tail, e_ctx); |
696 | e_ctx->n->cth = NULL; | 901 | e_ctx->n->cth = NULL; |
@@ -700,15 +905,24 @@ size_t node_experiment_start_cb (void *cls, size_t bufsize, void *buf) | |||
700 | return 0; | 905 | return 0; |
701 | } | 906 | } |
702 | 907 | ||
703 | size_t size = sizeof (struct GNUNET_EXPERIMENTATION_start_message); | 908 | name_len = strlen(e_ctx->e->name) + 1; |
704 | msg.header.size = htons (size); | 909 | size = sizeof (struct GED_start_message) + name_len; |
705 | msg.header.type = htons (GNUNET_MESSAGE_TYPE_EXPERIMENTATION_START); | ||
706 | 910 | ||
707 | memcpy (buf, &msg, size); | 911 | msg = GNUNET_malloc (size); |
912 | msg->header.size = htons (size); | ||
913 | msg->header.type = htons (GNUNET_MESSAGE_TYPE_EXPERIMENTATION_START); | ||
914 | msg->issuer = e_ctx->e->issuer; | ||
915 | msg->version_nbo = GNUNET_TIME_absolute_hton(e_ctx->e->version); | ||
916 | msg->len_name = htonl (name_len); | ||
917 | memcpy (&msg[1], e_ctx->e->name, name_len); | ||
918 | |||
919 | memcpy (buf, msg, size); | ||
920 | GNUNET_free (msg); | ||
708 | GNUNET_free (e_ctx); | 921 | GNUNET_free (e_ctx); |
709 | return size; | 922 | return size; |
710 | } | 923 | } |
711 | 924 | ||
925 | |||
712 | int | 926 | int |
713 | GED_nodes_rts (struct Node *n) | 927 | GED_nodes_rts (struct Node *n) |
714 | { | 928 | { |
@@ -742,7 +956,7 @@ GED_nodes_request_start (struct Node *n, struct Experiment *e) | |||
742 | e_ctx->n = n; | 956 | e_ctx->n = n; |
743 | e_ctx->e = e; | 957 | e_ctx->e = e; |
744 | n->cth = GNUNET_CORE_notify_transmit_ready (ch, GNUNET_NO, 0, FAST_TIMEOUT, &n->id, | 958 | n->cth = GNUNET_CORE_notify_transmit_ready (ch, GNUNET_NO, 0, FAST_TIMEOUT, &n->id, |
745 | sizeof (struct GNUNET_EXPERIMENTATION_start_message), | 959 | sizeof (struct GED_start_message) + strlen (e->name) + 1, |
746 | &node_experiment_start_cb, e_ctx); | 960 | &node_experiment_start_cb, e_ctx); |
747 | if (NULL == n->cth) | 961 | if (NULL == n->cth) |
748 | { | 962 | { |