diff options
author | Christian Fuchs <christian.fuchs@cfuchs.net> | 2013-09-05 13:11:59 +0000 |
---|---|---|
committer | Christian Fuchs <christian.fuchs@cfuchs.net> | 2013-09-05 13:11:59 +0000 |
commit | 55401c568a7644b64032bff774e330fdadfaf35d (patch) | |
tree | 58aa115d12a2472c24ce3f25ee71214c496cdccb /src/scalarproduct | |
parent | 166d7ab3218c717c8b9e75b0530f360040d5f6ba (diff) | |
download | gnunet-55401c568a7644b64032bff774e330fdadfaf35d.tar.gz gnunet-55401c568a7644b64032bff774e330fdadfaf35d.zip |
fixed dangling tasks in SP-service
removed destroy tunnel function, as it is no longer needed with new-mesh
tasks now get queued in a DLL and are removed from it upon execution. do_shutdown de-queues all outstanding tasks
Diffstat (limited to 'src/scalarproduct')
-rw-r--r-- | src/scalarproduct/gnunet-service-scalarproduct.c | 202 |
1 files changed, 129 insertions, 73 deletions
diff --git a/src/scalarproduct/gnunet-service-scalarproduct.c b/src/scalarproduct/gnunet-service-scalarproduct.c index 20a51624b..e54e9bfdf 100644 --- a/src/scalarproduct/gnunet-service-scalarproduct.c +++ b/src/scalarproduct/gnunet-service-scalarproduct.c | |||
@@ -160,7 +160,6 @@ struct ServiceSession | |||
160 | * tunnel-handle associated with our mesh handle | 160 | * tunnel-handle associated with our mesh handle |
161 | */ | 161 | */ |
162 | struct GNUNET_MESH_Tunnel * tunnel; | 162 | struct GNUNET_MESH_Tunnel * tunnel; |
163 | |||
164 | }; | 163 | }; |
165 | 164 | ||
166 | /** | 165 | /** |
@@ -180,6 +179,32 @@ struct MessageObject | |||
180 | struct GNUNET_MessageHeader * msg; | 179 | struct GNUNET_MessageHeader * msg; |
181 | }; | 180 | }; |
182 | 181 | ||
182 | /** | ||
183 | * Linked list for all queued tasks. | ||
184 | */ | ||
185 | struct TaskClosure | ||
186 | { | ||
187 | |||
188 | /** | ||
189 | * point to the next element of the list | ||
190 | */ | ||
191 | struct TaskClosure *next; | ||
192 | |||
193 | /** | ||
194 | * point to the previous element of the list | ||
195 | */ | ||
196 | struct TaskClosure *prev; | ||
197 | |||
198 | /** | ||
199 | * the handle associated with this task, canceled upon shutdown | ||
200 | */ | ||
201 | GNUNET_SCHEDULER_TaskIdentifier my_handle; | ||
202 | |||
203 | /** | ||
204 | * the closure, as it's always a session-struct, we don't cast this to void | ||
205 | */ | ||
206 | struct ServiceSession * my_session; | ||
207 | }; | ||
183 | /////////////////////////////////////////////////////////////////////////////// | 208 | /////////////////////////////////////////////////////////////////////////////// |
184 | // Global Variables | 209 | // Global Variables |
185 | /////////////////////////////////////////////////////////////////////////////// | 210 | /////////////////////////////////////////////////////////////////////////////// |
@@ -267,6 +292,15 @@ static struct ServiceSession * from_service_tail; | |||
267 | */ | 292 | */ |
268 | static int do_shutdown; | 293 | static int do_shutdown; |
269 | 294 | ||
295 | /** | ||
296 | * DLL for all out active, queued tasks. Purged upon disconnect | ||
297 | */ | ||
298 | static struct TaskClosure * tasklist_head; | ||
299 | /** | ||
300 | * DLL for all out active, queued tasks. Purged upon disconnect | ||
301 | */ | ||
302 | static struct TaskClosure * tasklist_tail; | ||
303 | |||
270 | /////////////////////////////////////////////////////////////////////////////// | 304 | /////////////////////////////////////////////////////////////////////////////// |
271 | // Helper Functions | 305 | // Helper Functions |
272 | /////////////////////////////////////////////////////////////////////////////// | 306 | /////////////////////////////////////////////////////////////////////////////// |
@@ -646,22 +680,6 @@ find_matching_session (struct ServiceSession * tail, | |||
646 | 680 | ||
647 | 681 | ||
648 | static void | 682 | static void |
649 | destroy_tunnel (void *cls, | ||
650 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
651 | { | ||
652 | struct ServiceSession * session = cls; | ||
653 | |||
654 | if (session->tunnel) | ||
655 | { | ||
656 | GNUNET_MESH_tunnel_destroy (session->tunnel); | ||
657 | session->tunnel = NULL; | ||
658 | } | ||
659 | session->service_transmit_handle = NULL; | ||
660 | // we need to set this to NULL so there is no problem with double-cancel later on. | ||
661 | } | ||
662 | |||
663 | |||
664 | static void | ||
665 | free_session (struct ServiceSession * session) | 683 | free_session (struct ServiceSession * session) |
666 | { | 684 | { |
667 | unsigned int i; | 685 | unsigned int i; |
@@ -690,7 +708,6 @@ free_session (struct ServiceSession * session) | |||
690 | // Event and Message Handlers | 708 | // Event and Message Handlers |
691 | /////////////////////////////////////////////////////////////////////////////// | 709 | /////////////////////////////////////////////////////////////////////////////// |
692 | 710 | ||
693 | |||
694 | /** | 711 | /** |
695 | * A client disconnected. | 712 | * A client disconnected. |
696 | * | 713 | * |
@@ -711,24 +728,24 @@ handle_client_disconnect (void *cls, | |||
711 | 728 | ||
712 | // start from the tail, old stuff will be there... | 729 | // start from the tail, old stuff will be there... |
713 | for (elem = from_client_head; NULL != elem; elem = next) | 730 | for (elem = from_client_head; NULL != elem; elem = next) |
714 | { | 731 | { |
715 | next = elem->next; | 732 | next = elem->next; |
716 | if (elem->client != client) | 733 | if (elem->client != client) |
717 | continue; | 734 | continue; |
718 | 735 | ||
719 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _ ("Client (%p) disconnected from us.\n"), client); | 736 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _ ("Client (%p) disconnected from us.\n"), client); |
720 | GNUNET_CONTAINER_DLL_remove (from_client_head, from_client_tail, elem); | 737 | GNUNET_CONTAINER_DLL_remove (from_client_head, from_client_tail, elem); |
721 | 738 | ||
722 | if (!(elem->role == BOB && elem->state == FINALIZED)) | 739 | if (!(elem->role == BOB && elem->state == FINALIZED)) |
723 | { | 740 | { |
724 | //we MUST terminate any client message underway | 741 | //we MUST terminate any client message underway |
725 | if (elem->service_transmit_handle && elem->tunnel) | 742 | if (elem->service_transmit_handle && elem->tunnel) |
726 | GNUNET_MESH_notify_transmit_ready_cancel (elem->service_transmit_handle); | 743 | GNUNET_MESH_notify_transmit_ready_cancel (elem->service_transmit_handle); |
727 | if (elem->tunnel && elem->state == WAITING_FOR_RESPONSE_FROM_SERVICE) | 744 | if (elem->tunnel && elem->state == WAITING_FOR_RESPONSE_FROM_SERVICE) |
728 | destroy_tunnel (elem, NULL); | 745 | GNUNET_MESH_tunnel_destroy (elem->tunnel); |
729 | } | ||
730 | free_session (elem); | ||
731 | } | 746 | } |
747 | free_session (elem); | ||
748 | } | ||
732 | } | 749 | } |
733 | 750 | ||
734 | 751 | ||
@@ -746,9 +763,13 @@ static void | |||
746 | prepare_client_end_notification (void * cls, | 763 | prepare_client_end_notification (void * cls, |
747 | const struct GNUNET_SCHEDULER_TaskContext * tc) | 764 | const struct GNUNET_SCHEDULER_TaskContext * tc) |
748 | { | 765 | { |
749 | struct ServiceSession * session = cls; | 766 | struct TaskClosure * task = cls; |
767 | struct ServiceSession * session = task->my_session; | ||
750 | struct GNUNET_SCALARPRODUCT_client_response * msg; | 768 | struct GNUNET_SCALARPRODUCT_client_response * msg; |
751 | struct MessageObject * msg_obj; | 769 | struct MessageObject * msg_obj; |
770 | |||
771 | GNUNET_CONTAINER_DLL_remove (tasklist_head, tasklist_tail, task); | ||
772 | GNUNET_free(task); | ||
752 | 773 | ||
753 | msg = GNUNET_new (struct GNUNET_SCALARPRODUCT_client_response); | 774 | msg = GNUNET_new (struct GNUNET_SCALARPRODUCT_client_response); |
754 | msg->header.type = htons (GNUNET_MESSAGE_TYPE_SCALARPRODUCT_SERVICE_TO_CLIENT); | 775 | msg->header.type = htons (GNUNET_MESSAGE_TYPE_SCALARPRODUCT_SERVICE_TO_CLIENT); |
@@ -919,11 +940,14 @@ prepare_service_response (gcry_mpi_t * r, | |||
919 | //disconnect our client | 940 | //disconnect our client |
920 | if ( ! request->service_transmit_handle) | 941 | if ( ! request->service_transmit_handle) |
921 | { | 942 | { |
943 | struct TaskClosure * task = GNUNET_new(struct TaskClosure); | ||
944 | |||
922 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _ ("Could not send service-response message via mesh!)\n")); | 945 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _ ("Could not send service-response message via mesh!)\n")); |
923 | GNUNET_CONTAINER_DLL_remove (from_client_head, from_client_tail, response); | 946 | GNUNET_CONTAINER_DLL_remove (from_client_head, from_client_tail, response); |
924 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, | 947 | task->my_session = response; |
925 | &prepare_client_end_notification, | 948 | task->my_handle = GNUNET_SCHEDULER_add_now (&prepare_client_end_notification, |
926 | response); | 949 | task); |
950 | GNUNET_CONTAINER_DLL_insert (tasklist_head, tasklist_tail, task); | ||
927 | return GNUNET_NO; | 951 | return GNUNET_NO; |
928 | } | 952 | } |
929 | return GNUNET_OK; | 953 | return GNUNET_OK; |
@@ -1156,7 +1180,8 @@ static void | |||
1156 | prepare_service_request (void *cls, | 1180 | prepare_service_request (void *cls, |
1157 | const struct GNUNET_SCHEDULER_TaskContext *tc) | 1181 | const struct GNUNET_SCHEDULER_TaskContext *tc) |
1158 | { | 1182 | { |
1159 | struct ServiceSession * session = cls; | 1183 | struct TaskClosure * task = cls; |
1184 | struct ServiceSession * session = task->my_session; | ||
1160 | unsigned char * current; | 1185 | unsigned char * current; |
1161 | struct GNUNET_SCALARPRODUCT_service_request * msg; | 1186 | struct GNUNET_SCALARPRODUCT_service_request * msg; |
1162 | struct MessageObject * msg_obj; | 1187 | struct MessageObject * msg_obj; |
@@ -1166,8 +1191,10 @@ prepare_service_request (void *cls, | |||
1166 | size_t element_length = 0; //gets initialized by gcry_mpi_print, but the compiler doesn't know that | 1191 | size_t element_length = 0; //gets initialized by gcry_mpi_print, but the compiler doesn't know that |
1167 | gcry_mpi_t a; | 1192 | gcry_mpi_t a; |
1168 | uint32_t value; | 1193 | uint32_t value; |
1194 | |||
1195 | GNUNET_CONTAINER_DLL_remove (tasklist_head, tasklist_tail, task); | ||
1196 | GNUNET_free(task); | ||
1169 | 1197 | ||
1170 | GNUNET_assert (NULL != cls); | ||
1171 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _ ("Successfully created new tunnel to peer (%s)!\n"), GNUNET_i2s (&session->peer)); | 1198 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _ ("Successfully created new tunnel to peer (%s)!\n"), GNUNET_i2s (&session->peer)); |
1172 | 1199 | ||
1173 | msg_length = sizeof (struct GNUNET_SCALARPRODUCT_service_request) | 1200 | msg_length = sizeof (struct GNUNET_SCALARPRODUCT_service_request) |
@@ -1180,12 +1207,15 @@ prepare_service_request (void *cls, | |||
1180 | + session->mask_length | 1207 | + session->mask_length |
1181 | + my_pubkey_external_length) | 1208 | + my_pubkey_external_length) |
1182 | { | 1209 | { |
1210 | struct TaskClosure * task = GNUNET_new(struct TaskClosure); | ||
1183 | // TODO FEATURE: fallback to fragmentation, in case the message is too long | 1211 | // TODO FEATURE: fallback to fragmentation, in case the message is too long |
1184 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _ ("Message too large, fragmentation is currently not supported!\n")); | 1212 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _ ("Message too large, fragmentation is currently not supported!\n")); |
1185 | GNUNET_CONTAINER_DLL_remove (from_client_head, from_client_tail, session); | 1213 | GNUNET_CONTAINER_DLL_remove (from_client_head, from_client_tail, session); |
1186 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, | 1214 | |
1187 | &prepare_client_end_notification, | 1215 | task->my_session = session; |
1188 | session); | 1216 | task->my_handle = GNUNET_SCHEDULER_add_now (&prepare_client_end_notification, |
1217 | task); | ||
1218 | GNUNET_CONTAINER_DLL_insert (tasklist_head, tasklist_tail, task); | ||
1189 | return; | 1219 | return; |
1190 | } | 1220 | } |
1191 | msg = GNUNET_malloc (msg_length); | 1221 | msg = GNUNET_malloc (msg_length); |
@@ -1261,13 +1291,16 @@ prepare_service_request (void *cls, | |||
1261 | msg_obj); | 1291 | msg_obj); |
1262 | if ( ! session->service_transmit_handle) | 1292 | if ( ! session->service_transmit_handle) |
1263 | { | 1293 | { |
1294 | struct TaskClosure * task = GNUNET_new(struct TaskClosure); | ||
1264 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Could not send mutlicast message to tunnel!\n")); | 1295 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Could not send mutlicast message to tunnel!\n")); |
1265 | GNUNET_free (msg_obj); | 1296 | GNUNET_free (msg_obj); |
1266 | GNUNET_free (msg); | 1297 | GNUNET_free (msg); |
1267 | GNUNET_CONTAINER_DLL_remove (from_client_head, from_client_tail, session); | 1298 | GNUNET_CONTAINER_DLL_remove (from_client_head, from_client_tail, session); |
1268 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, | 1299 | |
1269 | &prepare_client_end_notification, | 1300 | task->my_session = session; |
1270 | session); | 1301 | task->my_handle = GNUNET_SCHEDULER_add_now (&prepare_client_end_notification, |
1302 | task); | ||
1303 | GNUNET_CONTAINER_DLL_insert (tasklist_head, tasklist_tail, task); | ||
1271 | } | 1304 | } |
1272 | } | 1305 | } |
1273 | 1306 | ||
@@ -1287,6 +1320,7 @@ handle_client_request (void *cls, | |||
1287 | const struct GNUNET_MessageHeader *message) | 1320 | const struct GNUNET_MessageHeader *message) |
1288 | { | 1321 | { |
1289 | const struct GNUNET_SCALARPRODUCT_client_request * msg = (const struct GNUNET_SCALARPRODUCT_client_request *) message; | 1322 | const struct GNUNET_SCALARPRODUCT_client_request * msg = (const struct GNUNET_SCALARPRODUCT_client_request *) message; |
1323 | struct TaskClosure * task; | ||
1290 | struct ServiceSession * session; | 1324 | struct ServiceSession * session; |
1291 | uint16_t element_count; | 1325 | uint16_t element_count; |
1292 | uint16_t mask_length; | 1326 | uint16_t mask_length; |
@@ -1399,7 +1433,12 @@ handle_client_request (void *cls, | |||
1399 | return; | 1433 | return; |
1400 | } | 1434 | } |
1401 | session->state = WAITING_FOR_BOBS_CONNECT; | 1435 | session->state = WAITING_FOR_BOBS_CONNECT; |
1402 | GNUNET_SCHEDULER_add_now(&prepare_service_request, (void*) session); | 1436 | |
1437 | task = GNUNET_new(struct TaskClosure); | ||
1438 | task->my_session = session; | ||
1439 | task->my_handle = GNUNET_SCHEDULER_add_now (&prepare_service_request, task); | ||
1440 | GNUNET_CONTAINER_DLL_insert (tasklist_head, tasklist_tail, task); | ||
1441 | |||
1403 | GNUNET_SERVER_receive_done (client, GNUNET_YES); | 1442 | GNUNET_SERVER_receive_done (client, GNUNET_YES); |
1404 | } | 1443 | } |
1405 | else | 1444 | else |
@@ -1428,7 +1467,11 @@ handle_client_request (void *cls, | |||
1428 | if (GNUNET_OK != compute_service_response (requesting_session, session)) | 1467 | if (GNUNET_OK != compute_service_response (requesting_session, session)) |
1429 | { | 1468 | { |
1430 | GNUNET_CONTAINER_DLL_remove (from_client_head, from_client_tail, session); | 1469 | GNUNET_CONTAINER_DLL_remove (from_client_head, from_client_tail, session); |
1431 | GNUNET_SCHEDULER_add_now(&prepare_client_end_notification, session); | 1470 | |
1471 | task = GNUNET_new(struct TaskClosure); | ||
1472 | task->my_session = session; | ||
1473 | task->my_handle = GNUNET_SCHEDULER_add_now (&prepare_client_end_notification, task); | ||
1474 | GNUNET_CONTAINER_DLL_insert (tasklist_head, tasklist_tail, task); | ||
1432 | } | 1475 | } |
1433 | } | 1476 | } |
1434 | else | 1477 | else |
@@ -1483,6 +1526,7 @@ tunnel_destruction_handler (void *cls, | |||
1483 | struct ServiceSession * session = tunnel_ctx; | 1526 | struct ServiceSession * session = tunnel_ctx; |
1484 | struct ServiceSession * client_session; | 1527 | struct ServiceSession * client_session; |
1485 | struct ServiceSession * curr; | 1528 | struct ServiceSession * curr; |
1529 | struct TaskClosure * task; | ||
1486 | 1530 | ||
1487 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _ ("Peer disconnected, terminating session %s with peer (%s)\n"), GNUNET_h2s (&session->key), GNUNET_i2s (&session->peer)); | 1531 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _ ("Peer disconnected, terminating session %s with peer (%s)\n"), GNUNET_h2s (&session->key), GNUNET_i2s (&session->peer)); |
1488 | if (ALICE == session->role) { | 1532 | if (ALICE == session->role) { |
@@ -1496,12 +1540,13 @@ tunnel_destruction_handler (void *cls, | |||
1496 | GNUNET_CONTAINER_DLL_remove (from_client_head, from_client_tail, session); | 1540 | GNUNET_CONTAINER_DLL_remove (from_client_head, from_client_tail, session); |
1497 | break; | 1541 | break; |
1498 | } | 1542 | } |
1499 | // FIXME: dangling tasks, code duplication, use-after-free, fun... | 1543 | session->tunnel = NULL; |
1500 | GNUNET_SCHEDULER_add_now (&destroy_tunnel, | ||
1501 | session); | ||
1502 | // if this happened before we received the answer, we must terminate the session | 1544 | // if this happened before we received the answer, we must terminate the session |
1503 | GNUNET_SCHEDULER_add_now (&prepare_client_end_notification, | 1545 | task = GNUNET_new(struct TaskClosure); |
1504 | session); | 1546 | task->my_session = session; |
1547 | task->my_handle = GNUNET_SCHEDULER_add_now (&prepare_client_end_notification, | ||
1548 | task); | ||
1549 | GNUNET_CONTAINER_DLL_insert (tasklist_head, tasklist_tail, task); | ||
1505 | } | 1550 | } |
1506 | } | 1551 | } |
1507 | else { //(BOB == session->role) | 1552 | else { //(BOB == session->role) |
@@ -1528,8 +1573,12 @@ tunnel_destruction_handler (void *cls, | |||
1528 | { | 1573 | { |
1529 | // remove the session, we just found it in the queue, so it must be there | 1574 | // remove the session, we just found it in the queue, so it must be there |
1530 | GNUNET_CONTAINER_DLL_remove (from_client_head, from_client_tail, client_session); | 1575 | GNUNET_CONTAINER_DLL_remove (from_client_head, from_client_tail, client_session); |
1531 | GNUNET_SCHEDULER_add_now (&prepare_client_end_notification, | 1576 | |
1532 | client_session); | 1577 | task = GNUNET_new(struct TaskClosure); |
1578 | task->my_session = client_session; | ||
1579 | task->my_handle = GNUNET_SCHEDULER_add_now (&prepare_client_end_notification, | ||
1580 | task); | ||
1581 | GNUNET_CONTAINER_DLL_insert (tasklist_head, tasklist_tail, task); | ||
1533 | } | 1582 | } |
1534 | } | 1583 | } |
1535 | } | 1584 | } |
@@ -1636,7 +1685,8 @@ static void | |||
1636 | prepare_client_response (void *cls, | 1685 | prepare_client_response (void *cls, |
1637 | const struct GNUNET_SCHEDULER_TaskContext *tc) | 1686 | const struct GNUNET_SCHEDULER_TaskContext *tc) |
1638 | { | 1687 | { |
1639 | struct ServiceSession * session = cls; | 1688 | struct TaskClosure * task = cls; |
1689 | struct ServiceSession * session = task->my_session; | ||
1640 | struct GNUNET_SCALARPRODUCT_client_response * msg; | 1690 | struct GNUNET_SCALARPRODUCT_client_response * msg; |
1641 | unsigned char * product_exported = NULL; | 1691 | unsigned char * product_exported = NULL; |
1642 | size_t product_length = 0; | 1692 | size_t product_length = 0; |
@@ -1644,6 +1694,9 @@ prepare_client_response (void *cls, | |||
1644 | struct MessageObject * msg_obj; | 1694 | struct MessageObject * msg_obj; |
1645 | int8_t range = 0; | 1695 | int8_t range = 0; |
1646 | int sign; | 1696 | int sign; |
1697 | |||
1698 | GNUNET_CONTAINER_DLL_remove (tasklist_head, tasklist_tail, task); | ||
1699 | GNUNET_free(task); | ||
1647 | 1700 | ||
1648 | if (session->product) | 1701 | if (session->product) |
1649 | { | 1702 | { |
@@ -1888,11 +1941,13 @@ except: | |||
1888 | // and notify our client-session that we could not complete the session | 1941 | // and notify our client-session that we could not complete the session |
1889 | if (responder_session) | 1942 | if (responder_session) |
1890 | { | 1943 | { |
1944 | struct TaskClosure * task = GNUNET_new(struct TaskClosure); | ||
1891 | // we just found the responder session in this queue | 1945 | // we just found the responder session in this queue |
1892 | GNUNET_CONTAINER_DLL_remove (from_client_head, from_client_tail, responder_session); | 1946 | GNUNET_CONTAINER_DLL_remove (from_client_head, from_client_tail, responder_session); |
1893 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, | 1947 | task->my_session = responder_session; |
1894 | &prepare_client_end_notification, | 1948 | task->my_handle = GNUNET_SCHEDULER_add_now (&prepare_client_end_notification, |
1895 | responder_session); | 1949 | task); |
1950 | GNUNET_CONTAINER_DLL_insert (tasklist_head, tasklist_tail, task); | ||
1896 | } | 1951 | } |
1897 | return GNUNET_SYSERR; | 1952 | return GNUNET_SYSERR; |
1898 | } | 1953 | } |
@@ -1919,6 +1974,7 @@ handle_service_response (void *cls, | |||
1919 | 1974 | ||
1920 | struct ServiceSession * session; | 1975 | struct ServiceSession * session; |
1921 | struct GNUNET_SCALARPRODUCT_service_response * msg = (struct GNUNET_SCALARPRODUCT_service_response *) message; | 1976 | struct GNUNET_SCALARPRODUCT_service_response * msg = (struct GNUNET_SCALARPRODUCT_service_response *) message; |
1977 | struct TaskClosure * task; | ||
1922 | unsigned char * current; | 1978 | unsigned char * current; |
1923 | uint16_t count; | 1979 | uint16_t count; |
1924 | gcry_mpi_t s = NULL; | 1980 | gcry_mpi_t s = NULL; |
@@ -2025,11 +2081,14 @@ invalid_msg: | |||
2025 | // the tunnel has done its job, terminate our connection and the tunnel | 2081 | // the tunnel has done its job, terminate our connection and the tunnel |
2026 | // the peer will be notified that the tunnel was destroyed via tunnel_destruction_handler | 2082 | // the peer will be notified that the tunnel was destroyed via tunnel_destruction_handler |
2027 | GNUNET_CONTAINER_DLL_remove (from_client_head, from_client_tail, session); | 2083 | GNUNET_CONTAINER_DLL_remove (from_client_head, from_client_tail, session); |
2028 | GNUNET_SCHEDULER_add_now (&destroy_tunnel, session); // FIXME: use after free! | ||
2029 | // send message with product to client | 2084 | // send message with product to client |
2030 | /* session->current_task = */ GNUNET_SCHEDULER_add_now (&prepare_client_response, session); // FIXME: dangling task! | 2085 | |
2031 | return GNUNET_OK; | 2086 | task = GNUNET_new(struct TaskClosure); |
2032 | // if success: terminate the session gracefully, else terminate with error | 2087 | task->my_session = session; |
2088 | task->my_handle = GNUNET_SCHEDULER_add_now (&prepare_client_response, task); | ||
2089 | GNUNET_CONTAINER_DLL_insert (tasklist_head, tasklist_tail, task); | ||
2090 | // just close the connection. | ||
2091 | return GNUNET_SYSERR; | ||
2033 | } | 2092 | } |
2034 | 2093 | ||
2035 | 2094 | ||
@@ -2043,21 +2102,18 @@ static void | |||
2043 | shutdown_task (void *cls, | 2102 | shutdown_task (void *cls, |
2044 | const struct GNUNET_SCHEDULER_TaskContext *tc) | 2103 | const struct GNUNET_SCHEDULER_TaskContext *tc) |
2045 | { | 2104 | { |
2046 | struct ServiceSession * curr; | 2105 | struct ServiceSession * session; |
2047 | struct ServiceSession * next; | 2106 | struct TaskClosure * task; |
2048 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, _ ("Shutting down, initiating cleanup.\n")); | 2107 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, _ ("Shutting down, initiating cleanup.\n")); |
2049 | 2108 | ||
2050 | do_shutdown = GNUNET_YES; | 2109 | do_shutdown = GNUNET_YES; |
2110 | for (task = tasklist_head; NULL != task; task = task->next) | ||
2111 | GNUNET_SCHEDULER_cancel(task->my_handle); | ||
2112 | |||
2051 | // terminate all owned open tunnels. | 2113 | // terminate all owned open tunnels. |
2052 | for (curr = from_client_head; NULL != curr; curr = next) | 2114 | for (session = from_client_head; NULL != session; session = session->next) |
2053 | { | 2115 | if (FINALIZED != session->state) |
2054 | next = curr->next; | 2116 | GNUNET_MESH_tunnel_destroy (session->tunnel); |
2055 | if (FINALIZED != curr->state) | ||
2056 | { | ||
2057 | destroy_tunnel (curr, NULL); | ||
2058 | curr->state = FINALIZED; | ||
2059 | } | ||
2060 | } | ||
2061 | if (my_mesh) | 2117 | if (my_mesh) |
2062 | { | 2118 | { |
2063 | GNUNET_MESH_disconnect (my_mesh); | 2119 | GNUNET_MESH_disconnect (my_mesh); |