aboutsummaryrefslogtreecommitdiff
path: root/src/transport/gnunet-service-tng.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/transport/gnunet-service-tng.c')
-rw-r--r--src/transport/gnunet-service-tng.c152
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
9533static unsigned int
9534check_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
9536update_pm_next_attempt (struct PendingMessage *pm, 9561update_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,