diff options
Diffstat (limited to 'src/transport/gnunet-service-tng.c')
-rw-r--r-- | src/transport/gnunet-service-tng.c | 152 |
1 files changed, 118 insertions, 34 deletions
diff --git a/src/transport/gnunet-service-tng.c b/src/transport/gnunet-service-tng.c index 6b835a209..7b89be7cb 100644 --- a/src/transport/gnunet-service-tng.c +++ b/src/transport/gnunet-service-tng.c | |||
@@ -2285,6 +2285,12 @@ struct PendingMessage | |||
2285 | * Are we sending fragments at the moment? | 2285 | * Are we sending fragments at the moment? |
2286 | */ | 2286 | */ |
2287 | unsigned int frags_in_flight; | 2287 | unsigned int frags_in_flight; |
2288 | |||
2289 | /** | ||
2290 | * How many fragments do we have? | ||
2291 | **/ | ||
2292 | uint16_t frag_count; | ||
2293 | |||
2288 | /** | 2294 | /** |
2289 | * #GNUNET_YES once @e msg_uuid was initialized | 2295 | * #GNUNET_YES once @e msg_uuid was initialized |
2290 | */ | 2296 | */ |
@@ -9524,6 +9530,25 @@ reorder_root_pm (struct PendingMessage *pm, | |||
9524 | } | 9530 | } |
9525 | 9531 | ||
9526 | 9532 | ||
9533 | static unsigned int | ||
9534 | check_next_attempt_tree (struct PendingMessage *pm, | ||
9535 | struct GNUNET_TIME_Absolute next_attempt) | ||
9536 | { | ||
9537 | struct PendingMessage *pos; | ||
9538 | |||
9539 | pos = pm->head_frag; | ||
9540 | while (NULL != pos) | ||
9541 | { | ||
9542 | if (pos->next_attempt.abs_value_us != next_attempt.abs_value_us || | ||
9543 | GNUNET_YES == check_next_attempt_tree (pos, next_attempt)) | ||
9544 | return GNUNET_YES; | ||
9545 | pos = pos->next_frag; | ||
9546 | } | ||
9547 | |||
9548 | return GNUNET_NO; | ||
9549 | } | ||
9550 | |||
9551 | |||
9527 | /** | 9552 | /** |
9528 | * Change the value of the `next_attempt` field of @a pm | 9553 | * Change the value of the `next_attempt` field of @a pm |
9529 | * to @a next_attempt and re-order @a pm in the transmission | 9554 | * to @a next_attempt and re-order @a pm in the transmission |
@@ -9536,19 +9561,16 @@ static void | |||
9536 | update_pm_next_attempt (struct PendingMessage *pm, | 9561 | update_pm_next_attempt (struct PendingMessage *pm, |
9537 | struct GNUNET_TIME_Absolute next_attempt) | 9562 | struct GNUNET_TIME_Absolute next_attempt) |
9538 | { | 9563 | { |
9539 | |||
9540 | // TODO Do we really need a next_attempt value for PendingMessage other than the root Pending Message? | ||
9541 | pm->next_attempt = next_attempt; | ||
9542 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
9543 | "Next attempt for message <%llu> set to %s\n", | ||
9544 | pm->logging_uuid, | ||
9545 | GNUNET_STRINGS_absolute_time_to_string (next_attempt)); | ||
9546 | |||
9547 | if (NULL == pm->frag_parent) | 9564 | if (NULL == pm->frag_parent) |
9548 | { | 9565 | { |
9566 | pm->next_attempt = next_attempt; | ||
9567 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
9568 | "Next attempt for message <%llu> set to %lu\n", | ||
9569 | pm->logging_uuid, | ||
9570 | next_attempt.abs_value_us); | ||
9549 | reorder_root_pm (pm, next_attempt); | 9571 | reorder_root_pm (pm, next_attempt); |
9550 | } | 9572 | } |
9551 | else if ((PMT_RELIABILITY_BOX == pm->pmt) || (PMT_DV_BOX == pm->pmt)) | 9573 | else if ((PMT_RELIABILITY_BOX == pm->pmt) || (PMT_DV_BOX == pm->pmt))// || (PMT_FRAGMENT_BOX == pm->pmt)) |
9552 | { | 9574 | { |
9553 | struct PendingMessage *root = pm->frag_parent; | 9575 | struct PendingMessage *root = pm->frag_parent; |
9554 | 9576 | ||
@@ -9563,28 +9585,59 @@ update_pm_next_attempt (struct PendingMessage *pm, | |||
9563 | } | 9585 | } |
9564 | else | 9586 | else |
9565 | { | 9587 | { |
9566 | /* re-insert sort in fragment list */ | 9588 | struct PendingMessage *root = pm->frag_parent; |
9567 | struct PendingMessage *fp = pm->frag_parent; | 9589 | |
9568 | struct PendingMessage *pos; | 9590 | while (NULL != root->frag_parent) |
9569 | 9591 | root = root->frag_parent; | |
9570 | GNUNET_CONTAINER_MDLL_remove (frag, fp->head_frag, fp->tail_frag, pm); | 9592 | |
9571 | pos = fp->tail_frag; | 9593 | if (GNUNET_NO == root->frags_in_flight) |
9572 | while ((NULL != pos) && | ||
9573 | (next_attempt.abs_value_us > pos->next_attempt.abs_value_us)) | ||
9574 | pos = pos->prev_frag; | ||
9575 | GNUNET_CONTAINER_MDLL_insert_after (frag, | ||
9576 | fp->head_frag, | ||
9577 | fp->tail_frag, | ||
9578 | pos, | ||
9579 | pm); | ||
9580 | if (NULL == pos) | ||
9581 | { | 9594 | { |
9582 | pos = fp; | 9595 | root->next_attempt = next_attempt; |
9583 | // Get the root pm | 9596 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
9584 | while (NULL != pos->frag_parent) | 9597 | "Next attempt for fragmented message <%llu> (<%llu>)set to %lu\n", |
9585 | pos = pos->frag_parent; | 9598 | pm->logging_uuid, |
9586 | pos->next_attempt = next_attempt; | 9599 | root->logging_uuid, |
9587 | reorder_root_pm (pos, next_attempt); | 9600 | next_attempt.abs_value_us); |
9601 | } | ||
9602 | |||
9603 | pm->next_attempt = root->next_attempt; | ||
9604 | |||
9605 | if (root->bytes_msg == root->frag_off) | ||
9606 | root->frags_in_flight = check_next_attempt_tree (root, | ||
9607 | root->next_attempt); | ||
9608 | else | ||
9609 | root->frags_in_flight = GNUNET_YES; | ||
9610 | |||
9611 | if (GNUNET_NO == root->frags_in_flight) | ||
9612 | { | ||
9613 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
9614 | "We have no fragments in flight for message %llu, reorder root! Next attempt is %lu\n", | ||
9615 | root->logging_uuid, | ||
9616 | root->next_attempt.abs_value_us); | ||
9617 | reorder_root_pm (root, root->next_attempt); | ||
9618 | root->frag_count = 0; | ||
9619 | root->next_attempt = GNUNET_TIME_UNIT_ZERO_ABS; | ||
9620 | } | ||
9621 | else | ||
9622 | { | ||
9623 | double factor = (root->frag_count - 1) / root->frag_count; | ||
9624 | struct GNUNET_TIME_Relative s1; | ||
9625 | struct GNUNET_TIME_Relative s2; | ||
9626 | struct GNUNET_TIME_Relative plus_mean = | ||
9627 | GNUNET_TIME_absolute_get_duration (root->next_attempt); | ||
9628 | struct GNUNET_TIME_Relative plus = GNUNET_TIME_absolute_get_duration ( | ||
9629 | next_attempt); | ||
9630 | |||
9631 | s1 = GNUNET_TIME_relative_multiply (plus_mean, | ||
9632 | factor); | ||
9633 | s2 = GNUNET_TIME_relative_divide (plus, | ||
9634 | root->frag_count); | ||
9635 | plus_mean = GNUNET_TIME_relative_add (s1, s2); | ||
9636 | root->next_attempt = GNUNET_TIME_relative_to_absolute (plus_mean); | ||
9637 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
9638 | "We have fragments in flight for message %llu, do not reorder root! Actual next attempt %lu\n", | ||
9639 | root->logging_uuid, | ||
9640 | root->next_attempt.abs_value_us); | ||
9588 | } | 9641 | } |
9589 | } | 9642 | } |
9590 | } | 9643 | } |
@@ -10053,6 +10106,34 @@ transmit_on_queue (void *cls) | |||
10053 | else | 10106 | else |
10054 | { | 10107 | { |
10055 | struct GNUNET_TIME_Relative wait_duration; | 10108 | struct GNUNET_TIME_Relative wait_duration; |
10109 | unsigned int wait_multiplier; | ||
10110 | |||
10111 | if (PMT_FRAGMENT_BOX == pm->pmt) | ||
10112 | { | ||
10113 | struct PendingMessage *root; | ||
10114 | |||
10115 | root = pm->frag_parent; | ||
10116 | while (NULL != root->frag_parent) | ||
10117 | root = root->frag_parent; | ||
10118 | |||
10119 | root->frag_count++; | ||
10120 | wait_multiplier = (unsigned int) ceil (root->bytes_msg | ||
10121 | / (root->frag_off | ||
10122 | / root->frag_count)) * 4; | ||
10123 | } | ||
10124 | else | ||
10125 | { | ||
10126 | // No fragments, we use 4 RTT before retransmitting. | ||
10127 | wait_multiplier = 4; | ||
10128 | } | ||
10129 | |||
10130 | // Depending on how much pending message the VirtualLink is queueing, we wait longer. | ||
10131 | // wait_multiplier = wait_multiplier * pm->vl->pending_msg_num; | ||
10132 | |||
10133 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
10134 | "Wait multiplier %u num pending msg %u\n", | ||
10135 | wait_multiplier, | ||
10136 | pm->vl->pending_msg_num); | ||
10056 | 10137 | ||
10057 | /* Message not finished, waiting for acknowledgement. | 10138 | /* Message not finished, waiting for acknowledgement. |
10058 | Update time by which we might retransmit 's' based on queue | 10139 | Update time by which we might retransmit 's' based on queue |
@@ -10069,23 +10150,26 @@ transmit_on_queue (void *cls) | |||
10069 | queue->pd.aged_rtt.rel_value_us) | 10150 | queue->pd.aged_rtt.rel_value_us) |
10070 | wait_duration = queue->pd.aged_rtt; | 10151 | wait_duration = queue->pd.aged_rtt; |
10071 | else | 10152 | else |
10153 | { | ||
10072 | wait_duration = DEFAULT_ACK_WAIT_DURATION; | 10154 | wait_duration = DEFAULT_ACK_WAIT_DURATION; |
10155 | wait_multiplier = 4; | ||
10156 | } | ||
10073 | struct GNUNET_TIME_Absolute next = GNUNET_TIME_relative_to_absolute ( | 10157 | struct GNUNET_TIME_Absolute next = GNUNET_TIME_relative_to_absolute ( |
10074 | GNUNET_TIME_relative_multiply ( | 10158 | GNUNET_TIME_relative_multiply ( |
10075 | wait_duration, 4)); | 10159 | wait_duration, wait_multiplier)); |
10076 | struct GNUNET_TIME_Relative plus = GNUNET_TIME_relative_multiply ( | 10160 | struct GNUNET_TIME_Relative plus = GNUNET_TIME_relative_multiply ( |
10077 | wait_duration, 4); | 10161 | wait_duration, wait_multiplier); |
10078 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 10162 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
10079 | "Waiting %s (%s) for ACK until %s\n", | 10163 | "Waiting %s (%s) for ACK until %s\n", |
10080 | GNUNET_STRINGS_relative_time_to_string ( | 10164 | GNUNET_STRINGS_relative_time_to_string ( |
10081 | GNUNET_TIME_relative_multiply ( | 10165 | GNUNET_TIME_relative_multiply ( |
10082 | queue->pd.aged_rtt, 4), GNUNET_NO), | 10166 | queue->pd.aged_rtt, wait_multiplier), GNUNET_NO), |
10083 | GNUNET_STRINGS_relative_time_to_string (plus, GNUNET_YES), | 10167 | GNUNET_STRINGS_relative_time_to_string (plus, GNUNET_YES), |
10084 | GNUNET_STRINGS_absolute_time_to_string (next)); | 10168 | GNUNET_STRINGS_absolute_time_to_string (next)); |
10085 | update_pm_next_attempt (pm, | 10169 | update_pm_next_attempt (pm, |
10086 | GNUNET_TIME_relative_to_absolute ( | 10170 | GNUNET_TIME_relative_to_absolute ( |
10087 | GNUNET_TIME_relative_multiply (wait_duration, | 10171 | GNUNET_TIME_relative_multiply (wait_duration, |
10088 | 4))); | 10172 | wait_multiplier))); |
10089 | } | 10173 | } |
10090 | /* finally, re-schedule queue transmission task itself */ | 10174 | /* finally, re-schedule queue transmission task itself */ |
10091 | schedule_transmit_on_queue (GNUNET_TIME_UNIT_ZERO, | 10175 | schedule_transmit_on_queue (GNUNET_TIME_UNIT_ZERO, |