aboutsummaryrefslogtreecommitdiff
path: root/src/transport/gnunet-communicator-udp.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/transport/gnunet-communicator-udp.c')
-rw-r--r--src/transport/gnunet-communicator-udp.c185
1 files changed, 130 insertions, 55 deletions
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 */
1279static void
1280setup_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 */
2164static void
2165setup_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