aboutsummaryrefslogtreecommitdiff
path: root/src/scalarproduct
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2014-05-24 19:57:15 +0000
committerChristian Grothoff <christian@grothoff.org>2014-05-24 19:57:15 +0000
commit31536a9bb75502f4c090472f188e1eec138515f7 (patch)
tree2c75617baa1ca040ddfb6a59d90831624b3512b1 /src/scalarproduct
parent152cd13768915399f9e5137d78a2f75296a1b93e (diff)
downloadgnunet-31536a9bb75502f4c090472f188e1eec138515f7.tar.gz
gnunet-31536a9bb75502f4c090472f188e1eec138515f7.zip
cleaning up scalar product client API
Diffstat (limited to 'src/scalarproduct')
-rw-r--r--src/scalarproduct/gnunet-scalarproduct.c22
-rw-r--r--src/scalarproduct/gnunet-service-scalarproduct.c267
-rw-r--r--src/scalarproduct/scalarproduct.h142
-rw-r--r--src/scalarproduct/scalarproduct_api.c589
4 files changed, 482 insertions, 538 deletions
diff --git a/src/scalarproduct/gnunet-scalarproduct.c b/src/scalarproduct/gnunet-scalarproduct.c
index 2bb708fc9..88069d41d 100644
--- a/src/scalarproduct/gnunet-scalarproduct.c
+++ b/src/scalarproduct/gnunet-scalarproduct.c
@@ -261,22 +261,22 @@ run (void *cls,
261 _ ("Need elements to compute the vectorproduct, got none.\n")); 261 _ ("Need elements to compute the vectorproduct, got none.\n"));
262 return; 262 return;
263 } 263 }
264 264
265 elements = (struct GNUNET_SCALARPRODUCT_Element *) 265 elements = (struct GNUNET_SCALARPRODUCT_Element *)
266 GNUNET_malloc(sizeof(struct GNUNET_SCALARPRODUCT_Element)*element_count); 266 GNUNET_malloc(sizeof(struct GNUNET_SCALARPRODUCT_Element)*element_count);
267 267
268 for (i = 0; i < element_count;i++) 268 for (i = 0; i < element_count;i++)
269 { 269 {
270 struct GNUNET_SCALARPRODUCT_Element element; 270 struct GNUNET_SCALARPRODUCT_Element element;
271 char* separator=NULL; 271 char* separator=NULL;
272 272
273 // get the length of the current key,value; tupel 273 // get the length of the current key,value; tupel
274 for (end = begin; *end != ';'; end++) 274 for (end = begin; *end != ';'; end++)
275 if (*end == ',') 275 if (*end == ',')
276 separator = end; 276 separator = end;
277 277
278 // final element 278 // final element
279 if ((NULL == separator) 279 if ((NULL == separator)
280 || (begin == separator) 280 || (begin == separator)
281 || (separator == end - 1 )) { 281 || (separator == end - 1 )) {
282 LOG (GNUNET_ERROR_TYPE_ERROR, 282 LOG (GNUNET_ERROR_TYPE_ERROR,
@@ -284,20 +284,20 @@ run (void *cls,
284 GNUNET_free(elements); 284 GNUNET_free(elements);
285 return; 285 return;
286 } 286 }
287 287
288 // read the element's key 288 // read the element's key
289 *separator = 0; 289 *separator = 0;
290 GNUNET_CRYPTO_hash (begin, strlen (begin), &element.key); 290 GNUNET_CRYPTO_hash (begin, strlen (begin), &element.key);
291 291
292 // read the element's value 292 // read the element's value
293 if (1 != sscanf (separator+1, "%" SCNd32 ";", &element.value)) 293 if (1 != sscanf (separator+1, "%" SCNd64 ";", &element.value))
294 { 294 {
295 LOG (GNUNET_ERROR_TYPE_ERROR, 295 LOG (GNUNET_ERROR_TYPE_ERROR,
296 _ ("Could not convert `%s' to int32_t.\n"), begin); 296 _ ("Could not convert `%s' to int64_t.\n"), begin);
297 GNUNET_free(elements); 297 GNUNET_free(elements);
298 return; 298 return;
299 } 299 }
300 300
301 elements[i]=element; 301 elements[i]=element;
302 begin = end+1; 302 begin = end+1;
303 } 303 }
diff --git a/src/scalarproduct/gnunet-service-scalarproduct.c b/src/scalarproduct/gnunet-service-scalarproduct.c
index 568f68ffc..7758d7046 100644
--- a/src/scalarproduct/gnunet-service-scalarproduct.c
+++ b/src/scalarproduct/gnunet-service-scalarproduct.c
@@ -37,9 +37,119 @@
37 37
38#define LOG(kind,...) GNUNET_log_from (kind, "scalarproduct", __VA_ARGS__) 38#define LOG(kind,...) GNUNET_log_from (kind, "scalarproduct", __VA_ARGS__)
39 39
40/////////////////////////////////////////////////////////////////////////////// 40
41// Service Structure Definitions 41/**
42/////////////////////////////////////////////////////////////////////////////// 42 * Maximum count of elements we can put into a multipart message
43 */
44#define MULTIPART_ELEMENT_CAPACITY ((GNUNET_SERVER_MAX_MESSAGE_SIZE - 1 - sizeof (struct MultipartMessage)) / sizeof (struct GNUNET_CRYPTO_PaillierCiphertext))
45
46
47GNUNET_NETWORK_STRUCT_BEGIN
48
49/**
50 * Message type passed from requesting service Alice to responding
51 * service Bob to initiate a request and make Bob participate in our
52 * protocol
53 */
54struct ServiceRequestMessage
55{
56 /**
57 * GNUNET message header
58 */
59 struct GNUNET_MessageHeader header;
60
61 /**
62 * the transaction/session key used to identify a session
63 */
64 struct GNUNET_HashCode session_id;
65
66 /**
67 * Alice's public key
68 */
69 struct GNUNET_CRYPTO_PaillierPublicKey public_key;
70
71};
72
73
74/**
75 * FIXME.
76 */
77struct AliceCryptodataMessage
78{
79 /**
80 * GNUNET message header
81 */
82 struct GNUNET_MessageHeader header;
83
84 /**
85 * how many elements we appended to this message
86 */
87 uint32_t contained_element_count GNUNET_PACKED;
88
89 /**
90 * struct GNUNET_CRYPTO_PaillierCiphertext[contained_element_count]
91 */
92};
93
94
95/**
96 * Multipart Message type passed between to supply additional elements
97 * for the peer
98 */
99struct MultipartMessage
100{
101 /**
102 * GNUNET message header
103 */
104 struct GNUNET_MessageHeader header;
105
106 /**
107 * how many elements we supply within this message
108 */
109 uint32_t contained_element_count GNUNET_PACKED;
110
111 // struct GNUNET_CRYPTO_PaillierCiphertext[multipart_element_count]
112};
113
114
115/**
116 * Message type passed from responding service Bob to responding service Alice
117 * to complete a request and allow Alice to compute the result
118 */
119struct ServiceResponseMessage
120{
121 /**
122 * GNUNET message header
123 */
124 struct GNUNET_MessageHeader header;
125
126 /**
127 * how many elements the session input had
128 */
129 uint32_t total_element_count GNUNET_PACKED;
130
131 /**
132 * how many elements were included after the mask was applied
133 * including all multipart msgs.
134 */
135 uint32_t used_element_count GNUNET_PACKED;
136
137 /**
138 * how many elements this individual message delivers
139 */
140 uint32_t contained_element_count GNUNET_PACKED;
141
142 /**
143 * the transaction/session key used to identify a session
144 */
145 struct GNUNET_HashCode key;
146
147 /**
148 * followed by s | s' | k[i][perm]
149 */
150};
151
152GNUNET_NETWORK_STRUCT_END
43 153
44 154
45/** 155/**
@@ -599,15 +709,13 @@ prepare_client_end_notification (void * cls,
599 const struct GNUNET_SCHEDULER_TaskContext * tc) 709 const struct GNUNET_SCHEDULER_TaskContext * tc)
600{ 710{
601 struct ServiceSession * s = cls; 711 struct ServiceSession * s = cls;
602 struct GNUNET_SCALARPRODUCT_client_response * msg; 712 struct ClientResponseMessage * msg;
603 713
604 s->client_notification_task = GNUNET_SCHEDULER_NO_TASK; 714 s->client_notification_task = GNUNET_SCHEDULER_NO_TASK;
605 715
606 msg = GNUNET_new (struct GNUNET_SCALARPRODUCT_client_response); 716 msg = GNUNET_new (struct ClientResponseMessage);
717 msg->header.size = htons (sizeof (struct ClientResponseMessage));
607 msg->header.type = htons (GNUNET_MESSAGE_TYPE_SCALARPRODUCT_RESULT); 718 msg->header.type = htons (GNUNET_MESSAGE_TYPE_SCALARPRODUCT_RESULT);
608 memcpy (&msg->key, &s->session_id, sizeof (struct GNUNET_HashCode));
609 memcpy (&msg->peer, &s->peer, sizeof ( struct GNUNET_PeerIdentity));
610 msg->header.size = htons (sizeof (struct GNUNET_SCALARPRODUCT_client_response));
611 // signal error if not signalized, positive result-range field but zero length. 719 // signal error if not signalized, positive result-range field but zero length.
612 msg->product_length = htonl (0); 720 msg->product_length = htonl (0);
613 msg->status = htonl(s->active); 721 msg->status = htonl(s->active);
@@ -615,23 +723,28 @@ prepare_client_end_notification (void * cls,
615 s->msg = &msg->header; 723 s->msg = &msg->header;
616 724
617 //transmit this message to our client 725 //transmit this message to our client
618 s->client_transmit_handle = 726 s->client_transmit_handle
619 GNUNET_SERVER_notify_transmit_ready (s->client, 727 = GNUNET_SERVER_notify_transmit_ready (s->client,
620 sizeof (struct GNUNET_SCALARPRODUCT_client_response), 728 sizeof (struct ClientResponseMessage),
621 GNUNET_TIME_UNIT_FOREVER_REL, 729 GNUNET_TIME_UNIT_FOREVER_REL,
622 &cb_transfer_message, 730 &cb_transfer_message,
623 s); 731 s);
624 732
625 // if we could not even queue our request, something is wrong 733 // if we could not even queue our request, something is wrong
626 if (NULL == s->client_transmit_handle) { 734 if (NULL == s->client_transmit_handle)
627 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _ ("Could not send message to client (%p)!\n"), s->client); 735 {
736 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
737 _("Could not send message to client (%p)!\n"), s->client);
628 GNUNET_SERVER_client_disconnect(s->client); 738 GNUNET_SERVER_client_disconnect(s->client);
629 free_session_variables(s); 739 free_session_variables(s);
630 GNUNET_CONTAINER_DLL_remove (from_client_head, from_client_tail, s); 740 GNUNET_CONTAINER_DLL_remove (from_client_head, from_client_tail, s);
631 GNUNET_free(s); 741 GNUNET_free(s);
632 } 742 }
633 else 743 else
634 GNUNET_log (GNUNET_ERROR_TYPE_INFO, _ ("Sending session-end notification to client (%p) for session %s\n"), &s->client, GNUNET_h2s (&s->session_id)); 744 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
745 _("Sending session-end notification to client (%p) for session %s\n"),
746 s->client,
747 GNUNET_h2s (&s->session_id));
635} 748}
636 749
637 750
@@ -644,15 +757,17 @@ static void
644prepare_alices_cyrptodata_message (void *cls) 757prepare_alices_cyrptodata_message (void *cls)
645{ 758{
646 struct ServiceSession * s = cls; 759 struct ServiceSession * s = cls;
647 struct GNUNET_SCALARPRODUCT_alices_cryptodata_message * msg; 760 struct AliceCryptodataMessage * msg;
648 struct GNUNET_CRYPTO_PaillierCiphertext * payload; 761 struct GNUNET_CRYPTO_PaillierCiphertext * payload;
649 unsigned int i; 762 unsigned int i;
650 uint32_t msg_length; 763 uint32_t msg_length;
651 gcry_mpi_t a; 764 gcry_mpi_t a;
652 765
653 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _ ("Successfully created new channel to peer (%s)!\n"), GNUNET_i2s (&s->peer)); 766 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
767 _ ("Successfully created new channel to peer (%s)!\n"),
768 GNUNET_i2s (&s->peer));
654 769
655 msg_length = sizeof (struct GNUNET_SCALARPRODUCT_alices_cryptodata_message) 770 msg_length = sizeof (struct AliceCryptodataMessage)
656 +s->used_element_count * sizeof (struct GNUNET_CRYPTO_PaillierCiphertext); 771 +s->used_element_count * sizeof (struct GNUNET_CRYPTO_PaillierCiphertext);
657 772
658 if (GNUNET_SERVER_MAX_MESSAGE_SIZE > msg_length) { 773 if (GNUNET_SERVER_MAX_MESSAGE_SIZE > msg_length) {
@@ -660,9 +775,9 @@ prepare_alices_cyrptodata_message (void *cls)
660 } 775 }
661 else { 776 else {
662 //create a multipart msg, first we calculate a new msg size for the head msg 777 //create a multipart msg, first we calculate a new msg size for the head msg
663 s->transferred_element_count = (GNUNET_SERVER_MAX_MESSAGE_SIZE - 1 - sizeof (struct GNUNET_SCALARPRODUCT_alices_cryptodata_message)) 778 s->transferred_element_count = (GNUNET_SERVER_MAX_MESSAGE_SIZE - 1 - sizeof (struct AliceCryptodataMessage))
664 / sizeof (struct GNUNET_CRYPTO_PaillierCiphertext); 779 / sizeof (struct GNUNET_CRYPTO_PaillierCiphertext);
665 msg_length = sizeof (struct GNUNET_SCALARPRODUCT_alices_cryptodata_message) 780 msg_length = sizeof (struct AliceCryptodataMessage)
666 +s->transferred_element_count * sizeof (struct GNUNET_CRYPTO_PaillierCiphertext); 781 +s->transferred_element_count * sizeof (struct GNUNET_CRYPTO_PaillierCiphertext);
667 } 782 }
668 783
@@ -715,13 +830,13 @@ prepare_bobs_cryptodata_message_multipart (void *cls)
715{ 830{
716 struct ServiceSession * s = cls; 831 struct ServiceSession * s = cls;
717 struct GNUNET_CRYPTO_PaillierCiphertext * payload; 832 struct GNUNET_CRYPTO_PaillierCiphertext * payload;
718 struct GNUNET_SCALARPRODUCT_multipart_message * msg; 833 struct MultipartMessage * msg;
719 unsigned int i; 834 unsigned int i;
720 unsigned int j; 835 unsigned int j;
721 uint32_t msg_length; 836 uint32_t msg_length;
722 uint32_t todo_count; 837 uint32_t todo_count;
723 838
724 msg_length = sizeof (struct GNUNET_SCALARPRODUCT_multipart_message); 839 msg_length = sizeof (struct MultipartMessage);
725 todo_count = s->used_element_count - s->transferred_element_count; 840 todo_count = s->used_element_count - s->transferred_element_count;
726 841
727 if (todo_count > MULTIPART_ELEMENT_CAPACITY / 2) 842 if (todo_count > MULTIPART_ELEMENT_CAPACITY / 2)
@@ -793,13 +908,13 @@ prepare_bobs_cryptodata_message (void *cls,
793 const struct GNUNET_SCHEDULER_TaskContext 908 const struct GNUNET_SCHEDULER_TaskContext
794 * tc) 909 * tc)
795{ 910{
796 struct ServiceSession * s = (struct ServiceSession *) cls; 911 struct ServiceSession * s = cls;
797 struct GNUNET_SCALARPRODUCT_service_response * msg; 912 struct ServiceResponseMessage * msg;
798 uint32_t msg_length = 0; 913 uint32_t msg_length = 0;
799 struct GNUNET_CRYPTO_PaillierCiphertext * payload; 914 struct GNUNET_CRYPTO_PaillierCiphertext * payload;
800 int i; 915 int i;
801 916
802 msg_length = sizeof (struct GNUNET_SCALARPRODUCT_service_response) 917 msg_length = sizeof (struct ServiceResponseMessage)
803 + 2 * sizeof (struct GNUNET_CRYPTO_PaillierCiphertext); // s, stick 918 + 2 * sizeof (struct GNUNET_CRYPTO_PaillierCiphertext); // s, stick
804 919
805 if (GNUNET_SERVER_MAX_MESSAGE_SIZE > 920 if (GNUNET_SERVER_MAX_MESSAGE_SIZE >
@@ -885,7 +1000,7 @@ prepare_bobs_cryptodata_message (void *cls,
885 * @param request the requesting session + bob's requesting peer 1000 * @param request the requesting session + bob's requesting peer
886 */ 1001 */
887static void 1002static void
888compute_service_response (struct ServiceSession * session) 1003compute_service_response (struct ServiceSession *session)
889{ 1004{
890 int i; 1005 int i;
891 unsigned int * p; 1006 unsigned int * p;
@@ -1022,13 +1137,15 @@ cb_insert_element_sorted (void *cls,
1022 struct ServiceSession * s = (struct ServiceSession*) cls; 1137 struct ServiceSession * s = (struct ServiceSession*) cls;
1023 struct SortedValue * e = GNUNET_new (struct SortedValue); 1138 struct SortedValue * e = GNUNET_new (struct SortedValue);
1024 struct SortedValue * o = s->a_head; 1139 struct SortedValue * o = s->a_head;
1140 int64_t val;
1025 1141
1026 e->elem = value; 1142 e->elem = value;
1027 e->val = gcry_mpi_new (0); 1143 e->val = gcry_mpi_new (0);
1028 if (0 > e->elem->value) 1144 val = (int64_t) GNUNET_ntohll (e->elem->value);
1029 gcry_mpi_sub_ui (e->val, e->val, abs (e->elem->value)); 1145 if (0 > val)
1146 gcry_mpi_sub_ui (e->val, e->val, - val);
1030 else 1147 else
1031 gcry_mpi_add_ui (e->val, e->val, e->elem->value); 1148 gcry_mpi_add_ui (e->val, e->val, val);
1032 1149
1033 // insert as first element with the lowest key 1150 // insert as first element with the lowest key
1034 if (NULL == s->a_head 1151 if (NULL == s->a_head
@@ -1208,7 +1325,7 @@ prepare_client_response (void *cls,
1208 const struct GNUNET_SCHEDULER_TaskContext *tc) 1325 const struct GNUNET_SCHEDULER_TaskContext *tc)
1209{ 1326{
1210 struct ServiceSession * s = cls; 1327 struct ServiceSession * s = cls;
1211 struct GNUNET_SCALARPRODUCT_client_response * msg; 1328 struct ClientResponseMessage *msg;
1212 unsigned char * product_exported = NULL; 1329 unsigned char * product_exported = NULL;
1213 size_t product_length = 0; 1330 size_t product_length = 0;
1214 uint32_t msg_length = 0; 1331 uint32_t msg_length = 0;
@@ -1250,10 +1367,8 @@ prepare_client_response (void *cls,
1250 gcry_mpi_release (value); 1367 gcry_mpi_release (value);
1251 } 1368 }
1252 1369
1253 msg_length = sizeof (struct GNUNET_SCALARPRODUCT_client_response) +product_length; 1370 msg_length = sizeof (struct ClientResponseMessage) + product_length;
1254 msg = GNUNET_malloc (msg_length); 1371 msg = GNUNET_malloc (msg_length);
1255 msg->key = s->session_id;
1256 msg->peer = s->peer;
1257 if (product_exported != NULL) { 1372 if (product_exported != NULL) {
1258 memcpy (&msg[1], product_exported, product_length); 1373 memcpy (&msg[1], product_exported, product_length);
1259 GNUNET_free (product_exported); 1374 GNUNET_free (product_exported);
@@ -1285,27 +1400,31 @@ prepare_client_response (void *cls,
1285static void 1400static void
1286prepare_alices_computation_request (struct ServiceSession * s) 1401prepare_alices_computation_request (struct ServiceSession * s)
1287{ 1402{
1288 struct GNUNET_SCALARPRODUCT_service_request * msg; 1403 struct ServiceRequestMessage * msg;
1289 1404
1290 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _ ("Successfully created new channel to peer (%s)!\n"), GNUNET_i2s (&s->peer)); 1405 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1406 _("Successfully created new channel to peer (%s)!\n"),
1407 GNUNET_i2s (&s->peer));
1291 1408
1292 msg = GNUNET_new (struct GNUNET_SCALARPRODUCT_service_request); 1409 msg = GNUNET_new (struct ServiceRequestMessage);
1293 msg->header.type = htons (GNUNET_MESSAGE_TYPE_SCALARPRODUCT_ALICE_CRYPTODATA); 1410 msg->header.type = htons (GNUNET_MESSAGE_TYPE_SCALARPRODUCT_ALICE_CRYPTODATA);
1294 memcpy (&msg->session_id, &s->session_id, sizeof (struct GNUNET_HashCode)); 1411 memcpy (&msg->session_id, &s->session_id, sizeof (struct GNUNET_HashCode));
1295 msg->header.size = htons (sizeof (struct GNUNET_SCALARPRODUCT_service_request)); 1412 msg->header.size = htons (sizeof (struct ServiceRequestMessage));
1296 1413
1297 s->msg = (struct GNUNET_MessageHeader *) msg; 1414 s->msg = (struct GNUNET_MessageHeader *) msg;
1298 GNUNET_log (GNUNET_ERROR_TYPE_INFO, _ ("Transmitting service request.\n")); 1415 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1416 _("Transmitting service request.\n"));
1299 1417
1300 //transmit via cadet messaging 1418 //transmit via cadet messaging
1301 s->service_transmit_handle = GNUNET_CADET_notify_transmit_ready (s->channel, GNUNET_YES, 1419 s->service_transmit_handle
1302 GNUNET_TIME_UNIT_FOREVER_REL, 1420 = GNUNET_CADET_notify_transmit_ready (s->channel, GNUNET_YES,
1303 sizeof (struct GNUNET_SCALARPRODUCT_service_request), 1421 GNUNET_TIME_UNIT_FOREVER_REL,
1304 &cb_transfer_message, 1422 sizeof (struct ServiceRequestMessage),
1305 s); 1423 &cb_transfer_message,
1424 s);
1306 if (!s->service_transmit_handle) { 1425 if (!s->service_transmit_handle) {
1307 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1426 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1308 _ ("Could not send message to channel!\n")); 1427 _("Could not send message to channel!\n"));
1309 GNUNET_free (msg); 1428 GNUNET_free (msg);
1310 s->msg = NULL; 1429 s->msg = NULL;
1311 s->active = GNUNET_SYSERR; 1430 s->active = GNUNET_SYSERR;
@@ -1330,14 +1449,14 @@ static void
1330prepare_alices_cyrptodata_message_multipart (void *cls) 1449prepare_alices_cyrptodata_message_multipart (void *cls)
1331{ 1450{
1332 struct ServiceSession * s = cls; 1451 struct ServiceSession * s = cls;
1333 struct GNUNET_SCALARPRODUCT_multipart_message * msg; 1452 struct MultipartMessage * msg;
1334 struct GNUNET_CRYPTO_PaillierCiphertext * payload; 1453 struct GNUNET_CRYPTO_PaillierCiphertext * payload;
1335 unsigned int i; 1454 unsigned int i;
1336 uint32_t msg_length; 1455 uint32_t msg_length;
1337 uint32_t todo_count; 1456 uint32_t todo_count;
1338 gcry_mpi_t a; 1457 gcry_mpi_t a;
1339 1458
1340 msg_length = sizeof (struct GNUNET_SCALARPRODUCT_multipart_message); 1459 msg_length = sizeof (struct MultipartMessage);
1341 todo_count = s->used_element_count - s->transferred_element_count; 1460 todo_count = s->used_element_count - s->transferred_element_count;
1342 1461
1343 if (todo_count > MULTIPART_ELEMENT_CAPACITY) 1462 if (todo_count > MULTIPART_ELEMENT_CAPACITY)
@@ -1472,7 +1591,7 @@ handle_client_message_multipart (void *cls,
1472 struct GNUNET_SERVER_Client *client, 1591 struct GNUNET_SERVER_Client *client,
1473 const struct GNUNET_MessageHeader *message) 1592 const struct GNUNET_MessageHeader *message)
1474{ 1593{
1475 const struct GNUNET_SCALARPRODUCT_computation_message_multipart * msg = (const struct GNUNET_SCALARPRODUCT_computation_message_multipart *) message; 1594 const struct ComputationMultipartMessage * msg = (const struct ComputationMultipartMessage *) message;
1476 struct ServiceSession * s; 1595 struct ServiceSession * s;
1477 uint32_t contained_count; 1596 uint32_t contained_count;
1478 struct GNUNET_SCALARPRODUCT_Element * elements; 1597 struct GNUNET_SCALARPRODUCT_Element * elements;
@@ -1488,8 +1607,9 @@ handle_client_message_multipart (void *cls,
1488 contained_count = ntohl (msg->element_count_contained); 1607 contained_count = ntohl (msg->element_count_contained);
1489 1608
1490 //sanity check: is the message as long as the message_count fields suggests? 1609 //sanity check: is the message as long as the message_count fields suggests?
1491 if ((ntohs (msg->header.size) != (sizeof (struct GNUNET_SCALARPRODUCT_computation_message_multipart) +contained_count * sizeof (struct GNUNET_SCALARPRODUCT_Element))) 1610 if ((ntohs (msg->header.size) != (sizeof (struct ComputationMultipartMessage) +contained_count * sizeof (struct GNUNET_SCALARPRODUCT_Element)))
1492 || (0 == contained_count) || (s->total < s->transferred_element_count + contained_count)) { 1611 || (0 == contained_count) || (s->total < s->transferred_element_count + contained_count))
1612 {
1493 GNUNET_break_op (0); 1613 GNUNET_break_op (0);
1494 GNUNET_SERVER_receive_done (client, GNUNET_OK); 1614 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1495 return; 1615 return;
@@ -1501,7 +1621,7 @@ handle_client_message_multipart (void *cls,
1501 struct GNUNET_SET_Element set_elem; 1621 struct GNUNET_SET_Element set_elem;
1502 struct GNUNET_SCALARPRODUCT_Element * elem; 1622 struct GNUNET_SCALARPRODUCT_Element * elem;
1503 1623
1504 if (0 == ntohl (elements[i].value)) 1624 if (0 == GNUNET_ntohll (elements[i].value))
1505 continue; 1625 continue;
1506 1626
1507 elem = GNUNET_new (struct GNUNET_SCALARPRODUCT_Element); 1627 elem = GNUNET_new (struct GNUNET_SCALARPRODUCT_Element);
@@ -1549,7 +1669,7 @@ handle_client_message (void *cls,
1549 struct GNUNET_SERVER_Client *client, 1669 struct GNUNET_SERVER_Client *client,
1550 const struct GNUNET_MessageHeader *message) 1670 const struct GNUNET_MessageHeader *message)
1551{ 1671{
1552 const struct GNUNET_SCALARPRODUCT_computation_message * msg = (const struct GNUNET_SCALARPRODUCT_computation_message *) message; 1672 const struct ComputationMessage * msg = (const struct ComputationMessage *) message;
1553 struct ServiceSession * s; 1673 struct ServiceSession * s;
1554 uint32_t contained_count; 1674 uint32_t contained_count;
1555 uint32_t total_count; 1675 uint32_t total_count;
@@ -1577,8 +1697,10 @@ handle_client_message (void *cls,
1577 } 1697 }
1578 1698
1579 //sanity check: is the message as long as the message_count fields suggests? 1699 //sanity check: is the message as long as the message_count fields suggests?
1580 if ((ntohs (msg->header.size) != (sizeof (struct GNUNET_SCALARPRODUCT_computation_message) +contained_count * sizeof (struct GNUNET_SCALARPRODUCT_Element))) 1700 if ((ntohs (msg->header.size) !=
1581 || (0 == total_count)) { 1701 (sizeof (struct ComputationMessage) + contained_count * sizeof (struct GNUNET_SCALARPRODUCT_Element)))
1702 || (0 == total_count))
1703 {
1582 GNUNET_break_op (0); 1704 GNUNET_break_op (0);
1583 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 1705 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1584 return; 1706 return;
@@ -1611,7 +1733,7 @@ handle_client_message (void *cls,
1611 struct GNUNET_SET_Element set_elem; 1733 struct GNUNET_SET_Element set_elem;
1612 struct GNUNET_SCALARPRODUCT_Element * elem; 1734 struct GNUNET_SCALARPRODUCT_Element * elem;
1613 1735
1614 if (0 == ntohl (elements[i].value)) 1736 if (0 == GNUNET_ntohll (elements[i].value))
1615 continue; 1737 continue;
1616 1738
1617 elem = GNUNET_new (struct GNUNET_SCALARPRODUCT_Element); 1739 elem = GNUNET_new (struct GNUNET_SCALARPRODUCT_Element);
@@ -1862,7 +1984,7 @@ handle_alices_cyrptodata_message_multipart (void *cls,
1862 const struct GNUNET_MessageHeader * message) 1984 const struct GNUNET_MessageHeader * message)
1863{ 1985{
1864 struct ServiceSession * s; 1986 struct ServiceSession * s;
1865 const struct GNUNET_SCALARPRODUCT_multipart_message * msg = (const struct GNUNET_SCALARPRODUCT_multipart_message *) message; 1987 const struct MultipartMessage * msg = (const struct MultipartMessage *) message;
1866 struct GNUNET_CRYPTO_PaillierCiphertext *payload; 1988 struct GNUNET_CRYPTO_PaillierCiphertext *payload;
1867 uint32_t contained_elements; 1989 uint32_t contained_elements;
1868 uint32_t msg_length; 1990 uint32_t msg_length;
@@ -1875,11 +1997,11 @@ handle_alices_cyrptodata_message_multipart (void *cls,
1875 goto except; 1997 goto except;
1876 } 1998 }
1877 // shorter than minimum? 1999 // shorter than minimum?
1878 if (ntohs (msg->header.size) <= sizeof (struct GNUNET_SCALARPRODUCT_multipart_message)) { 2000 if (ntohs (msg->header.size) <= sizeof (struct MultipartMessage)) {
1879 goto except; 2001 goto except;
1880 } 2002 }
1881 contained_elements = ntohl (msg->contained_element_count); 2003 contained_elements = ntohl (msg->contained_element_count);
1882 msg_length = sizeof (struct GNUNET_SCALARPRODUCT_multipart_message) 2004 msg_length = sizeof (struct MultipartMessage)
1883 +contained_elements * sizeof (struct GNUNET_CRYPTO_PaillierCiphertext); 2005 +contained_elements * sizeof (struct GNUNET_CRYPTO_PaillierCiphertext);
1884 //sanity check 2006 //sanity check
1885 if ((ntohs (msg->header.size) != msg_length) 2007 if ((ntohs (msg->header.size) != msg_length)
@@ -1946,7 +2068,7 @@ handle_alices_cyrptodata_message (void *cls,
1946 const struct GNUNET_MessageHeader * message) 2068 const struct GNUNET_MessageHeader * message)
1947{ 2069{
1948 struct ServiceSession * s; 2070 struct ServiceSession * s;
1949 const struct GNUNET_SCALARPRODUCT_alices_cryptodata_message * msg = (const struct GNUNET_SCALARPRODUCT_alices_cryptodata_message *) message; 2071 const struct AliceCryptodataMessage * msg = (const struct AliceCryptodataMessage *) message;
1950 struct GNUNET_CRYPTO_PaillierCiphertext *payload; 2072 struct GNUNET_CRYPTO_PaillierCiphertext *payload;
1951 uint32_t contained_elements = 0; 2073 uint32_t contained_elements = 0;
1952 uint32_t msg_length; 2074 uint32_t msg_length;
@@ -1966,12 +2088,13 @@ handle_alices_cyrptodata_message (void *cls,
1966 } 2088 }
1967 2089
1968 // shorter than minimum? 2090 // shorter than minimum?
1969 if (ntohs (msg->header.size) <= sizeof (struct GNUNET_SCALARPRODUCT_multipart_message)) { 2091 if (ntohs (msg->header.size) <= sizeof (struct MultipartMessage))
2092 {
1970 goto invalid_msg; 2093 goto invalid_msg;
1971 } 2094 }
1972 2095
1973 contained_elements = ntohl (msg->contained_element_count); 2096 contained_elements = ntohl (msg->contained_element_count);
1974 msg_length = sizeof (struct GNUNET_SCALARPRODUCT_alices_cryptodata_message) 2097 msg_length = sizeof (struct AliceCryptodataMessage)
1975 +contained_elements * sizeof (struct GNUNET_CRYPTO_PaillierCiphertext); 2098 +contained_elements * sizeof (struct GNUNET_CRYPTO_PaillierCiphertext);
1976 2099
1977 //sanity check: is the message as long as the message_count fields suggests? 2100 //sanity check: is the message as long as the message_count fields suggests?
@@ -2039,7 +2162,7 @@ handle_alices_computation_request (void *cls,
2039{ 2162{
2040 struct ServiceSession * s; 2163 struct ServiceSession * s;
2041 struct ServiceSession * client_session; 2164 struct ServiceSession * client_session;
2042 const struct GNUNET_SCALARPRODUCT_service_request * msg = (const struct GNUNET_SCALARPRODUCT_service_request *) message; 2165 const struct ServiceRequestMessage * msg = (const struct ServiceRequestMessage *) message;
2043 2166
2044 s = (struct ServiceSession *) * channel_ctx; 2167 s = (struct ServiceSession *) * channel_ctx;
2045 if ((BOB != s->role) || (s->total != 0)) { 2168 if ((BOB != s->role) || (s->total != 0)) {
@@ -2053,7 +2176,7 @@ handle_alices_computation_request (void *cls,
2053 return GNUNET_SYSERR; 2176 return GNUNET_SYSERR;
2054 } 2177 }
2055 // shorter than expected? 2178 // shorter than expected?
2056 if (ntohs (msg->header.size) != sizeof (struct GNUNET_SCALARPRODUCT_service_request)) { 2179 if (ntohs (msg->header.size) != sizeof (struct ServiceRequestMessage)) {
2057 GNUNET_free (s); 2180 GNUNET_free (s);
2058 GNUNET_break_op (0); 2181 GNUNET_break_op (0);
2059 return GNUNET_SYSERR; 2182 return GNUNET_SYSERR;
@@ -2155,7 +2278,7 @@ handle_bobs_cryptodata_multipart (void *cls,
2155 const struct GNUNET_MessageHeader * message) 2278 const struct GNUNET_MessageHeader * message)
2156{ 2279{
2157 struct ServiceSession * s; 2280 struct ServiceSession * s;
2158 const struct GNUNET_SCALARPRODUCT_multipart_message * msg = (const struct GNUNET_SCALARPRODUCT_multipart_message *) message; 2281 const struct MultipartMessage * msg = (const struct MultipartMessage *) message;
2159 struct GNUNET_CRYPTO_PaillierCiphertext * payload; 2282 struct GNUNET_CRYPTO_PaillierCiphertext * payload;
2160 size_t i; 2283 size_t i;
2161 uint32_t contained = 0; 2284 uint32_t contained = 0;
@@ -2169,14 +2292,14 @@ handle_bobs_cryptodata_multipart (void *cls,
2169 goto invalid_msg; 2292 goto invalid_msg;
2170 } 2293 }
2171 msg_size = ntohs (msg->header.size); 2294 msg_size = ntohs (msg->header.size);
2172 required_size = sizeof (struct GNUNET_SCALARPRODUCT_multipart_message) 2295 required_size = sizeof (struct MultipartMessage)
2173 + 2 * sizeof (struct GNUNET_CRYPTO_PaillierCiphertext); 2296 + 2 * sizeof (struct GNUNET_CRYPTO_PaillierCiphertext);
2174 // shorter than minimum? 2297 // shorter than minimum?
2175 if (required_size > msg_size) { 2298 if (required_size > msg_size) {
2176 goto invalid_msg; 2299 goto invalid_msg;
2177 } 2300 }
2178 contained = ntohl (msg->contained_element_count); 2301 contained = ntohl (msg->contained_element_count);
2179 required_size = sizeof (struct GNUNET_SCALARPRODUCT_multipart_message) 2302 required_size = sizeof (struct MultipartMessage)
2180 + 2 * contained * sizeof (struct GNUNET_CRYPTO_PaillierCiphertext); 2303 + 2 * contained * sizeof (struct GNUNET_CRYPTO_PaillierCiphertext);
2181 //sanity check: is the message as long as the message_count fields suggests? 2304 //sanity check: is the message as long as the message_count fields suggests?
2182 if ((required_size != msg_size) || (s->used_element_count < s->transferred_element_count + contained)) { 2305 if ((required_size != msg_size) || (s->used_element_count < s->transferred_element_count + contained)) {
@@ -2239,12 +2362,12 @@ invalid_msg:
2239 */ 2362 */
2240static int 2363static int
2241handle_bobs_cryptodata_message (void *cls, 2364handle_bobs_cryptodata_message (void *cls,
2242 struct GNUNET_CADET_Channel * channel, 2365 struct GNUNET_CADET_Channel *channel,
2243 void **channel_ctx, 2366 void **channel_ctx,
2244 const struct GNUNET_MessageHeader * message) 2367 const struct GNUNET_MessageHeader *message)
2245{ 2368{
2246 struct ServiceSession * s; 2369 struct ServiceSession * s;
2247 const struct GNUNET_SCALARPRODUCT_service_response * msg = (const struct GNUNET_SCALARPRODUCT_service_response *) message; 2370 const struct ServiceResponseMessage *msg = (const struct ServiceResponseMessage *) message;
2248 struct GNUNET_CRYPTO_PaillierCiphertext * payload; 2371 struct GNUNET_CRYPTO_PaillierCiphertext * payload;
2249 size_t i; 2372 size_t i;
2250 uint32_t contained = 0; 2373 uint32_t contained = 0;
@@ -2261,13 +2384,13 @@ handle_bobs_cryptodata_message (void *cls,
2261 } 2384 }
2262 //we need at least a full message without elements attached 2385 //we need at least a full message without elements attached
2263 msg_size = ntohs (msg->header.size); 2386 msg_size = ntohs (msg->header.size);
2264 required_size = sizeof (struct GNUNET_SCALARPRODUCT_service_response) + 2 * sizeof (struct GNUNET_CRYPTO_PaillierCiphertext); 2387 required_size = sizeof (struct ServiceResponseMessage) + 2 * sizeof (struct GNUNET_CRYPTO_PaillierCiphertext);
2265 2388
2266 if (required_size > msg_size) { 2389 if (required_size > msg_size) {
2267 goto invalid_msg; 2390 goto invalid_msg;
2268 } 2391 }
2269 contained = ntohl (msg->contained_element_count); 2392 contained = ntohl (msg->contained_element_count);
2270 required_size = sizeof (struct GNUNET_SCALARPRODUCT_service_response) 2393 required_size = sizeof (struct ServiceResponseMessage)
2271 + 2 * contained * sizeof (struct GNUNET_CRYPTO_PaillierCiphertext) 2394 + 2 * contained * sizeof (struct GNUNET_CRYPTO_PaillierCiphertext)
2272 + 2 * sizeof (struct GNUNET_CRYPTO_PaillierCiphertext); 2395 + 2 * sizeof (struct GNUNET_CRYPTO_PaillierCiphertext);
2273 //sanity check: is the message as long as the message_count fields suggests? 2396 //sanity check: is the message as long as the message_count fields suggests?
diff --git a/src/scalarproduct/scalarproduct.h b/src/scalarproduct/scalarproduct.h
index 6837b3abc..4bafb18fb 100644
--- a/src/scalarproduct/scalarproduct.h
+++ b/src/scalarproduct/scalarproduct.h
@@ -33,14 +33,8 @@
33extern "C" 33extern "C"
34{ 34{
35#endif 35#endif
36///////////////////////////////////////////////////////////////////////////////
37// Defines
38///////////////////////////////////////////////////////////////////////////////
39 36
40/** 37GNUNET_NETWORK_STRUCT_BEGIN
41 * Maximum count of elements we can put into a multipart message
42 */
43#define MULTIPART_ELEMENT_CAPACITY ((GNUNET_SERVER_MAX_MESSAGE_SIZE - 1 - sizeof (struct GNUNET_SCALARPRODUCT_multipart_message)) / sizeof (struct GNUNET_CRYPTO_PaillierCiphertext))
44 38
45/** 39/**
46 * Log an error message at log-level 'level' that indicates 40 * Log an error message at log-level 'level' that indicates
@@ -49,15 +43,12 @@ extern "C"
49 */ 43 */
50#define LOG_GCRY(level, cmd, rc) do { LOG(level, _("`%s' failed at %s:%d with error: %s\n"), cmd, __FILE__, __LINE__, gcry_strerror(rc)); } while(0) 44#define LOG_GCRY(level, cmd, rc) do { LOG(level, _("`%s' failed at %s:%d with error: %s\n"), cmd, __FILE__, __LINE__, gcry_strerror(rc)); } while(0)
51 45
52///////////////////////////////////////////////////////////////////////////////
53// Scalar Product Message Types
54///////////////////////////////////////////////////////////////////////////////
55 46
56/** 47/**
57 * Message type passed from client to service 48 * Message type passed from client to service
58 * to initiate a request or responder role 49 * to initiate a request or responder role
59 */ 50 */
60struct GNUNET_SCALARPRODUCT_computation_message 51struct ComputationMessage
61{ 52{
62 /** 53 /**
63 * GNUNET message header 54 * GNUNET message header
@@ -68,13 +59,18 @@ struct GNUNET_SCALARPRODUCT_computation_message
68 * how many elements the vector in payload contains 59 * how many elements the vector in payload contains
69 */ 60 */
70 uint32_t element_count_total GNUNET_PACKED; 61 uint32_t element_count_total GNUNET_PACKED;
71 62
72 /** 63 /**
73 * contained elements the vector in payload contains 64 * contained elements the vector in payload contains
74 */ 65 */
75 uint32_t element_count_contained GNUNET_PACKED; 66 uint32_t element_count_contained GNUNET_PACKED;
76 67
77 /** 68 /**
69 * Always zero.
70 */
71 uint32_t reserved GNUNET_PACKED;
72
73 /**
78 * the transaction/session key used to identify a session 74 * the transaction/session key used to identify a session
79 */ 75 */
80 struct GNUNET_HashCode session_key; 76 struct GNUNET_HashCode session_key;
@@ -89,16 +85,17 @@ struct GNUNET_SCALARPRODUCT_computation_message
89 */ 85 */
90}; 86};
91 87
88
92/** 89/**
93 * multipart messages following GNUNET_SCALARPRODUCT_client_request 90 * multipart messages following `struct ComputationMessage`
94 */ 91 */
95struct GNUNET_SCALARPRODUCT_computation_message_multipart 92struct ComputationMultipartMessage
96{ 93{
97 /** 94 /**
98 * GNUNET message header 95 * GNUNET message header
99 */ 96 */
100 struct GNUNET_MessageHeader header; 97 struct GNUNET_MessageHeader header;
101 98
102 /** 99 /**
103 * contained elements the vector in payload contains 100 * contained elements the vector in payload contains
104 */ 101 */
@@ -111,105 +108,10 @@ struct GNUNET_SCALARPRODUCT_computation_message_multipart
111 108
112 109
113/** 110/**
114 * Message type passed from requesting service Alice to responding service Bob
115 * to initiate a request and make bob participate in our protocol
116 */
117struct GNUNET_SCALARPRODUCT_service_request {
118 /**
119 * GNUNET message header
120 */
121 struct GNUNET_MessageHeader header;
122
123 /**
124 * the transaction/session key used to identify a session
125 */
126 struct GNUNET_HashCode session_id;
127
128 /**
129 * Alice's public key
130 */
131 struct GNUNET_CRYPTO_PaillierPublicKey public_key;
132
133};
134
135
136/**
137 * Message type passed from requesting service Alice to responding service Bob
138 * to initiate a request and make bob participate in our protocol
139 */
140struct GNUNET_SCALARPRODUCT_alices_cryptodata_message {
141 /**
142 * GNUNET message header
143 */
144 struct GNUNET_MessageHeader header;
145
146 /**
147 * how many elements we appended to this message
148 */
149 uint32_t contained_element_count GNUNET_PACKED;
150
151 /**
152 * struct GNUNET_CRYPTO_PaillierCiphertext[contained_element_count]
153 */
154};
155
156/**
157 * Multipart Message type passed between to supply additional elements for the peer
158 */
159struct GNUNET_SCALARPRODUCT_multipart_message {
160 /**
161 * GNUNET message header
162 */
163 struct GNUNET_MessageHeader header;
164
165 /**
166 * how many elements we supply within this message
167 */
168 uint32_t contained_element_count GNUNET_PACKED;
169
170 // struct GNUNET_CRYPTO_PaillierCiphertext[multipart_element_count]
171};
172
173/**
174 * Message type passed from responding service Bob to responding service Alice
175 * to complete a request and allow Alice to compute the result
176 */
177struct GNUNET_SCALARPRODUCT_service_response {
178 /**
179 * GNUNET message header
180 */
181 struct GNUNET_MessageHeader header;
182
183 /**
184 * how many elements the session input had
185 */
186 uint32_t total_element_count GNUNET_PACKED;
187
188 /**
189 * how many elements were included after the mask was applied including all multipart msgs.
190 */
191 uint32_t used_element_count GNUNET_PACKED;
192
193 /**
194 * how many elements this individual message delivers
195 */
196 uint32_t contained_element_count GNUNET_PACKED;
197
198 /**
199 * the transaction/session key used to identify a session
200 */
201 struct GNUNET_HashCode key;
202
203 /**
204 * followed by s | s' | k[i][perm]
205 */
206};
207
208/**
209 * Message type passed from service client 111 * Message type passed from service client
210 * to finalize a session as requester or responder 112 * to finalize a session as requester or responder
211 */ 113 */
212struct GNUNET_SCALARPRODUCT_client_response 114struct ClientResponseMessage
213{ 115{
214 /** 116 /**
215 * GNUNET message header 117 * GNUNET message header
@@ -222,30 +124,22 @@ struct GNUNET_SCALARPRODUCT_client_response
222 uint32_t product_length GNUNET_PACKED; 124 uint32_t product_length GNUNET_PACKED;
223 125
224 /** 126 /**
225 * the transaction/session key used to identify a session
226 */
227 struct GNUNET_HashCode key;
228
229 /**
230 * the identity of a remote peer we want to communicate with
231 */
232 struct GNUNET_PeerIdentity peer;
233
234 /**
235 * status information about the outcome of this session 127 * status information about the outcome of this session
236 */ 128 */
237 int32_t status; 129 int32_t status GNUNET_PACKED;
238 130
239 /** 131 /**
240 * Workaround for libgcrypt: -1 if negative, 0 if zero, else 1 132 * Workaround for libgcrypt: -1 if negative, 0 if zero, else 1
241 */ 133 */
242 int8_t range; 134 int32_t range GNUNET_PACKED;
243 135
244 /** 136 /**
245 * followed by product of length product_length (or nothing) 137 * followed by product of length product_length (or nothing)
246 */ 138 */
247}; 139};
248 140
141GNUNET_NETWORK_STRUCT_END
142
249#ifdef __cplusplus 143#ifdef __cplusplus
250} 144}
251#endif 145#endif
diff --git a/src/scalarproduct/scalarproduct_api.c b/src/scalarproduct/scalarproduct_api.c
index 3b92af579..ea62027ab 100644
--- a/src/scalarproduct/scalarproduct_api.c
+++ b/src/scalarproduct/scalarproduct_api.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 (C) 2013 Christian Grothoff (and other contributing authors) 3 (C) 2013, 2014 Christian Grothoff (and other contributing authors)
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published 6 it under the terms of the GNU General Public License as published
@@ -23,7 +23,7 @@
23 * @brief API for the scalarproduct 23 * @brief API for the scalarproduct
24 * @author Christian Fuchs 24 * @author Christian Fuchs
25 * @author Gaurav Kukreja 25 * @author Gaurav Kukreja
26 * 26 * @author Christian Grothoff
27 */ 27 */
28#include "platform.h" 28#include "platform.h"
29#include "gnunet_util_lib.h" 29#include "gnunet_util_lib.h"
@@ -34,16 +34,19 @@
34 34
35#define LOG(kind,...) GNUNET_log_from (kind, "scalarproduct-api",__VA_ARGS__) 35#define LOG(kind,...) GNUNET_log_from (kind, "scalarproduct-api",__VA_ARGS__)
36 36
37/**************************************************************
38 *** Datatype Declarations **********
39 **************************************************************/
40 37
41/** 38/**
42 * the abstraction function for our internal callback 39 * The abstraction function for our internal callback
40 *
41 * @param h computation handle
42 * @param msg response we got, NULL on errors
43 * @param status processing status code
43 */ 44 */
44typedef void (*GNUNET_SCALARPRODUCT_ResponseMessageHandler) (void *cls, 45typedef void
45 const struct GNUNET_MessageHeader *msg, 46(*GNUNET_SCALARPRODUCT_ResponseMessageHandler) (struct GNUNET_SCALARPRODUCT_ComputationHandle *h,
46 enum GNUNET_SCALARPRODUCT_ResponseStatus status); 47 const struct ClientResponseMessage *msg,
48 enum GNUNET_SCALARPRODUCT_ResponseStatus status);
49
47 50
48/** 51/**
49 * A handle returned for each computation 52 * A handle returned for each computation
@@ -61,11 +64,6 @@ struct GNUNET_SCALARPRODUCT_ComputationHandle
61 struct GNUNET_CLIENT_Connection *client; 64 struct GNUNET_CLIENT_Connection *client;
62 65
63 /** 66 /**
64 * Handle for statistics.
65 */
66 struct GNUNET_STATISTICS_Handle *stats;
67
68 /**
69 * The shared session key identifying this computation 67 * The shared session key identifying this computation
70 */ 68 */
71 struct GNUNET_HashCode key; 69 struct GNUNET_HashCode key;
@@ -76,31 +74,26 @@ struct GNUNET_SCALARPRODUCT_ComputationHandle
76 struct GNUNET_CLIENT_TransmitHandle *th; 74 struct GNUNET_CLIENT_TransmitHandle *th;
77 75
78 /** 76 /**
79 * count of all elements we offer for computation 77 * count of all @e elements we offer for computation
80 */ 78 */
81 uint32_t element_count_total; 79 uint32_t element_count_total;
82 80
83 /** 81 /**
84 * count of the transfered elements we offer for computation 82 * count of the transfered @e elements we offer for computation
85 */ 83 */
86 uint32_t element_count_transfered; 84 uint32_t element_count_transfered;
87 85
88 /** 86 /**
89 * the client's elements which 87 * the client's elements which
90 */ 88 */
91 struct GNUNET_SCALARPRODUCT_Element * elements; 89 struct GNUNET_SCALARPRODUCT_Element *elements;
92 90
93 /** 91 /**
94 * Message to be sent to the scalarproduct service 92 * Message to be sent to the scalarproduct service
95 */ 93 */
96 void * msg; 94 struct GNUNET_MessageHeader *msg;
97 95
98 /** 96 /**
99 * The client's msg handler callback
100 */
101 union
102 {
103 /**
104 * Function to call after transmission of the request (Bob). 97 * Function to call after transmission of the request (Bob).
105 */ 98 */
106 GNUNET_SCALARPRODUCT_ContinuationWithStatus cont_status; 99 GNUNET_SCALARPRODUCT_ContinuationWithStatus cont_status;
@@ -109,101 +102,99 @@ struct GNUNET_SCALARPRODUCT_ComputationHandle
109 * Function to call after transmission of the request (Alice). 102 * Function to call after transmission of the request (Alice).
110 */ 103 */
111 GNUNET_SCALARPRODUCT_DatumProcessor cont_datum; 104 GNUNET_SCALARPRODUCT_DatumProcessor cont_datum;
112 };
113 105
114 /** 106 /**
115 * Closure for 'cont'. 107 * Closure for @e cont_status or @e cont_datum.
116 */ 108 */
117 void *cont_cls; 109 void *cont_cls;
118 110
119 /** 111 /**
120 * API internal callback for results and failures to be forwarded to the client 112 * API internal callback for results and failures to be forwarded to
113 * the client.
121 */ 114 */
122 GNUNET_SCALARPRODUCT_ResponseMessageHandler response_proc; 115 GNUNET_SCALARPRODUCT_ResponseMessageHandler response_proc;
123
124 /**
125 *
126 */
127 GNUNET_SCHEDULER_TaskIdentifier cont_multipart;
128};
129
130/**************************************************************
131 *** Forward Function Declarations **********
132 **************************************************************/
133
134void
135GNUNET_SCALARPRODUCT_cancel (struct GNUNET_SCALARPRODUCT_ComputationHandle * h);
136 116
137static size_t do_send_message (void *cls, size_t size, void *buf); 117};
138/**************************************************************
139 *** Static Function Declarations **********
140 **************************************************************/
141 118
142 119
143/** 120/**
144 * Handles the STATUS received from the service for a response, does not contain a payload 121 * Handles the STATUS received from the service for a response, does
122 * not contain a payload.
145 * 123 *
146 * @param cls our Handle 124 * @param h our Handle
147 * @param msg Pointer to the response received 125 * @param msg Pointer to the response received
148 * @param status the condition the request was terminated with (eg: disconnect) 126 * @param status the condition the request was terminated with (eg: disconnect)
149 */ 127 */
150static void 128static void
151process_status_message (void *cls, 129process_status_message (struct GNUNET_SCALARPRODUCT_ComputationHandle *h,
152 const struct GNUNET_MessageHeader *msg, 130 const struct ClientResponseMessage *msg,
153 enum GNUNET_SCALARPRODUCT_ResponseStatus status) 131 enum GNUNET_SCALARPRODUCT_ResponseStatus status)
154{ 132{
155 struct GNUNET_SCALARPRODUCT_ComputationHandle *qe = cls; 133 if (NULL != h->cont_status)
156 134 h->cont_status (h->cont_cls,
157 qe->cont_status (qe->cont_cls, status); 135 status);
136 GNUNET_SCALARPRODUCT_cancel (h);
158} 137}
159 138
160 139
161/** 140/**
162 * Handles the RESULT received from the service for a request, should contain a result MPI value 141 * Handles the RESULT received from the service for a request, should
142 * contain a result MPI value
163 * 143 *
164 * @param cls our Handle 144 * @param h our Handle
165 * @param msg Pointer to the response received 145 * @param msg Pointer to the response received
166 * @param status the condition the request was terminated with (eg: disconnect) 146 * @param status the condition the request was terminated with (eg: disconnect)
167 */ 147 */
168static void 148static void
169process_result_message (void *cls, 149process_result_message (struct GNUNET_SCALARPRODUCT_ComputationHandle *h,
170 const struct GNUNET_MessageHeader *msg, 150 const struct ClientResponseMessage *msg,
171 enum GNUNET_SCALARPRODUCT_ResponseStatus status) 151 enum GNUNET_SCALARPRODUCT_ResponseStatus status)
172{ 152{
173 struct GNUNET_SCALARPRODUCT_ComputationHandle *qe = cls; 153 size_t product_len = ntohl (msg->product_length);
174 const struct GNUNET_SCALARPRODUCT_client_response *message =
175 (const struct GNUNET_SCALARPRODUCT_client_response *) msg;
176 gcry_mpi_t result = NULL; 154 gcry_mpi_t result = NULL;
177 gcry_error_t rc; 155 gcry_error_t rc;
156 gcry_mpi_t num;
157 size_t rsize;
178 158
159 if (ntohs (msg->header.size) - sizeof (struct ClientResponseMessage)
160 != product_len)
161 {
162 GNUNET_break (0);
163 status = GNUNET_SCALARPRODUCT_Status_InvalidResponse;
164 }
179 if (GNUNET_SCALARPRODUCT_Status_Success == status) 165 if (GNUNET_SCALARPRODUCT_Status_Success == status)
166 {
167 result = gcry_mpi_new (0);
168
169 if (0 < product_len)
180 { 170 {
181 size_t product_len = ntohl (message->product_length); 171 rsize = 0;
182 result = gcry_mpi_new (0); 172 if (0 != (rc = gcry_mpi_scan (&num, GCRYMPI_FMT_STD,
183 173 &msg[1],
184 if (0 < product_len) 174 product_len,
185 { 175 &rsize)))
186 gcry_mpi_t num; 176 {
187 size_t read = 0; 177 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR,
188 178 "gcry_mpi_scan",
189 if (0 != (rc = gcry_mpi_scan (&num, GCRYMPI_FMT_STD, &message[1], product_len, &read))) 179 rc);
190 { 180 gcry_mpi_release (result);
191 LOG_GCRY(GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc); 181 result = NULL;
192 gcry_mpi_release (result); 182 status = GNUNET_SCALARPRODUCT_Status_InvalidResponse;
193 result = NULL; 183 }
194 status = GNUNET_SCALARPRODUCT_Status_InvalidResponse; 184 else
195 } 185 {
196 else 186 if (0 < ntohl (msg->range))
197 { 187 gcry_mpi_add (result, result, num);
198 if (0 < message->range) 188 else if (0 > ntohl (msg->range))
199 gcry_mpi_add (result, result, num); 189 gcry_mpi_sub (result, result, num);
200 else if (0 > message->range) 190 gcry_mpi_release (num);
201 gcry_mpi_sub (result, result, num); 191 }
202 gcry_mpi_release (num);
203 }
204 }
205 } 192 }
206 qe->cont_datum (qe->cont_cls, status, result); 193 }
194 h->cont_datum (h->cont_cls, status, result);
195 if (NULL != result)
196 gcry_mpi_release (result);
197 GNUNET_SCALARPRODUCT_cancel (h);
207} 198}
208 199
209 200
@@ -216,144 +207,114 @@ process_result_message (void *cls,
216 * @param msg Pointer to the data received in response 207 * @param msg Pointer to the data received in response
217 */ 208 */
218static void 209static void
219receive_cb (void *cls, const struct GNUNET_MessageHeader *msg) 210receive_cb (void *cls,
211 const struct GNUNET_MessageHeader *msg)
220{ 212{
221 struct GNUNET_SCALARPRODUCT_ComputationHandle *h = cls; 213 struct GNUNET_SCALARPRODUCT_ComputationHandle *h = cls;
222 const struct GNUNET_SCALARPRODUCT_client_response *message = 214 const struct ClientResponseMessage *message;
223 (const struct GNUNET_SCALARPRODUCT_client_response *) msg;
224 enum GNUNET_SCALARPRODUCT_ResponseStatus status = GNUNET_SCALARPRODUCT_Status_InvalidResponse;
225 215
226 if (NULL == msg) 216 if (NULL == msg)
227 { 217 {
228 LOG (GNUNET_ERROR_TYPE_WARNING, "Disconnected by Service.\n"); 218 LOG (GNUNET_ERROR_TYPE_INFO,
229 status = GNUNET_SCALARPRODUCT_Status_ServiceDisconnected; 219 "Disconnected from SCALARPRODUCT service.\n");
230 } 220 h->response_proc (h,
231 else if ((GNUNET_SYSERR != message->status) && (0 < message->product_length )) 221 NULL,
232 { 222 GNUNET_SCALARPRODUCT_Status_ServiceDisconnected);
233 // response for the responder client, successful 223 return;
234 GNUNET_STATISTICS_update (h->stats,
235 gettext_noop ("# SUC responder result messages received"), 1,
236 GNUNET_NO);
237
238 status = GNUNET_SCALARPRODUCT_Status_Success;
239 }
240 else if (message->status == GNUNET_SYSERR){
241 // service signaled an error
242 status = GNUNET_SCALARPRODUCT_Status_Failure;
243 } 224 }
244 225 if (ntohs (msg->size) != sizeof (struct ClientResponseMessage))
245 if (h->cont_status != NULL) 226 {
246 h->response_proc (h, msg, status); 227 GNUNET_break (0);
247 228 h->response_proc (h,
248 GNUNET_free (h); 229 NULL,
249} 230 GNUNET_SCALARPRODUCT_Status_InvalidResponse);
250 231 return;
251
252static void
253send_multipart (void * cls, const struct GNUNET_SCHEDULER_TaskContext * tc)
254{
255 struct GNUNET_SCALARPRODUCT_ComputationHandle *h = (struct GNUNET_SCALARPRODUCT_ComputationHandle *) cls;
256 struct GNUNET_SCALARPRODUCT_computation_message_multipart *msg;
257 uint32_t size;
258 uint32_t todo;
259
260 h->cont_multipart = GNUNET_SCHEDULER_NO_TASK;
261
262 todo = h->element_count_total - h->element_count_transfered;
263 size = sizeof (struct GNUNET_SCALARPRODUCT_computation_message_multipart) +todo * sizeof (struct GNUNET_SCALARPRODUCT_Element);
264 if (GNUNET_SERVER_MAX_MESSAGE_SIZE <= size) {
265 //create a multipart msg, first we calculate a new msg size for the head msg
266 todo = (GNUNET_SERVER_MAX_MESSAGE_SIZE - 1 - sizeof (struct GNUNET_SCALARPRODUCT_computation_message_multipart)) / sizeof (struct GNUNET_SCALARPRODUCT_Element);
267 size = sizeof (struct GNUNET_SCALARPRODUCT_computation_message_multipart) +todo * sizeof (struct GNUNET_SCALARPRODUCT_Element);
268 } 232 }
269 233 message = (const struct ClientResponseMessage *) msg;
270 msg = (struct GNUNET_SCALARPRODUCT_computation_message_multipart*) GNUNET_malloc (size); 234 if (GNUNET_SYSERR == ntohl (message->status))
271 h->msg = msg; 235 {
272 msg->header.size = htons (size); 236 h->response_proc (h,
273 msg->header.type = htons (GNUNET_MESSAGE_TYPE_SCALARPRODUCT_CLIENT_MUTLIPART); 237 NULL,
274 msg->element_count_contained = htonl (todo); 238 GNUNET_SCALARPRODUCT_Status_Failure);
275 239 return;
276 memcpy (&msg[1], &h->elements[h->element_count_transfered], todo * sizeof (struct GNUNET_SCALARPRODUCT_Element));
277 h->element_count_transfered += todo;
278
279 h->th = GNUNET_CLIENT_notify_transmit_ready (h->client, size,
280 GNUNET_TIME_UNIT_FOREVER_REL,
281 GNUNET_YES, // retry is OK in the initial stage
282 &do_send_message, h);
283
284 if (!h->th) {
285 LOG (GNUNET_ERROR_TYPE_ERROR,
286 _ ("Failed to send a multipart message to the scalarproduct service\n"));
287 GNUNET_STATISTICS_update (h->stats,
288 gettext_noop ("# transmission request failures"),
289 1, GNUNET_NO);
290 GNUNET_STATISTICS_destroy (h->stats, GNUNET_YES);
291 GNUNET_CLIENT_disconnect (h->client);
292 GNUNET_free (h->msg);
293 h->msg = NULL;
294 if (h->cont_status != NULL)
295 h->response_proc (h, NULL, GNUNET_SCALARPRODUCT_Status_Failure);
296
297 GNUNET_SCALARPRODUCT_cancel (cls);
298 } 240 }
241 h->response_proc (h,
242 message,
243 GNUNET_SCALARPRODUCT_Status_Success);
299} 244}
300 245
246
301/** 247/**
302 * Transmits the request to the VectorProduct Service 248 * Transmits the request to the SCALARPRODUCT service
303 * 249 *
304 * @param cls Closure 250 * @param cls Closure with the `struct GNUNET_SCALARPRODUCT_ComputationHandle`
305 * @param size Size of the buffer 251 * @param size Size of the buffer @a buf
306 * @param buf Pointer to the buffer 252 * @param buf Pointer to the buffer
307 *
308 * @return Size of the message sent 253 * @return Size of the message sent
309 */ 254 */
310static size_t 255static size_t
311do_send_message (void *cls, size_t size, 256do_send_message (void *cls,
257 size_t size,
312 void *buf) 258 void *buf)
313{ 259{
314 struct GNUNET_SCALARPRODUCT_ComputationHandle *h = cls; 260 struct GNUNET_SCALARPRODUCT_ComputationHandle *h = cls;
261 struct ComputationMultipartMessage *msg;
262 size_t ret;
263 uint32_t nsize;
264 uint32_t todo;
315 265
316 if (NULL == buf) { 266 h->th = NULL;
317 LOG (GNUNET_ERROR_TYPE_DEBUG, "Failed to transmit request to SCALARPRODUCT.\n"); 267 if (NULL == buf)
318 GNUNET_STATISTICS_update (h->stats, 268 {
319 gettext_noop ("# transmission request failures"), 269 LOG (GNUNET_ERROR_TYPE_DEBUG,
320 1, GNUNET_NO); 270 "Failed to transmit request to SCALARPRODUCT.\n");
321 271 /* notify caller about the error, done here */
322 // notify caller about the error, done here. 272 h->response_proc (h, NULL,
323 if (h->cont_status != NULL) 273 GNUNET_SCALARPRODUCT_Status_Failure);
324 h->response_proc (h, NULL, GNUNET_SCALARPRODUCT_Status_Failure);
325
326 GNUNET_SCALARPRODUCT_cancel (cls);
327 return 0; 274 return 0;
328 } 275 }
329 memcpy (buf, h->msg, size); 276 ret = ntohs (h->msg->size);
330 277 memcpy (buf, h->msg, ret);
331 GNUNET_free (h->msg); 278 GNUNET_free (h->msg);
332 h->msg = NULL; 279 h->msg = NULL;
333 h->th = NULL;
334
335#if INSANE_STATISTICS
336 GNUNET_STATISTICS_update (h->stats,
337 gettext_noop ("# bytes sent to scalarproduct"), 1,
338 GNUNET_NO);
339#endif
340 280
341 /* done sending */ 281 /* done sending? */
342 if (h->element_count_total == h->element_count_transfered) { 282 if (h->element_count_total == h->element_count_transfered)
343 GNUNET_CLIENT_receive (h->client, &receive_cb, h, 283 {
284 GNUNET_CLIENT_receive (h->client,
285 &receive_cb, h,
344 GNUNET_TIME_UNIT_FOREVER_REL); 286 GNUNET_TIME_UNIT_FOREVER_REL);
345 return size; 287 return ret;
346 } 288 }
347
348 h->cont_multipart = GNUNET_SCHEDULER_add_now (&send_multipart, h);
349
350 return size;
351}
352 289
290 todo = h->element_count_total - h->element_count_transfered;
291 nsize = sizeof (struct ComputationMultipartMessage)
292 + todo * sizeof (struct GNUNET_SCALARPRODUCT_Element);
293 if (GNUNET_SERVER_MAX_MESSAGE_SIZE <= size)
294 {
295 /* cannot do all of them, limit to what is possible in one message */
296 todo = (GNUNET_SERVER_MAX_MESSAGE_SIZE - 1 - sizeof (struct ComputationMultipartMessage))
297 / sizeof (struct GNUNET_SCALARPRODUCT_Element);
298 nsize = sizeof (struct ComputationMultipartMessage)
299 + todo * sizeof (struct GNUNET_SCALARPRODUCT_Element);
300 }
353 301
354/************************************************************** 302 msg = GNUNET_malloc (nsize);
355 *** API ********** 303 h->msg = &msg->header;
356 **************************************************************/ 304 msg->header.size = htons (nsize);
305 msg->header.type = htons (GNUNET_MESSAGE_TYPE_SCALARPRODUCT_CLIENT_MUTLIPART);
306 msg->element_count_contained = htonl (todo);
307 memcpy (&msg[1],
308 &h->elements[h->element_count_transfered],
309 todo * sizeof (struct GNUNET_SCALARPRODUCT_Element));
310 h->element_count_transfered += todo;
311 h->th = GNUNET_CLIENT_notify_transmit_ready (h->client, nsize,
312 GNUNET_TIME_UNIT_FOREVER_REL,
313 GNUNET_NO,
314 &do_send_message, h);
315 GNUNET_assert (NULL != h->th);
316 return ret;
317}
357 318
358 319
359/** 320/**
@@ -362,96 +323,75 @@ do_send_message (void *cls, size_t size,
362 * @param cfg the gnunet configuration handle 323 * @param cfg the gnunet configuration handle
363 * @param key Session key unique to the requesting client 324 * @param key Session key unique to the requesting client
364 * @param elements Array of elements of the vector 325 * @param elements Array of elements of the vector
365 * @param element_count Number of elements in the vector 326 * @param element_count Number of elements in the @a elements vector
366 * @param cont Callback function 327 * @param cont Callback function
367 * @param cont_cls Closure for the callback function 328 * @param cont_cls Closure for @a cont
368 *
369 * @return a new handle for this computation 329 * @return a new handle for this computation
370 */ 330 */
371struct GNUNET_SCALARPRODUCT_ComputationHandle * 331struct GNUNET_SCALARPRODUCT_ComputationHandle *
372GNUNET_SCALARPRODUCT_accept_computation (const struct GNUNET_CONFIGURATION_Handle * cfg, 332GNUNET_SCALARPRODUCT_accept_computation (const struct GNUNET_CONFIGURATION_Handle *cfg,
373 const struct GNUNET_HashCode * session_key, 333 const struct GNUNET_HashCode *session_key,
374 const struct GNUNET_SCALARPRODUCT_Element * elements, 334 const struct GNUNET_SCALARPRODUCT_Element *elements,
375 uint32_t element_count, 335 uint32_t element_count,
376 GNUNET_SCALARPRODUCT_ContinuationWithStatus cont, 336 GNUNET_SCALARPRODUCT_ContinuationWithStatus cont,
377 void * cont_cls) 337 void *cont_cls)
378{ 338{
379 struct GNUNET_SCALARPRODUCT_ComputationHandle *h; 339 struct GNUNET_SCALARPRODUCT_ComputationHandle *h;
380 struct GNUNET_SCALARPRODUCT_computation_message *msg; 340 struct ComputationMessage *msg;
381 uint32_t size; 341 uint32_t size;
382 uint16_t possible; 342 uint16_t possible;
383 343
384 GNUNET_assert (GNUNET_SERVER_MAX_MESSAGE_SIZE >= sizeof (struct GNUNET_SCALARPRODUCT_computation_message)
385 + element_count * sizeof (int32_t));
386 h = GNUNET_new (struct GNUNET_SCALARPRODUCT_ComputationHandle); 344 h = GNUNET_new (struct GNUNET_SCALARPRODUCT_ComputationHandle);
345 h->cont_status = cont;
346 h->cont_cls = cont_cls;
347 h->response_proc = &process_status_message;
348 h->cfg = cfg;
349 h->key = *session_key;
387 h->client = GNUNET_CLIENT_connect ("scalarproduct", cfg); 350 h->client = GNUNET_CLIENT_connect ("scalarproduct", cfg);
388 if (!h->client)
389 {
390 LOG (GNUNET_ERROR_TYPE_ERROR,
391 _ ("Failed to connect to the scalarproduct service\n"));
392 GNUNET_free (h);
393 return NULL;
394 }
395 h->stats = GNUNET_STATISTICS_create ("scalarproduct-api", cfg);
396 if (!h->stats)
397 {
398 LOG (GNUNET_ERROR_TYPE_ERROR,
399 _ ("Failed to send a message to the statistics service\n"));
400 GNUNET_CLIENT_disconnect (h->client);
401 GNUNET_free (h);
402 return NULL;
403 }
404
405 h->element_count_total = element_count; 351 h->element_count_total = element_count;
406 size = sizeof (struct GNUNET_SCALARPRODUCT_computation_message) + element_count * sizeof (struct GNUNET_SCALARPRODUCT_Element); 352 if (NULL == h->client)
407 if (GNUNET_SERVER_MAX_MESSAGE_SIZE > size) { 353 {
354 /* scalarproduct configuration error */
355 GNUNET_break (0);
356 GNUNET_free (h);
357 return NULL;
358 }
359 size = sizeof (struct ComputationMessage)
360 + element_count * sizeof (struct GNUNET_SCALARPRODUCT_Element);
361 if (GNUNET_SERVER_MAX_MESSAGE_SIZE > size)
362 {
408 possible = element_count; 363 possible = element_count;
409 h->element_count_transfered = element_count; 364 h->element_count_transfered = element_count;
410 } 365 }
411 else { 366 else
412 //create a multipart msg, first we calculate a new msg size for the head msg 367 {
413 possible = (GNUNET_SERVER_MAX_MESSAGE_SIZE - 1 - sizeof (struct GNUNET_SCALARPRODUCT_computation_message)) / sizeof (struct GNUNET_SCALARPRODUCT_Element); 368 /* create a multipart msg, first we calculate a new msg size for the head msg */
369 possible = (GNUNET_SERVER_MAX_MESSAGE_SIZE - 1 - sizeof (struct ComputationMessage))
370 / sizeof (struct GNUNET_SCALARPRODUCT_Element);
414 h->element_count_transfered = possible; 371 h->element_count_transfered = possible;
415 size = sizeof (struct GNUNET_SCALARPRODUCT_computation_message) + possible*sizeof (struct GNUNET_SCALARPRODUCT_Element); 372 size = sizeof (struct ComputationMessage)
416 h->elements = (struct GNUNET_SCALARPRODUCT_Element*) 373 + possible * sizeof (struct GNUNET_SCALARPRODUCT_Element);
417 GNUNET_malloc (sizeof(struct GNUNET_SCALARPRODUCT_Element) * element_count); 374 h->elements = GNUNET_malloc (sizeof(struct GNUNET_SCALARPRODUCT_Element) * element_count);
418 memcpy (h->elements, elements, sizeof (struct GNUNET_SCALARPRODUCT_Element)*element_count); 375 memcpy (h->elements,
376 elements,
377 sizeof (struct GNUNET_SCALARPRODUCT_Element) * element_count);
419 } 378 }
420 379
421 h->cont_status = cont; 380 msg = GNUNET_malloc (size);
422 h->cont_cls = cont_cls; 381 h->msg = &msg->header;
423 h->response_proc = &process_status_message;
424 h->cfg = cfg;
425 memcpy (&h->key, session_key, sizeof (struct GNUNET_HashCode));
426
427 msg = (struct GNUNET_SCALARPRODUCT_computation_message*) GNUNET_malloc (size);
428 h->msg = msg;
429 msg->header.size = htons (size); 382 msg->header.size = htons (size);
430 msg->header.type = htons (GNUNET_MESSAGE_TYPE_SCALARPRODUCT_CLIENT_TO_BOB); 383 msg->header.type = htons (GNUNET_MESSAGE_TYPE_SCALARPRODUCT_CLIENT_TO_BOB);
431 msg->element_count_total = htonl (element_count); 384 msg->element_count_total = htonl (element_count);
432 msg->element_count_contained = htonl (possible); 385 msg->element_count_contained = htonl (possible);
433 386 msg->session_key = *session_key;
434 memcpy (&msg->session_key, session_key, sizeof (struct GNUNET_HashCode)); 387 memcpy (&msg[1],
435 memcpy (&msg[1], elements, possible); 388 elements,
436 389 possible);
437 h->th = GNUNET_CLIENT_notify_transmit_ready (h->client, size, 390 h->th = GNUNET_CLIENT_notify_transmit_ready (h->client, size,
438 GNUNET_TIME_UNIT_FOREVER_REL, 391 GNUNET_TIME_UNIT_FOREVER_REL,
439 GNUNET_YES, // retry is OK in the initial stage 392 GNUNET_YES, /* retry is OK in the initial stage */
440 &do_send_message, h); 393 &do_send_message, h);
441 if (!h->th) 394 GNUNET_assert (NULL != h->th);
442 {
443 LOG (GNUNET_ERROR_TYPE_ERROR,
444 _ ("Failed to send a message to the scalarproduct service\n"));
445 GNUNET_STATISTICS_update (h->stats,
446 gettext_noop ("# transmission request failures"),
447 1, GNUNET_NO);
448 GNUNET_STATISTICS_destroy (h->stats, GNUNET_YES);
449 GNUNET_CLIENT_disconnect (h->client);
450 GNUNET_free (h->msg);
451 GNUNET_free_non_null (h->elements);
452 GNUNET_free (h);
453 return NULL;
454 }
455 return h; 395 return h;
456} 396}
457 397
@@ -463,99 +403,82 @@ GNUNET_SCALARPRODUCT_accept_computation (const struct GNUNET_CONFIGURATION_Handl
463 * @param session_key Session key should be unique to the requesting client 403 * @param session_key Session key should be unique to the requesting client
464 * @param peer PeerID of the other peer 404 * @param peer PeerID of the other peer
465 * @param elements Array of elements of the vector 405 * @param elements Array of elements of the vector
466 * @param element_count Number of elements in the vector 406 * @param element_count Number of elements in the @a elements vector
467 * @param cont Callback function 407 * @param cont Callback function
468 * @param cont_cls Closure for the callback function 408 * @param cont_cls Closure for @a cont
469 *
470 * @return a new handle for this computation 409 * @return a new handle for this computation
471 */ 410 */
472struct GNUNET_SCALARPRODUCT_ComputationHandle * 411struct GNUNET_SCALARPRODUCT_ComputationHandle *
473GNUNET_SCALARPRODUCT_start_computation (const struct GNUNET_CONFIGURATION_Handle * cfg, 412GNUNET_SCALARPRODUCT_start_computation (const struct GNUNET_CONFIGURATION_Handle *cfg,
474 const struct GNUNET_HashCode * session_key, 413 const struct GNUNET_HashCode *session_key,
475 const struct GNUNET_PeerIdentity *peer, 414 const struct GNUNET_PeerIdentity *peer,
476 const struct GNUNET_SCALARPRODUCT_Element * elements, 415 const struct GNUNET_SCALARPRODUCT_Element *elements,
477 uint32_t element_count, 416 uint32_t element_count,
478 GNUNET_SCALARPRODUCT_DatumProcessor cont, 417 GNUNET_SCALARPRODUCT_DatumProcessor cont,
479 void * cont_cls) 418 void *cont_cls)
480{ 419{
481 struct GNUNET_SCALARPRODUCT_ComputationHandle *h; 420 struct GNUNET_SCALARPRODUCT_ComputationHandle *h;
482 struct GNUNET_SCALARPRODUCT_computation_message *msg; 421 struct ComputationMessage *msg;
483 uint32_t size; 422 uint32_t size;
484 uint16_t possible; 423 uint32_t possible;
485 424
486 h = GNUNET_new (struct GNUNET_SCALARPRODUCT_ComputationHandle); 425 h = GNUNET_new (struct GNUNET_SCALARPRODUCT_ComputationHandle);
487 h->client = GNUNET_CLIENT_connect ("scalarproduct", cfg); 426 h->client = GNUNET_CLIENT_connect ("scalarproduct", cfg);
488 if (!h->client) 427 if (NULL == h->client)
489 { 428 {
490 LOG (GNUNET_ERROR_TYPE_ERROR, 429 /* missconfigured scalarproduct service */
491 _ ("Failed to connect to the scalarproduct service\n")); 430 GNUNET_break (0);
492 GNUNET_free (h); 431 GNUNET_free (h);
493 return NULL; 432 return NULL;
494 } 433 }
495 h->stats = GNUNET_STATISTICS_create ("scalarproduct-api", cfg);
496 if (!h->stats)
497 {
498 LOG (GNUNET_ERROR_TYPE_ERROR,
499 _ ("Failed to send a message to the statistics service\n"));
500 GNUNET_CLIENT_disconnect (h->client);
501 GNUNET_free (h);
502 return NULL;
503 }
504
505 h->element_count_total = element_count; 434 h->element_count_total = element_count;
506 size = sizeof (struct GNUNET_SCALARPRODUCT_computation_message) + element_count * sizeof (struct GNUNET_SCALARPRODUCT_Element); 435 h->cont_datum = cont;
507 if (GNUNET_SERVER_MAX_MESSAGE_SIZE > size) { 436 h->cont_cls = cont_cls;
437 h->response_proc = &process_result_message;
438 h->cfg = cfg;
439 h->key = *session_key;
440 size = sizeof (struct ComputationMessage)
441 + element_count * sizeof (struct GNUNET_SCALARPRODUCT_Element);
442 if (GNUNET_SERVER_MAX_MESSAGE_SIZE > size)
443 {
508 possible = element_count; 444 possible = element_count;
509 h->element_count_transfered = element_count; 445 h->element_count_transfered = element_count;
510 } 446 }
511 else { 447 else
512 //create a multipart msg, first we calculate a new msg size for the head msg 448 {
513 possible = (GNUNET_SERVER_MAX_MESSAGE_SIZE - 1 - sizeof (struct GNUNET_SCALARPRODUCT_computation_message)) / sizeof (struct GNUNET_SCALARPRODUCT_Element); 449 /* create a multipart msg, first we calculate a new msg size for the head msg */
450 possible = (GNUNET_SERVER_MAX_MESSAGE_SIZE - 1 - sizeof (struct ComputationMessage))
451 / sizeof (struct GNUNET_SCALARPRODUCT_Element);
514 h->element_count_transfered = possible; 452 h->element_count_transfered = possible;
515 size = sizeof (struct GNUNET_SCALARPRODUCT_computation_message) + possible*sizeof (struct GNUNET_SCALARPRODUCT_Element); 453 size = sizeof (struct ComputationMessage)
516 h->elements = (struct GNUNET_SCALARPRODUCT_Element*) 454 + possible * sizeof (struct GNUNET_SCALARPRODUCT_Element);
517 GNUNET_malloc (sizeof(struct GNUNET_SCALARPRODUCT_Element) * element_count); 455 h->elements = GNUNET_malloc (sizeof(struct GNUNET_SCALARPRODUCT_Element) * element_count);
518 memcpy (h->elements, elements, sizeof (struct GNUNET_SCALARPRODUCT_Element) * element_count); 456 memcpy (h->elements,
457 elements,
458 sizeof (struct GNUNET_SCALARPRODUCT_Element) * element_count);
519 } 459 }
520
521 h->cont_datum = cont;
522 h->cont_cls = cont_cls;
523 h->response_proc = &process_result_message;
524 h->cfg = cfg;
525 memcpy (&h->key, session_key, sizeof (struct GNUNET_HashCode));
526 460
527 msg = (struct GNUNET_SCALARPRODUCT_computation_message*) GNUNET_malloc (size); 461 msg = GNUNET_malloc (size);
528 h->msg = msg; 462 h->msg = &msg->header;
529 msg->header.size = htons (size); 463 msg->header.size = htons (size);
530 msg->header.type = htons (GNUNET_MESSAGE_TYPE_SCALARPRODUCT_CLIENT_TO_ALICE); 464 msg->header.type = htons (GNUNET_MESSAGE_TYPE_SCALARPRODUCT_CLIENT_TO_ALICE);
531 msg->element_count_total = htonl (element_count); 465 msg->element_count_total = htonl (element_count);
532 msg->element_count_contained = htonl (possible); 466 msg->element_count_contained = htonl (possible);
533 467 msg->reserved = htonl (0);
534 memcpy (&msg->peer, peer, sizeof (struct GNUNET_PeerIdentity)); 468 msg->peer = *peer;
535 memcpy (&msg->session_key, session_key, sizeof (struct GNUNET_HashCode)); 469 msg->session_key = *session_key;
536 memcpy (&msg[1], elements, sizeof (struct GNUNET_SCALARPRODUCT_Element) * possible); 470 memcpy (&msg[1],
537 471 elements,
472 sizeof (struct GNUNET_SCALARPRODUCT_Element) * possible);
538 h->th = GNUNET_CLIENT_notify_transmit_ready (h->client, size, 473 h->th = GNUNET_CLIENT_notify_transmit_ready (h->client, size,
539 GNUNET_TIME_UNIT_FOREVER_REL, 474 GNUNET_TIME_UNIT_FOREVER_REL,
540 GNUNET_YES, // retry is OK in the initial stage 475 GNUNET_YES, /* retry is OK in the initial stage */
541 &do_send_message, h); 476 &do_send_message, h);
542 if (!h->th) 477 GNUNET_assert (NULL != h->th);
543 {
544 LOG (GNUNET_ERROR_TYPE_ERROR,
545 _ ("Failed to send a message to the scalarproduct service\n"));
546 GNUNET_STATISTICS_update (h->stats,
547 gettext_noop ("# transmission request failures"),
548 1, GNUNET_NO);
549 GNUNET_STATISTICS_destroy (h->stats, GNUNET_YES);
550 GNUNET_CLIENT_disconnect (h->client);
551 GNUNET_free (h->msg);
552 GNUNET_free_non_null (h->elements);
553 GNUNET_free (h);
554 return NULL;
555 }
556 return h; 478 return h;
557} 479}
558 480
481
559/** 482/**
560 * Cancel an ongoing computation or revoke our collaboration offer. 483 * Cancel an ongoing computation or revoke our collaboration offer.
561 * Closes the connection to the service 484 * Closes the connection to the service
@@ -563,16 +486,20 @@ GNUNET_SCALARPRODUCT_start_computation (const struct GNUNET_CONFIGURATION_Handle
563 * @param h computation handle to terminate 486 * @param h computation handle to terminate
564 */ 487 */
565void 488void
566GNUNET_SCALARPRODUCT_cancel (struct GNUNET_SCALARPRODUCT_ComputationHandle * h) 489GNUNET_SCALARPRODUCT_cancel (struct GNUNET_SCALARPRODUCT_ComputationHandle *h)
567{ 490{
568 if (NULL != h->th) 491 if (NULL != h->th)
492 {
569 GNUNET_CLIENT_notify_transmit_ready_cancel (h->th); 493 GNUNET_CLIENT_notify_transmit_ready_cancel (h->th);
570 if (GNUNET_SCHEDULER_NO_TASK != h->cont_multipart) 494 h->th = NULL;
571 GNUNET_SCHEDULER_cancel (h->cont_multipart); 495 }
572 GNUNET_free_non_null (h->elements); 496 GNUNET_free_non_null (h->elements);
573 GNUNET_free_non_null (h->msg); 497 GNUNET_free_non_null (h->msg);
574 GNUNET_CLIENT_disconnect (h->client); 498 if (NULL != h->client)
575 GNUNET_STATISTICS_destroy (h->stats, GNUNET_YES); 499 {
500 GNUNET_CLIENT_disconnect (h->client);
501 h->client = NULL;
502 }
576 GNUNET_free (h); 503 GNUNET_free (h);
577} 504}
578 505