aboutsummaryrefslogtreecommitdiff
path: root/src/transport/gnunet-service-tng.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2019-01-21 20:15:27 +0100
committerChristian Grothoff <christian@grothoff.org>2019-01-21 20:15:27 +0100
commit25b14e096d09acfee96219de359ecaa0b56e2a34 (patch)
tree773192bc2baf260f946b16b75da16e93fc927140 /src/transport/gnunet-service-tng.c
parent32b38707097f8dc9f7f39c526f67414f24283eca (diff)
downloadgnunet-25b14e096d09acfee96219de359ecaa0b56e2a34.tar.gz
gnunet-25b14e096d09acfee96219de359ecaa0b56e2a34.zip
work out fragment/ack/dv messages, start implementation (tng)
Diffstat (limited to 'src/transport/gnunet-service-tng.c')
-rw-r--r--src/transport/gnunet-service-tng.c338
1 files changed, 329 insertions, 9 deletions
diff --git a/src/transport/gnunet-service-tng.c b/src/transport/gnunet-service-tng.c
index e205fa3d7..3365ea5d5 100644
--- a/src/transport/gnunet-service-tng.c
+++ b/src/transport/gnunet-service-tng.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2010-2016, 2018 GNUnet e.V. 3 Copyright (C) 2010-2016, 2018, 2019 GNUnet e.V.
4 4
5 GNUnet is free software: you can redistribute it and/or modify it 5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published 6 under the terms of the GNU Affero General Public License as published
@@ -182,6 +182,7 @@ struct EphemeralConfirmation
182 182
183}; 183};
184 184
185
185/** 186/**
186 * Plaintext of the variable-size payload that is encrypted 187 * Plaintext of the variable-size payload that is encrypted
187 * within a `struct TransportBackchannelEncapsulationMessage` 188 * within a `struct TransportBackchannelEncapsulationMessage`
@@ -225,6 +226,236 @@ struct TransportBackchannelRequestPayload
225 226
226}; 227};
227 228
229
230/**
231 * Outer layer of an encapsulated unfragmented application message sent
232 * over an unreliable channel.
233 */
234struct TransportReliabilityBox
235{
236 /**
237 * Type is #GNUNET_MESSAGE_TYPE_TRANSPORT_RELIABILITY_BOX
238 */
239 struct GNUNET_MessageHeader header;
240
241 /**
242 * Number of messages still to be sent before a commulative
243 * ACK is requested. Zero if an ACK is requested immediately.
244 * In NBO. Note that the receiver may send the ACK faster
245 * if it believes that is reasonable.
246 */
247 uint32_t ack_countdown GNUNET_PACKED;
248
249 /**
250 * Unique ID of the message used for signalling receipt of
251 * messages sent over possibly unreliable channels. Should
252 * be a random.
253 */
254 struct GNUNET_ShortHashCode msg_uuid;
255};
256
257
258/**
259 * Confirmation that the receiver got a
260 * #GNUNET_MESSAGE_TYPE_TRANSPORT_RELIABILITY_BOX. Note that the
261 * confirmation may be transmitted over a completely different queue,
262 * so ACKs are identified by a combination of PID of sender and
263 * message UUID, without the queue playing any role!
264 */
265struct TransportReliabilityAckMessage
266{
267 /**
268 * Type is #GNUNET_MESSAGE_TYPE_TRANSPORT_RELIABILITY_ACK
269 */
270 struct GNUNET_MessageHeader header;
271
272 /**
273 * Reserved. Zero.
274 */
275 uint32_t reserved GNUNET_PACKED;
276
277 /**
278 * How long was the ACK delayed relative to the average time of
279 * receipt of the messages being acknowledged? Used to calculate
280 * the average RTT by taking the receipt time of the ack minus the
281 * average transmission time of the sender minus this value.
282 */
283 struct GNUNET_TIME_RelativeNBO avg_ack_delay;
284
285 /* followed by any number of `struct GNUNET_ShortHashCode`
286 messages providing ACKs */
287};
288
289
290/**
291 * Outer layer of an encapsulated fragmented application message.
292 */
293struct TransportFragmentBox
294{
295 /**
296 * Type is #GNUNET_MESSAGE_TYPE_TRANSPORT_FRAGMENT
297 */
298 struct GNUNET_MessageHeader header;
299
300 /**
301 * Unique ID of this fragment (and fragment transmission!). Will
302 * change even if a fragement is retransmitted to make each
303 * transmission attempt unique! Should be incremented by one for
304 * each fragment transmission. If a client receives a duplicate
305 * fragment (same @e frag_off), it must send
306 * #GNUNET_MESSAGE_TYPE_TRANSPORT_FRAGMENT_ACK immediately.
307 */
308 uint32_t frag_uuid GNUNET_PACKED;
309
310 /**
311 * Original message ID for of the message that all the1
312 * fragments belong to. Must be the same for all fragments.
313 */
314 struct GNUNET_ShortHashCode msg_uuid;
315
316 /**
317 * Offset of this fragment in the overall message.
318 */
319 uint16_t frag_off GNUNET_PACKED;
320
321 /**
322 * Total size of the message that is being fragmented.
323 */
324 uint16_t msg_size GNUNET_PACKED;
325
326};
327
328
329/**
330 * Outer layer of an fragmented application message sent over a queue
331 * with finite MTU. When a #GNUNET_MESSAGE_TYPE_TRANSPORT_FRAGMENT is
332 * received, the receiver has two RTTs or 64 further fragments with
333 * the same basic message time to send an acknowledgement, possibly
334 * acknowledging up to 65 fragments in one ACK. ACKs must also be
335 * sent immediately once all fragments were sent.
336 */
337struct TransportFragmentAckMessage
338{
339 /**
340 * Type is #GNUNET_MESSAGE_TYPE_TRANSPORT_FRAGMENT_ACK
341 */
342 struct GNUNET_MessageHeader header;
343
344 /**
345 * Unique ID of the lowest fragment UUID being acknowledged.
346 */
347 uint32_t frag_uuid GNUNET_PACKED;
348
349 /**
350 * Bitfield of up to 64 additional fragments following the
351 * @e msg_uuid being acknowledged by this message.
352 */
353 uint64_t extra_acks GNUNET_PACKED;
354
355 /**
356 * Original message ID for of the message that all the
357 * fragments belong to.
358 */
359 struct GNUNET_ShortHashCode msg_uuid;
360
361 /**
362 * How long was the ACK delayed relative to the average time of
363 * receipt of the fragments being acknowledged? Used to calculate
364 * the average RTT by taking the receipt time of the ack minus the
365 * average transmission time of the sender minus this value.
366 */
367 struct GNUNET_TIME_RelativeNBO avg_ack_delay;
368};
369
370
371/**
372 * Internal message used by transport for distance vector learning.
373 * If @e num_hops does not exceed the threshold, peers should append
374 * themselves to the peer list and flood the message (possibly only
375 * to a subset of their neighbours to limit discoverability of the
376 * network topology). To the extend that the @e bidirectional bits
377 * are set, peers may learn the inverse paths even if they did not
378 * initiate.
379 *
380 * Unless received on a bidirectional queue and @e num_hops just
381 * zero, peers that can forward to the initator should always try to
382 * forward to the initiator.
383 */
384struct TransportDVLearn
385{
386 /**
387 * Type is #GNUNET_MESSAGE_TYPE_TRANSPORT_DV_LEARN
388 */
389 struct GNUNET_MessageHeader header;
390
391 /**
392 * Number of hops this messages has travelled, in NBO. Zero if
393 * sent by initiator.
394 */
395 uint16_t num_hops GNUNET_PACKED;
396
397 /**
398 * Bitmask of the last 16 hops indicating whether they are confirmed
399 * available (without DV) in both directions or not, in NBO. Used
400 * to possibly instantly learn a path in both directions. Each peer
401 * should shift this value by one to the left, and then set the
402 * lowest bit IF the current sender can be reached from it (without
403 * DV routing).
404 */
405 uint16_t bidirectional GNUNET_PACKED;
406
407 /**
408 * Peers receiving this message and delaying forwarding to other
409 * peers for any reason should increment this value such as to
410 * enable the origin to determine the actual network-only delay
411 * in addition to the real-time delay (assuming the message loops
412 * back to the origin).
413 */
414 struct GNUNET_TIME_Relative cummulative_non_network_delay;
415
416 /**
417 * Identity of the peer that started this learning activity.
418 */
419 struct GNUNET_PeerIdentity initiator;
420
421 /* Followed by @e num_hops `struct GNUNET_PeerIdentity` values,
422 excluding the initiator of the DV trace; the last entry is the
423 current sender; the current peer must not be included except if
424 it is the sender. */
425
426};
427
428
429/**
430 * Outer layer of an encapsulated message send over multiple hops.
431 */
432struct TransportDVBox
433{
434 /**
435 * Type is #GNUNET_MESSAGE_TYPE_TRANSPORT_DV
436 */
437 struct GNUNET_MessageHeader header;
438
439 /**
440 * Number of hops this messages includes. In NBO.
441 */
442 uint16_t num_hops GNUNET_PACKED;
443
444 /**
445 * Position of our peer in the sequence.
446 * To be incremented at each hop. In NBO.
447 */
448 uint16_t current_hop GNUNET_PACKED;
449
450 /* Followed by @e num_hops `struct GNUNET_PeerIdentity` values;
451 the first is the sender, the last the receiver; the current
452 peer may be one in the middle. */
453
454 /* Followed by the actual message, which itself may be
455 another box, but not a DV_LEARN message! */
456};
457
458
228GNUNET_NETWORK_STRUCT_END 459GNUNET_NETWORK_STRUCT_END
229 460
230 461
@@ -1780,6 +2011,68 @@ schedule_transmit_on_queue (struct GNUNET_ATS_Session *queue)
1780 2011
1781 2012
1782/** 2013/**
2014 * Fragment the given @a pm to the given @a mtu. Adds
2015 * additional fragments to the neighbour as well. If the
2016 * @a mtu is too small, generates and error for the @a pm
2017 * and returns NULL.
2018 *
2019 * @param pm pending message to fragment for transmission
2020 * @param mtu MTU to apply
2021 * @return new message to transmit
2022 */
2023static struct PendingMessage *
2024fragment_message (struct PendingMessage *pm,
2025 uint16_t mtu)
2026{
2027 if (0)
2028 {
2029 /* mtu too small */
2030 // FIMXE: bitch
2031 client_send_response (pm,
2032 GNUNET_NO,
2033 0);
2034 return NULL;
2035 }
2036
2037 /* FIXME: return first fragment here! */
2038 return NULL;
2039}
2040
2041
2042/**
2043 * Reliability-box the given @a pm. On error (can there be any), NULL
2044 * may be returned, otherwise the "replacement" for @a pm (which
2045 * should then be added to the respective neighbour's queue instead of
2046 * @a pm). If the @a pm is already fragmented or reliability boxed,
2047 * or itself an ACK, this function simply returns @a pm.
2048 *
2049 * @param pm pending message to box for transmission over unreliabile queue
2050 * @return new message to transmit
2051 */
2052static struct PendingMessage *
2053reliability_box_message (struct PendingMessage *pm)
2054{
2055 if (0) // FIXME
2056 {
2057 /* already fragmented or reliability boxed, do nothing */
2058 return pm;
2059 }
2060 if (0) // FIXME
2061 {
2062 /* failed hard */
2063 // FIMXE: bitch
2064 client_send_response (pm,
2065 GNUNET_NO,
2066 0);
2067 return NULL;
2068 }
2069
2070 /* FIXME: return boxed PM here! */
2071 return NULL;
2072}
2073
2074
2075/**
1783 * We believe we are ready to transmit a message on a queue. Double-checks 2076 * We believe we are ready to transmit a message on a queue. Double-checks
1784 * with the queue's "tracker_out" and then gives the message to the 2077 * with the queue's "tracker_out" and then gives the message to the
1785 * communicator for transmission (updating the tracker, and re-scheduling 2078 * communicator for transmission (updating the tracker, and re-scheduling
@@ -1793,6 +2086,7 @@ transmit_on_queue (void *cls)
1793 struct GNUNET_ATS_Session *queue = cls; 2086 struct GNUNET_ATS_Session *queue = cls;
1794 struct Neighbour *n = queue->neighbour; 2087 struct Neighbour *n = queue->neighbour;
1795 struct PendingMessage *pm; 2088 struct PendingMessage *pm;
2089 uint32_t overhead;
1796 2090
1797 queue->transmit_task = NULL; 2091 queue->transmit_task = NULL;
1798 if (NULL == (pm = n->pending_msg_head)) 2092 if (NULL == (pm = n->pending_msg_head))
@@ -1803,15 +2097,41 @@ transmit_on_queue (void *cls)
1803 schedule_transmit_on_queue (queue); 2097 schedule_transmit_on_queue (queue);
1804 if (NULL != queue->transmit_task) 2098 if (NULL != queue->transmit_task)
1805 return; /* do it later */ 2099 return; /* do it later */
2100 overhead = 0;
2101 if (GNUNET_TRANSPORT_CC_RELIABLE != queue->tc->details.communicator.cc)
2102 overhead += sizeof (struct TransportReliabilityBox);
2103 if ( (0 != queue->mtu) &&
2104 (pm->bytes_msg + overhead > queue->mtu) )
2105 pm = fragment_message (pm,
2106 queue->mtu);
2107 if (NULL == pm)
2108 {
2109 /* Fragmentation failed, try next message... */
2110 schedule_transmit_on_queue (queue);
2111 return;
2112 }
2113 if (GNUNET_TRANSPORT_CC_RELIABLE != queue->tc->details.communicator.cc)
2114 pm = reliability_box_message (pm);
2115 if (NULL == pm)
2116 {
2117 /* Reliability boxing failed, try next message... */
2118 schedule_transmit_on_queue (queue);
2119 return;
2120 }
2121
2122 // FIXME: actually do transmission
1806 2123
1807 // FIXME: do transmission (fragmentation, adding signalling / RTT tracking logic, etc.) 2124 // FIXME: unless 'pm' is an ACK or control, move 'pm' back in the
1808 // FIXME: upon success, do (not here in continuation!) 2125 // transmission queue (simplistic: to the end, better: with position
1809 if (0) 2126 // depending on type, timeout, etc.)
1810 { 2127
1811 client_send_response (pm, 2128 // FIXME: do something similar in defragmentation / reliability ACK handling!
1812 GNUNET_YES, 2129 if (GNUNET_TRANSPORT_CC_RELIABLE == queue->tc->details.communicator.cc)
1813 0); 2130 {
1814 } 2131 client_send_response (pm,
2132 GNUNET_YES,
2133 pm->bytes_msg);
2134 }
1815 /* finally, re-schedule self */ 2135 /* finally, re-schedule self */
1816 schedule_transmit_on_queue (queue); 2136 schedule_transmit_on_queue (queue);
1817} 2137}