aboutsummaryrefslogtreecommitdiff
path: root/src/cadet
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2017-01-29 16:58:21 +0100
committerChristian Grothoff <christian@grothoff.org>2017-01-29 16:58:21 +0100
commit65fd774bf2f5ab1ccef337af7371b31e0e7e26a1 (patch)
tree3508d19b228e238f8d37a657a52a58ac7a92a49d /src/cadet
parent4df291c913da262e7060ddae6114f83433b50473 (diff)
downloadgnunet-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.c88
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 */
169static void
170update_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) )