diff options
author | Christian Grothoff <christian@grothoff.org> | 2019-04-15 23:30:02 +0200 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2019-04-15 23:30:02 +0200 |
commit | c3ea963e7c675ffb507ed94930321aef97d86adf (patch) | |
tree | be908d03b248cdda40846473ac97e1e99e1453ab /src/transport | |
parent | bdc605b20237d49213d1ab37d62752a5f97d1d2e (diff) | |
download | gnunet-c3ea963e7c675ffb507ed94930321aef97d86adf.tar.gz gnunet-c3ea963e7c675ffb507ed94930321aef97d86adf.zip |
implement basic reliability ACK handling
Diffstat (limited to 'src/transport')
-rw-r--r-- | src/transport/gnunet-service-tng.c | 84 |
1 files changed, 79 insertions, 5 deletions
diff --git a/src/transport/gnunet-service-tng.c b/src/transport/gnunet-service-tng.c index 6a8a3fc4d..15a634286 100644 --- a/src/transport/gnunet-service-tng.c +++ b/src/transport/gnunet-service-tng.c | |||
@@ -33,15 +33,15 @@ | |||
33 | * transport-to-transport traffic) | 33 | * transport-to-transport traffic) |
34 | * | 34 | * |
35 | * Implement next: | 35 | * Implement next: |
36 | * - backchannel message encryption & decryption | ||
36 | * - DV data structures: | 37 | * - DV data structures: |
37 | * + using DV routes! | 38 | * + using DV routes! |
38 | * - handling of DV-boxed messages that need to be forwarded | 39 | * - handling of DV-boxed messages that need to be forwarded |
39 | * - route_message implementation, including using DV data structures | 40 | * - route_message implementation, including using DV data structures |
40 | * (but not when routing certain message types, like DV learn, | 41 | * (but not when routing certain message types, like DV learn, |
41 | * MUST pay attention to content here -- or pass extra flags?) | 42 | * MUST pay attention to content here -- or pass extra flags?) |
42 | * - ACK handling / retransmission | 43 | * - retransmission |
43 | * - track RTT, distance, loss, etc. | 44 | * - track RTT, distance, loss, etc. => requires extra data structures! |
44 | * - backchannel message encryption & decryption | ||
45 | * | 45 | * |
46 | * Later: | 46 | * Later: |
47 | * - change transport-core API to provide proper flow control in both | 47 | * - change transport-core API to provide proper flow control in both |
@@ -56,6 +56,11 @@ | |||
56 | * fully build fragments just before transmission (optimization, should | 56 | * fully build fragments just before transmission (optimization, should |
57 | * reduce CPU and memory use) | 57 | * reduce CPU and memory use) |
58 | * | 58 | * |
59 | * Optimizations: | ||
60 | * - use shorthashmap on msg_uuid's when matching reliability/fragment ACKs | ||
61 | * against our pending message queue (requires additional per neighbour | ||
62 | * hash map to be maintained, avoids possible linear scan on pending msgs) | ||
63 | * | ||
59 | * Design realizations / discussion: | 64 | * Design realizations / discussion: |
60 | * - communicators do flow control by calling MQ "notify sent" | 65 | * - communicators do flow control by calling MQ "notify sent" |
61 | * when 'ready'. They determine flow implicitly (i.e. TCP blocking) | 66 | * when 'ready'. They determine flow implicitly (i.e. TCP blocking) |
@@ -3828,6 +3833,9 @@ handle_fragment_ack (void *cls, | |||
3828 | // the queue used is unique? | 3833 | // the queue used is unique? |
3829 | // -> how can we get loss rates? | 3834 | // -> how can we get loss rates? |
3830 | // -> or, add extra state to Box and ACK to identify queue? | 3835 | // -> or, add extra state to Box and ACK to identify queue? |
3836 | // IDEA: generate MULTIPLE frag-uuids per fragment and track | ||
3837 | // the queue with the fragment! (-> this logic must | ||
3838 | // be moved into check_ack_against_pm!) | ||
3831 | (void) avg_ack_delay; | 3839 | (void) avg_ack_delay; |
3832 | } | 3840 | } |
3833 | else | 3841 | else |
@@ -3926,9 +3934,75 @@ handle_reliability_ack (void *cls, | |||
3926 | const struct TransportReliabilityAckMessage *ra) | 3934 | const struct TransportReliabilityAckMessage *ra) |
3927 | { | 3935 | { |
3928 | struct CommunicatorMessageContext *cmc = cls; | 3936 | struct CommunicatorMessageContext *cmc = cls; |
3937 | struct Neighbour *n; | ||
3938 | unsigned int n_acks; | ||
3939 | const struct GNUNET_ShortHashCode *msg_uuids; | ||
3940 | struct PendingMessage *nxt; | ||
3941 | int matched; | ||
3942 | |||
3943 | n = GNUNET_CONTAINER_multipeermap_get (neighbours, | ||
3944 | &cmc->im.sender); | ||
3945 | if (NULL == n) | ||
3946 | { | ||
3947 | struct GNUNET_SERVICE_Client *client = cmc->tc->client; | ||
3948 | |||
3949 | GNUNET_break (0); | ||
3950 | finish_cmc_handling (cmc); | ||
3951 | GNUNET_SERVICE_client_drop (client); | ||
3952 | return; | ||
3953 | } | ||
3954 | n_acks = (ntohs (ra->header.size) - sizeof (*ra)) | ||
3955 | / sizeof (struct GNUNET_ShortHashCode); | ||
3956 | msg_uuids = (const struct GNUNET_ShortHashCode *) &ra[1]; | ||
3957 | |||
3958 | /* FIXME-OPTIMIZE: maybe use another hash map here? */ | ||
3959 | matched = GNUNET_NO; | ||
3960 | for (struct PendingMessage *pm = n->pending_msg_head; | ||
3961 | NULL != pm; | ||
3962 | pm = nxt) | ||
3963 | { | ||
3964 | int in_list; | ||
3965 | |||
3966 | nxt = pm->next_neighbour; | ||
3967 | in_list = GNUNET_NO; | ||
3968 | for (unsigned int i=0;i<n_acks;i++) | ||
3969 | { | ||
3970 | if (0 != | ||
3971 | GNUNET_memcmp (&msg_uuids[i], | ||
3972 | &pm->msg_uuid)) | ||
3973 | continue; | ||
3974 | in_list = GNUNET_YES; | ||
3975 | break; | ||
3976 | } | ||
3977 | if (GNUNET_NO == in_list) | ||
3978 | continue; | ||
3979 | |||
3980 | /* this pm was acked! */ | ||
3981 | matched = GNUNET_YES; | ||
3982 | free_pending_message (pm); | ||
3929 | 3983 | ||
3930 | // FIXME: do work: find message that was acknowledged, and | 3984 | { |
3931 | // remove from transmission queue; update RTT. | 3985 | struct GNUNET_TIME_Relative avg_ack_delay |
3986 | = GNUNET_TIME_relative_ntoh (ra->avg_ack_delay); | ||
3987 | // FIXME: update RTT and other reliability data! | ||
3988 | // ISSUE: we don't know which of n's queues the message(s) | ||
3989 | // took (and in fact the different messages might have gone | ||
3990 | // over different queues and possibly over multiple). | ||
3991 | // => track queues with PendingMessages, and update RTT only if | ||
3992 | // the queue used is unique? | ||
3993 | // -> how can we get loss rates? | ||
3994 | // -> or, add extra state to MSG and ACKs to identify queue? | ||
3995 | // -> if we do this, might just do the same for the avg_ack_delay! | ||
3996 | (void) avg_ack_delay; | ||
3997 | } | ||
3998 | } | ||
3999 | if (GNUNET_NO == matched) | ||
4000 | { | ||
4001 | GNUNET_STATISTICS_update (GST_stats, | ||
4002 | "# FRAGMENT_ACKS dropped, no matching pending message", | ||
4003 | 1, | ||
4004 | GNUNET_NO); | ||
4005 | } | ||
3932 | finish_cmc_handling (cmc); | 4006 | finish_cmc_handling (cmc); |
3933 | } | 4007 | } |
3934 | 4008 | ||