diff options
author | Sree Harsha Totakura <totakura@in.tum.de> | 2013-05-07 14:35:46 +0000 |
---|---|---|
committer | Sree Harsha Totakura <totakura@in.tum.de> | 2013-05-07 14:35:46 +0000 |
commit | 05aa8d8001e3977adb5d68d851db608c075dffee (patch) | |
tree | 2c4e23e307a917d67fb41719f2b858bccea590aa /src/testbed/gnunet-service-testbed_peers.c | |
parent | 3029a328070bd5eb422261fb3559b01f415ae51c (diff) | |
download | gnunet-05aa8d8001e3977adb5d68d851db608c075dffee.tar.gz gnunet-05aa8d8001e3977adb5d68d851db608c075dffee.zip |
fix #2665: peer reconfiguration now implemented
Diffstat (limited to 'src/testbed/gnunet-service-testbed_peers.c')
-rw-r--r-- | src/testbed/gnunet-service-testbed_peers.c | 340 |
1 files changed, 295 insertions, 45 deletions
diff --git a/src/testbed/gnunet-service-testbed_peers.c b/src/testbed/gnunet-service-testbed_peers.c index 3de4af03a..34c1bf085 100644 --- a/src/testbed/gnunet-service-testbed_peers.c +++ b/src/testbed/gnunet-service-testbed_peers.c | |||
@@ -85,6 +85,61 @@ struct ManageServiceContext | |||
85 | 85 | ||
86 | 86 | ||
87 | /** | 87 | /** |
88 | * Context information for peer re-configure operations | ||
89 | */ | ||
90 | struct PeerReconfigureContext | ||
91 | { | ||
92 | /** | ||
93 | * DLL next for inclusoin in peer reconfigure operations list | ||
94 | */ | ||
95 | struct PeerReconfigureContext *next; | ||
96 | |||
97 | /** | ||
98 | * DLL prev | ||
99 | */ | ||
100 | struct PeerReconfigureContext *prev; | ||
101 | |||
102 | /** | ||
103 | * The client which gave this operation to us | ||
104 | */ | ||
105 | struct GNUNET_SERVER_Client *client; | ||
106 | |||
107 | /** | ||
108 | * The configuration handle to use as the new template | ||
109 | */ | ||
110 | struct GNUNET_CONFIGURATION_Handle *cfg; | ||
111 | |||
112 | /** | ||
113 | * The id of the operation | ||
114 | */ | ||
115 | uint64_t op_id; | ||
116 | |||
117 | /** | ||
118 | * The id of the peer which has to be reconfigured | ||
119 | */ | ||
120 | uint32_t peer_id; | ||
121 | |||
122 | /** | ||
123 | * The the peer stopped? Used while cleaning up this context to decide | ||
124 | * whether the asynchronous stop request through Testing/ARM API has to be | ||
125 | * cancelled | ||
126 | */ | ||
127 | uint8_t stopped; | ||
128 | }; | ||
129 | |||
130 | /** | ||
131 | * The DLL head for the peer reconfigure list | ||
132 | */ | ||
133 | static struct PeerReconfigureContext *prc_head; | ||
134 | |||
135 | /** | ||
136 | * The DLL tail for the peer reconfigure list | ||
137 | */ | ||
138 | static struct PeerReconfigureContext *prc_tail; | ||
139 | |||
140 | |||
141 | |||
142 | /** | ||
88 | * DLL head for queue of manage service requests | 143 | * DLL head for queue of manage service requests |
89 | */ | 144 | */ |
90 | static struct ManageServiceContext *mctx_head; | 145 | static struct ManageServiceContext *mctx_head; |
@@ -253,10 +308,7 @@ GST_handle_peer_create (void *cls, struct GNUNET_SERVER_Client *client, | |||
253 | struct ForwardedOperationContext *fo_ctxt; | 308 | struct ForwardedOperationContext *fo_ctxt; |
254 | struct Route *route; | 309 | struct Route *route; |
255 | struct Peer *peer; | 310 | struct Peer *peer; |
256 | char *config; | 311 | char *emsg; |
257 | size_t dest_size; | ||
258 | int ret; | ||
259 | uint32_t config_size; | ||
260 | uint32_t host_id; | 312 | uint32_t host_id; |
261 | uint32_t peer_id; | 313 | uint32_t peer_id; |
262 | uint16_t msize; | 314 | uint16_t msize; |
@@ -272,8 +324,17 @@ GST_handle_peer_create (void *cls, struct GNUNET_SERVER_Client *client, | |||
272 | msg = (const struct GNUNET_TESTBED_PeerCreateMessage *) message; | 324 | msg = (const struct GNUNET_TESTBED_PeerCreateMessage *) message; |
273 | host_id = ntohl (msg->host_id); | 325 | host_id = ntohl (msg->host_id); |
274 | peer_id = ntohl (msg->peer_id); | 326 | peer_id = ntohl (msg->peer_id); |
275 | if (UINT32_MAX == peer_id) | 327 | if (VALID_PEER_ID (peer_id)) |
276 | { | 328 | { |
329 | (void) GNUNET_asprintf (&emsg, "Peer with ID %u already exists", peer_id); | ||
330 | GST_send_operation_fail_msg (client, GNUNET_ntohll (msg->operation_id), | ||
331 | emsg); | ||
332 | GNUNET_free (emsg); | ||
333 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | ||
334 | return; | ||
335 | } | ||
336 | if (UINT32_MAX == peer_id) | ||
337 | { | ||
277 | GST_send_operation_fail_msg (client, GNUNET_ntohll (msg->operation_id), | 338 | GST_send_operation_fail_msg (client, GNUNET_ntohll (msg->operation_id), |
278 | "Cannot create peer with given ID"); | 339 | "Cannot create peer with given ID"); |
279 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 340 | GNUNET_SERVER_receive_done (client, GNUNET_OK); |
@@ -281,39 +342,14 @@ GST_handle_peer_create (void *cls, struct GNUNET_SERVER_Client *client, | |||
281 | } | 342 | } |
282 | if (host_id == GST_context->host_id) | 343 | if (host_id == GST_context->host_id) |
283 | { | 344 | { |
284 | char *emsg; | ||
285 | |||
286 | /* We are responsible for this peer */ | 345 | /* We are responsible for this peer */ |
287 | msize -= sizeof (struct GNUNET_TESTBED_PeerCreateMessage); | 346 | cfg = GNUNET_TESTBED_extract_config_ (message); |
288 | config_size = ntohl (msg->config_size); | 347 | if (NULL == cfg) |
289 | config = GNUNET_malloc (config_size); | ||
290 | dest_size = config_size; | ||
291 | if (Z_OK != | ||
292 | (ret = | ||
293 | uncompress ((Bytef *) config, (uLongf *) & dest_size, | ||
294 | (const Bytef *) &msg[1], (uLong) msize))) | ||
295 | { | ||
296 | GNUNET_break (0); /* uncompression error */ | ||
297 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | ||
298 | return; | ||
299 | } | ||
300 | if (config_size != dest_size) | ||
301 | { | ||
302 | GNUNET_break (0); /* Uncompressed config size mismatch */ | ||
303 | GNUNET_free (config); | ||
304 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | ||
305 | return; | ||
306 | } | ||
307 | cfg = GNUNET_CONFIGURATION_create (); | ||
308 | if (GNUNET_OK != | ||
309 | GNUNET_CONFIGURATION_deserialize (cfg, config, config_size, GNUNET_NO)) | ||
310 | { | 348 | { |
311 | GNUNET_break (0); /* Configuration parsing error */ | 349 | GNUNET_break (0); |
312 | GNUNET_free (config); | ||
313 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | 350 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); |
314 | return; | 351 | return; |
315 | } | 352 | } |
316 | GNUNET_free (config); | ||
317 | GNUNET_CONFIGURATION_set_value_number (cfg, "TESTBED", "PEERID", | 353 | GNUNET_CONFIGURATION_set_value_number (cfg, "TESTBED", "PEERID", |
318 | (unsigned long long) peer_id); | 354 | (unsigned long long) peer_id); |
319 | peer = GNUNET_malloc (sizeof (struct Peer)); | 355 | peer = GNUNET_malloc (sizeof (struct Peer)); |
@@ -359,7 +395,6 @@ GST_handle_peer_create (void *cls, struct GNUNET_SERVER_Client *client, | |||
359 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 395 | GNUNET_SERVER_receive_done (client, GNUNET_OK); |
360 | return; | 396 | return; |
361 | } | 397 | } |
362 | |||
363 | peer = GNUNET_malloc (sizeof (struct Peer)); | 398 | peer = GNUNET_malloc (sizeof (struct Peer)); |
364 | peer->is_remote = GNUNET_YES; | 399 | peer->is_remote = GNUNET_YES; |
365 | peer->id = peer_id; | 400 | peer->id = peer_id; |
@@ -369,7 +404,7 @@ GST_handle_peer_create (void *cls, struct GNUNET_SERVER_Client *client, | |||
369 | GNUNET_SERVER_client_keep (client); | 404 | GNUNET_SERVER_client_keep (client); |
370 | fo_ctxt->client = client; | 405 | fo_ctxt->client = client; |
371 | fo_ctxt->operation_id = GNUNET_ntohll (msg->operation_id); | 406 | fo_ctxt->operation_id = GNUNET_ntohll (msg->operation_id); |
372 | fo_ctxt->cls = peer; //GST_slave_list[route->dest]->controller; | 407 | fo_ctxt->cls = peer; |
373 | fo_ctxt->type = OP_PEER_CREATE; | 408 | fo_ctxt->type = OP_PEER_CREATE; |
374 | fo_ctxt->opc = | 409 | fo_ctxt->opc = |
375 | GNUNET_TESTBED_forward_operation_msg_ (GST_slave_list | 410 | GNUNET_TESTBED_forward_operation_msg_ (GST_slave_list |
@@ -405,7 +440,7 @@ GST_handle_peer_destroy (void *cls, struct GNUNET_SERVER_Client *client, | |||
405 | peer_id = ntohl (msg->peer_id); | 440 | peer_id = ntohl (msg->peer_id); |
406 | LOG_DEBUG ("Received peer destory on peer: %u and operation id: %ul\n", | 441 | LOG_DEBUG ("Received peer destory on peer: %u and operation id: %ul\n", |
407 | peer_id, GNUNET_ntohll (msg->operation_id)); | 442 | peer_id, GNUNET_ntohll (msg->operation_id)); |
408 | if ((GST_peer_list_size <= peer_id) || (NULL == GST_peer_list[peer_id])) | 443 | if (!VALID_PEER_ID (peer_id)) |
409 | { | 444 | { |
410 | LOG (GNUNET_ERROR_TYPE_ERROR, | 445 | LOG (GNUNET_ERROR_TYPE_ERROR, |
411 | "Asked to destroy a non existent peer with id: %u\n", peer_id); | 446 | "Asked to destroy a non existent peer with id: %u\n", peer_id); |
@@ -448,6 +483,40 @@ GST_handle_peer_destroy (void *cls, struct GNUNET_SERVER_Client *client, | |||
448 | 483 | ||
449 | 484 | ||
450 | /** | 485 | /** |
486 | * Stats a peer | ||
487 | * | ||
488 | * @param peer the peer to start | ||
489 | * @return GNUNET_OK upon success; GNUNET_SYSERR upon failure | ||
490 | */ | ||
491 | static int | ||
492 | start_peer (struct Peer *peer) | ||
493 | { | ||
494 | GNUNET_assert (GNUNET_NO == peer->is_remote); | ||
495 | if (GNUNET_OK != GNUNET_TESTING_peer_start (peer->details.local.peer)) | ||
496 | return GNUNET_SYSERR; | ||
497 | peer->details.local.is_running = GNUNET_YES; | ||
498 | return GNUNET_OK; | ||
499 | } | ||
500 | |||
501 | |||
502 | /** | ||
503 | * Stops a peer | ||
504 | * | ||
505 | * @param peer the peer to stop | ||
506 | * @return GNUNET_OK upon success; GNUNET_SYSERR upon failure | ||
507 | */ | ||
508 | static int | ||
509 | stop_peer (struct Peer *peer) | ||
510 | { | ||
511 | GNUNET_assert (GNUNET_NO == peer->is_remote); | ||
512 | if (GNUNET_OK != GNUNET_TESTING_peer_kill (peer->details.local.peer)) | ||
513 | return GNUNET_SYSERR; | ||
514 | peer->details.local.is_running = GNUNET_NO; | ||
515 | return GNUNET_OK; | ||
516 | } | ||
517 | |||
518 | |||
519 | /** | ||
451 | * Message handler for GNUNET_MESSAGE_TYPE_TESTBED_DESTROYPEER messages | 520 | * Message handler for GNUNET_MESSAGE_TYPE_TESTBED_DESTROYPEER messages |
452 | * | 521 | * |
453 | * @param cls NULL | 522 | * @param cls NULL |
@@ -466,7 +535,7 @@ GST_handle_peer_start (void *cls, struct GNUNET_SERVER_Client *client, | |||
466 | 535 | ||
467 | msg = (const struct GNUNET_TESTBED_PeerStartMessage *) message; | 536 | msg = (const struct GNUNET_TESTBED_PeerStartMessage *) message; |
468 | peer_id = ntohl (msg->peer_id); | 537 | peer_id = ntohl (msg->peer_id); |
469 | if ((peer_id >= GST_peer_list_size) || (NULL == GST_peer_list[peer_id])) | 538 | if (!VALID_PEER_ID (peer_id)) |
470 | { | 539 | { |
471 | GNUNET_break (0); | 540 | GNUNET_break (0); |
472 | LOG (GNUNET_ERROR_TYPE_ERROR, | 541 | LOG (GNUNET_ERROR_TYPE_ERROR, |
@@ -495,14 +564,13 @@ GST_handle_peer_start (void *cls, struct GNUNET_SERVER_Client *client, | |||
495 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 564 | GNUNET_SERVER_receive_done (client, GNUNET_OK); |
496 | return; | 565 | return; |
497 | } | 566 | } |
498 | if (GNUNET_OK != GNUNET_TESTING_peer_start (peer->details.local.peer)) | 567 | if (GNUNET_OK != start_peer (peer)) |
499 | { | 568 | { |
500 | GST_send_operation_fail_msg (client, GNUNET_ntohll (msg->operation_id), | 569 | GST_send_operation_fail_msg (client, GNUNET_ntohll (msg->operation_id), |
501 | "Failed to start"); | 570 | "Failed to start"); |
502 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 571 | GNUNET_SERVER_receive_done (client, GNUNET_OK); |
503 | return; | 572 | return; |
504 | } | 573 | } |
505 | peer->details.local.is_running = GNUNET_YES; | ||
506 | reply = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_PeerEventMessage)); | 574 | reply = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_PeerEventMessage)); |
507 | reply->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_PEER_EVENT); | 575 | reply->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_PEER_EVENT); |
508 | reply->header.size = htons (sizeof (struct GNUNET_TESTBED_PeerEventMessage)); | 576 | reply->header.size = htons (sizeof (struct GNUNET_TESTBED_PeerEventMessage)); |
@@ -535,7 +603,7 @@ GST_handle_peer_stop (void *cls, struct GNUNET_SERVER_Client *client, | |||
535 | msg = (const struct GNUNET_TESTBED_PeerStopMessage *) message; | 603 | msg = (const struct GNUNET_TESTBED_PeerStopMessage *) message; |
536 | peer_id = ntohl (msg->peer_id); | 604 | peer_id = ntohl (msg->peer_id); |
537 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Received PEER_STOP for peer %u\n", peer_id); | 605 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Received PEER_STOP for peer %u\n", peer_id); |
538 | if ((peer_id >= GST_peer_list_size) || (NULL == GST_peer_list[peer_id])) | 606 | if (!VALID_PEER_ID (peer_id)) |
539 | { | 607 | { |
540 | GST_send_operation_fail_msg (client, GNUNET_ntohll (msg->operation_id), | 608 | GST_send_operation_fail_msg (client, GNUNET_ntohll (msg->operation_id), |
541 | "Peer not found"); | 609 | "Peer not found"); |
@@ -565,7 +633,7 @@ GST_handle_peer_stop (void *cls, struct GNUNET_SERVER_Client *client, | |||
565 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 633 | GNUNET_SERVER_receive_done (client, GNUNET_OK); |
566 | return; | 634 | return; |
567 | } | 635 | } |
568 | if (GNUNET_OK != GNUNET_TESTING_peer_kill (peer->details.local.peer)) | 636 | if (GNUNET_OK != stop_peer (peer)) |
569 | { | 637 | { |
570 | LOG (GNUNET_ERROR_TYPE_WARNING, "Stopping peer %u failed\n", peer_id); | 638 | LOG (GNUNET_ERROR_TYPE_WARNING, "Stopping peer %u failed\n", peer_id); |
571 | GST_send_operation_fail_msg (client, GNUNET_ntohll (msg->operation_id), | 639 | GST_send_operation_fail_msg (client, GNUNET_ntohll (msg->operation_id), |
@@ -574,7 +642,6 @@ GST_handle_peer_stop (void *cls, struct GNUNET_SERVER_Client *client, | |||
574 | return; | 642 | return; |
575 | } | 643 | } |
576 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Peer %u successfully stopped\n", peer_id); | 644 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Peer %u successfully stopped\n", peer_id); |
577 | peer->details.local.is_running = GNUNET_NO; | ||
578 | reply = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_PeerEventMessage)); | 645 | reply = GNUNET_malloc (sizeof (struct GNUNET_TESTBED_PeerEventMessage)); |
579 | reply->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_PEER_EVENT); | 646 | reply->header.type = htons (GNUNET_MESSAGE_TYPE_TESTBED_PEER_EVENT); |
580 | reply->header.size = htons (sizeof (struct GNUNET_TESTBED_PeerEventMessage)); | 647 | reply->header.size = htons (sizeof (struct GNUNET_TESTBED_PeerEventMessage)); |
@@ -601,6 +668,7 @@ GST_handle_peer_get_config (void *cls, struct GNUNET_SERVER_Client *client, | |||
601 | { | 668 | { |
602 | const struct GNUNET_TESTBED_PeerGetConfigurationMessage *msg; | 669 | const struct GNUNET_TESTBED_PeerGetConfigurationMessage *msg; |
603 | struct GNUNET_TESTBED_PeerConfigurationInformationMessage *reply; | 670 | struct GNUNET_TESTBED_PeerConfigurationInformationMessage *reply; |
671 | struct ForwardedOperationContext *fopc; | ||
604 | struct Peer *peer; | 672 | struct Peer *peer; |
605 | char *config; | 673 | char *config; |
606 | char *xconfig; | 674 | char *xconfig; |
@@ -611,7 +679,8 @@ GST_handle_peer_get_config (void *cls, struct GNUNET_SERVER_Client *client, | |||
611 | 679 | ||
612 | msg = (const struct GNUNET_TESTBED_PeerGetConfigurationMessage *) message; | 680 | msg = (const struct GNUNET_TESTBED_PeerGetConfigurationMessage *) message; |
613 | peer_id = ntohl (msg->peer_id); | 681 | peer_id = ntohl (msg->peer_id); |
614 | if ((peer_id >= GST_peer_list_size) || (NULL == GST_peer_list[peer_id])) | 682 | LOG_DEBUG ("Received GET_CONFIG for peer %u\n", peer_id); |
683 | if (!VALID_PEER_ID (peer_id)) | ||
615 | { | 684 | { |
616 | GST_send_operation_fail_msg (client, GNUNET_ntohll (msg->operation_id), | 685 | GST_send_operation_fail_msg (client, GNUNET_ntohll (msg->operation_id), |
617 | "Peer not found"); | 686 | "Peer not found"); |
@@ -621,8 +690,6 @@ GST_handle_peer_get_config (void *cls, struct GNUNET_SERVER_Client *client, | |||
621 | peer = GST_peer_list[peer_id]; | 690 | peer = GST_peer_list[peer_id]; |
622 | if (GNUNET_YES == peer->is_remote) | 691 | if (GNUNET_YES == peer->is_remote) |
623 | { | 692 | { |
624 | struct ForwardedOperationContext *fopc; | ||
625 | |||
626 | LOG_DEBUG ("Forwarding PEER_GET_CONFIG for peer: %u\n", peer_id); | 693 | LOG_DEBUG ("Forwarding PEER_GET_CONFIG for peer: %u\n", peer_id); |
627 | fopc = GNUNET_malloc (sizeof (struct ForwardedOperationContext)); | 694 | fopc = GNUNET_malloc (sizeof (struct ForwardedOperationContext)); |
628 | GNUNET_SERVER_client_keep (client); | 695 | GNUNET_SERVER_client_keep (client); |
@@ -666,6 +733,189 @@ GST_handle_peer_get_config (void *cls, struct GNUNET_SERVER_Client *client, | |||
666 | 733 | ||
667 | 734 | ||
668 | /** | 735 | /** |
736 | * Cleans up the given PeerReconfigureContext | ||
737 | * | ||
738 | * @param prc the PeerReconfigureContext | ||
739 | */ | ||
740 | static void | ||
741 | cleanup_prc (struct PeerReconfigureContext *prc) | ||
742 | { | ||
743 | struct Peer *peer; | ||
744 | |||
745 | if (VALID_PEER_ID (prc->peer_id)) | ||
746 | { | ||
747 | peer = GST_peer_list [prc->peer_id]; | ||
748 | if (1 != prc->stopped) | ||
749 | { | ||
750 | GNUNET_TESTING_peer_stop_async_cancel (peer->details.local.peer); | ||
751 | stop_peer (peer); /* Stop the peer synchronously */ | ||
752 | } | ||
753 | } | ||
754 | if (NULL != prc->cfg) | ||
755 | GNUNET_CONFIGURATION_destroy (prc->cfg); | ||
756 | GNUNET_SERVER_client_drop (prc->client); | ||
757 | GNUNET_CONTAINER_DLL_remove (prc_head, prc_tail, prc); | ||
758 | GNUNET_free (prc); | ||
759 | } | ||
760 | |||
761 | |||
762 | /** | ||
763 | * Cleans up the Peer reconfigure context list | ||
764 | */ | ||
765 | void | ||
766 | GST_free_prcq () | ||
767 | { | ||
768 | while (NULL != prc_head) | ||
769 | cleanup_prc (prc_head); | ||
770 | } | ||
771 | |||
772 | |||
773 | /** | ||
774 | * Callback to inform whether the peer is running or stopped. | ||
775 | * | ||
776 | * @param cls the closure given to GNUNET_TESTING_peer_stop_async() | ||
777 | * @param peer the respective peer whose status is being reported | ||
778 | * @param success GNUNET_YES if the peer is stopped; GNUNET_SYSERR upon any | ||
779 | * error | ||
780 | */ | ||
781 | static void | ||
782 | prc_stop_cb (void *cls, struct GNUNET_TESTING_Peer *p, int success) | ||
783 | { | ||
784 | struct PeerReconfigureContext *prc = cls; | ||
785 | struct Peer *peer; | ||
786 | char *emsg; | ||
787 | |||
788 | GNUNET_assert (VALID_PEER_ID (prc->peer_id)); | ||
789 | peer = GST_peer_list [prc->peer_id]; | ||
790 | GNUNET_assert (GNUNET_NO == peer->is_remote); | ||
791 | GNUNET_TESTING_peer_destroy (peer->details.local.peer); | ||
792 | GNUNET_CONFIGURATION_destroy (peer->details.local.cfg); | ||
793 | peer->details.local.cfg = prc->cfg; | ||
794 | prc->cfg = NULL; | ||
795 | prc->stopped = 1; | ||
796 | emsg = NULL; | ||
797 | peer->details.local.peer | ||
798 | = GNUNET_TESTING_peer_configure (GST_context->system, | ||
799 | peer->details.local.cfg, peer->id, | ||
800 | NULL /* Peer id */ , | ||
801 | &emsg); | ||
802 | if (NULL == peer->details.local.peer) | ||
803 | { | ||
804 | GST_send_operation_fail_msg (prc->client, prc->op_id, emsg); | ||
805 | goto cleanup; | ||
806 | } | ||
807 | if (GNUNET_OK != start_peer (peer)) | ||
808 | { | ||
809 | |||
810 | GST_send_operation_fail_msg (prc->client, prc->op_id, | ||
811 | "Failed to start reconfigured peer"); | ||
812 | goto cleanup; | ||
813 | } | ||
814 | GST_send_operation_success_msg (prc->client, prc->op_id); | ||
815 | |||
816 | cleanup: | ||
817 | cleanup_prc (prc); | ||
818 | return; | ||
819 | } | ||
820 | |||
821 | |||
822 | /** | ||
823 | * Handler for GNUNET_MESSAGE_TYPDE_TESTBED_RECONFIGURE_PEER type messages. | ||
824 | * Should stop the peer asyncronously, destroy it and create it again with the | ||
825 | * new configuration. | ||
826 | * | ||
827 | * @param cls NULL | ||
828 | * @param client identification of the client | ||
829 | * @param message the actual message | ||
830 | */ | ||
831 | void | ||
832 | GST_handle_peer_reconfigure (void *cls, struct GNUNET_SERVER_Client *client, | ||
833 | const struct GNUNET_MessageHeader *message) | ||
834 | { | ||
835 | const struct GNUNET_TESTBED_PeerReconfigureMessage *msg; | ||
836 | struct Peer *peer; | ||
837 | struct GNUNET_CONFIGURATION_Handle *cfg; | ||
838 | struct ForwardedOperationContext *fopc; | ||
839 | struct PeerReconfigureContext *prc; | ||
840 | uint64_t op_id; | ||
841 | uint32_t peer_id; | ||
842 | uint16_t msize; | ||
843 | |||
844 | msize = ntohs (message->size); | ||
845 | if (msize <= sizeof (struct GNUNET_TESTBED_PeerReconfigureMessage)) | ||
846 | { | ||
847 | GNUNET_break_op (0); | ||
848 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | ||
849 | return; | ||
850 | } | ||
851 | msg = (const struct GNUNET_TESTBED_PeerReconfigureMessage *) message; | ||
852 | peer_id = ntohl (msg->peer_id); | ||
853 | op_id = GNUNET_ntohll (msg->operation_id); | ||
854 | if (!VALID_PEER_ID (peer_id)) | ||
855 | { | ||
856 | GNUNET_break (0); | ||
857 | GST_send_operation_fail_msg (client, op_id, "Peer not found"); | ||
858 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | ||
859 | return; | ||
860 | } | ||
861 | peer = GST_peer_list[peer_id]; | ||
862 | if (GNUNET_YES == peer->is_remote) | ||
863 | { | ||
864 | LOG_DEBUG ("Forwarding PEER_RECONFIGURE for peer: %u\n", peer_id); | ||
865 | fopc = GNUNET_malloc (sizeof (struct ForwardedOperationContext)); | ||
866 | GNUNET_SERVER_client_keep (client); | ||
867 | fopc->client = client; | ||
868 | fopc->operation_id = op_id; | ||
869 | fopc->type = OP_PEER_RECONFIGURE; | ||
870 | fopc->opc = | ||
871 | GNUNET_TESTBED_forward_operation_msg_ (peer->details.remote. | ||
872 | slave->controller, | ||
873 | fopc->operation_id, &msg->header, | ||
874 | &GST_forwarded_operation_reply_relay, | ||
875 | fopc); | ||
876 | fopc->timeout_task = | ||
877 | GNUNET_SCHEDULER_add_delayed (GST_timeout, &GST_forwarded_operation_timeout, | ||
878 | fopc); | ||
879 | GNUNET_CONTAINER_DLL_insert_tail (fopcq_head, fopcq_tail, fopc); | ||
880 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | ||
881 | return; | ||
882 | } | ||
883 | LOG_DEBUG ("Received PEER_RECONFIGURE for peer %u\n", peer_id); | ||
884 | if (0 < peer->reference_cnt) | ||
885 | { | ||
886 | GNUNET_break (0); | ||
887 | GST_send_operation_fail_msg (client, op_id, "Peer in use"); | ||
888 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | ||
889 | return; | ||
890 | } | ||
891 | if (GNUNET_YES == peer->destroy_flag) | ||
892 | { | ||
893 | GNUNET_break (0); | ||
894 | GST_send_operation_fail_msg (client, op_id, "Peer is being destroyed"); | ||
895 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | ||
896 | return; | ||
897 | } | ||
898 | cfg = GNUNET_TESTBED_extract_config_ (message); | ||
899 | if (NULL == cfg) | ||
900 | { | ||
901 | GNUNET_break (0); | ||
902 | GST_send_operation_fail_msg (client, op_id, "Compression error"); | ||
903 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | ||
904 | return; | ||
905 | } | ||
906 | prc = GNUNET_malloc (sizeof (struct PeerReconfigureContext)); | ||
907 | prc->cfg = cfg; | ||
908 | prc->peer_id = peer_id; | ||
909 | prc->op_id = op_id; | ||
910 | prc->client = client; | ||
911 | GNUNET_SERVER_client_keep (client); | ||
912 | GNUNET_CONTAINER_DLL_insert_tail (prc_head, prc_tail, prc); | ||
913 | GNUNET_TESTING_peer_stop_async (peer->details.local.peer, prc_stop_cb, prc); | ||
914 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | ||
915 | } | ||
916 | |||
917 | |||
918 | /** | ||
669 | * Cleanup the context information created for managing a peer's service | 919 | * Cleanup the context information created for managing a peer's service |
670 | * | 920 | * |
671 | * @param mctx the ManageServiceContext | 921 | * @param mctx the ManageServiceContext |