aboutsummaryrefslogtreecommitdiff
path: root/src/scalarproduct
diff options
context:
space:
mode:
authorChristian Fuchs <christian.fuchs@cfuchs.net>2013-09-05 13:11:59 +0000
committerChristian Fuchs <christian.fuchs@cfuchs.net>2013-09-05 13:11:59 +0000
commit55401c568a7644b64032bff774e330fdadfaf35d (patch)
tree58aa115d12a2472c24ce3f25ee71214c496cdccb /src/scalarproduct
parent166d7ab3218c717c8b9e75b0530f360040d5f6ba (diff)
downloadgnunet-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.c202
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 */
185struct 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 */
268static int do_shutdown; 293static int do_shutdown;
269 294
295/**
296 * DLL for all out active, queued tasks. Purged upon disconnect
297 */
298static struct TaskClosure * tasklist_head;
299/**
300 * DLL for all out active, queued tasks. Purged upon disconnect
301 */
302static 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
648static void 682static void
649destroy_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
664static void
665free_session (struct ServiceSession * session) 683free_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
746prepare_client_end_notification (void * cls, 763prepare_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
1156prepare_service_request (void *cls, 1180prepare_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
1636prepare_client_response (void *cls, 1685prepare_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
2043shutdown_task (void *cls, 2102shutdown_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);