diff options
author | Christian Grothoff <christian@grothoff.org> | 2013-08-23 13:42:15 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2013-08-23 13:42:15 +0000 |
commit | 33b89b07e0ea833955f64d07b7e54e64aab500e9 (patch) | |
tree | cfc01062d4d6951606b00bc62ac087ae78cb500c /src/scalarproduct/test_scalarproduct_api_regression2.c | |
parent | 22ab4538a2f7a21c0c831599a56d50c147de0ae5 (diff) | |
download | gnunet-33b89b07e0ea833955f64d07b7e54e64aab500e9.tar.gz gnunet-33b89b07e0ea833955f64d07b7e54e64aab500e9.zip |
-more vector -> scalar renaming
Diffstat (limited to 'src/scalarproduct/test_scalarproduct_api_regression2.c')
-rw-r--r-- | src/scalarproduct/test_scalarproduct_api_regression2.c | 931 |
1 files changed, 931 insertions, 0 deletions
diff --git a/src/scalarproduct/test_scalarproduct_api_regression2.c b/src/scalarproduct/test_scalarproduct_api_regression2.c new file mode 100644 index 000000000..8a0162b40 --- /dev/null +++ b/src/scalarproduct/test_scalarproduct_api_regression2.c | |||
@@ -0,0 +1,931 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | (C) 2013 Christian Grothoff (and other contributing authors) | ||
4 | |||
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 | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
18 | Boston, MA 02111-1307, USA. | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file vectorproduct/test_vectorproduct_api_regression2.c | ||
23 | * @brief Regression test, destroys requester service before receiving response | ||
24 | * responder service | ||
25 | * @author Gaurav Kukreja | ||
26 | * @author Christian Fuchs | ||
27 | */ | ||
28 | |||
29 | #include <string.h> | ||
30 | |||
31 | #include <inttypes.h> | ||
32 | #include "platform.h" | ||
33 | #include "gnunet_util_lib.h" | ||
34 | #include "gnunet_testbed_service.h" | ||
35 | #include "gnunet_common.h" | ||
36 | #include "gnunet_vectorproduct_service.h" | ||
37 | #include "gnunet_protocols.h" | ||
38 | |||
39 | #define LOG(kind,...) GNUNET_log_from (kind, "test-vectorproduct-api-regression2",__VA_ARGS__) | ||
40 | #define NUM_PEERS 2 | ||
41 | |||
42 | /** | ||
43 | * Structure for holding peer's sockets and IO Handles | ||
44 | */ | ||
45 | struct PeerData | ||
46 | { | ||
47 | /** | ||
48 | * Handle to testbed peer | ||
49 | */ | ||
50 | struct GNUNET_TESTBED_Peer *peer; | ||
51 | |||
52 | /** | ||
53 | * The service connect operation to stream | ||
54 | */ | ||
55 | struct GNUNET_TESTBED_Operation *op; | ||
56 | |||
57 | /** | ||
58 | * Our Peer id | ||
59 | */ | ||
60 | struct GNUNET_PeerIdentity our_id; | ||
61 | |||
62 | /** | ||
63 | * Pointer to Vector Product Handle | ||
64 | */ | ||
65 | struct GNUNET_VECTORPRODUCT_Handle *vh; | ||
66 | }; | ||
67 | |||
68 | /** | ||
69 | * Different states in test setup | ||
70 | */ | ||
71 | enum SetupState | ||
72 | { | ||
73 | /** | ||
74 | * Get the identity of peer 1 | ||
75 | */ | ||
76 | PEER1_GET_IDENTITY, | ||
77 | |||
78 | /** | ||
79 | * Get the identity of peer 2 | ||
80 | */ | ||
81 | PEER2_GET_IDENTITY, | ||
82 | |||
83 | /** | ||
84 | * Connect to stream service of peer 1 | ||
85 | */ | ||
86 | PEER1_VECTORPRODUCT_CONNECT, | ||
87 | |||
88 | /** | ||
89 | * Connect to stream service of peer 2 | ||
90 | */ | ||
91 | PEER2_VECTORPRODUCT_CONNECT | ||
92 | |||
93 | }; | ||
94 | |||
95 | /****************************************************************************** | ||
96 | *** Global Variables ***************************** | ||
97 | ******************************************************************************/ | ||
98 | |||
99 | /** | ||
100 | * Maximum allowed message-ids we can check in one go (with one GNUNET_message) | ||
101 | */ | ||
102 | static unsigned int max_mids; | ||
103 | |||
104 | /** | ||
105 | * Session Key used by both the test peers | ||
106 | */ | ||
107 | char input_key[103] = "helloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhelloworldhe"; | ||
108 | |||
109 | /** | ||
110 | * Input elements for peer1 | ||
111 | */ | ||
112 | char input_elements_peer1[] = "11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11"; | ||
113 | //char input_elements_peer1[] = "11,11,11"; | ||
114 | |||
115 | /** | ||
116 | * Input Mask for peer 1 | ||
117 | */ | ||
118 | char input_mask_peer1[] = "1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1"; | ||
119 | //char input_mask_peer1[] = "1,1,1"; | ||
120 | |||
121 | /** | ||
122 | * the array of converted message IDs to send to our service | ||
123 | */ | ||
124 | static int32_t * elements_peer1 = NULL; | ||
125 | |||
126 | /** | ||
127 | * the array of converted message IDs to send to our service | ||
128 | */ | ||
129 | static unsigned char * mask_peer1 = NULL; | ||
130 | |||
131 | /** | ||
132 | * Number of elements | ||
133 | */ | ||
134 | uint16_t element_count_peer1 = 0; | ||
135 | |||
136 | /** | ||
137 | * Input elements for peer2 | ||
138 | */ | ||
139 | char input_elements_peer2[] = "11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11"; | ||
140 | //char input_elements_peer2[] = "11,11,11"; | ||
141 | |||
142 | /** | ||
143 | * Input Mask for peer 2 | ||
144 | */ | ||
145 | char input_mask_peer2[] = "1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1"; | ||
146 | //char input_mask_peer2[] = "1,1,1"; | ||
147 | |||
148 | /** | ||
149 | * the array of converted message IDs to send to our service | ||
150 | */ | ||
151 | static int32_t * elements_peer2 = NULL; | ||
152 | |||
153 | /** | ||
154 | * the array of converted message IDs to send to our service | ||
155 | */ | ||
156 | static unsigned char * mask_peer2 = NULL; | ||
157 | |||
158 | /** | ||
159 | * Number of elements | ||
160 | */ | ||
161 | uint16_t element_count_peer2 = 0; | ||
162 | |||
163 | /** | ||
164 | * Data context for peer 1 | ||
165 | */ | ||
166 | static struct PeerData peer1; | ||
167 | |||
168 | /** | ||
169 | * Data context for peer 2 | ||
170 | */ | ||
171 | static struct PeerData peer2; | ||
172 | |||
173 | /** | ||
174 | * Various states during test setup | ||
175 | */ | ||
176 | static enum SetupState setup_state; | ||
177 | |||
178 | /** | ||
179 | * Testbed operation handle | ||
180 | */ | ||
181 | static struct GNUNET_TESTBED_Operation *op; | ||
182 | |||
183 | static int ok; | ||
184 | |||
185 | static int responder_ok; | ||
186 | |||
187 | static int requester_ok; | ||
188 | |||
189 | static GNUNET_SCHEDULER_TaskIdentifier abort_task; | ||
190 | /****************************************************************************** | ||
191 | *** Static Functions ***************************** | ||
192 | ******************************************************************************/ | ||
193 | |||
194 | static void | ||
195 | do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); | ||
196 | |||
197 | |||
198 | /** | ||
199 | * Close sockets and stop testing deamons nicely | ||
200 | */ | ||
201 | static void | ||
202 | do_close (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
203 | { | ||
204 | static int closed; | ||
205 | |||
206 | if (peer1.op != NULL) | ||
207 | { | ||
208 | do_shutdown (&peer1, NULL); | ||
209 | } | ||
210 | |||
211 | if (peer2.op != NULL) | ||
212 | { | ||
213 | do_shutdown (&peer2, NULL); | ||
214 | } | ||
215 | |||
216 | if (GNUNET_SCHEDULER_NO_TASK != abort_task) | ||
217 | { | ||
218 | GNUNET_SCHEDULER_cancel (abort_task); | ||
219 | abort_task = GNUNET_SCHEDULER_NO_TASK; | ||
220 | GNUNET_SCHEDULER_shutdown (); /* For shutting down testbed */ | ||
221 | } | ||
222 | |||
223 | if (!closed) | ||
224 | { | ||
225 | closed++; | ||
226 | GNUNET_SCHEDULER_shutdown (); /* For shutting down testbed */ | ||
227 | } | ||
228 | } | ||
229 | |||
230 | /** | ||
231 | * Shutdown a peer | ||
232 | * | ||
233 | * @param cls closure is a pointer to the struct PeerData of the peer to be disconnected | ||
234 | * @param tc Task Context | ||
235 | */ | ||
236 | static void | ||
237 | do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
238 | { | ||
239 | static int shutdown; | ||
240 | shutdown++; | ||
241 | struct PeerData* peer = (struct PeerData*) cls; | ||
242 | |||
243 | // peer->op contains handle to the TESTBED_connect_service operation | ||
244 | // calling operation done, leads to call to vectorproduct_da | ||
245 | if (peer->op != NULL) | ||
246 | { | ||
247 | if (peer == &peer1) | ||
248 | LOG (GNUNET_ERROR_TYPE_INFO, "Disconnecting Peer1\n\n"); | ||
249 | else if (peer == &peer2) | ||
250 | LOG (GNUNET_ERROR_TYPE_INFO, "Disconnecting Peer2\n\n"); | ||
251 | |||
252 | GNUNET_TESTBED_operation_done (peer->op); | ||
253 | peer->op = NULL; | ||
254 | } | ||
255 | |||
256 | if (peer1.op == NULL && peer2.op == NULL) | ||
257 | GNUNET_SCHEDULER_add_now (&do_close, NULL); | ||
258 | } | ||
259 | |||
260 | |||
261 | /** | ||
262 | * Something went wrong and timed out. Kill everything and set error flag | ||
263 | */ | ||
264 | static void | ||
265 | do_abort (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
266 | { | ||
267 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "test: ABORT due to Timeout\n"); | ||
268 | ok = GNUNET_SYSERR; | ||
269 | abort_task = GNUNET_SCHEDULER_NO_TASK; | ||
270 | GNUNET_SCHEDULER_add_now (&do_shutdown, &peer1); | ||
271 | GNUNET_SCHEDULER_add_now (&do_shutdown, &peer2); | ||
272 | } | ||
273 | |||
274 | |||
275 | /** | ||
276 | * Controller event callback | ||
277 | * | ||
278 | * @param cls NULL | ||
279 | * @param event the controller event | ||
280 | */ | ||
281 | static void | ||
282 | controller_event_cb (void *cls, | ||
283 | const struct GNUNET_TESTBED_EventInformation *event) | ||
284 | { | ||
285 | switch (event->type) | ||
286 | { | ||
287 | case GNUNET_TESTBED_ET_OPERATION_FINISHED: | ||
288 | switch (setup_state) | ||
289 | { | ||
290 | case PEER1_VECTORPRODUCT_CONNECT: | ||
291 | case PEER2_VECTORPRODUCT_CONNECT: | ||
292 | GNUNET_assert (NULL == event->details.operation_finished.emsg); | ||
293 | break; | ||
294 | default: | ||
295 | GNUNET_assert (0); | ||
296 | } | ||
297 | break; | ||
298 | default: | ||
299 | GNUNET_assert (0); | ||
300 | } | ||
301 | } | ||
302 | |||
303 | |||
304 | static void | ||
305 | responder_callback (void *cls, | ||
306 | const struct GNUNET_HashCode * key, | ||
307 | enum GNUNET_VECTORPRODUCT_ResponseStatus status) | ||
308 | { | ||
309 | if (status == GNUNET_VECTORPRODUCT_Status_Failure) | ||
310 | { | ||
311 | LOG (GNUNET_ERROR_TYPE_WARNING, "Responder Client received status failure\n"); | ||
312 | responder_ok = -1; | ||
313 | } | ||
314 | else if (status == GNUNET_VECTORPRODUCT_Status_InvalidResponse) | ||
315 | { | ||
316 | LOG (GNUNET_ERROR_TYPE_WARNING, "Responder Client received status invalid response\n"); | ||
317 | responder_ok = -1; | ||
318 | } | ||
319 | else if (GNUNET_VECTORPRODUCT_Status_Timeout == status) | ||
320 | { | ||
321 | LOG (GNUNET_ERROR_TYPE_WARNING, "Responder Client received timeout occured\n"); | ||
322 | // In this regression test, requester is supposed to fail due to timeout | ||
323 | // therefore responder_ok is set to 1, to make regression test pass | ||
324 | responder_ok = 1; | ||
325 | } | ||
326 | else if (GNUNET_VECTORPRODUCT_Status_ServiceDisconnected == status) | ||
327 | { | ||
328 | LOG (GNUNET_ERROR_TYPE_WARNING, "Responder Client received service disconnected!!\n"); | ||
329 | responder_ok = -1; | ||
330 | } | ||
331 | else if (GNUNET_VECTORPRODUCT_Status_Success == status) | ||
332 | { | ||
333 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Responder Client expected response received!\n"); | ||
334 | responder_ok = 1; | ||
335 | } | ||
336 | else | ||
337 | { | ||
338 | LOG (GNUNET_ERROR_TYPE_WARNING, "Responder Client status = %d!\n", (int) status); | ||
339 | responder_ok = -1; | ||
340 | } | ||
341 | // TODO : Responder Session Complete. Shutdown Test Cleanly!!! | ||
342 | //do_shutdown(&peer1, NULL); | ||
343 | GNUNET_SCHEDULER_add_now (&do_shutdown, &peer1); | ||
344 | return; | ||
345 | } | ||
346 | |||
347 | |||
348 | static void | ||
349 | requester_callback (void *cls, | ||
350 | const struct GNUNET_HashCode * key, | ||
351 | const struct GNUNET_PeerIdentity * peer, | ||
352 | enum GNUNET_VECTORPRODUCT_ResponseStatus status, | ||
353 | uint16_t size, struct GNUNET_VECTORPRODUCT_client_response *msg, | ||
354 | uint16_t type) | ||
355 | { | ||
356 | uint32_t product_len; | ||
357 | |||
358 | if (status == GNUNET_VECTORPRODUCT_Status_Failure) | ||
359 | { | ||
360 | LOG (GNUNET_ERROR_TYPE_WARNING, "Requester Client received status failure\n"); | ||
361 | // In this regression test, requester is supposed to receive status failure | ||
362 | // therefore requester_ok is set to 1, to make regression test pass | ||
363 | requester_ok = 1; | ||
364 | } | ||
365 | else if (status == GNUNET_VECTORPRODUCT_Status_InvalidResponse) | ||
366 | { | ||
367 | LOG (GNUNET_ERROR_TYPE_WARNING, "Requester Client received status invalid response\n"); | ||
368 | requester_ok = -1; | ||
369 | } | ||
370 | else if (GNUNET_VECTORPRODUCT_Status_Timeout == status) | ||
371 | { | ||
372 | LOG (GNUNET_ERROR_TYPE_WARNING, "Requester Client timeout occured\n"); | ||
373 | requester_ok = -1; | ||
374 | } | ||
375 | else if (GNUNET_VECTORPRODUCT_Status_ServiceDisconnected == status) | ||
376 | { | ||
377 | LOG (GNUNET_ERROR_TYPE_WARNING, "Requester Client service disconnected!!\n"); | ||
378 | requester_ok = -1; | ||
379 | } | ||
380 | else if (GNUNET_VECTORPRODUCT_Status_Success != status) | ||
381 | { | ||
382 | LOG (GNUNET_ERROR_TYPE_WARNING, "Requester Client Status = %d\n", (int) status); | ||
383 | requester_ok = -1; | ||
384 | } | ||
385 | else if (GNUNET_VECTORPRODUCT_Status_Success == status) | ||
386 | { | ||
387 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Requester Client expected response received!\n"); | ||
388 | |||
389 | product_len = ntohl (msg->product_length); | ||
390 | |||
391 | if (0 < product_len) | ||
392 | { | ||
393 | gcry_mpi_t result; | ||
394 | gcry_error_t ret = 0; | ||
395 | size_t read = 0; | ||
396 | |||
397 | ret = gcry_mpi_scan (&result, GCRYMPI_FMT_USG, (void *) &msg[1], product_len, &read); | ||
398 | |||
399 | if (0 != ret) | ||
400 | { | ||
401 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not convert to mpi to value!\n"); | ||
402 | ok = -1; | ||
403 | } | ||
404 | else | ||
405 | { | ||
406 | uint16_t i = 0; | ||
407 | |||
408 | // calculate expected product | ||
409 | gcry_mpi_t expected_result; | ||
410 | gcry_mpi_t v1; | ||
411 | gcry_mpi_t v2; | ||
412 | gcry_mpi_t v1_v2_prod; | ||
413 | |||
414 | expected_result = gcry_mpi_new (0); | ||
415 | |||
416 | for (i = 0; i < element_count_peer1; i++) | ||
417 | { | ||
418 | uint32_t value; | ||
419 | v1_v2_prod = gcry_mpi_new (0); | ||
420 | |||
421 | // long to gcry_mpi_t | ||
422 | value = elements_peer1[i] >= 0 ? elements_peer1[i] : -elements_peer1[i]; | ||
423 | if (elements_peer1[i] < 0) | ||
424 | { | ||
425 | v1 = gcry_mpi_new (0); | ||
426 | gcry_mpi_sub_ui (v1, v1, value); | ||
427 | } | ||
428 | else | ||
429 | v1 = gcry_mpi_set_ui (NULL, value); | ||
430 | |||
431 | // long to gcry_mpi_t | ||
432 | value = elements_peer2[i] >= 0 ? elements_peer2[i] : -elements_peer2[i]; | ||
433 | if (elements_peer2[i] < 0) | ||
434 | { | ||
435 | v2 = gcry_mpi_new (0); | ||
436 | gcry_mpi_sub_ui (v2, v2, value); | ||
437 | } | ||
438 | else | ||
439 | v2 = gcry_mpi_set_ui (NULL, value); | ||
440 | |||
441 | gcry_mpi_mul (v1_v2_prod, v1, v2); | ||
442 | gcry_mpi_add (expected_result, expected_result, v1_v2_prod); | ||
443 | |||
444 | gcry_mpi_release (v1); | ||
445 | gcry_mpi_release (v2); | ||
446 | gcry_mpi_release (v1_v2_prod); | ||
447 | |||
448 | } | ||
449 | |||
450 | // compare the result | ||
451 | if (!gcry_mpi_cmp (expected_result, result)) | ||
452 | { | ||
453 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Scalar Product matches expected Result!!\n"); | ||
454 | requester_ok = 1; | ||
455 | } | ||
456 | else | ||
457 | { | ||
458 | LOG (GNUNET_ERROR_TYPE_WARNING, "Scalar Product DOES NOT match expected Result!!\n"); | ||
459 | requester_ok = -1; | ||
460 | } | ||
461 | gcry_mpi_release (result); | ||
462 | gcry_mpi_release (expected_result); | ||
463 | } | ||
464 | } | ||
465 | else | ||
466 | { //currently not used, but if we get more info due to MESH we will need this | ||
467 | LOG (GNUNET_ERROR_TYPE_WARNING, "Error during computation of vector product, return code: %d\n", product_len); | ||
468 | requester_ok = -1; | ||
469 | } | ||
470 | } | ||
471 | |||
472 | //do_shutdown(&peer2, NULL); | ||
473 | GNUNET_SCHEDULER_add_now (&do_shutdown, &peer2); | ||
474 | return; | ||
475 | } | ||
476 | |||
477 | |||
478 | static struct GNUNET_VECTORPRODUCT_QueueEntry * | ||
479 | requester_request () | ||
480 | { | ||
481 | GNUNET_assert (peer2.vh != NULL); | ||
482 | |||
483 | unsigned int i; | ||
484 | //uint16_t element_count_peer2 = 0; | ||
485 | uint16_t mask_length = 0; | ||
486 | char * begin = input_elements_peer2; | ||
487 | char * end; | ||
488 | int32_t element; | ||
489 | |||
490 | struct GNUNET_VECTORPRODUCT_QueueEntry *qe; | ||
491 | |||
492 | struct GNUNET_HashCode key; | ||
493 | GNUNET_CRYPTO_hash (input_key, strlen (input_key), &key); | ||
494 | |||
495 | int exit_loop = 0; | ||
496 | /* Read input_elements_peer2, and put in elements_peer2 array */ | ||
497 | do | ||
498 | { | ||
499 | unsigned int mcount = element_count_peer2; | ||
500 | //ignore empty rows of ,,,,,, | ||
501 | while (*begin == ',') | ||
502 | begin++; | ||
503 | // get the length of the current element and replace , with null | ||
504 | for (end = begin; *end && *end != ','; end++); | ||
505 | |||
506 | if (*end == '\0') | ||
507 | exit_loop = 1; | ||
508 | |||
509 | if (1 != sscanf (begin, "%" SCNd32, &element)) | ||
510 | { | ||
511 | FPRINTF (stderr, _ ("Could not convert `%s' to int32_t.\n"), begin); | ||
512 | ok = -1; | ||
513 | return NULL; | ||
514 | } | ||
515 | |||
516 | GNUNET_array_append (elements_peer2, mcount, element); | ||
517 | element_count_peer2++; | ||
518 | |||
519 | begin = ++end; | ||
520 | } | ||
521 | while (!exit_loop && element_count_peer2 < max_mids); | ||
522 | |||
523 | GNUNET_assert (elements_peer2 != NULL); | ||
524 | GNUNET_assert (element_count_peer2 >= 1); | ||
525 | mask_length = element_count_peer2 / 8 + (element_count_peer2 % 8 ? 1 : 0); | ||
526 | mask_peer2 = GNUNET_malloc ((element_count_peer2 / 8) + 2); | ||
527 | GNUNET_assert (NULL != mask_peer2); | ||
528 | |||
529 | /* Read input_mask_peer2 and read in mask_peer2 array */ | ||
530 | if (NULL != input_mask_peer2) | ||
531 | { | ||
532 | begin = input_mask_peer2; | ||
533 | unsigned short mask_count = 0; | ||
534 | int exit_loop = 0; | ||
535 | |||
536 | do | ||
537 | { | ||
538 | //ignore empty rows of ,,,,,, | ||
539 | while (* begin == ',') | ||
540 | begin++; | ||
541 | // get the length of the current element and replace , with null | ||
542 | // gnunet_ascii-armor uses base32, thus we can use , as separator! | ||
543 | for (end = begin; *end && *end != ','; end++); | ||
544 | |||
545 | if (*end == '\0') | ||
546 | exit_loop = 1; | ||
547 | |||
548 | if (1 != sscanf (begin, "%" SCNd32, &element)) | ||
549 | { | ||
550 | FPRINTF (stderr, _ ("Could not convert `%s' to int32_t.\n"), begin); | ||
551 | ok = -1; | ||
552 | return NULL; | ||
553 | } | ||
554 | |||
555 | GNUNET_assert (mask_count <= element_count_peer2); | ||
556 | |||
557 | if (element) | ||
558 | mask_peer2[mask_count / 8] = mask_peer2[mask_count / 8] | 1 << (mask_count % 8); | ||
559 | |||
560 | mask_count++; | ||
561 | begin = ++end; | ||
562 | } | ||
563 | while (!exit_loop); | ||
564 | // +1 to see if we would have more data, which would indicate malformed/superficial input | ||
565 | GNUNET_assert (mask_count == element_count_peer2); | ||
566 | } | ||
567 | else | ||
568 | { | ||
569 | for (i = 0; i <= mask_length; i++) | ||
570 | mask_peer2[i] = UCHAR_MAX; // all 1's | ||
571 | } | ||
572 | |||
573 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Responder peer key %s\n", &peer1.our_id); | ||
574 | |||
575 | // TODO : Create the mask array | ||
576 | qe = GNUNET_VECTORPRODUCT_request (peer2.vh, | ||
577 | &key, | ||
578 | &peer1.our_id, | ||
579 | element_count_peer2, | ||
580 | mask_length, | ||
581 | elements_peer2, mask_peer2, | ||
582 | GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10), | ||
583 | &requester_callback, | ||
584 | NULL); | ||
585 | |||
586 | if (qe == NULL) | ||
587 | { | ||
588 | FPRINTF (stderr, "%s", _ ("Could not send request to vectorproduct service! Exitting!")); | ||
589 | ok = -1; | ||
590 | return NULL; | ||
591 | } | ||
592 | |||
593 | return qe; | ||
594 | } | ||
595 | |||
596 | |||
597 | /** | ||
598 | * Function prepares the message to be sent by peer1 to its vectorproduct service | ||
599 | * to prepare response, and wait for a request session to be initiated by peer1 | ||
600 | */ | ||
601 | static struct GNUNET_VECTORPRODUCT_QueueEntry * | ||
602 | responder_prepare_response () | ||
603 | { | ||
604 | GNUNET_assert (peer1.vh != NULL); | ||
605 | |||
606 | unsigned int i; | ||
607 | //uint16_t element_count_peer1 = 0; | ||
608 | char * begin = input_elements_peer1; | ||
609 | char * end; | ||
610 | int32_t element; | ||
611 | |||
612 | struct GNUNET_VECTORPRODUCT_QueueEntry *qe; | ||
613 | |||
614 | struct GNUNET_HashCode key; | ||
615 | GNUNET_CRYPTO_hash (input_key, strlen (input_key), &key); | ||
616 | |||
617 | int exit_loop = 0; | ||
618 | /* Read input_elements_peer1, and put in elements_peer1 array */ | ||
619 | do | ||
620 | { | ||
621 | unsigned int mcount = element_count_peer1; | ||
622 | //ignore empty rows of ,,,,,, | ||
623 | while (*begin == ',') | ||
624 | begin++; | ||
625 | // get the length of the current element and replace , with null | ||
626 | for (end = begin; *end && *end != ','; end++); | ||
627 | |||
628 | if (*end == '\0') | ||
629 | exit_loop = 1; | ||
630 | |||
631 | if (*end == ',') | ||
632 | *end = '\0'; | ||
633 | |||
634 | if (1 != sscanf (begin, "%" SCNd32, &element)) | ||
635 | { | ||
636 | FPRINTF (stderr, _ ("Could not convert `%s' to int32_t.\n"), begin); | ||
637 | ok = -1; | ||
638 | return NULL; | ||
639 | } | ||
640 | |||
641 | GNUNET_array_append (elements_peer1, mcount, element); | ||
642 | element_count_peer1++; | ||
643 | |||
644 | begin = ++end; | ||
645 | } | ||
646 | while (!exit_loop && element_count_peer1 < max_mids); | ||
647 | |||
648 | GNUNET_assert (elements_peer1 != NULL); | ||
649 | GNUNET_assert (element_count_peer1 >= 1); | ||
650 | |||
651 | qe = GNUNET_VECTORPRODUCT_prepare_response (peer1.vh, | ||
652 | &key, | ||
653 | element_count_peer1, | ||
654 | elements_peer1, | ||
655 | GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10), | ||
656 | &responder_callback, | ||
657 | NULL); | ||
658 | |||
659 | if (qe == NULL) | ||
660 | { | ||
661 | FPRINTF (stderr, "%s", _ ("Could not send request to vectorproduct service! Exitting!")); | ||
662 | ok = -1; | ||
663 | return NULL; | ||
664 | } | ||
665 | return qe; | ||
666 | } | ||
667 | |||
668 | |||
669 | /** | ||
670 | * Scheduler task to initiate requester client | ||
671 | * | ||
672 | * @param cls void* to struct PeerData | ||
673 | * @param tc Task Context | ||
674 | */ | ||
675 | static void | ||
676 | request_task (void *cls, | ||
677 | const struct GNUNET_SCHEDULER_TaskContext | ||
678 | * tc) | ||
679 | { | ||
680 | struct PeerData * peer = cls; | ||
681 | |||
682 | requester_request (); | ||
683 | return; | ||
684 | } | ||
685 | |||
686 | |||
687 | /** | ||
688 | * Scheduler task to initiate responder client | ||
689 | * | ||
690 | * @param cls void* to struct PeerData | ||
691 | * @param tc Task Context | ||
692 | */ | ||
693 | static void | ||
694 | prepare_response_task (void *cls, | ||
695 | const struct GNUNET_SCHEDULER_TaskContext | ||
696 | * tc) | ||
697 | { | ||
698 | struct PeerData * peer = cls; | ||
699 | |||
700 | responder_prepare_response (); | ||
701 | return; | ||
702 | } | ||
703 | |||
704 | |||
705 | static void | ||
706 | peer_stop_callback (void *cls, | ||
707 | const char *emsg) | ||
708 | { | ||
709 | GNUNET_TESTBED_peer_destroy (peer2.peer); | ||
710 | } | ||
711 | |||
712 | /** | ||
713 | * Destroys Peer2 i.e. the initiator peer (Alice) This function is scheduled to | ||
714 | * run a few milliseconds after the request has been sent to the Responding Peer (Bob). | ||
715 | * This function tries to emulate a crash of Peer2. | ||
716 | * | ||
717 | * @param cls Not used | ||
718 | * @param tc Task Context - Not used | ||
719 | */ | ||
720 | static void | ||
721 | destroy_server (void *cls, | ||
722 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
723 | { | ||
724 | LOG (GNUNET_ERROR_TYPE_INFO, "\n***\nKilling the Requesting Client, hopefully before it receives response\n***\n"); | ||
725 | do_shutdown (&peer2, NULL); | ||
726 | GNUNET_TESTBED_peer_stop (peer2.peer, &peer_stop_callback, NULL); | ||
727 | } | ||
728 | |||
729 | |||
730 | /** | ||
731 | * Adapter function called to destroy a connection to | ||
732 | * a service. This function is called when GNUNET_TESTBED_operation_done is | ||
733 | * called for peer->op, which holds the handle for GNUNET_TESTBED_service_connect | ||
734 | * operation. | ||
735 | * | ||
736 | * @param cls closure | ||
737 | * @param op_result service handle returned from the connect adapter | ||
738 | */ | ||
739 | static void | ||
740 | vectorproduct_da (void *cls, void *op_result) | ||
741 | { | ||
742 | struct PeerData* peer = (struct PeerData*) cls; | ||
743 | |||
744 | GNUNET_VECTORPRODUCT_disconnect (peer->vh); | ||
745 | return; | ||
746 | } | ||
747 | |||
748 | |||
749 | /** | ||
750 | * Adapter function called to establish a connection to | ||
751 | * a service. This function is called to by GNUNET_TESTBED_service_connect. | ||
752 | * | ||
753 | * @param cls closure | ||
754 | * @param cfg configuration of the peer to connect to; will be available until | ||
755 | * GNUNET_TESTBED_operation_done() is called on the operation returned | ||
756 | * from GNUNET_TESTBED_service_connect() | ||
757 | * @return service handle to return in 'op_result', NULL on error | ||
758 | */ | ||
759 | static void * | ||
760 | vectorproduct_ca (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg) | ||
761 | { | ||
762 | struct PeerData *p = cls; | ||
763 | |||
764 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer %u (`%s') started\n", (&peer1 == p) ? 1 : 2, | ||
765 | GNUNET_i2s (&p->our_id)); | ||
766 | |||
767 | switch (setup_state) | ||
768 | { | ||
769 | case PEER1_VECTORPRODUCT_CONNECT: | ||
770 | /* Connect peer 2 to vectorproduct service */ | ||
771 | /* The connect adapter vectorproduct_ca will be called to perform the actual connection */ | ||
772 | { | ||
773 | peer2.op = GNUNET_TESTBED_service_connect (&peer2, peer2.peer, "vectorproduct", | ||
774 | NULL, NULL, vectorproduct_ca, | ||
775 | vectorproduct_da, &peer2); | ||
776 | setup_state = PEER2_VECTORPRODUCT_CONNECT; | ||
777 | } | ||
778 | |||
779 | /* Actually connect peer 1 to vectorproduct service */ | ||
780 | peer1.vh = GNUNET_VECTORPRODUCT_connect (cfg); | ||
781 | return peer1.vh; | ||
782 | |||
783 | case PEER2_VECTORPRODUCT_CONNECT: | ||
784 | /* Actually connect peer 2 to vectorproduct service */ | ||
785 | peer2.vh = GNUNET_VECTORPRODUCT_connect (cfg); | ||
786 | |||
787 | |||
788 | if (peer1.vh != NULL && peer2.vh != NULL) | ||
789 | { | ||
790 | GNUNET_SCHEDULER_add_now (&prepare_response_task, &peer1); | ||
791 | GNUNET_SCHEDULER_add_now (&request_task, &peer2); | ||
792 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 6), | ||
793 | &destroy_server, NULL); | ||
794 | } | ||
795 | else | ||
796 | { | ||
797 | // TODO : Handle error. One of the peers is not connected. Cleanly shutdown | ||
798 | ok = -1; | ||
799 | return NULL; | ||
800 | } | ||
801 | return peer2.vh; | ||
802 | default: | ||
803 | GNUNET_assert (0); | ||
804 | } | ||
805 | } | ||
806 | |||
807 | |||
808 | /** | ||
809 | * Callback to be called when the requested peer information is available | ||
810 | * | ||
811 | * @param cb_cls the closure from GNUNET_TETSBED_peer_get_information() | ||
812 | * @param op the operation this callback corresponds to | ||
813 | * @param pinfo the result; will be NULL if the operation has failed | ||
814 | * @param emsg error message if the operation has failed; will be NULL if the | ||
815 | * operation is successfull | ||
816 | */ | ||
817 | static void | ||
818 | peerinfo_cb (void *cb_cls, struct GNUNET_TESTBED_Operation *op_, | ||
819 | const struct GNUNET_TESTBED_PeerInformation *pinfo, | ||
820 | const char *emsg) | ||
821 | { | ||
822 | GNUNET_assert (NULL == emsg); | ||
823 | GNUNET_assert (op == op_); | ||
824 | switch (setup_state) | ||
825 | { | ||
826 | case PEER1_GET_IDENTITY: | ||
827 | { | ||
828 | memcpy (&peer1.our_id, pinfo->result.id, | ||
829 | sizeof (struct GNUNET_PeerIdentity)); | ||
830 | GNUNET_TESTBED_operation_done (op); | ||
831 | |||
832 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer 1 id: %s\n", GNUNET_i2s_full | ||
833 | (&peer1.our_id)); | ||
834 | |||
835 | /* Request for peer id of peer 2*/ | ||
836 | op = GNUNET_TESTBED_peer_get_information (peer2.peer, | ||
837 | GNUNET_TESTBED_PIT_IDENTITY, | ||
838 | &peerinfo_cb, NULL); | ||
839 | setup_state = PEER2_GET_IDENTITY; | ||
840 | } | ||
841 | break; | ||
842 | case PEER2_GET_IDENTITY: | ||
843 | { | ||
844 | memcpy (&peer2.our_id, pinfo->result.id, | ||
845 | sizeof (struct GNUNET_PeerIdentity)); | ||
846 | GNUNET_TESTBED_operation_done (op); | ||
847 | |||
848 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer 2 id: %s\n", GNUNET_i2s_full | ||
849 | (&peer2.our_id)); | ||
850 | |||
851 | /* Connect peer 1 to vectorproduct service */ | ||
852 | /* The connect adapter vectorproduct_ca will be called to perform the actual connection */ | ||
853 | peer1.op = GNUNET_TESTBED_service_connect (&peer1, peer1.peer, "vectorproduct", | ||
854 | NULL, NULL, vectorproduct_ca, | ||
855 | vectorproduct_da, &peer1); | ||
856 | setup_state = PEER1_VECTORPRODUCT_CONNECT; | ||
857 | } | ||
858 | break; | ||
859 | default: | ||
860 | GNUNET_assert (0); | ||
861 | } | ||
862 | } | ||
863 | |||
864 | |||
865 | /** | ||
866 | * Signature of a main function for a testcase. | ||
867 | * | ||
868 | * @param cls closure | ||
869 | * @param num_peers number of peers in 'peers' | ||
870 | * @param peers handle to peers run in the testbed | ||
871 | */ | ||
872 | static void | ||
873 | test_master (void *cls, unsigned int num_peers, | ||
874 | struct GNUNET_TESTBED_Peer **peers) | ||
875 | { | ||
876 | GNUNET_assert (NULL != peers); | ||
877 | GNUNET_assert (NULL != peers[0]); | ||
878 | GNUNET_assert (NULL != peers[1]); | ||
879 | peer1.peer = peers[0]; | ||
880 | peer2.peer = peers[1]; | ||
881 | /* Get the peer identity and configuration of peer 1 */ | ||
882 | op = GNUNET_TESTBED_peer_get_information (peer1.peer, | ||
883 | GNUNET_TESTBED_PIT_IDENTITY, | ||
884 | &peerinfo_cb, NULL); | ||
885 | setup_state = PEER1_GET_IDENTITY; | ||
886 | abort_task = | ||
887 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply | ||
888 | (GNUNET_TIME_UNIT_SECONDS, 20), &do_abort, | ||
889 | NULL); | ||
890 | } | ||
891 | |||
892 | |||
893 | /** | ||
894 | * Main function | ||
895 | */ | ||
896 | int | ||
897 | main (int argc, char **argv) | ||
898 | { | ||
899 | uint64_t event_mask; | ||
900 | |||
901 | ok = GNUNET_NO; | ||
902 | event_mask = 0; | ||
903 | event_mask |= (1LL << GNUNET_TESTBED_ET_OPERATION_FINISHED); | ||
904 | max_mids = (GNUNET_SERVER_MAX_MESSAGE_SIZE - sizeof (struct GNUNET_MessageHeader)) | ||
905 | / sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) - 1; | ||
906 | |||
907 | (void) GNUNET_TESTBED_test_run ("test_vectorproduct_api_regression2", | ||
908 | "test_vectorproduct_api_data.conf", | ||
909 | NUM_PEERS, event_mask, &controller_event_cb, | ||
910 | NULL, | ||
911 | &test_master, NULL); | ||
912 | if (GNUNET_SYSERR == ok) | ||
913 | { | ||
914 | LOG (GNUNET_ERROR_TYPE_ERROR, "Test failing due to some error before calling API for request or prepare_response\n"); | ||
915 | return 1; | ||
916 | } | ||
917 | else if (GNUNET_SYSERR == responder_ok) | ||
918 | { | ||
919 | LOG (GNUNET_ERROR_TYPE_ERROR, "Test failing due to some error in response for responding_client\n"); | ||
920 | return 1; | ||
921 | } | ||
922 | else if (GNUNET_SYSERR == requester_ok) | ||
923 | { | ||
924 | LOG (GNUNET_ERROR_TYPE_ERROR, "Test failing due to some error in response for requesting client\n"); | ||
925 | return 1; | ||
926 | } | ||
927 | else | ||
928 | return 0; | ||
929 | } | ||
930 | |||
931 | |||