diff options
author | Christian Grothoff <christian@grothoff.org> | 2017-01-29 16:58:21 +0100 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2017-01-29 16:58:21 +0100 |
commit | 65fd774bf2f5ab1ccef337af7371b31e0e7e26a1 (patch) | |
tree | 3508d19b228e238f8d37a657a52a58ac7a92a49d /src/cadet | |
parent | 4df291c913da262e7060ddae6114f83433b50473 (diff) | |
download | gnunet-65fd774bf2f5ab1ccef337af7371b31e0e7e26a1.tar.gz gnunet-65fd774bf2f5ab1ccef337af7371b31e0e7e26a1.zip |
fix ready_cb notifications to ensure they exactly happen only when needed
Diffstat (limited to 'src/cadet')
-rw-r--r-- | src/cadet/gnunet-service-cadet-new_connection.c | 88 |
1 files changed, 55 insertions, 33 deletions
diff --git a/src/cadet/gnunet-service-cadet-new_connection.c b/src/cadet/gnunet-service-cadet-new_connection.c index ac16f1a9e..fdc6de620 100644 --- a/src/cadet/gnunet-service-cadet-new_connection.c +++ b/src/cadet/gnunet-service-cadet-new_connection.c | |||
@@ -159,6 +159,37 @@ struct CadetConnection | |||
159 | 159 | ||
160 | 160 | ||
161 | /** | 161 | /** |
162 | * Update the connection state. Also triggers the necessary | ||
163 | * MQM notifications. | ||
164 | * | ||
165 | * @param cc connection to update the state for | ||
166 | * @param new_state new state for @a cc | ||
167 | * @param new_mqm_ready new `mqm_ready` state for @a cc | ||
168 | */ | ||
169 | static void | ||
170 | update_state (struct CadetConnection *cc, | ||
171 | enum CadetConnectionState new_state, | ||
172 | int new_mqm_ready) | ||
173 | { | ||
174 | int old_ready; | ||
175 | int new_ready; | ||
176 | |||
177 | if ( (new_state == cc->state) && | ||
178 | (new_mqm_ready == cc->mqm_ready) ) | ||
179 | return; /* no change, nothing to do */ | ||
180 | old_ready = ( (CADET_CONNECTION_READY == cc->state) && | ||
181 | (GNUNET_YES == cc->mqm_ready) ); | ||
182 | new_ready = ( (CADET_CONNECTION_READY == new_state) && | ||
183 | (GNUNET_YES == new_mqm_ready) ); | ||
184 | cc->state = new_state; | ||
185 | cc->mqm_ready = new_mqm_ready; | ||
186 | if (old_ready != new_ready) | ||
187 | cc->ready_cb (cc->ready_cb_cls, | ||
188 | new_ready); | ||
189 | } | ||
190 | |||
191 | |||
192 | /** | ||
162 | * Destroy a connection, part of the internal implementation. Called | 193 | * Destroy a connection, part of the internal implementation. Called |
163 | * only from #GCC_destroy_from_core() or #GCC_destroy_from_tunnel(). | 194 | * only from #GCC_destroy_from_core() or #GCC_destroy_from_tunnel(). |
164 | * | 195 | * |
@@ -354,18 +385,15 @@ GCC_handle_connection_create_ack (struct CadetConnection *cc) | |||
354 | GNUNET_SCHEDULER_cancel (cc->task); | 385 | GNUNET_SCHEDULER_cancel (cc->task); |
355 | cc->task = NULL; | 386 | cc->task = NULL; |
356 | } | 387 | } |
357 | cc->state = CADET_CONNECTION_READY; | 388 | update_state (cc, |
358 | if (GNUNET_YES == cc->mqm_ready) | 389 | CADET_CONNECTION_READY, |
359 | { | 390 | cc->mqm_ready); |
360 | cc->ready_cb (cc->ready_cb_cls, | 391 | if ( (NULL == cc->keepalive_qe) && |
361 | GNUNET_YES); | 392 | (GNUNET_YES == cc->mqm_ready) && |
362 | if ( (NULL == cc->keepalive_qe) && | 393 | (NULL == cc->task) ) |
363 | (GNUNET_YES == cc->mqm_ready) && | 394 | cc->task = GNUNET_SCHEDULER_add_delayed (keepalive_period, |
364 | (NULL == cc->task) ) | 395 | &send_keepalive, |
365 | cc->task = GNUNET_SCHEDULER_add_delayed (keepalive_period, | 396 | cc); |
366 | &send_keepalive, | ||
367 | cc); | ||
368 | } | ||
369 | } | 397 | } |
370 | 398 | ||
371 | 399 | ||
@@ -472,8 +500,9 @@ send_create (void *cls) | |||
472 | "Sending CADET_CONNECTION_CREATE message for %s\n", | 500 | "Sending CADET_CONNECTION_CREATE message for %s\n", |
473 | GCC_2s (cc)); | 501 | GCC_2s (cc)); |
474 | cc->env = env; | 502 | cc->env = env; |
475 | cc->mqm_ready = GNUNET_NO; | 503 | update_state (cc, |
476 | cc->state = CADET_CONNECTION_SENT; | 504 | CADET_CONNECTION_SENT, |
505 | GNUNET_NO); | ||
477 | GCP_send (cc->mq_man, | 506 | GCP_send (cc->mq_man, |
478 | env); | 507 | env); |
479 | } | 508 | } |
@@ -501,8 +530,9 @@ send_create_ack (void *cls) | |||
501 | GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE_ACK); | 530 | GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE_ACK); |
502 | ack_msg->cid = cc->cid; | 531 | ack_msg->cid = cc->cid; |
503 | cc->env = env; | 532 | cc->env = env; |
504 | cc->mqm_ready = GNUNET_NO; | 533 | update_state (cc, |
505 | cc->state = CADET_CONNECTION_READY; | 534 | CADET_CONNECTION_READY, |
535 | GNUNET_NO); | ||
506 | GCP_send (cc->mq_man, | 536 | GCP_send (cc->mq_man, |
507 | env); | 537 | env); |
508 | } | 538 | } |
@@ -524,14 +554,11 @@ GCC_handle_duplicate_create (struct CadetConnection *cc) | |||
524 | "Got duplicate CREATE for %s, scheduling another ACK (%s)\n", | 554 | "Got duplicate CREATE for %s, scheduling another ACK (%s)\n", |
525 | GCC_2s (cc), | 555 | GCC_2s (cc), |
526 | (GNUNET_YES == cc->mqm_ready) ? "MQM ready" : "MQM busy"); | 556 | (GNUNET_YES == cc->mqm_ready) ? "MQM ready" : "MQM busy"); |
527 | /* Tell tunnel that we are not ready for transmission anymore | ||
528 | (until CREATE_ACK is done) */ | ||
529 | if (CADET_CONNECTION_READY == cc->state) | ||
530 | cc->ready_cb (cc->ready_cb_cls, | ||
531 | GNUNET_NO); | ||
532 | /* Revert back to the state of having only received the 'CREATE', | 557 | /* Revert back to the state of having only received the 'CREATE', |
533 | and immediately proceed to send the CREATE_ACK. */ | 558 | and immediately proceed to send the CREATE_ACK. */ |
534 | cc->state = CADET_CONNECTION_CREATE_RECEIVED; | 559 | update_state (cc, |
560 | CADET_CONNECTION_CREATE_RECEIVED, | ||
561 | cc->mqm_ready); | ||
535 | if (NULL != cc->task) | 562 | if (NULL != cc->task) |
536 | GNUNET_SCHEDULER_cancel (cc->task); | 563 | GNUNET_SCHEDULER_cancel (cc->task); |
537 | cc->task = GNUNET_SCHEDULER_add_now (&send_create_ack, | 564 | cc->task = GNUNET_SCHEDULER_add_now (&send_create_ack, |
@@ -571,24 +598,21 @@ manage_first_hop_mq (void *cls, | |||
571 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 598 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
572 | "Core MQ for %s went down\n", | 599 | "Core MQ for %s went down\n", |
573 | GCC_2s (cc)); | 600 | GCC_2s (cc)); |
574 | cc->state = CADET_CONNECTION_NEW; | 601 | update_state (cc, |
602 | CADET_CONNECTION_NEW, | ||
603 | GNUNET_NO); | ||
575 | cc->retry_delay = GNUNET_TIME_UNIT_ZERO; | 604 | cc->retry_delay = GNUNET_TIME_UNIT_ZERO; |
576 | if (NULL != cc->task) | 605 | if (NULL != cc->task) |
577 | { | 606 | { |
578 | GNUNET_SCHEDULER_cancel (cc->task); | 607 | GNUNET_SCHEDULER_cancel (cc->task); |
579 | cc->task = NULL; | 608 | cc->task = NULL; |
580 | } | 609 | } |
581 | if (GNUNET_YES == cc->mqm_ready) | ||
582 | { | ||
583 | cc->mqm_ready = GNUNET_NO; | ||
584 | if (CADET_CONNECTION_READY == cc->state) | ||
585 | cc->ready_cb (cc->ready_cb_cls, | ||
586 | GNUNET_NO); | ||
587 | } | ||
588 | return; | 610 | return; |
589 | } | 611 | } |
590 | 612 | ||
591 | cc->mqm_ready = GNUNET_YES; | 613 | update_state (cc, |
614 | cc->state, | ||
615 | GNUNET_YES); | ||
592 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 616 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
593 | "Core MQ for %s became available in state %d\n", | 617 | "Core MQ for %s became available in state %d\n", |
594 | GCC_2s (cc), | 618 | GCC_2s (cc), |
@@ -617,8 +641,6 @@ manage_first_hop_mq (void *cls, | |||
617 | cc); | 641 | cc); |
618 | break; | 642 | break; |
619 | case CADET_CONNECTION_READY: | 643 | case CADET_CONNECTION_READY: |
620 | cc->ready_cb (cc->ready_cb_cls, | ||
621 | GNUNET_YES); | ||
622 | if ( (NULL == cc->keepalive_qe) && | 644 | if ( (NULL == cc->keepalive_qe) && |
623 | (GNUNET_YES == cc->mqm_ready) && | 645 | (GNUNET_YES == cc->mqm_ready) && |
624 | (NULL == cc->task) ) | 646 | (NULL == cc->task) ) |