diff options
author | Christian Grothoff <christian@grothoff.org> | 2019-01-30 07:26:53 +0100 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2019-01-30 07:26:53 +0100 |
commit | 5d021c879a1c83ba222d09f1e0dc2a0a081bc799 (patch) | |
tree | 4b06f3996a97a497f52445880a55d0bebaeedad1 /src | |
parent | 30e251fac34c48bafe5862f26a7dcfad4c6a39f8 (diff) | |
download | gnunet-5d021c879a1c83ba222d09f1e0dc2a0a081bc799.tar.gz gnunet-5d021c879a1c83ba222d09f1e0dc2a0a081bc799.zip |
implement MTU calculation and adjustments
Diffstat (limited to 'src')
-rw-r--r-- | src/include/gnunet_tun_lib.h | 1 | ||||
-rw-r--r-- | src/transport/gnunet-communicator-tcp.c | 5 | ||||
-rw-r--r-- | src/transport/gnunet-communicator-udp.c | 185 |
3 files changed, 136 insertions, 55 deletions
diff --git a/src/include/gnunet_tun_lib.h b/src/include/gnunet_tun_lib.h index 8fb6f32f0..11c43e8b7 100644 --- a/src/include/gnunet_tun_lib.h +++ b/src/include/gnunet_tun_lib.h | |||
@@ -58,6 +58,7 @@ | |||
58 | * 8 bytes for IPv4, 4 bytes for port, 1 byte for "4", 2 bytes for "-", | 58 | * 8 bytes for IPv4, 4 bytes for port, 1 byte for "4", 2 bytes for "-", |
59 | * one byte for 0-termination. | 59 | * one byte for 0-termination. |
60 | */ | 60 | */ |
61 | |||
61 | #define GNUNET_TUN_IPV4_REGEXLEN 16 | 62 | #define GNUNET_TUN_IPV4_REGEXLEN 16 |
62 | 63 | ||
63 | 64 | ||
diff --git a/src/transport/gnunet-communicator-tcp.c b/src/transport/gnunet-communicator-tcp.c index d86fa03b6..1d10b82e5 100644 --- a/src/transport/gnunet-communicator-tcp.c +++ b/src/transport/gnunet-communicator-tcp.c | |||
@@ -590,6 +590,11 @@ queue_destroy (struct Queue *queue) | |||
590 | queue->mq = NULL; | 590 | queue->mq = NULL; |
591 | GNUNET_MQ_destroy (mq); | 591 | GNUNET_MQ_destroy (mq); |
592 | } | 592 | } |
593 | if (NULL != queue->qh) | ||
594 | { | ||
595 | GNUNET_TRANSPORT_communicator_mq_del (queue->qh); | ||
596 | queue->qh = NULL; | ||
597 | } | ||
593 | GNUNET_assert (GNUNET_YES == | 598 | GNUNET_assert (GNUNET_YES == |
594 | GNUNET_CONTAINER_multipeermap_remove (queue_map, | 599 | GNUNET_CONTAINER_multipeermap_remove (queue_map, |
595 | &queue->target, | 600 | &queue->target, |
diff --git a/src/transport/gnunet-communicator-udp.c b/src/transport/gnunet-communicator-udp.c index 12c409b3d..c88f7f6f5 100644 --- a/src/transport/gnunet-communicator-udp.c +++ b/src/transport/gnunet-communicator-udp.c | |||
@@ -24,16 +24,14 @@ | |||
24 | * @author Christian Grothoff | 24 | * @author Christian Grothoff |
25 | * | 25 | * |
26 | * TODO: | 26 | * TODO: |
27 | * - figure out what to do with MTU: 1280 for IPv6 is obvious; | ||
28 | * what for IPv4? 1500? Also, consider differences in | ||
29 | * headers for with/without box: need to give MIN of both | ||
30 | * to TNG (as TNG expects a fixed MTU!), or maybe | ||
31 | * we create a FRESH MQ while we have available BOXes SQNs? | ||
32 | * (otherwise padding will REALLY hurt) | ||
33 | * - add and use util/ check for IPv6 availability (#V6) | 27 | * - add and use util/ check for IPv6 availability (#V6) |
34 | * - consider imposing transmission limits in the absence | 28 | * - consider imposing transmission limits in the absence |
35 | * of ACKs; or: maybe this should be done at TNG service level? | 29 | * of ACKs; or: maybe this should be done at TNG service level? |
36 | * - handle addresses discovered from broadcasts (#) | 30 | * (at least the receiver might want to enforce limits on |
31 | * KX/DH operations per sender in here) | ||
32 | * - overall, we should look more into flow control support | ||
33 | * (either in backchannel, or general solution in TNG service) | ||
34 | * - handle addresses discovered from broadcasts (#BC) | ||
37 | * (think: what was the story again on address validation? | 35 | * (think: what was the story again on address validation? |
38 | * where is the API for that!?!) | 36 | * where is the API for that!?!) |
39 | * - support DNS names in BINDTO option (#5528) | 37 | * - support DNS names in BINDTO option (#5528) |
@@ -535,6 +533,12 @@ struct ReceiverAddress | |||
535 | struct SharedSecret *ss_tail; | 533 | struct SharedSecret *ss_tail; |
536 | 534 | ||
537 | /** | 535 | /** |
536 | * Address of the receiver in the human-readable format | ||
537 | * with the #COMMUNICATOR_ADDRESS_PREFIX. | ||
538 | */ | ||
539 | char *foreign_addr; | ||
540 | |||
541 | /** | ||
538 | * Address of the other peer. | 542 | * Address of the other peer. |
539 | */ | 543 | */ |
540 | struct sockaddr *address; | 544 | struct sockaddr *address; |
@@ -794,6 +798,11 @@ receiver_destroy (struct ReceiverAddress *receiver) | |||
794 | receiver->mq = NULL; | 798 | receiver->mq = NULL; |
795 | GNUNET_MQ_destroy (mq); | 799 | GNUNET_MQ_destroy (mq); |
796 | } | 800 | } |
801 | if (NULL != receiver->qh) | ||
802 | { | ||
803 | GNUNET_TRANSPORT_communicator_mq_del (receiver->qh); | ||
804 | receiver->qh = NULL; | ||
805 | } | ||
797 | GNUNET_assert (GNUNET_YES == | 806 | GNUNET_assert (GNUNET_YES == |
798 | GNUNET_CONTAINER_multipeermap_remove (receivers, | 807 | GNUNET_CONTAINER_multipeermap_remove (receivers, |
799 | &receiver->target, | 808 | &receiver->target, |
@@ -805,6 +814,7 @@ receiver_destroy (struct ReceiverAddress *receiver) | |||
805 | GNUNET_CONTAINER_multipeermap_size (receivers), | 814 | GNUNET_CONTAINER_multipeermap_size (receivers), |
806 | GNUNET_NO); | 815 | GNUNET_NO); |
807 | GNUNET_free (receiver->address); | 816 | GNUNET_free (receiver->address); |
817 | GNUNET_free (receiver->foreign_addr); | ||
808 | GNUNET_free (receiver); | 818 | GNUNET_free (receiver); |
809 | } | 819 | } |
810 | 820 | ||
@@ -1260,6 +1270,17 @@ setup_shared_secret_enc (const struct GNUNET_CRYPTO_EcdhePrivateKey *ephemeral, | |||
1260 | 1270 | ||
1261 | 1271 | ||
1262 | /** | 1272 | /** |
1273 | * Setup the MQ for the @a receiver. If a queue exists, | ||
1274 | * the existing one is destroyed. Then the MTU is | ||
1275 | * recalculated and a fresh queue is initialized. | ||
1276 | * | ||
1277 | * @param receiver receiver to setup MQ for | ||
1278 | */ | ||
1279 | static void | ||
1280 | setup_receiver_mq (struct ReceiverAddress *receiver); | ||
1281 | |||
1282 | |||
1283 | /** | ||
1263 | * We received an ACK for @a pid. Check if it is for | 1284 | * We received an ACK for @a pid. Check if it is for |
1264 | * the receiver in @a value and if so, handle it and | 1285 | * the receiver in @a value and if so, handle it and |
1265 | * return #GNUNET_NO. Otherwise, return #GNUNET_YES. | 1286 | * return #GNUNET_NO. Otherwise, return #GNUNET_YES. |
@@ -1292,11 +1313,13 @@ handle_ack (void *cls, | |||
1292 | 1313 | ||
1293 | if (allowed > ss->sequence_allowed) | 1314 | if (allowed > ss->sequence_allowed) |
1294 | { | 1315 | { |
1295 | if (0 == receiver->acks_available) | 1316 | receiver->acks_available += (allowed - ss->sequence_allowed); |
1317 | if ((allowed - ss->sequence_allowed) | ||
1318 | == receiver->acks_available) | ||
1296 | { | 1319 | { |
1297 | /* FIXME: update MTU / MQ of 'receiver'! */ | 1320 | /* we just incremented from zero => MTU change! */ |
1321 | setup_receiver_mq (receiver); | ||
1298 | } | 1322 | } |
1299 | receiver->acks_available += (allowed - ss->sequence_allowed); | ||
1300 | ss->sequence_allowed = allowed; | 1323 | ss->sequence_allowed = allowed; |
1301 | /* move ss to head to avoid discarding it anytime soon! */ | 1324 | /* move ss to head to avoid discarding it anytime soon! */ |
1302 | GNUNET_CONTAINER_DLL_remove (receiver->ss_head, | 1325 | GNUNET_CONTAINER_DLL_remove (receiver->ss_head, |
@@ -1649,7 +1672,7 @@ sock_read (void *cls) | |||
1649 | "# broadcasts received", | 1672 | "# broadcasts received", |
1650 | 1, | 1673 | 1, |
1651 | GNUNET_NO); | 1674 | GNUNET_NO); |
1652 | // FIXME: we effectively just got a HELLO! | 1675 | // FIXME #BC: we effectively just got a HELLO! |
1653 | // trigger verification NOW! | 1676 | // trigger verification NOW! |
1654 | return; | 1677 | return; |
1655 | } | 1678 | } |
@@ -2012,7 +2035,6 @@ mq_send (struct GNUNET_MQ_Handle *mq, | |||
2012 | return; | 2035 | return; |
2013 | } /* End of KX encryption method */ | 2036 | } /* End of KX encryption method */ |
2014 | 2037 | ||
2015 | // FIXME: add support for BOX encryption method! | ||
2016 | /* begin "BOX" encryption method, scan for ACKs from tail! */ | 2038 | /* begin "BOX" encryption method, scan for ACKs from tail! */ |
2017 | for (struct SharedSecret *ss = receiver->ss_tail; | 2039 | for (struct SharedSecret *ss = receiver->ss_tail; |
2018 | NULL != ss; | 2040 | NULL != ss; |
@@ -2062,7 +2084,8 @@ mq_send (struct GNUNET_MQ_Handle *mq, | |||
2062 | receiver->acks_available--; | 2084 | receiver->acks_available--; |
2063 | if (0 == receiver->acks_available) | 2085 | if (0 == receiver->acks_available) |
2064 | { | 2086 | { |
2065 | /* FIXME: update MTU / MQ of 'receiver'! */ | 2087 | /* We have no more ACKs => MTU change! */ |
2088 | setup_receiver_mq (receiver); | ||
2066 | } | 2089 | } |
2067 | return; | 2090 | return; |
2068 | } | 2091 | } |
@@ -2132,6 +2155,77 @@ mq_error (void *cls, | |||
2132 | 2155 | ||
2133 | 2156 | ||
2134 | /** | 2157 | /** |
2158 | * Setup the MQ for the @a receiver. If a queue exists, | ||
2159 | * the existing one is destroyed. Then the MTU is | ||
2160 | * recalculated and a fresh queue is initialized. | ||
2161 | * | ||
2162 | * @param receiver receiver to setup MQ for | ||
2163 | */ | ||
2164 | static void | ||
2165 | setup_receiver_mq (struct ReceiverAddress *receiver) | ||
2166 | { | ||
2167 | size_t base_mtu; | ||
2168 | |||
2169 | if (NULL != receiver->qh) | ||
2170 | { | ||
2171 | GNUNET_TRANSPORT_communicator_mq_del (receiver->qh); | ||
2172 | receiver->qh = NULL; | ||
2173 | } | ||
2174 | GNUNET_assert (NULL == receiver->mq); | ||
2175 | switch (receiver->address->sa_family) | ||
2176 | { | ||
2177 | case AF_INET: | ||
2178 | base_mtu | ||
2179 | = 1480 /* Ethernet MTU, 1500 - Ethernet header - VLAN tag */ | ||
2180 | - sizeof (struct GNUNET_TUN_IPv4Header) /* 20 */ | ||
2181 | - sizeof (struct GNUNET_TUN_UdpHeader) /* 8 */; | ||
2182 | break; | ||
2183 | case AF_INET6: | ||
2184 | base_mtu | ||
2185 | = 1280 /* Minimum MTU required by IPv6 */ | ||
2186 | - sizeof (struct GNUNET_TUN_IPv6Header) /* 40 */ | ||
2187 | - sizeof (struct GNUNET_TUN_UdpHeader) /* 8 */; | ||
2188 | break; | ||
2189 | default: | ||
2190 | GNUNET_assert (0); | ||
2191 | break; | ||
2192 | } | ||
2193 | if (0 == receiver->acks_available) | ||
2194 | { | ||
2195 | /* MTU based on full KX messages */ | ||
2196 | receiver->mtu | ||
2197 | = base_mtu | ||
2198 | - sizeof (struct InitialKX) /* 48 */ | ||
2199 | - sizeof (struct UDPConfirmation); /* 104 */ | ||
2200 | } | ||
2201 | else | ||
2202 | { | ||
2203 | /* MTU based on BOXed messages */ | ||
2204 | receiver->mtu | ||
2205 | = base_mtu - sizeof (struct UDPBox); | ||
2206 | } | ||
2207 | /* => Effective MTU for CORE will range from 1080 (IPv6 + KX) to | ||
2208 | 1404 (IPv4 + Box) bytes, depending on circumstances... */ | ||
2209 | receiver->mq | ||
2210 | = GNUNET_MQ_queue_for_callbacks (&mq_send, | ||
2211 | &mq_destroy, | ||
2212 | &mq_cancel, | ||
2213 | receiver, | ||
2214 | NULL, | ||
2215 | &mq_error, | ||
2216 | receiver); | ||
2217 | receiver->qh | ||
2218 | = GNUNET_TRANSPORT_communicator_mq_add (ch, | ||
2219 | &receiver->target, | ||
2220 | receiver->foreign_addr, | ||
2221 | receiver->mtu, | ||
2222 | receiver->nt, | ||
2223 | GNUNET_TRANSPORT_CS_OUTBOUND, | ||
2224 | receiver->mq); | ||
2225 | } | ||
2226 | |||
2227 | |||
2228 | /** | ||
2135 | * Setup a receiver for transmission. Setup the MQ processing and | 2229 | * Setup a receiver for transmission. Setup the MQ processing and |
2136 | * inform transport that the queue is ready. | 2230 | * inform transport that the queue is ready. |
2137 | * | 2231 | * |
@@ -2161,54 +2255,35 @@ receiver_setup (const struct GNUNET_PeerIdentity *target, | |||
2161 | receiver->hn = GNUNET_CONTAINER_heap_insert (receivers_heap, | 2255 | receiver->hn = GNUNET_CONTAINER_heap_insert (receivers_heap, |
2162 | receiver, | 2256 | receiver, |
2163 | receiver->timeout.abs_value_us); | 2257 | receiver->timeout.abs_value_us); |
2164 | receiver->mq | ||
2165 | = GNUNET_MQ_queue_for_callbacks (&mq_send, | ||
2166 | &mq_destroy, | ||
2167 | &mq_cancel, | ||
2168 | receiver, | ||
2169 | NULL, | ||
2170 | &mq_error, | ||
2171 | receiver); | ||
2172 | receiver->mtu = 1200 /* FIXME: MTU OK? */; | ||
2173 | if (NULL == timeout_task) | ||
2174 | timeout_task = GNUNET_SCHEDULER_add_now (&check_timeouts, | ||
2175 | NULL); | ||
2176 | GNUNET_STATISTICS_set (stats, | 2258 | GNUNET_STATISTICS_set (stats, |
2177 | "# receivers active", | 2259 | "# receivers active", |
2178 | GNUNET_CONTAINER_multipeermap_size (receivers), | 2260 | GNUNET_CONTAINER_multipeermap_size (receivers), |
2179 | GNUNET_NO); | 2261 | GNUNET_NO); |
2262 | switch (address->sa_family) | ||
2180 | { | 2263 | { |
2181 | char *foreign_addr; | 2264 | case AF_INET: |
2182 | 2265 | GNUNET_asprintf (&receiver->foreign_addr, | |
2183 | switch (address->sa_family) | 2266 | "%s-%s", |
2184 | { | 2267 | COMMUNICATOR_ADDRESS_PREFIX, |
2185 | case AF_INET: | 2268 | GNUNET_a2s (receiver->address, |
2186 | GNUNET_asprintf (&foreign_addr, | 2269 | receiver->address_len)); |
2187 | "%s-%s", | 2270 | break; |
2188 | COMMUNICATOR_ADDRESS_PREFIX, | 2271 | case AF_INET6: |
2189 | GNUNET_a2s (receiver->address, | 2272 | GNUNET_asprintf (&receiver->foreign_addr, |
2190 | receiver->address_len)); | 2273 | "%s-%s", |
2191 | break; | 2274 | COMMUNICATOR_ADDRESS_PREFIX, |
2192 | case AF_INET6: | 2275 | GNUNET_a2s (receiver->address, |
2193 | GNUNET_asprintf (&foreign_addr, | 2276 | receiver->address_len)); |
2194 | "%s-%s", | 2277 | break; |
2195 | COMMUNICATOR_ADDRESS_PREFIX, | 2278 | default: |
2196 | GNUNET_a2s (receiver->address, | 2279 | GNUNET_assert (0); |
2197 | receiver->address_len)); | ||
2198 | break; | ||
2199 | default: | ||
2200 | GNUNET_assert (0); | ||
2201 | } | ||
2202 | receiver->qh | ||
2203 | = GNUNET_TRANSPORT_communicator_mq_add (ch, | ||
2204 | &receiver->target, | ||
2205 | foreign_addr, | ||
2206 | receiver->mtu, | ||
2207 | receiver->nt, | ||
2208 | GNUNET_TRANSPORT_CS_OUTBOUND, | ||
2209 | receiver->mq); | ||
2210 | GNUNET_free (foreign_addr); | ||
2211 | } | 2280 | } |
2281 | |||
2282 | setup_receiver_mq (receiver); | ||
2283 | |||
2284 | if (NULL == timeout_task) | ||
2285 | timeout_task = GNUNET_SCHEDULER_add_now (&check_timeouts, | ||
2286 | NULL); | ||
2212 | return receiver; | 2287 | return receiver; |
2213 | } | 2288 | } |
2214 | 2289 | ||