diff options
author | Christian Grothoff <christian@grothoff.org> | 2012-05-08 19:17:03 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2012-05-08 19:17:03 +0000 |
commit | 6623d76dcb3659204935e462a8d0d415c7748a99 (patch) | |
tree | 9d89e4f33b7c60bbd08d2ed85a7d439b963044e6 | |
parent | 31adadd3c4ca45d147392d6fa5ee839be1037740 (diff) | |
download | gnunet-6623d76dcb3659204935e462a8d0d415c7748a99.tar.gz gnunet-6623d76dcb3659204935e462a8d0d415c7748a99.zip |
-allow helper send to be cancelled
-rw-r--r-- | src/core/gnunet-service-core_kx.c | 15 | ||||
-rw-r--r-- | src/dns/gnunet-service-dns.c | 8 | ||||
-rw-r--r-- | src/include/gnunet_helper_lib.h | 23 | ||||
-rw-r--r-- | src/util/helper.c | 135 |
4 files changed, 122 insertions, 59 deletions
diff --git a/src/core/gnunet-service-core_kx.c b/src/core/gnunet-service-core_kx.c index 3f415ebc9..f162184eb 100644 --- a/src/core/gnunet-service-core_kx.c +++ b/src/core/gnunet-service-core_kx.c | |||
@@ -41,7 +41,7 @@ | |||
41 | /** | 41 | /** |
42 | * Set to GNUNET_YES to perform some slightly expensive internal invariant checks. | 42 | * Set to GNUNET_YES to perform some slightly expensive internal invariant checks. |
43 | */ | 43 | */ |
44 | #define EXTRA_CHECKS GNUNET_NO | 44 | #define EXTRA_CHECKS GNUNET_YES |
45 | 45 | ||
46 | /** | 46 | /** |
47 | * How long do we wait for SET_KEY confirmation initially? | 47 | * How long do we wait for SET_KEY confirmation initially? |
@@ -877,6 +877,12 @@ GSC_KX_handle_set_key (struct GSC_KeyExchangeInfo *kx, | |||
877 | (GNUNET_OK != GNUNET_CRYPTO_aes_check_session_key (&k))) | 877 | (GNUNET_OK != GNUNET_CRYPTO_aes_check_session_key (&k))) |
878 | { | 878 | { |
879 | /* failed to decrypt !? */ | 879 | /* failed to decrypt !? */ |
880 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
881 | "Invalid key %x decrypted by %s from message %u (origin: %s)\n", | ||
882 | (unsigned int) GNUNET_CRYPTO_crc32_n (&k, sizeof (struct GNUNET_CRYPTO_AesSessionKey)), | ||
883 | GNUNET_i2s (&GSC_my_identity), | ||
884 | (unsigned int) GNUNET_CRYPTO_crc32_n (&m->encrypted_key, sizeof (struct GNUNET_CRYPTO_RsaEncryptedData)), | ||
885 | GNUNET_h2s (&kx->peer.hashPubKey)); | ||
880 | GNUNET_break_op (0); | 886 | GNUNET_break_op (0); |
881 | return; | 887 | return; |
882 | } | 888 | } |
@@ -1058,6 +1064,13 @@ setup_fresh_setkey (struct GSC_KeyExchangeInfo *kx) | |||
1058 | GNUNET_CRYPTO_AesSessionKey), | 1064 | GNUNET_CRYPTO_AesSessionKey), |
1059 | kx->public_key, | 1065 | kx->public_key, |
1060 | &skm->encrypted_key)); | 1066 | &skm->encrypted_key)); |
1067 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1068 | "Encrypting key %x for %s resulting in message %u (origin: %s)\n", | ||
1069 | (unsigned int) GNUNET_CRYPTO_crc32_n (&kx->encrypt_key, sizeof (struct GNUNET_CRYPTO_AesSessionKey)), | ||
1070 | GNUNET_i2s (&kx->peer), | ||
1071 | (unsigned int) GNUNET_CRYPTO_crc32_n (&skm->encrypted_key, sizeof (struct GNUNET_CRYPTO_RsaEncryptedData)), | ||
1072 | GNUNET_h2s (&GSC_my_identity.hashPubKey)); | ||
1073 | |||
1061 | GNUNET_assert (GNUNET_OK == | 1074 | GNUNET_assert (GNUNET_OK == |
1062 | GNUNET_CRYPTO_rsa_sign (my_private_key, &skm->purpose, | 1075 | GNUNET_CRYPTO_rsa_sign (my_private_key, &skm->purpose, |
1063 | &skm->signature)); | 1076 | &skm->signature)); |
diff --git a/src/dns/gnunet-service-dns.c b/src/dns/gnunet-service-dns.c index 3a8aa054e..173fd24e8 100644 --- a/src/dns/gnunet-service-dns.c +++ b/src/dns/gnunet-service-dns.c | |||
@@ -631,10 +631,10 @@ request_done (struct RequestRecord *rr) | |||
631 | } | 631 | } |
632 | /* final checks & sending */ | 632 | /* final checks & sending */ |
633 | GNUNET_assert (off == reply_len); | 633 | GNUNET_assert (off == reply_len); |
634 | GNUNET_HELPER_send (hijacker, | 634 | (void) GNUNET_HELPER_send (hijacker, |
635 | hdr, | 635 | hdr, |
636 | GNUNET_YES, | 636 | GNUNET_YES, |
637 | NULL, NULL); | 637 | NULL, NULL); |
638 | GNUNET_STATISTICS_update (stats, | 638 | GNUNET_STATISTICS_update (stats, |
639 | gettext_noop ("# DNS requests answered via TUN interface"), | 639 | gettext_noop ("# DNS requests answered via TUN interface"), |
640 | 1, GNUNET_NO); | 640 | 1, GNUNET_NO); |
diff --git a/src/include/gnunet_helper_lib.h b/src/include/gnunet_helper_lib.h index 7115748fc..9c1bc21e2 100644 --- a/src/include/gnunet_helper_lib.h +++ b/src/include/gnunet_helper_lib.h | |||
@@ -75,6 +75,12 @@ typedef void (*GNUNET_HELPER_Continuation)(void *cls, | |||
75 | 75 | ||
76 | 76 | ||
77 | /** | 77 | /** |
78 | * Handle to cancel 'send' | ||
79 | */ | ||
80 | struct GNUNET_HELPER_SendHandle; | ||
81 | |||
82 | |||
83 | /** | ||
78 | * Send an message to the helper. | 84 | * Send an message to the helper. |
79 | * | 85 | * |
80 | * @param h helper to send message to | 86 | * @param h helper to send message to |
@@ -82,10 +88,11 @@ typedef void (*GNUNET_HELPER_Continuation)(void *cls, | |||
82 | * @param can_drop can the message be dropped if there is already one in the queue? | 88 | * @param can_drop can the message be dropped if there is already one in the queue? |
83 | * @param cont continuation to run once the message is out | 89 | * @param cont continuation to run once the message is out |
84 | * @param cont_cls closure for 'cont' | 90 | * @param cont_cls closure for 'cont' |
85 | * @return GNUNET_YES if the message will be sent | 91 | * @return NULL if the message was dropped, |
86 | * GNUNET_NO if the message was dropped | 92 | * otherwise handle to cancel *cont* (actual transmission may |
93 | * not be abortable) | ||
87 | */ | 94 | */ |
88 | int | 95 | struct GNUNET_HELPER_SendHandle * |
89 | GNUNET_HELPER_send (struct GNUNET_HELPER_Handle *h, | 96 | GNUNET_HELPER_send (struct GNUNET_HELPER_Handle *h, |
90 | const struct GNUNET_MessageHeader *msg, | 97 | const struct GNUNET_MessageHeader *msg, |
91 | int can_drop, | 98 | int can_drop, |
@@ -93,4 +100,14 @@ GNUNET_HELPER_send (struct GNUNET_HELPER_Handle *h, | |||
93 | void *cont_cls); | 100 | void *cont_cls); |
94 | 101 | ||
95 | 102 | ||
103 | /** | ||
104 | * Cancel a 'send' operation. If possible, transmitting the | ||
105 | * message is also aborted, but at least 'cont' won't be | ||
106 | * called. | ||
107 | * | ||
108 | * @param sh operation to cancel | ||
109 | */ | ||
110 | void | ||
111 | GNUNET_HELPER_send_cancel (struct GNUNET_HELPER_SendHandle *sh); | ||
112 | |||
96 | #endif /* end of include guard: GNUNET_HELPER_LIB_H */ | 113 | #endif /* end of include guard: GNUNET_HELPER_LIB_H */ |
diff --git a/src/util/helper.c b/src/util/helper.c index 9cf39bbfd..146a2e20d 100644 --- a/src/util/helper.c +++ b/src/util/helper.c | |||
@@ -31,24 +31,29 @@ | |||
31 | /** | 31 | /** |
32 | * Entry in the queue of messages we need to transmit to the helper. | 32 | * Entry in the queue of messages we need to transmit to the helper. |
33 | */ | 33 | */ |
34 | struct HelperMessageQueueEntry | 34 | struct GNUNET_HELPER_SendHandle |
35 | { | 35 | { |
36 | 36 | ||
37 | /** | 37 | /** |
38 | * This is an entry in a DLL. | 38 | * This is an entry in a DLL. |
39 | */ | 39 | */ |
40 | struct HelperMessageQueueEntry *next; | 40 | struct GNUNET_HELPER_SendHandle *next; |
41 | 41 | ||
42 | /** | 42 | /** |
43 | * This is an entry in a DLL. | 43 | * This is an entry in a DLL. |
44 | */ | 44 | */ |
45 | struct HelperMessageQueueEntry *prev; | 45 | struct GNUNET_HELPER_SendHandle *prev; |
46 | 46 | ||
47 | /** | 47 | /** |
48 | * Message to transmit (allocated at the end of this struct) | 48 | * Message to transmit (allocated at the end of this struct) |
49 | */ | 49 | */ |
50 | const struct GNUNET_MessageHeader *msg; | 50 | const struct GNUNET_MessageHeader *msg; |
51 | 51 | ||
52 | /** | ||
53 | * The handle to a helper process. | ||
54 | */ | ||
55 | struct GNUNET_HELPER_Handle *h; | ||
56 | |||
52 | /** | 57 | /** |
53 | * Function to call upon completion. | 58 | * Function to call upon completion. |
54 | */ | 59 | */ |
@@ -106,12 +111,12 @@ struct GNUNET_HELPER_Handle | |||
106 | /** | 111 | /** |
107 | * First message queued for transmission to helper. | 112 | * First message queued for transmission to helper. |
108 | */ | 113 | */ |
109 | struct HelperMessageQueueEntry *mq_head; | 114 | struct GNUNET_HELPER_SendHandle *sh_head; |
110 | 115 | ||
111 | /** | 116 | /** |
112 | * Last message queued for transmission to helper. | 117 | * Last message queued for transmission to helper. |
113 | */ | 118 | */ |
114 | struct HelperMessageQueueEntry *mq_tail; | 119 | struct GNUNET_HELPER_SendHandle *sh_tail; |
115 | 120 | ||
116 | /** | 121 | /** |
117 | * Binary to run. | 122 | * Binary to run. |
@@ -148,7 +153,7 @@ struct GNUNET_HELPER_Handle | |||
148 | static void | 153 | static void |
149 | stop_helper (struct GNUNET_HELPER_Handle *h) | 154 | stop_helper (struct GNUNET_HELPER_Handle *h) |
150 | { | 155 | { |
151 | struct HelperMessageQueueEntry *qe; | 156 | struct GNUNET_HELPER_SendHandle *sh; |
152 | 157 | ||
153 | if (NULL != h->helper_proc) | 158 | if (NULL != h->helper_proc) |
154 | { | 159 | { |
@@ -184,14 +189,14 @@ stop_helper (struct GNUNET_HELPER_Handle *h) | |||
184 | h->helper_out = NULL; | 189 | h->helper_out = NULL; |
185 | h->fh_from_helper = NULL; | 190 | h->fh_from_helper = NULL; |
186 | } | 191 | } |
187 | while (NULL != (qe = h->mq_head)) | 192 | while (NULL != (sh = h->sh_head)) |
188 | { | 193 | { |
189 | GNUNET_CONTAINER_DLL_remove (h->mq_head, | 194 | GNUNET_CONTAINER_DLL_remove (h->sh_head, |
190 | h->mq_tail, | 195 | h->sh_tail, |
191 | qe); | 196 | sh); |
192 | if (NULL != qe->cont) | 197 | if (NULL != sh->cont) |
193 | qe->cont (qe->cont_cls, GNUNET_NO); | 198 | sh->cont (sh->cont_cls, GNUNET_NO); |
194 | GNUNET_free (qe); | 199 | GNUNET_free (sh); |
195 | } | 200 | } |
196 | /* purge MST buffer */ | 201 | /* purge MST buffer */ |
197 | (void) GNUNET_SERVER_mst_receive (h->mst, NULL, NULL, 0, GNUNET_YES, GNUNET_NO); | 202 | (void) GNUNET_SERVER_mst_receive (h->mst, NULL, NULL, 0, GNUNET_YES, GNUNET_NO); |
@@ -380,17 +385,17 @@ GNUNET_HELPER_start (const char *binary_name, | |||
380 | void | 385 | void |
381 | GNUNET_HELPER_stop (struct GNUNET_HELPER_Handle *h) | 386 | GNUNET_HELPER_stop (struct GNUNET_HELPER_Handle *h) |
382 | { | 387 | { |
383 | struct HelperMessageQueueEntry *qe; | 388 | struct GNUNET_HELPER_SendHandle *sh; |
384 | 389 | ||
385 | /* signal pending writes that we were stopped */ | 390 | /* signal pending writes that we were stopped */ |
386 | while (NULL != (qe = h->mq_head)) | 391 | while (NULL != (sh = h->sh_head)) |
387 | { | 392 | { |
388 | GNUNET_CONTAINER_DLL_remove (h->mq_head, | 393 | GNUNET_CONTAINER_DLL_remove (h->sh_head, |
389 | h->mq_tail, | 394 | h->sh_tail, |
390 | qe); | 395 | sh); |
391 | if (NULL != qe->cont) | 396 | if (NULL != sh->cont) |
392 | qe->cont (qe->cont_cls, GNUNET_SYSERR); | 397 | sh->cont (sh->cont_cls, GNUNET_SYSERR); |
393 | GNUNET_free (qe); | 398 | GNUNET_free (sh); |
394 | } | 399 | } |
395 | stop_helper (h); | 400 | stop_helper (h); |
396 | GNUNET_SERVER_mst_destroy (h->mst); | 401 | GNUNET_SERVER_mst_destroy (h->mst); |
@@ -409,7 +414,7 @@ helper_write (void *cls, | |||
409 | const struct GNUNET_SCHEDULER_TaskContext *tc) | 414 | const struct GNUNET_SCHEDULER_TaskContext *tc) |
410 | { | 415 | { |
411 | struct GNUNET_HELPER_Handle *h = cls; | 416 | struct GNUNET_HELPER_Handle *h = cls; |
412 | struct HelperMessageQueueEntry *qe; | 417 | struct GNUNET_HELPER_SendHandle *sh; |
413 | const char *buf; | 418 | const char *buf; |
414 | ssize_t t; | 419 | ssize_t t; |
415 | 420 | ||
@@ -421,10 +426,10 @@ helper_write (void *cls, | |||
421 | h->fh_to_helper, &helper_write, h); | 426 | h->fh_to_helper, &helper_write, h); |
422 | return; | 427 | return; |
423 | } | 428 | } |
424 | if (NULL == (qe = h->mq_head)) | 429 | if (NULL == (sh = h->sh_head)) |
425 | return; /* how did this happen? */ | 430 | return; /* how did this happen? */ |
426 | buf = (const char*) qe->msg; | 431 | buf = (const char*) sh->msg; |
427 | t = GNUNET_DISK_file_write (h->fh_to_helper, &buf[qe->wpos], ntohs (qe->msg->size) - qe->wpos); | 432 | t = GNUNET_DISK_file_write (h->fh_to_helper, &buf[sh->wpos], ntohs (sh->msg->size) - sh->wpos); |
428 | if (t <= 0) | 433 | if (t <= 0) |
429 | { | 434 | { |
430 | /* On write-error, restart the helper */ | 435 | /* On write-error, restart the helper */ |
@@ -439,17 +444,17 @@ helper_write (void *cls, | |||
439 | &restart_task, h); | 444 | &restart_task, h); |
440 | return; | 445 | return; |
441 | } | 446 | } |
442 | qe->wpos += t; | 447 | sh->wpos += t; |
443 | if (qe->wpos == ntohs (qe->msg->size)) | 448 | if (sh->wpos == ntohs (sh->msg->size)) |
444 | { | 449 | { |
445 | GNUNET_CONTAINER_DLL_remove (h->mq_head, | 450 | GNUNET_CONTAINER_DLL_remove (h->sh_head, |
446 | h->mq_tail, | 451 | h->sh_tail, |
447 | qe); | 452 | sh); |
448 | if (NULL != qe->cont) | 453 | if (NULL != sh->cont) |
449 | qe->cont (qe->cont_cls, GNUNET_YES); | 454 | sh->cont (sh->cont_cls, GNUNET_YES); |
450 | GNUNET_free (qe); | 455 | GNUNET_free (sh); |
451 | } | 456 | } |
452 | if (NULL != h->mq_head) | 457 | if (NULL != h->sh_head) |
453 | h->write_task = GNUNET_SCHEDULER_add_write_file (GNUNET_TIME_UNIT_FOREVER_REL, | 458 | h->write_task = GNUNET_SCHEDULER_add_write_file (GNUNET_TIME_UNIT_FOREVER_REL, |
454 | h->fh_to_helper, | 459 | h->fh_to_helper, |
455 | &helper_write, | 460 | &helper_write, |
@@ -466,40 +471,68 @@ helper_write (void *cls, | |||
466 | * @param cont continuation to run once the message is out (PREREQ_DONE on succees, CANCEL | 471 | * @param cont continuation to run once the message is out (PREREQ_DONE on succees, CANCEL |
467 | * if the helper process died, NULL during GNUNET_HELPER_stop). | 472 | * if the helper process died, NULL during GNUNET_HELPER_stop). |
468 | * @param cont_cls closure for 'cont' | 473 | * @param cont_cls closure for 'cont' |
469 | * @return GNUNET_YES if the message will be sent | 474 | * @return NULL if the message was dropped, |
470 | * GNUNET_NO if the message was dropped | 475 | * otherwise handle to cancel *cont* (actual transmission may |
476 | * not be abortable) | ||
471 | */ | 477 | */ |
472 | int | 478 | struct GNUNET_HELPER_SendHandle * |
473 | GNUNET_HELPER_send (struct GNUNET_HELPER_Handle *h, | 479 | GNUNET_HELPER_send (struct GNUNET_HELPER_Handle *h, |
474 | const struct GNUNET_MessageHeader *msg, | 480 | const struct GNUNET_MessageHeader *msg, |
475 | int can_drop, | 481 | int can_drop, |
476 | GNUNET_HELPER_Continuation cont, | 482 | GNUNET_HELPER_Continuation cont, |
477 | void *cont_cls) | 483 | void *cont_cls) |
478 | { | 484 | { |
479 | struct HelperMessageQueueEntry *qe; | 485 | struct GNUNET_HELPER_SendHandle *sh; |
480 | uint16_t mlen; | 486 | uint16_t mlen; |
481 | 487 | ||
482 | if (NULL == h->fh_to_helper) | 488 | if (NULL == h->fh_to_helper) |
483 | return GNUNET_NO; | 489 | return NULL; |
484 | if ( (GNUNET_YES == can_drop) && | 490 | if ( (GNUNET_YES == can_drop) && |
485 | (h->mq_head != NULL) ) | 491 | (NULL != h->sh_head) ) |
486 | return GNUNET_NO; | 492 | return NULL; |
487 | mlen = ntohs (msg->size); | 493 | mlen = ntohs (msg->size); |
488 | qe = GNUNET_malloc (sizeof (struct HelperMessageQueueEntry) + mlen); | 494 | sh = GNUNET_malloc (sizeof (struct GNUNET_HELPER_SendHandle) + mlen); |
489 | qe->msg = (const struct GNUNET_MessageHeader*) &qe[1]; | 495 | sh->msg = (const struct GNUNET_MessageHeader*) &sh[1]; |
490 | memcpy (&qe[1], msg, mlen); | 496 | memcpy (&sh[1], msg, mlen); |
491 | qe->cont = cont; | 497 | sh->h = h; |
492 | qe->cont_cls = cont_cls; | 498 | sh->cont = cont; |
493 | GNUNET_CONTAINER_DLL_insert_tail (h->mq_head, | 499 | sh->cont_cls = cont_cls; |
494 | h->mq_tail, | 500 | GNUNET_CONTAINER_DLL_insert_tail (h->sh_head, |
495 | qe); | 501 | h->sh_tail, |
502 | sh); | ||
496 | if (GNUNET_SCHEDULER_NO_TASK == h->write_task) | 503 | if (GNUNET_SCHEDULER_NO_TASK == h->write_task) |
497 | h->write_task = GNUNET_SCHEDULER_add_write_file (GNUNET_TIME_UNIT_FOREVER_REL, | 504 | h->write_task = GNUNET_SCHEDULER_add_write_file (GNUNET_TIME_UNIT_FOREVER_REL, |
498 | h->fh_to_helper, | 505 | h->fh_to_helper, |
499 | &helper_write, | 506 | &helper_write, |
500 | h); | 507 | h); |
501 | 508 | ||
502 | return GNUNET_YES; | 509 | return sh; |
510 | } | ||
511 | |||
512 | /** | ||
513 | * Cancel a 'send' operation. If possible, transmitting the | ||
514 | * message is also aborted, but at least 'cont' won't be | ||
515 | * called. | ||
516 | * | ||
517 | * @param sh operation to cancel | ||
518 | */ | ||
519 | void | ||
520 | GNUNET_HELPER_send_cancel (struct GNUNET_HELPER_SendHandle *sh) | ||
521 | { | ||
522 | struct GNUNET_HELPER_Handle *h = sh->h; | ||
523 | |||
524 | sh->cont = NULL; | ||
525 | sh->cont_cls = NULL; | ||
526 | if (0 == sh->wpos) | ||
527 | { | ||
528 | GNUNET_CONTAINER_DLL_remove (h->sh_head, h->sh_tail, sh); | ||
529 | if (NULL == h->sh_head) | ||
530 | { | ||
531 | GNUNET_SCHEDULER_cancel (h->write_task); | ||
532 | h->write_task = GNUNET_SCHEDULER_NO_TASK; | ||
533 | } | ||
534 | GNUNET_free (sh); | ||
535 | } | ||
503 | } | 536 | } |
504 | 537 | ||
505 | 538 | ||