aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/transport/gnunet-service-tng.c181
1 files changed, 33 insertions, 148 deletions
diff --git a/src/transport/gnunet-service-tng.c b/src/transport/gnunet-service-tng.c
index eb3cc2de9..803a8e518 100644
--- a/src/transport/gnunet-service-tng.c
+++ b/src/transport/gnunet-service-tng.c
@@ -27,69 +27,50 @@
27 * - review retransmission logic, right now there is no smartness there! 27 * - review retransmission logic, right now there is no smartness there!
28 * => congestion control, etc [PERFORMANCE-BASICS] 28 * => congestion control, etc [PERFORMANCE-BASICS]
29 * 29 *
30 * Optimizations: 30 * Optimizations-Statistics:
31 * - Track ACK losses based on ACK-counter [ROUTING]
32 * - Need to track total bandwidth per VirtualLink and adjust how frequently
33 * we send FC messages based on bandwidth-delay-product (and relation
34 * to the window size!). See OPTIMIZE-FC-BDP.
35 * - Consider more statistics in #check_connection_quality() [FIXME-CONQ-STATISTICS]
36 * - Adapt available_fc_window_size, using larger values for high-bandwidth
37 * and high-latency links *if* we have the RAM [GOODPUT / utilization / stalls]
38 * - Set last_window_consum_limit promise properly based on
39 * latency and bandwidth of the respective connection [GOODPUT / utilization / stalls]
40 *
41 * Optimizations-DV:
31 * - When forwarding DV learn messages, if a peer is reached that 42 * - When forwarding DV learn messages, if a peer is reached that
32 * has a *bidirectional* link to the origin beyond 1st hop, 43 * has a *bidirectional* link to the origin beyond 1st hop,
33 * do NOT forward it to peers _other_ than the origin, as 44 * do NOT forward it to peers _other_ than the origin, as
34 * there is clearly a better path directly from the origin to 45 * there is clearly a better path directly from the origin to
35 * whatever else we could reach. 46 * whatever else we could reach.
36 * - queue_send_msg by API design has to make a copy
37 * of the payload, and route_message on top of that requires a malloc/free.
38 * Change design to approximate "zero" copy better... [CPU]
39 * - could avoid copying body of message into each fragment and keep
40 * fragments as just pointers into the original message and only
41 * fully build fragments just before transmission (optimization, should
42 * reduce CPU and memory use) [CPU, MEMORY]
43 * - if messages are below MTU, consider adding ACKs and other stuff
44 * to the same transmission to avoid tiny messages (requires planning at
45 * receiver, and additional MST-style demultiplex at receiver!) [PACKET COUNT]
46 * - When we passively learned DV (with unconfirmed freshness), we 47 * - When we passively learned DV (with unconfirmed freshness), we
47 * right now add the path to our list but with a zero path_valid_until 48 * right now add the path to our list but with a zero path_valid_until
48 * time and only use it for unconfirmed routes. However, we could consider 49 * time and only use it for unconfirmed routes. However, we could consider
49 * triggering an explicit validation mechansim ourselves, specifically routing 50 * triggering an explicit validation mechansim ourselves, specifically routing
50 * a challenge-response message over the path [ROUTING] 51 * a challenge-response message over the path [ROUTING]
51 * - Track ACK losses based on ACK-counter [ROUTING] 52 * = if available, try to confirm unconfirmed DV paths when trying to establish
52 * - Fragments send over a reliable channel could do without the
53 * AcknowledgementUUIDP altogether, as they won't be acked! [BANDWIDTH]
54 * (-> have 2nd type of acknowledgment message; low priority, as we
55 * do not have an MTU-limited *reliable* communicator)
56 * - Adapt available_fc_window_size, using larger values for high-bandwidth
57 * and high-latency links *if* we have the RAM [GOODPUT / utilization / stalls]
58 * - Set last_window_consum_limit promise properly based on
59 * latency and bandwidth of the respective connection [GOODPUT / utilization / stalls]
60 * - Need to track total bandwidth per VirtualLink and adjust how frequently
61 * we send FC messages based on bandwidth-delay-product (and relation
62 * to the window size!). See OPTIMIZE-FC-BDP.
63 * - if available, try to confirm unconfirmed DV paths when trying to establish
64 * virtual link for a `struct IncomingRequest`. (i.e. if DVH is 53 * virtual link for a `struct IncomingRequest`. (i.e. if DVH is
65 * unconfirmed, incoming requests cause us to try to validate a passively 54 * unconfirmed, incoming requests cause us to try to validate a passively
66 * learned path (requires new message type!)) 55 * learned path (requires new message type!))
67 * 56 *
68 * Design realizations / discussion: 57 * Optimizations-Fragmentation:
69 * - communicators do flow control by calling MQ "notify sent" 58 * - Fragments send over a reliable channel could do without the
70 * when 'ready'. They determine flow implicitly (i.e. TCP blocking) 59 * AcknowledgementUUIDP altogether, as they won't be acked! [BANDWIDTH]
71 * or explicitly via backchannel FC ACKs. As long as the 60 * (-> have 2nd type of acknowledgment message; low priority, as we
72 * channel is not full, they may 'notify sent' even if the other 61 * do not have an MTU-limited *reliable* communicator) [FIXME-FRAG-REL-UUID]
73 * peer has not yet confirmed receipt. The other peer confirming 62 * - if messages are below MTU, consider adding ACKs and other stuff
74 * is _only_ for FC, not for more reliable transmission; reliable 63 * to the same transmission to avoid tiny messages (requires planning at
75 * transmission (i.e. of fragments) is left to _transport_. 64 * receiver, and additional MST-style demultiplex at receiver!) [PACKET COUNT]
76 * - ACKs sent back in uni-directional communicators are done via 65 *
77 * the background channel API; here transport _may_ initially 66 * Optimizations-internals:
78 * broadcast (with bounded # hops) if no path is known; 67 * - queue_send_msg by API design has to make a copy
79 * - transport should _integrate_ DV-routing and build a view of 68 * of the payload, and route_message on top of that requires a malloc/free.
80 * the network; then background channel traffic can be 69 * Change design to approximate "zero" copy better... [CPU]
81 * routed via DV as well as explicit "DV" traffic. 70 * - could avoid copying body of message into each fragment and keep
82 * - background channel is also used for ACKs and NAT traversal support 71 * fragments as just pointers into the original message and only
83 * - transport service is responsible for AEAD'ing the background 72 * fully build fragments just before transmission (optimization, should
84 * channel, timestamps and monotonic time are used against replay 73 * reduce CPU and memory use) [CPU, MEMORY]
85 * of old messages -> peerstore needs to be supplied with
86 * "latest timestamps seen" data
87 * - if transport implements DV, we likely need a 3rd peermap
88 * in addition to ephemerals and (direct) neighbours
89 * ==> check if stuff needs to be moved out of "Neighbour"
90 * - transport should encapsualte core-level messages and do its
91 * own ACKing for RTT/goodput/loss measurements _and_ fragment
92 * for retransmission
93 */ 74 */
94#include "platform.h" 75#include "platform.h"
95#include "gnunet_util_lib.h" 76#include "gnunet_util_lib.h"
@@ -1309,18 +1290,6 @@ struct VirtualLink
1309 struct DistanceVector *dv; 1290 struct DistanceVector *dv;
1310 1291
1311 /** 1292 /**
1312 * Last challenge we received from @a n.
1313 * FIXME: where do we need this?
1314 */
1315 struct ChallengeNonceP n_challenge;
1316
1317 /**
1318 * Last challenge we used with @a n for flow control.
1319 * FIXME: where do we need this?
1320 */
1321 struct ChallengeNonceP my_challenge;
1322
1323 /**
1324 * Sender timestamp of @e n_challenge, used to generate out-of-order 1293 * Sender timestamp of @e n_challenge, used to generate out-of-order
1325 * challenges (as sender's timestamps must be monotonically 1294 * challenges (as sender's timestamps must be monotonically
1326 * increasing). FIXME: where do we need this? 1295 * increasing). FIXME: where do we need this?
@@ -4223,7 +4192,7 @@ queue_send_msg (struct Queue *queue,
4223 GNUNET_ERROR_TYPE_DEBUG, 4192 GNUNET_ERROR_TYPE_DEBUG,
4224 "Queueing %u bytes of payload for transmission <%llu> on queue %llu to %s\n", 4193 "Queueing %u bytes of payload for transmission <%llu> on queue %llu to %s\n",
4225 (unsigned int) payload_size, 4194 (unsigned int) payload_size,
4226 pm->logging_uuid, 4195 (NULL == pm) ? 0 : pm->logging_uuid,
4227 (unsigned long long) queue->qid, 4196 (unsigned long long) queue->qid,
4228 GNUNET_i2s (&queue->neighbour->pid)); 4197 GNUNET_i2s (&queue->neighbour->pid));
4229 env = GNUNET_MQ_msg_extra (smt, 4198 env = GNUNET_MQ_msg_extra (smt,
@@ -7555,89 +7524,6 @@ check_incoming_msg (void *cls,
7555} 7524}
7556 7525
7557 7526
7558#if 0
7559/**
7560 * We received a @a challenge from another peer, check if we can
7561 * increase the flow control window to that peer.
7562 *
7563 * @param vl virtual link
7564 * @param challenge the challenge we received
7565 * @param sender_time when did the peer send the message?
7566 * @param last_window_consum_limit maximum number of kb the sender
7567 * promises to use of the previous window (if any)
7568 */
7569static void
7570update_fc_window (struct VirtualLink *vl,
7571 struct GNUNET_TIME_Absolute sender_time,
7572 uint32_t last_window_consum_limit)
7573{
7574 // FIXME: update to new FC logic
7575 if (0 == GNUNET_memcmp (challenge, &vl->n_challenge))
7576 {
7577 uint32_t avail;
7578
7579 /* Challenge identical to last one, update
7580 @a last_window_consum_limit (to minimum) */
7581 vl->last_fc_window_size_remaining =
7582 GNUNET_MIN (last_window_consum_limit, vl->last_fc_window_size_remaining);
7583 /* window could have shrunk! */
7584 if (vl->available_fc_window_size > vl->last_fc_window_size_remaining)
7585 avail = vl->available_fc_window_size - vl->last_fc_window_size_remaining;
7586 else
7587 avail = 0;
7588 /* guard against integer overflow */
7589 if (vl->incoming_fc_window_size_used + avail >=
7590 vl->incoming_fc_window_size_used)
7591 vl->incoming_fc_window_size = vl->incoming_fc_window_size_used + avail;
7592 else
7593 vl->incoming_fc_window_size = UINT32_MAX;
7594 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
7595 "Updated window to %u/%u kb (%u used) for virtual link to %s!\n",
7596 vl->incoming_fc_window_size,
7597 vl->available_fc_window_size,
7598 vl->incoming_fc_window_size_used,
7599 GNUNET_i2s (&vl->target));
7600 return;
7601 }
7602 if (vl->n_challenge_time.abs_value_us >= sender_time.abs_value_us)
7603 {
7604 GNUNET_STATISTICS_update (GST_stats,
7605 "# Challenges ignored: sender time not increasing",
7606 1,
7607 GNUNET_NO);
7608 return;
7609 }
7610 /* new challenge! */
7611 if (vl->incoming_fc_window_size_used > last_window_consum_limit)
7612 {
7613 /* lying peer: it already used more than it promised it would ever use! */
7614 GNUNET_break_op (0);
7615 last_window_consum_limit = vl->incoming_fc_window_size_used;
7616 }
7617 /* What remains is at most the difference between what we already processed
7618 and what the sender promises to limit itself to. */
7619 vl->last_fc_window_size_remaining =
7620 last_window_consum_limit - vl->incoming_fc_window_size_used;
7621 vl->n_challenge = *challenge;
7622 vl->n_challenge_time = sender_time;
7623 vl->incoming_fc_window_size_used = 0;
7624 /* window could have shrunk! */
7625 if (vl->available_fc_window_size > vl->last_fc_window_size_remaining)
7626 vl->incoming_fc_window_size =
7627 vl->available_fc_window_size - vl->last_fc_window_size_remaining;
7628 else
7629 vl->incoming_fc_window_size = 0;
7630 GNUNET_log (
7631 GNUNET_ERROR_TYPE_DEBUG,
7632 "New window at %u/%u kb (%u left on previous) for virtual link to %s!\n",
7633 vl->incoming_fc_window_size,
7634 vl->available_fc_window_size,
7635 vl->last_fc_window_size_remaining,
7636 GNUNET_i2s (&vl->target));
7637}
7638#endif
7639
7640
7641/** 7527/**
7642 * Closure for #check_known_address. 7528 * Closure for #check_known_address.
7643 */ 7529 */
@@ -8153,7 +8039,6 @@ handle_validation_response (
8153 n->vl = vl; 8039 n->vl = vl;
8154 vl->core_recv_window = RECV_WINDOW_SIZE; 8040 vl->core_recv_window = RECV_WINDOW_SIZE;
8155 vl->available_fc_window_size = DEFAULT_WINDOW_SIZE; 8041 vl->available_fc_window_size = DEFAULT_WINDOW_SIZE;
8156 vl->my_challenge = tvr->challenge;
8157 vl->visibility_task = 8042 vl->visibility_task =
8158 GNUNET_SCHEDULER_add_at (q->validated_until, &check_link_down, vl); 8043 GNUNET_SCHEDULER_add_at (q->validated_until, &check_link_down, vl);
8159 GNUNET_break (GNUNET_YES == 8044 GNUNET_break (GNUNET_YES ==
@@ -8747,7 +8632,7 @@ select_best_pending_from_link (struct PendingMessageScoreContext *sc,
8747 relb = GNUNET_NO; /* if we fragment, we never also reliability box */ 8632 relb = GNUNET_NO; /* if we fragment, we never also reliability box */
8748 if (GNUNET_TRANSPORT_CC_RELIABLE == queue->tc->details.communicator.cc) 8633 if (GNUNET_TRANSPORT_CC_RELIABLE == queue->tc->details.communicator.cc)
8749 { 8634 {
8750 /* FIXME-OPTIMIZE: we could use an optimized, shorter fragmentation 8635 /* FIXME-FRAG-REL-UUID: we could use an optimized, shorter fragmentation
8751 header without the ACK UUID when using a *reliable* channel! */ 8636 header without the ACK UUID when using a *reliable* channel! */
8752 } 8637 }
8753 real_overhead = overhead + sizeof (struct TransportFragmentBoxMessage); 8638 real_overhead = overhead + sizeof (struct TransportFragmentBoxMessage);
@@ -9440,7 +9325,7 @@ check_connection_quality (void *cls,
9440 ctx->num_queues++; 9325 ctx->num_queues++;
9441 if (0 == ctx->k--) 9326 if (0 == ctx->k--)
9442 ctx->q = q; 9327 ctx->q = q;
9443 /* OPTIMIZE-FIXME: in the future, add reliability / goodput 9328 /* FIXME-CONQ-STATISTICS: in the future, add reliability / goodput
9444 statistics and consider those as well here? */ 9329 statistics and consider those as well here? */
9445 if (q->pd.aged_rtt.rel_value_us < DV_QUALITY_RTT_THRESHOLD.rel_value_us) 9330 if (q->pd.aged_rtt.rel_value_us < DV_QUALITY_RTT_THRESHOLD.rel_value_us)
9446 do_inc = GNUNET_YES; 9331 do_inc = GNUNET_YES;