diff options
author | Christian Fuchs <christian.fuchs@cfuchs.net> | 2013-10-18 13:47:30 +0000 |
---|---|---|
committer | Christian Fuchs <christian.fuchs@cfuchs.net> | 2013-10-18 13:47:30 +0000 |
commit | 34365eb5c053d520dce3cc1f90921dc03e42fcdf (patch) | |
tree | a143cf6dd4ab46ce179346442dca21ff92ed01ce /src/scalarproduct | |
parent | 543d8cafc55fde62db363750d9a75536c73cbd79 (diff) | |
download | gnunet-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.c | 89 | ||||
-rwxr-xr-x | src/scalarproduct/test_scalarproduct.sh | 45 |
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 | |||
2280 | invalid_msg: | 2292 | invalid_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 | |||
2384 | invalid_msg: | 2397 | invalid_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: | ||
4 | INPUTALICE="-k AAAA -e 10,10,10" | ||
5 | INPUTBOB="-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 |
5 | PREFIX=/tmp/test-scalarproduct`date +%H%M%S` | 8 | PREFIX=/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? |
8 | CFGALICE="-c $PREFIX/0/config" | 11 | CFGALICE="-c $PREFIX/0/config" |
9 | CFGBOB="-c $PREFIX/1/config" | 12 | CFGBOB="-c $PREFIX/1/config" |
10 | 13 | # log at which loglevel? | |
11 | #log at which loglevel? | 14 | LOGLEVEL=DEBUG |
12 | LOG="-L ERROR" | 15 | |
13 | 16 | echo start | |
14 | #launch two peers in line topology | 17 | # launch two peers in line topology non-interactively |
15 | GNUNET_TESTING_PREFIX=$PREFIX ../testbed/gnunet-testbed-profiler $LOG -c test_scalarproduct.conf -p 2 2>gnunet_error.log & | 18 | # |
16 | sleep 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) |
22 | GNUNET_LOG="scalarproduct;;;;$LOGLEVEL" GNUNET_TESTING_PREFIX=$PREFIX ../testbed/gnunet-testbed-profiler -n -c test_scalarproduct.conf -p 2 2>service.log & | ||
23 | sleep 2 | ||
24 | echo tesbed up | ||
25 | |||
26 | # get bob's peer ID, necessary for alice | ||
19 | PEERIDBOB=`gnunet-peerinfo -qs $CFGB` | 27 | PEERIDBOB=`gnunet-peerinfo -qs $CFGB` |
28 | echo peerinfo receivd | ||
20 | 29 | ||
21 | #payload for this test on both sides | 30 | GNUNET_LOG="scalarproduct;;;;$LOGLEVEL" gnunet-scalarproduct $CFGBOB $INPUTBOB 2>bob.log & |
22 | INPUTALICE="-k AAAA -e 10,10,10" | 31 | echo bob started |
23 | INPUTBOB="-k AAAA -e 10,10,10" | 32 | GNUNET_LOG="scalarproduct;;;;$LOGLEVEL" gnunet-scalarproduct $CFGALICE $INPUTALICE -p $PEERIDBOB 2>alice.log |
33 | echo alice returned | ||
24 | 34 | ||
25 | echo "gnunet-scalarproduct $LOG $CFGBOB $INPUTBOB &" | 35 | # termiante the testbed |
26 | echo "gnunet-scalarproduct $LOG $CFGALICE $INPUTALICE -p $PEERIDBOB -L ERROR" | 36 | kill $( pgrep -P $$ | tr '\n' ' ' ) |
27 | gnunet-scalarproduct $LOG $CFGBOB $INPUTBOB 2>bob_error.log & | 37 | echo killed testbed |
28 | RESULT=`gnunet-scalarproduct $LOG $CFGALICE $INPUTALICE -p $PEERIDBOB 2>alice_error.log` | ||
29 | 38 | ||
30 | EXPECTED="12C" | 39 | EXPECTED="12C" |
31 | if [ "$RESULT" == "$EXPECTED" ] | 40 | if [ "$RESULT" == "$EXPECTED" ] |