aboutsummaryrefslogtreecommitdiff
path: root/src/scalarproduct
diff options
context:
space:
mode:
authorChristian Fuchs <christian.fuchs@cfuchs.net>2013-09-03 13:19:33 +0000
committerChristian Fuchs <christian.fuchs@cfuchs.net>2013-09-03 13:19:33 +0000
commit76e693d3f91ae0054c310586048852c239f0d851 (patch)
tree16663a8c69eced2f4a8d0bc04e6138a766f40014 /src/scalarproduct
parentdc91365855b72f0c97c0a7abc6eac7d479704daf (diff)
downloadgnunet-76e693d3f91ae0054c310586048852c239f0d851.tar.gz
gnunet-76e693d3f91ae0054c310586048852c239f0d851.zip
updated scalarproduct service to be compatible with the new mesh API
Diffstat (limited to 'src/scalarproduct')
-rw-r--r--src/scalarproduct/gnunet-service-scalarproduct.c200
1 files changed, 82 insertions, 118 deletions
diff --git a/src/scalarproduct/gnunet-service-scalarproduct.c b/src/scalarproduct/gnunet-service-scalarproduct.c
index d7c8f436b..20a51624b 100644
--- a/src/scalarproduct/gnunet-service-scalarproduct.c
+++ b/src/scalarproduct/gnunet-service-scalarproduct.c
@@ -903,7 +903,6 @@ prepare_service_response (gcry_mpi_t * r,
903 GNUNET_MESH_notify_transmit_ready (request->tunnel, 903 GNUNET_MESH_notify_transmit_ready (request->tunnel,
904 GNUNET_YES, 904 GNUNET_YES,
905 GNUNET_TIME_UNIT_FOREVER_REL, 905 GNUNET_TIME_UNIT_FOREVER_REL,
906 &request->peer, //must be specified, we are a slave/participant/non-owner
907 msg_length, 906 msg_length,
908 &do_send_message, 907 &do_send_message,
909 msg_obj); 908 msg_obj);
@@ -1155,8 +1154,7 @@ except:
1155 */ 1154 */
1156static void 1155static void
1157prepare_service_request (void *cls, 1156prepare_service_request (void *cls,
1158 const struct GNUNET_PeerIdentity * peer, 1157 const struct GNUNET_SCHEDULER_TaskContext *tc)
1159 const struct GNUNET_ATS_Information * atsi)
1160{ 1158{
1161 struct ServiceSession * session = cls; 1159 struct ServiceSession * session = cls;
1162 unsigned char * current; 1160 unsigned char * current;
@@ -1170,8 +1168,7 @@ prepare_service_request (void *cls,
1170 uint32_t value; 1168 uint32_t value;
1171 1169
1172 GNUNET_assert (NULL != cls); 1170 GNUNET_assert (NULL != cls);
1173 GNUNET_assert (NULL != peer); 1171 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _ ("Successfully created new tunnel to peer (%s)!\n"), GNUNET_i2s (&session->peer));
1174 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _ ("Successfully created new tunnel to peer (%s)!\n"), GNUNET_i2s (peer));
1175 1172
1176 msg_length = sizeof (struct GNUNET_SCALARPRODUCT_service_request) 1173 msg_length = sizeof (struct GNUNET_SCALARPRODUCT_service_request)
1177 + session->used_element_count * PAILLIER_ELEMENT_LENGTH 1174 + session->used_element_count * PAILLIER_ELEMENT_LENGTH
@@ -1259,7 +1256,6 @@ prepare_service_request (void *cls,
1259 session->state = WAITING_FOR_RESPONSE_FROM_SERVICE; 1256 session->state = WAITING_FOR_RESPONSE_FROM_SERVICE;
1260 session->service_transmit_handle = GNUNET_MESH_notify_transmit_ready (session->tunnel, GNUNET_YES, 1257 session->service_transmit_handle = GNUNET_MESH_notify_transmit_ready (session->tunnel, GNUNET_YES,
1261 GNUNET_TIME_UNIT_FOREVER_REL, 1258 GNUNET_TIME_UNIT_FOREVER_REL,
1262 peer, //multicast to all targets, maybe useful in the future
1263 msg_length, 1259 msg_length,
1264 &do_send_message, 1260 &do_send_message,
1265 msg_obj); 1261 msg_obj);
@@ -1275,46 +1271,6 @@ prepare_service_request (void *cls,
1275 } 1271 }
1276} 1272}
1277 1273
1278
1279/**
1280 * Method called whenever a peer has disconnected from the tunnel.
1281 * Implementations of this callback must NOT call
1282 * #GNUNET_MESH_tunnel_destroy immediately, but instead schedule those
1283 * to run in some other task later. However, calling
1284 * #GNUNET_MESH_notify_transmit_ready_cancel is allowed.
1285 *
1286 * @param cls closure
1287 * @param peer peer identity the tunnel stopped working with
1288 */
1289static void
1290tunnel_peer_disconnect_handler (void *cls, const struct GNUNET_PeerIdentity * peer)
1291{
1292 // as we have only one peer connected in each session, just remove the session and say good bye
1293 struct ServiceSession * session = cls;
1294 struct ServiceSession * curr;
1295
1296 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1297 "Peer (%s) disconnected from our tunnel!\n",
1298 GNUNET_i2s (peer));
1299
1300 if ((session->role == ALICE) && (FINALIZED != session->state) && ( ! do_shutdown))
1301 {
1302 for (curr = from_client_head; NULL != curr; curr = curr->next)
1303 if (curr == session)
1304 {
1305 GNUNET_CONTAINER_DLL_remove (from_client_head, from_client_tail, session);
1306 break;
1307 }
1308 // FIXME: dangling tasks, code duplication, use-after-free, fun...
1309 GNUNET_SCHEDULER_add_now (&destroy_tunnel,
1310 session);
1311 // if this happened before we received the answer, we must terminate the session
1312 GNUNET_SCHEDULER_add_now (&prepare_client_end_notification,
1313 session);
1314 }
1315}
1316
1317
1318/** 1274/**
1319 * Handler for a client request message. 1275 * Handler for a client request message.
1320 * Can either be type A or B 1276 * Can either be type A or B
@@ -1428,9 +1384,11 @@ handle_client_request (void *cls,
1428 GNUNET_log (GNUNET_ERROR_TYPE_INFO, _ ("Creating new tunnel to for session with key %s.\n"), GNUNET_h2s (&session->key)); 1384 GNUNET_log (GNUNET_ERROR_TYPE_INFO, _ ("Creating new tunnel to for session with key %s.\n"), GNUNET_h2s (&session->key));
1429 GNUNET_CONTAINER_DLL_insert (from_client_head, from_client_tail, session); 1385 GNUNET_CONTAINER_DLL_insert (from_client_head, from_client_tail, session);
1430 session->tunnel = GNUNET_MESH_tunnel_create (my_mesh, session, 1386 session->tunnel = GNUNET_MESH_tunnel_create (my_mesh, session,
1431 prepare_service_request, 1387 &session->peer,
1432 tunnel_peer_disconnect_handler, 1388 GNUNET_APPLICATION_TYPE_SCALARPRODUCT,
1433 session); 1389 GNUNET_NO,
1390 GNUNET_YES);
1391 //prepare_service_request, tunnel_peer_disconnect_handler,
1434 if ( ! session->tunnel) 1392 if ( ! session->tunnel)
1435 { 1393 {
1436 GNUNET_break (0); 1394 GNUNET_break (0);
@@ -1440,9 +1398,9 @@ handle_client_request (void *cls,
1440 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 1398 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1441 return; 1399 return;
1442 } 1400 }
1443 GNUNET_MESH_peer_request_connect_add (session->tunnel, &session->peer);
1444 GNUNET_SERVER_receive_done (client, GNUNET_YES);
1445 session->state = WAITING_FOR_BOBS_CONNECT; 1401 session->state = WAITING_FOR_BOBS_CONNECT;
1402 GNUNET_SCHEDULER_add_now(&prepare_service_request, (void*) session);
1403 GNUNET_SERVER_receive_done (client, GNUNET_YES);
1446 } 1404 }
1447 else 1405 else
1448 { 1406 {
@@ -1470,9 +1428,7 @@ handle_client_request (void *cls,
1470 if (GNUNET_OK != compute_service_response (requesting_session, session)) 1428 if (GNUNET_OK != compute_service_response (requesting_session, session))
1471 { 1429 {
1472 GNUNET_CONTAINER_DLL_remove (from_client_head, from_client_tail, session); 1430 GNUNET_CONTAINER_DLL_remove (from_client_head, from_client_tail, session);
1473 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, 1431 GNUNET_SCHEDULER_add_now(&prepare_client_end_notification, session);
1474 &prepare_client_end_notification,
1475 session);
1476 } 1432 }
1477 } 1433 }
1478 else 1434 else
@@ -1494,9 +1450,10 @@ handle_client_request (void *cls,
1494 * (can be NULL -- that's not an error) 1450 * (can be NULL -- that's not an error)
1495 */ 1451 */
1496static void * 1452static void *
1497tunnel_incoming_handler (void *cls, struct GNUNET_MESH_Tunnel *tunnel, 1453tunnel_incoming_handler (void *cls,
1454 struct GNUNET_MESH_Tunnel *tunnel,
1498 const struct GNUNET_PeerIdentity *initiator, 1455 const struct GNUNET_PeerIdentity *initiator,
1499 const struct GNUNET_ATS_Information *atsi) 1456 uint32_t port)
1500{ 1457{
1501 1458
1502 struct ServiceSession * c = GNUNET_new (struct ServiceSession); 1459 struct ServiceSession * c = GNUNET_new (struct ServiceSession);
@@ -1507,55 +1464,74 @@ tunnel_incoming_handler (void *cls, struct GNUNET_MESH_Tunnel *tunnel,
1507 return c; 1464 return c;
1508} 1465}
1509 1466
1510
1511/** 1467/**
1512 * Function called whenever an inbound tunnel is destroyed. Should clean up 1468 * Function called whenever a tunnel is destroyed. Should clean up
1513 * any associated state. 1469 * any associated state.
1470 *
1471 * It must NOT call GNUNET_MESH_tunnel_destroy on the tunnel.
1514 * 1472 *
1515 * @param cls closure (set from #GNUNET_MESH_connect) 1473 * @param cls closure (set from GNUNET_MESH_connect)
1516 * @param tunnel connection to the other end (henceforth invalid) 1474 * @param tunnel connection to the other end (henceforth invalid)
1517 * @param tunnel_ctx place where local state associated 1475 * @param tunnel_ctx place where local state associated
1518 * with the tunnel is stored (our 'struct TunnelState') 1476 * with the tunnel is stored
1519 */ 1477 */
1520static void 1478static void
1521tunnel_destruction_handler (void *cls, 1479tunnel_destruction_handler (void *cls,
1522 const struct GNUNET_MESH_Tunnel *tunnel, 1480 const struct GNUNET_MESH_Tunnel *tunnel,
1523 void *tunnel_ctx) 1481 void *tunnel_ctx)
1524{ 1482{
1525 struct ServiceSession * service_session = tunnel_ctx; 1483 struct ServiceSession * session = tunnel_ctx;
1526 struct ServiceSession * client_session; 1484 struct ServiceSession * client_session;
1527 struct ServiceSession * curr; 1485 struct ServiceSession * curr;
1486
1487 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) {
1489 // as we have only one peer connected in each session, just remove the session
1528 1490
1529 GNUNET_assert (service_session); 1491 if ((FINALIZED != session->state) && (!do_shutdown))
1530 if (!memcmp (&service_session->peer, &me, sizeof (struct GNUNET_PeerIdentity))) 1492 {
1531 return; 1493 for (curr = from_client_head; NULL != curr; curr = curr->next)
1532 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _ ("Tunnel destroyed, terminating session with peer (%s)\n"), GNUNET_i2s (&service_session->peer)); 1494 if (curr == session)
1533 // remove the session, unless it has already been dequeued, but somehow still active 1495 {
1534 // this could bug without the IF in case the queue is empty and the service session was the only one know to the service 1496 GNUNET_CONTAINER_DLL_remove (from_client_head, from_client_tail, session);
1535 for (curr = from_service_head; NULL != curr; curr = curr->next) 1497 break;
1536 if (curr == service_session) 1498 }
1537 { 1499 // FIXME: dangling tasks, code duplication, use-after-free, fun...
1538 GNUNET_CONTAINER_DLL_remove (from_service_head, from_service_tail, curr); 1500 GNUNET_SCHEDULER_add_now (&destroy_tunnel,
1539 break; 1501 session);
1540 } 1502 // if this happened before we received the answer, we must terminate the session
1541 // there is a client waiting for this service session, terminate it, too! 1503 GNUNET_SCHEDULER_add_now (&prepare_client_end_notification,
1542 // i assume the tupel of key and element count is unique. if it was not the rest of the code would not work either. 1504 session);
1543 client_session = find_matching_session (from_client_tail, 1505 }
1544 &service_session->key, 1506 }
1545 service_session->element_count, 1507 else { //(BOB == session->role)
1546 NULL, NULL); 1508
1547 free_session (service_session); 1509 // remove the session, unless it has already been dequeued, but somehow still active
1548 1510 // this could bug without the IF in case the queue is empty and the service session was the only one know to the service
1549 // the client has to check if it was waiting for a result 1511 for (curr = from_service_head; NULL != curr; curr = curr->next)
1550 // or if it was a responder, no point in adding more statefulness 1512 if (curr == session)
1551 if (client_session && ( ! do_shutdown)) 1513 {
1514 GNUNET_CONTAINER_DLL_remove (from_service_head, from_service_tail, curr);
1515 break;
1516 }
1517 // there is a client waiting for this service session, terminate it, too!
1518 // i assume the tupel of key and element count is unique. if it was not the rest of the code would not work either.
1519 client_session = find_matching_session (from_client_tail,
1520 &session->key,
1521 session->element_count,
1522 NULL, NULL);
1523 free_session (session);
1524
1525 // the client has to check if it was waiting for a result
1526 // or if it was a responder, no point in adding more statefulness
1527 if (client_session && (!do_shutdown))
1552 { 1528 {
1553 // remove the session, we just found it in the queue, so it must be there 1529 // remove the session, we just found it in the queue, so it must be there
1554 GNUNET_CONTAINER_DLL_remove (from_client_head, from_client_tail, client_session); 1530 GNUNET_CONTAINER_DLL_remove (from_client_head, from_client_tail, client_session);
1555 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, 1531 GNUNET_SCHEDULER_add_now (&prepare_client_end_notification,
1556 &prepare_client_end_notification, 1532 client_session);
1557 client_session);
1558 } 1533 }
1534 }
1559} 1535}
1560 1536
1561 1537
@@ -1752,9 +1728,7 @@ static int
1752handle_service_request (void *cls, 1728handle_service_request (void *cls,
1753 struct GNUNET_MESH_Tunnel * tunnel, 1729 struct GNUNET_MESH_Tunnel * tunnel,
1754 void **tunnel_ctx, 1730 void **tunnel_ctx,
1755 const struct GNUNET_PeerIdentity * sender, 1731 const struct GNUNET_MessageHeader * message)
1756 const struct GNUNET_MessageHeader * message,
1757 const struct GNUNET_ATS_Information * atsi)
1758{ 1732{
1759 struct ServiceSession * session; 1733 struct ServiceSession * session;
1760 const struct GNUNET_SCALARPRODUCT_service_request * msg = (const struct GNUNET_SCALARPRODUCT_service_request *) message; 1734 const struct GNUNET_SCALARPRODUCT_service_request * msg = (const struct GNUNET_SCALARPRODUCT_service_request *) message;
@@ -1769,22 +1743,18 @@ handle_service_request (void *cls,
1769 enum SessionState needed_state; 1743 enum SessionState needed_state;
1770 1744
1771 session = (struct ServiceSession *) * tunnel_ctx; 1745 session = (struct ServiceSession *) * tunnel_ctx;
1746 if (BOB != session->role){
1747 GNUNET_break_op(0);
1748 return GNUNET_SYSERR;
1749 }
1772 // is this tunnel already in use? 1750 // is this tunnel already in use?
1773 if ( (session->next) || (from_service_head == session)) 1751 if ( (session->next) || (from_service_head == session))
1774 { 1752 {
1775 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _ ("Got a service request over a tunnel that is already in use, ignoring!\n")); 1753 GNUNET_break_op(0);
1776 return GNUNET_SYSERR; 1754 return GNUNET_SYSERR;
1777 } 1755 }
1778 // Check if message was sent by me, which would be bad! 1756 // Check if message was sent by me, which would be bad!
1779 if ( ! memcmp (sender, &me, sizeof (struct GNUNET_PeerIdentity))) 1757 if ( ! memcmp (&session->peer, &me, sizeof (struct GNUNET_PeerIdentity)))
1780 {
1781 GNUNET_break (0);
1782 GNUNET_free (session);
1783 return GNUNET_SYSERR;
1784 }
1785 // this protocol can at best be 1:N, but never M:N!
1786 // Check if the sender is not the peer, I am connected to, which would be bad!
1787 if (memcmp (sender, &session->peer, sizeof (struct GNUNET_PeerIdentity)))
1788 { 1758 {
1789 GNUNET_break (0); 1759 GNUNET_break (0);
1790 GNUNET_free (session); 1760 GNUNET_free (session);
@@ -1819,14 +1789,14 @@ handle_service_request (void *cls,
1819 &msg->key, 1789 &msg->key,
1820 element_count, 1790 element_count,
1821 NULL, 1791 NULL,
1822 sender)) 1792 NULL))
1823 { 1793 {
1824 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _ ("Got message with duplicate session key (`%s'), ignoring service request.\n"), (const char *) &(msg->key)); 1794 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _ ("Got message with duplicate session key (`%s'), ignoring service request.\n"), (const char *) &(msg->key));
1825 GNUNET_free (session); 1795 GNUNET_free (session);
1826 return GNUNET_SYSERR; 1796 return GNUNET_SYSERR;
1827 } 1797 }
1828 1798
1829 memcpy (&session->peer, sender, sizeof (struct GNUNET_PeerIdentity)); 1799 memcpy (&session->peer, &session->peer, sizeof (struct GNUNET_PeerIdentity));
1830 session->state = REQUEST_FROM_SERVICE_RECEIVED; 1800 session->state = REQUEST_FROM_SERVICE_RECEIVED;
1831 session->element_count = ntohs (msg->element_count); 1801 session->element_count = ntohs (msg->element_count);
1832 session->used_element_count = used_elements; 1802 session->used_element_count = used_elements;
@@ -1944,9 +1914,7 @@ static int
1944handle_service_response (void *cls, 1914handle_service_response (void *cls,
1945 struct GNUNET_MESH_Tunnel * tunnel, 1915 struct GNUNET_MESH_Tunnel * tunnel,
1946 void **tunnel_ctx, 1916 void **tunnel_ctx,
1947 const struct GNUNET_PeerIdentity * sender, 1917 const struct GNUNET_MessageHeader * message)
1948 const struct GNUNET_MessageHeader * message,
1949 const struct GNUNET_ATS_Information * atsi)
1950{ 1918{
1951 1919
1952 struct ServiceSession * session; 1920 struct ServiceSession * session;
@@ -1964,18 +1932,15 @@ handle_service_response (void *cls,
1964 int rc; 1932 int rc;
1965 1933
1966 GNUNET_assert (NULL != message); 1934 GNUNET_assert (NULL != message);
1967 GNUNET_assert (NULL != sender);
1968 GNUNET_assert (NULL != tunnel_ctx);
1969 session = (struct ServiceSession *) * tunnel_ctx; 1935 session = (struct ServiceSession *) * tunnel_ctx;
1970 GNUNET_assert (NULL != session); 1936 if (ALICE != session->role){
1937 GNUNET_break_op(0);
1938 return GNUNET_SYSERR;
1939 }
1940
1971 count = session->used_element_count; 1941 count = session->used_element_count;
1972 session->product = NULL; 1942 session->product = NULL;
1973 1943
1974 if (memcmp (&session->peer, sender, sizeof (struct GNUNET_PeerIdentity)))
1975 {
1976 GNUNET_break_op (0);
1977 goto invalid_msg;
1978 }
1979 //we need at least a peer and one message id to compare 1944 //we need at least a peer and one message id to compare
1980 if (sizeof (struct GNUNET_SCALARPRODUCT_service_response) > ntohs (msg->header.size)) 1945 if (sizeof (struct GNUNET_SCALARPRODUCT_service_response) > ntohs (msg->header.size))
1981 { 1946 {
@@ -2123,11 +2088,10 @@ run (void *cls,
2123 { &handle_service_response, GNUNET_MESSAGE_TYPE_SCALARPRODUCT_BOB_TO_ALICE, 0}, 2088 { &handle_service_response, GNUNET_MESSAGE_TYPE_SCALARPRODUCT_BOB_TO_ALICE, 0},
2124 {NULL, 0, 0} 2089 {NULL, 0, 0}
2125 }; 2090 };
2126 static GNUNET_MESH_ApplicationType mesh_types[] = { 2091 static const uint32_t ports[] = {
2127 GNUNET_APPLICATION_TYPE_SCALARPRODUCT, 2092 GNUNET_APPLICATION_TYPE_SCALARPRODUCT,
2128 GNUNET_APPLICATION_TYPE_END 2093 0
2129 }; 2094 };
2130
2131 //generate private/public key set 2095 //generate private/public key set
2132 GNUNET_log (GNUNET_ERROR_TYPE_INFO, _ ("Generating Paillier-Keyset.\n")); 2096 GNUNET_log (GNUNET_ERROR_TYPE_INFO, _ ("Generating Paillier-Keyset.\n"));
2133 generate_keyset (); 2097 generate_keyset ();
@@ -2142,7 +2106,7 @@ run (void *cls,
2142 my_mesh = GNUNET_MESH_connect (c, NULL, 2106 my_mesh = GNUNET_MESH_connect (c, NULL,
2143 &tunnel_incoming_handler, 2107 &tunnel_incoming_handler,
2144 &tunnel_destruction_handler, 2108 &tunnel_destruction_handler,
2145 mesh_handlers, mesh_types); 2109 mesh_handlers, ports);
2146 if (!my_mesh) 2110 if (!my_mesh)
2147 { 2111 {
2148 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _ ("Connect to MESH failed\n")); 2112 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _ ("Connect to MESH failed\n"));