aboutsummaryrefslogtreecommitdiff
path: root/src/scalarproduct
diff options
context:
space:
mode:
authorChristian Fuchs <christian.fuchs@cfuchs.net>2013-10-18 13:47:30 +0000
committerChristian Fuchs <christian.fuchs@cfuchs.net>2013-10-18 13:47:30 +0000
commit34365eb5c053d520dce3cc1f90921dc03e42fcdf (patch)
treea143cf6dd4ab46ce179346442dca21ff92ed01ce /src/scalarproduct
parent543d8cafc55fde62db363750d9a75536c73cbd79 (diff)
downloadgnunet-34365eb5c053d520dce3cc1f90921dc03e42fcdf.tar.gz
gnunet-34365eb5c053d520dce3cc1f90921dc03e42fcdf.zip
finished SP-testcase
SP now properly resets a couple of freed values fixed a double-free fixed a logics bug in handle_service_response
Diffstat (limited to 'src/scalarproduct')
-rw-r--r--src/scalarproduct/gnunet-service-scalarproduct.c89
-rwxr-xr-xsrc/scalarproduct/test_scalarproduct.sh45
2 files changed, 78 insertions, 56 deletions
diff --git a/src/scalarproduct/gnunet-service-scalarproduct.c b/src/scalarproduct/gnunet-service-scalarproduct.c
index c19213aa7..47e1697e3 100644
--- a/src/scalarproduct/gnunet-service-scalarproduct.c
+++ b/src/scalarproduct/gnunet-service-scalarproduct.c
@@ -692,7 +692,6 @@ find_matching_session (struct ServiceSession * tail,
692 return NULL; 692 return NULL;
693} 693}
694 694
695
696/** 695/**
697 * Safely frees ALL memory areas referenced by a session. 696 * Safely frees ALL memory areas referenced by a session.
698 * 697 *
@@ -709,7 +708,10 @@ free_session_variables (struct ServiceSession * session)
709 GNUNET_free (session->a); 708 GNUNET_free (session->a);
710 session->a = NULL; 709 session->a = NULL;
711 } 710 }
712 GNUNET_free_non_null (session->mask); 711 if (session->mask) {
712 GNUNET_free (session->mask);
713 session->mask = NULL;
714 }
713 if (session->r) { 715 if (session->r) {
714 for (i = 0; i < session->used; i++) 716 for (i = 0; i < session->used; i++)
715 if (session->r[i]) gcry_mpi_release (session->r[i]); 717 if (session->r[i]) gcry_mpi_release (session->r[i]);
@@ -722,24 +724,24 @@ free_session_variables (struct ServiceSession * session)
722 GNUNET_free (session->r_prime); 724 GNUNET_free (session->r_prime);
723 session->r_prime = NULL; 725 session->r_prime = NULL;
724 } 726 }
725 if (session->s){ 727 if (session->s) {
726 gcry_mpi_release (session->s); 728 gcry_mpi_release (session->s);
727 session->s = NULL; 729 session->s = NULL;
728 } 730 }
729 731
730 if (session->s_prime){ 732 if (session->s_prime) {
731 gcry_mpi_release (session->s_prime); 733 gcry_mpi_release (session->s_prime);
732 session->s_prime = NULL; 734 session->s_prime = NULL;
733 } 735 }
734 736
735 if (session->product){ 737 if (session->product) {
736 gcry_mpi_release (session->product); 738 gcry_mpi_release (session->product);
737 session->product = NULL; 739 session->product = NULL;
738 } 740 }
739 741
740 if (session->remote_pubkey){ 742 if (session->remote_pubkey) {
741 gcry_sexp_release (session->remote_pubkey); 743 gcry_sexp_release (session->remote_pubkey);
742 session->remote_pubkey = NULL; 744 session->remote_pubkey = NULL;
743 } 745 }
744 746
745 if (session->vector) { 747 if (session->vector) {
@@ -849,7 +851,8 @@ prepare_client_end_notification (void * cls,
849 } 851 }
850 else 852 else
851 GNUNET_log (GNUNET_ERROR_TYPE_INFO, _ ("Sending session-end notification to client (%p) for session %s\n"), &session->client, GNUNET_h2s (&session->key)); 853 GNUNET_log (GNUNET_ERROR_TYPE_INFO, _ ("Sending session-end notification to client (%p) for session %s\n"), &session->client, GNUNET_h2s (&session->key));
852 854
855 free_session_variables (session);
853} 856}
854 857
855 858
@@ -943,6 +946,7 @@ prepare_client_response (void *cls,
943 _ ("Sent result to client (%p), this session (%s) has ended!\n"), 946 _ ("Sent result to client (%p), this session (%s) has ended!\n"),
944 session->client, 947 session->client,
945 GNUNET_h2s (&session->key)); 948 GNUNET_h2s (&session->key));
949 free_session_variables (session);
946} 950}
947 951
948 952
@@ -1003,7 +1007,9 @@ prepare_service_response_multipart (void *cls)
1003 GNUNET_free (element_exported); 1007 GNUNET_free (element_exported);
1004 for (i = session->transferred; i < session->transferred; i++) { 1008 for (i = session->transferred; i < session->transferred; i++) {
1005 gcry_mpi_release (session->r_prime[i]); 1009 gcry_mpi_release (session->r_prime[i]);
1010 session->r_prime[i] = NULL;
1006 gcry_mpi_release (session->r[i]); 1011 gcry_mpi_release (session->r[i]);
1012 session->r[i] = NULL;
1007 } 1013 }
1008 session->transferred += todo_count; 1014 session->transferred += todo_count;
1009 session->msg = (struct GNUNET_MessageHeader *) msg; 1015 session->msg = (struct GNUNET_MessageHeader *) msg;
@@ -1135,10 +1141,14 @@ prepare_service_response (gcry_mpi_t s,
1135 GNUNET_free (element_exported); 1141 GNUNET_free (element_exported);
1136 for (i = 0; i < session->transferred; i++) { 1142 for (i = 0; i < session->transferred; i++) {
1137 gcry_mpi_release (session->r_prime[i]); 1143 gcry_mpi_release (session->r_prime[i]);
1144 session->r_prime[i] = NULL;
1138 gcry_mpi_release (session->r[i]); 1145 gcry_mpi_release (session->r[i]);
1146 session->r[i] = NULL;
1139 } 1147 }
1140 gcry_mpi_release (s); 1148 gcry_mpi_release (s);
1149 session->s = NULL;
1141 gcry_mpi_release (s_prime); 1150 gcry_mpi_release (s_prime);
1151 session->s_prime = NULL;
1142 1152
1143 session->msg = (struct GNUNET_MessageHeader *) msg; 1153 session->msg = (struct GNUNET_MessageHeader *) msg;
1144 session->service_transmit_handle = 1154 session->service_transmit_handle =
@@ -1851,7 +1861,7 @@ tunnel_destruction_handler (void *cls,
1851 GNUNET_i2s (&session->peer)); 1861 GNUNET_i2s (&session->peer));
1852 if (ALICE == session->role) { 1862 if (ALICE == session->role) {
1853 // as we have only one peer connected in each session, just remove the session 1863 // as we have only one peer connected in each session, just remove the session
1854 1864
1855 if ((SERVICE_RESPONSE_RECEIVED > session->state) && (!do_shutdown)) { 1865 if ((SERVICE_RESPONSE_RECEIVED > session->state) && (!do_shutdown)) {
1856 session->tunnel = NULL; 1866 session->tunnel = NULL;
1857 // if this happened before we received the answer, we must terminate the session 1867 // if this happened before we received the answer, we must terminate the session
@@ -2235,6 +2245,7 @@ handle_service_response_multipart (void *cls,
2235 size_t i; 2245 size_t i;
2236 uint32_t contained = 0; 2246 uint32_t contained = 0;
2237 size_t msg_size; 2247 size_t msg_size;
2248 size_t required_size;
2238 int rc; 2249 int rc;
2239 2250
2240 GNUNET_assert (NULL != message); 2251 GNUNET_assert (NULL != message);
@@ -2243,15 +2254,17 @@ handle_service_response_multipart (void *cls,
2243 if ((ALICE != session->role) || (WAITING_FOR_MULTIPART_TRANSMISSION != session->state)) { 2254 if ((ALICE != session->role) || (WAITING_FOR_MULTIPART_TRANSMISSION != session->state)) {
2244 goto invalid_msg; 2255 goto invalid_msg;
2245 } 2256 }
2257 msg_size = ntohs (msg->header.size);
2258 required_size = sizeof (struct GNUNET_SCALARPRODUCT_multipart_message) + 2 * PAILLIER_ELEMENT_LENGTH;
2246 // shorter than minimum? 2259 // shorter than minimum?
2247 if (ntohs (msg->header.size) <= sizeof (struct GNUNET_SCALARPRODUCT_multipart_message)) { 2260 if (required_size > msg_size) {
2248 goto invalid_msg; 2261 goto invalid_msg;
2249 } 2262 }
2250 contained = ntohl (msg->multipart_element_count); 2263 contained = ntohl (msg->multipart_element_count);
2251 msg_size = sizeof (struct GNUNET_SCALARPRODUCT_multipart_message) 2264 required_size = sizeof (struct GNUNET_SCALARPRODUCT_multipart_message)
2252 + 2 * contained * PAILLIER_ELEMENT_LENGTH; 2265 + 2 * contained * PAILLIER_ELEMENT_LENGTH;
2253 //sanity check: is the message as long as the message_count fields suggests? 2266 //sanity check: is the message as long as the message_count fields suggests?
2254 if ((ntohs (msg->header.size) != msg_size) || (session->used < contained)) { 2267 if ((required_size != msg_size) || (session->used < session->transferred + contained)) {
2255 goto invalid_msg; 2268 goto invalid_msg;
2256 } 2269 }
2257 current = (unsigned char *) &msg[1]; 2270 current = (unsigned char *) &msg[1];
@@ -2274,19 +2287,19 @@ handle_service_response_multipart (void *cls,
2274 if (session->transferred != session->used) 2287 if (session->transferred != session->used)
2275 return GNUNET_OK; 2288 return GNUNET_OK;
2276 session->state = SERVICE_RESPONSE_RECEIVED; 2289 session->state = SERVICE_RESPONSE_RECEIVED;
2277 session->product = compute_scalar_product (session); 2290 session->product = compute_scalar_product (session); //never NULL
2278 return GNUNET_SYSERR; // terminate the tunnel right away, we are done here! 2291
2279
2280invalid_msg: 2292invalid_msg:
2281 GNUNET_break_op (0); 2293 GNUNET_break_op (NULL != session->product);
2282 free_session_variables (session); 2294
2283 session->state = FINALIZED;
2284 session->tunnel = NULL;
2285 // send message with product to client 2295 // send message with product to client
2286 if (ALICE == session->role) 2296 if (ALICE == session->role){
2297 session->state = FINALIZED;
2298 session->tunnel = NULL;
2287 session->client_notification_task = 2299 session->client_notification_task =
2288 GNUNET_SCHEDULER_add_now (&prepare_client_response, 2300 GNUNET_SCHEDULER_add_now (&prepare_client_response,
2289 session); 2301 session);
2302 }
2290 // the tunnel has done its job, terminate our connection and the tunnel 2303 // the tunnel has done its job, terminate our connection and the tunnel
2291 // the peer will be notified that the tunnel was destroyed via tunnel_destruction_handler 2304 // the peer will be notified that the tunnel was destroyed via tunnel_destruction_handler
2292 // just close the connection, as recommended by Christian 2305 // just close the connection, as recommended by Christian
@@ -2317,27 +2330,28 @@ handle_service_response (void *cls,
2317 size_t i; 2330 size_t i;
2318 uint32_t contained = 0; 2331 uint32_t contained = 0;
2319 size_t msg_size; 2332 size_t msg_size;
2333 size_t required_size;
2320 int rc; 2334 int rc;
2321 2335
2322 GNUNET_assert (NULL != message); 2336 GNUNET_assert (NULL != message);
2323 session = (struct ServiceSession *) * tunnel_ctx; 2337 session = (struct ServiceSession *) * tunnel_ctx;
2324 // are we in the correct state? 2338 // are we in the correct state?
2325 if (session->state != WAITING_FOR_SERVICE_REQUEST) { 2339 if (WAITING_FOR_SERVICE_RESPONSE != session->state) {
2326 goto invalid_msg; 2340 goto invalid_msg;
2327 } 2341 }
2328 //we need at least a full message without elements attached 2342 //we need at least a full message without elements attached
2329 msg_size = ntohs (msg->header.size); 2343 msg_size = ntohs (msg->header.size);
2330 size_t expected = sizeof (struct GNUNET_SCALARPRODUCT_service_response) + 2 * PAILLIER_ELEMENT_LENGTH; 2344 required_size = sizeof (struct GNUNET_SCALARPRODUCT_service_response) + 2 * PAILLIER_ELEMENT_LENGTH;
2331 2345
2332 if (expected > msg_size) { 2346 if (required_size > msg_size) {
2333 goto invalid_msg; 2347 goto invalid_msg;
2334 } 2348 }
2335 contained = ntohl (msg->contained_element_count); 2349 contained = ntohl (msg->contained_element_count);
2336 msg_size = sizeof (struct GNUNET_SCALARPRODUCT_service_response) 2350 required_size = sizeof (struct GNUNET_SCALARPRODUCT_service_response)
2337 + 2 * contained * PAILLIER_ELEMENT_LENGTH 2351 + 2 * contained * PAILLIER_ELEMENT_LENGTH
2338 + 2 * PAILLIER_ELEMENT_LENGTH; 2352 + 2 * PAILLIER_ELEMENT_LENGTH;
2339 //sanity check: is the message as long as the message_count fields suggests? 2353 //sanity check: is the message as long as the message_count fields suggests?
2340 if ((ntohs (msg->header.size) != msg_size) || (session->used < contained)) { 2354 if ((msg_size != required_size) || (session->used < contained)) {
2341 goto invalid_msg; 2355 goto invalid_msg;
2342 } 2356 }
2343 session->state = WAITING_FOR_MULTIPART_TRANSMISSION; 2357 session->state = WAITING_FOR_MULTIPART_TRANSMISSION;
@@ -2378,19 +2392,18 @@ handle_service_response (void *cls,
2378 return GNUNET_OK; //wait for the other multipart chunks 2392 return GNUNET_OK; //wait for the other multipart chunks
2379 2393
2380 session->state = SERVICE_RESPONSE_RECEIVED; 2394 session->state = SERVICE_RESPONSE_RECEIVED;
2381 session->product = compute_scalar_product (session); 2395 session->product = compute_scalar_product (session); //never NULL
2382 return GNUNET_SYSERR; // terminate the tunnel right away, we are done here! 2396
2383
2384invalid_msg: 2397invalid_msg:
2385 GNUNET_break_op (0); 2398 GNUNET_break_op (NULL != session->product);
2386 free_session_variables (session);
2387 session->state = FINALIZED;
2388 session->tunnel = NULL;
2389 // send message with product to client 2399 // send message with product to client
2390 if (ALICE == session->role) 2400 if (ALICE == session->role){
2401 session->state = FINALIZED;
2402 session->tunnel = NULL;
2391 session->client_notification_task = 2403 session->client_notification_task =
2392 GNUNET_SCHEDULER_add_now (&prepare_client_response, 2404 GNUNET_SCHEDULER_add_now (&prepare_client_response,
2393 session); 2405 session);
2406 }
2394 // the tunnel has done its job, terminate our connection and the tunnel 2407 // the tunnel has done its job, terminate our connection and the tunnel
2395 // the peer will be notified that the tunnel was destroyed via tunnel_destruction_handler 2408 // the peer will be notified that the tunnel was destroyed via tunnel_destruction_handler
2396 // just close the connection, as recommended by Christian 2409 // just close the connection, as recommended by Christian
diff --git a/src/scalarproduct/test_scalarproduct.sh b/src/scalarproduct/test_scalarproduct.sh
index 29f78ef9b..eaffd925d 100755
--- a/src/scalarproduct/test_scalarproduct.sh
+++ b/src/scalarproduct/test_scalarproduct.sh
@@ -1,31 +1,40 @@
1#!/bin/bash 1#!/bin/bash
2# compute a simple scalar product 2# compute a simple scalar product
3# payload for this test:
4INPUTALICE="-k AAAA -e 10,10,10"
5INPUTBOB="-k AAAA -e 10,10,10"
3 6
4#necessary to make the testing prefix deterministic, so we can access the config files 7# necessary to make the testing prefix deterministic, so we can access the config files
5PREFIX=/tmp/test-scalarproduct`date +%H%M%S` 8PREFIX=/tmp/test-scalarproduct`date +%H%M%S`
6 9
7#where can we find the peers config files? 10# where can we find the peers config files?
8CFGALICE="-c $PREFIX/0/config" 11CFGALICE="-c $PREFIX/0/config"
9CFGBOB="-c $PREFIX/1/config" 12CFGBOB="-c $PREFIX/1/config"
10 13# log at which loglevel?
11#log at which loglevel? 14LOGLEVEL=DEBUG
12LOG="-L ERROR" 15
13 16echo start
14#launch two peers in line topology 17# launch two peers in line topology non-interactively
15GNUNET_TESTING_PREFIX=$PREFIX ../testbed/gnunet-testbed-profiler $LOG -c test_scalarproduct.conf -p 2 2>gnunet_error.log & 18#
16sleep 5 19# interactive mode would terminate the test immediately
17 20# because the rest of the script is already in stdin,
18#get bob's peer ID, necessary for alice 21# thus redirecting stdin does not suffice)
22GNUNET_LOG="scalarproduct;;;;$LOGLEVEL" GNUNET_TESTING_PREFIX=$PREFIX ../testbed/gnunet-testbed-profiler -n -c test_scalarproduct.conf -p 2 2>service.log &
23sleep 2
24echo tesbed up
25
26# get bob's peer ID, necessary for alice
19PEERIDBOB=`gnunet-peerinfo -qs $CFGB` 27PEERIDBOB=`gnunet-peerinfo -qs $CFGB`
28echo peerinfo receivd
20 29
21#payload for this test on both sides 30GNUNET_LOG="scalarproduct;;;;$LOGLEVEL" gnunet-scalarproduct $CFGBOB $INPUTBOB 2>bob.log &
22INPUTALICE="-k AAAA -e 10,10,10" 31echo bob started
23INPUTBOB="-k AAAA -e 10,10,10" 32GNUNET_LOG="scalarproduct;;;;$LOGLEVEL" gnunet-scalarproduct $CFGALICE $INPUTALICE -p $PEERIDBOB 2>alice.log
33echo alice returned
24 34
25echo "gnunet-scalarproduct $LOG $CFGBOB $INPUTBOB &" 35# termiante the testbed
26echo "gnunet-scalarproduct $LOG $CFGALICE $INPUTALICE -p $PEERIDBOB -L ERROR" 36kill $( pgrep -P $$ | tr '\n' ' ' )
27gnunet-scalarproduct $LOG $CFGBOB $INPUTBOB 2>bob_error.log & 37echo killed testbed
28RESULT=`gnunet-scalarproduct $LOG $CFGALICE $INPUTALICE -p $PEERIDBOB 2>alice_error.log`
29 38
30EXPECTED="12C" 39EXPECTED="12C"
31if [ "$RESULT" == "$EXPECTED" ] 40if [ "$RESULT" == "$EXPECTED" ]