diff options
author | ng0 <ng0@n0.is> | 2019-04-23 14:50:21 +0000 |
---|---|---|
committer | ng0 <ng0@n0.is> | 2019-04-23 14:50:21 +0000 |
commit | 510d62445a15811a9b9de98cffa085f3da592025 (patch) | |
tree | fedcd77483cc14a686add6bceb6ef97b682c454b | |
parent | 050f5f3f5d783bd080d838d04eb8837672627afb (diff) | |
parent | c929c783cc70935dcebe9fd61634573a47de5a01 (diff) | |
download | gnunet-510d62445a15811a9b9de98cffa085f3da592025.tar.gz gnunet-510d62445a15811a9b9de98cffa085f3da592025.zip |
Merge branch 'master' of gnunet.org:gnunet
-rw-r--r-- | src/include/gnunet_protocols.h | 7 | ||||
-rw-r--r-- | src/transport/gnunet-service-tng.c | 1565 |
2 files changed, 1063 insertions, 509 deletions
diff --git a/src/include/gnunet_protocols.h b/src/include/gnunet_protocols.h index e402460c0..27a7034b0 100644 --- a/src/include/gnunet_protocols.h +++ b/src/include/gnunet_protocols.h | |||
@@ -2121,7 +2121,7 @@ extern "C" { | |||
2121 | 2121 | ||
2122 | /** M<->S<->C: PSYC message which contains a header and one or more message | 2122 | /** M<->S<->C: PSYC message which contains a header and one or more message |
2123 | * parts. */ | 2123 | * parts. */ |
2124 | #define GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_HEADER \ | 2124 | #define GNUNET_MESSAGE_TYPE_PSYC_MESSAGE_HEADER \ |
2125 | 692 // FIXME: start using this where appropriate | 2125 | 692 // FIXME: start using this where appropriate |
2126 | 2126 | ||
2127 | /** Message part: method */ | 2127 | /** Message part: method */ |
@@ -3108,11 +3108,6 @@ extern "C" { | |||
3108 | #define GNUNET_MESSAGE_TYPE_TRANSPORT_FRAGMENT 1214 | 3108 | #define GNUNET_MESSAGE_TYPE_TRANSPORT_FRAGMENT 1214 |
3109 | 3109 | ||
3110 | /** | 3110 | /** |
3111 | * Acknowledgement generated for a fragment. | ||
3112 | */ | ||
3113 | #define GNUNET_MESSAGE_TYPE_TRANSPORT_FRAGMENT_ACK 1215 | ||
3114 | |||
3115 | /** | ||
3116 | * Wrapper around non-fragmented CORE message used to measure RTT | 3111 | * Wrapper around non-fragmented CORE message used to measure RTT |
3117 | * and ensure reliability. | 3112 | * and ensure reliability. |
3118 | */ | 3113 | */ |
diff --git a/src/transport/gnunet-service-tng.c b/src/transport/gnunet-service-tng.c index 7683ed016..e128a4abf 100644 --- a/src/transport/gnunet-service-tng.c +++ b/src/transport/gnunet-service-tng.c | |||
@@ -24,9 +24,13 @@ | |||
24 | * | 24 | * |
25 | * TODO: | 25 | * TODO: |
26 | * Implement next: | 26 | * Implement next: |
27 | * - track RTT, distance, loss, etc. => requires extra data structures! | 27 | * - FIXME: looping over neighbours when calling forward_dv_learn()! |
28 | * - FIXME: transmit_on_queue: track dvh we may be using and pass it to | ||
29 | * fragment_message() and reliability_box_message() if applicable | ||
28 | * - proper use/initialization of timestamps in messages exchanged | 30 | * - proper use/initialization of timestamps in messages exchanged |
29 | * during DV learning | 31 | * during DV learning |
32 | * - persistence of monotonic time from DVInit to prevent | ||
33 | * replay attacks using DVInit messages | ||
30 | * - persistence of monotonic time obtained from other peers | 34 | * - persistence of monotonic time obtained from other peers |
31 | * in PEERSTORE (by message type) -- done for backchannel, needed elsewhere? | 35 | * in PEERSTORE (by message type) -- done for backchannel, needed elsewhere? |
32 | * - change transport-core API to provide proper flow control in both | 36 | * - change transport-core API to provide proper flow control in both |
@@ -38,12 +42,11 @@ | |||
38 | * | 42 | * |
39 | * Later: | 43 | * Later: |
40 | * - review retransmission logic, right now there is no smartness there! | 44 | * - review retransmission logic, right now there is no smartness there! |
41 | * => congestion control, flow control, etc (requires RTT, loss, etc.) | 45 | * => congestion control, flow control, etc |
42 | * | 46 | * |
43 | * Optimizations: | 47 | * Optimizations: |
44 | * - use shorthashmap on msg_uuid's when matching reliability/fragment ACKs | 48 | * - AcknowledgementUUIDPs are overkill with 256 bits (128 would do) |
45 | * against our pending message queue (requires additional per neighbour | 49 | * => Need 128 bit hash map though! |
46 | * hash map to be maintained, avoids possible linear scan on pending msgs) | ||
47 | * - queue_send_msg and route_message both by API design have to make copies | 50 | * - queue_send_msg and route_message both by API design have to make copies |
48 | * of the payload, and route_message on top of that requires a malloc/free. | 51 | * of the payload, and route_message on top of that requires a malloc/free. |
49 | * Change design to approximate "zero" copy better... | 52 | * Change design to approximate "zero" copy better... |
@@ -95,6 +98,11 @@ | |||
95 | #include "gnunet_signatures.h" | 98 | #include "gnunet_signatures.h" |
96 | #include "transport.h" | 99 | #include "transport.h" |
97 | 100 | ||
101 | /** | ||
102 | * Maximum number of messages we acknowledge together in one | ||
103 | * cummulative ACK. Larger values may save a bit of bandwidth. | ||
104 | */ | ||
105 | #define MAX_CUMMULATIVE_ACKS 64 | ||
98 | 106 | ||
99 | /** | 107 | /** |
100 | * What is the size we assume for a read operation in the | 108 | * What is the size we assume for a read operation in the |
@@ -103,6 +111,12 @@ | |||
103 | #define IN_PACKET_SIZE_WITHOUT_MTU 128 | 111 | #define IN_PACKET_SIZE_WITHOUT_MTU 128 |
104 | 112 | ||
105 | /** | 113 | /** |
114 | * Number of slots we keep of historic data for computation of | ||
115 | * goodput / message loss ratio. | ||
116 | */ | ||
117 | #define GOODPUT_AGING_SLOTS 4 | ||
118 | |||
119 | /** | ||
106 | * Minimum number of hops we should forward DV learn messages | 120 | * Minimum number of hops we should forward DV learn messages |
107 | * even if they are NOT useful for us in hope of looping | 121 | * even if they are NOT useful for us in hope of looping |
108 | * back to the initiator? | 122 | * back to the initiator? |
@@ -190,6 +204,14 @@ | |||
190 | GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_DAYS, 1) | 204 | GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_DAYS, 1) |
191 | 205 | ||
192 | /** | 206 | /** |
207 | * How long until we forget about historic accumulators and thus | ||
208 | * reset the ACK counter? Should exceed the maximum time an | ||
209 | * active connection experiences without an ACK. | ||
210 | */ | ||
211 | #define ACK_CUMMULATOR_TIMEOUT \ | ||
212 | GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 4) | ||
213 | |||
214 | /** | ||
193 | * What is the non-randomized base frequency at which we | 215 | * What is the non-randomized base frequency at which we |
194 | * would initiate DV learn messages? | 216 | * would initiate DV learn messages? |
195 | */ | 217 | */ |
@@ -248,6 +270,55 @@ | |||
248 | GNUNET_NETWORK_STRUCT_BEGIN | 270 | GNUNET_NETWORK_STRUCT_BEGIN |
249 | 271 | ||
250 | /** | 272 | /** |
273 | * Unique identifier we attach to a message. | ||
274 | */ | ||
275 | struct MessageUUIDP | ||
276 | { | ||
277 | /** | ||
278 | * Unique value, generated by incrementing the | ||
279 | * `message_uuid_ctr` of `struct Neighbour`. | ||
280 | */ | ||
281 | uint64_t uuid GNUNET_PACKED; | ||
282 | }; | ||
283 | |||
284 | |||
285 | /** | ||
286 | * Unique identifier to map an acknowledgement to a transmission. | ||
287 | */ | ||
288 | struct AcknowledgementUUIDP | ||
289 | { | ||
290 | /** | ||
291 | * The UUID value. Not actually a hash, but a random value. | ||
292 | */ | ||
293 | struct GNUNET_ShortHashCode value; | ||
294 | }; | ||
295 | |||
296 | |||
297 | /** | ||
298 | * Unique identifier we attach to a message. | ||
299 | */ | ||
300 | struct FragmentUUIDP | ||
301 | { | ||
302 | /** | ||
303 | * Unique value identifying a fragment, in NBO. | ||
304 | */ | ||
305 | uint32_t uuid GNUNET_PACKED; | ||
306 | }; | ||
307 | |||
308 | |||
309 | /** | ||
310 | * Type of a nonce used for challenges. | ||
311 | */ | ||
312 | struct ChallengeNonceP | ||
313 | { | ||
314 | /** | ||
315 | * The value of the nonce. Note that this is NOT a hash. | ||
316 | */ | ||
317 | struct GNUNET_ShortHashCode value; | ||
318 | }; | ||
319 | |||
320 | |||
321 | /** | ||
251 | * Outer layer of an encapsulated backchannel message. | 322 | * Outer layer of an encapsulated backchannel message. |
252 | */ | 323 | */ |
253 | struct TransportBackchannelEncapsulationMessage | 324 | struct TransportBackchannelEncapsulationMessage |
@@ -335,7 +406,7 @@ struct EphemeralConfirmationPS | |||
335 | * Plaintext of the variable-size payload that is encrypted | 406 | * Plaintext of the variable-size payload that is encrypted |
336 | * within a `struct TransportBackchannelEncapsulationMessage` | 407 | * within a `struct TransportBackchannelEncapsulationMessage` |
337 | */ | 408 | */ |
338 | struct TransportBackchannelRequestPayload | 409 | struct TransportBackchannelRequestPayloadP |
339 | { | 410 | { |
340 | 411 | ||
341 | /** | 412 | /** |
@@ -389,7 +460,7 @@ struct TransportBackchannelRequestPayload | |||
389 | * Outer layer of an encapsulated unfragmented application message sent | 460 | * Outer layer of an encapsulated unfragmented application message sent |
390 | * over an unreliable channel. | 461 | * over an unreliable channel. |
391 | */ | 462 | */ |
392 | struct TransportReliabilityBox | 463 | struct TransportReliabilityBoxMessage |
393 | { | 464 | { |
394 | /** | 465 | /** |
395 | * Type is #GNUNET_MESSAGE_TYPE_TRANSPORT_RELIABILITY_BOX | 466 | * Type is #GNUNET_MESSAGE_TYPE_TRANSPORT_RELIABILITY_BOX |
@@ -409,7 +480,27 @@ struct TransportReliabilityBox | |||
409 | * messages sent over possibly unreliable channels. Should | 480 | * messages sent over possibly unreliable channels. Should |
410 | * be a random. | 481 | * be a random. |
411 | */ | 482 | */ |
412 | struct GNUNET_ShortHashCode msg_uuid; | 483 | struct AcknowledgementUUIDP ack_uuid; |
484 | }; | ||
485 | |||
486 | |||
487 | /** | ||
488 | * Acknowledgement payload. | ||
489 | */ | ||
490 | struct TransportCummulativeAckPayloadP | ||
491 | { | ||
492 | /** | ||
493 | * How long was the ACK delayed for generating cummulative ACKs? | ||
494 | * Used to calculate the correct network RTT by taking the receipt | ||
495 | * time of the ack minus the transmission time of the sender minus | ||
496 | * this value. | ||
497 | */ | ||
498 | struct GNUNET_TIME_RelativeNBO ack_delay; | ||
499 | |||
500 | /** | ||
501 | * UUID of a message being acknowledged. | ||
502 | */ | ||
503 | struct AcknowledgementUUIDP ack_uuid; | ||
413 | }; | 504 | }; |
414 | 505 | ||
415 | 506 | ||
@@ -428,19 +519,12 @@ struct TransportReliabilityAckMessage | |||
428 | struct GNUNET_MessageHeader header; | 519 | struct GNUNET_MessageHeader header; |
429 | 520 | ||
430 | /** | 521 | /** |
431 | * Reserved. Zero. | 522 | * Counter of ACKs transmitted by the sender to us. Incremented |
523 | * by one for each ACK, used to detect how many ACKs were lost. | ||
432 | */ | 524 | */ |
433 | uint32_t reserved GNUNET_PACKED; | 525 | uint32_t ack_counter GNUNET_PACKED; |
434 | 526 | ||
435 | /** | 527 | /* followed by any number of `struct TransportCummulativeAckPayloadP` |
436 | * How long was the ACK delayed relative to the average time of | ||
437 | * receipt of the messages being acknowledged? Used to calculate | ||
438 | * the average RTT by taking the receipt time of the ack minus the | ||
439 | * average transmission time of the sender minus this value. | ||
440 | */ | ||
441 | struct GNUNET_TIME_RelativeNBO avg_ack_delay; | ||
442 | |||
443 | /* followed by any number of `struct GNUNET_ShortHashCode` | ||
444 | messages providing ACKs */ | 528 | messages providing ACKs */ |
445 | }; | 529 | }; |
446 | 530 | ||
@@ -448,7 +532,7 @@ struct TransportReliabilityAckMessage | |||
448 | /** | 532 | /** |
449 | * Outer layer of an encapsulated fragmented application message. | 533 | * Outer layer of an encapsulated fragmented application message. |
450 | */ | 534 | */ |
451 | struct TransportFragmentBox | 535 | struct TransportFragmentBoxMessage |
452 | { | 536 | { |
453 | /** | 537 | /** |
454 | * Type is #GNUNET_MESSAGE_TYPE_TRANSPORT_FRAGMENT | 538 | * Type is #GNUNET_MESSAGE_TYPE_TRANSPORT_FRAGMENT |
@@ -458,18 +542,17 @@ struct TransportFragmentBox | |||
458 | /** | 542 | /** |
459 | * Unique ID of this fragment (and fragment transmission!). Will | 543 | * Unique ID of this fragment (and fragment transmission!). Will |
460 | * change even if a fragement is retransmitted to make each | 544 | * change even if a fragement is retransmitted to make each |
461 | * transmission attempt unique! Should be incremented by one for | 545 | * transmission attempt unique! If a client receives a duplicate |
462 | * each fragment transmission. If a client receives a duplicate | 546 | * fragment (same @e frag_off for same @a msg_uuid, it must send |
463 | * fragment (same @e frag_off), it must send | 547 | * #GNUNET_MESSAGE_TYPE_TRANSPORT_RELIABILITY_ACK immediately. |
464 | * #GNUNET_MESSAGE_TYPE_TRANSPORT_FRAGMENT_ACK immediately. | ||
465 | */ | 548 | */ |
466 | uint32_t frag_uuid GNUNET_PACKED; | 549 | struct AcknowledgementUUIDP ack_uuid; |
467 | 550 | ||
468 | /** | 551 | /** |
469 | * Original message ID for of the message that all the1 | 552 | * Original message ID for of the message that all the fragments |
470 | * fragments belong to. Must be the same for all fragments. | 553 | * belong to. Must be the same for all fragments. |
471 | */ | 554 | */ |
472 | struct GNUNET_ShortHashCode msg_uuid; | 555 | struct MessageUUIDP msg_uuid; |
473 | 556 | ||
474 | /** | 557 | /** |
475 | * Offset of this fragment in the overall message. | 558 | * Offset of this fragment in the overall message. |
@@ -484,54 +567,6 @@ struct TransportFragmentBox | |||
484 | 567 | ||
485 | 568 | ||
486 | /** | 569 | /** |
487 | * Outer layer of an fragmented application message sent over a queue | ||
488 | * with finite MTU. When a #GNUNET_MESSAGE_TYPE_TRANSPORT_FRAGMENT is | ||
489 | * received, the receiver has two RTTs or 64 further fragments with | ||
490 | * the same basic message time to send an acknowledgement, possibly | ||
491 | * acknowledging up to 65 fragments in one ACK. ACKs must also be | ||
492 | * sent immediately once all fragments were sent. | ||
493 | */ | ||
494 | struct TransportFragmentAckMessage | ||
495 | { | ||
496 | /** | ||
497 | * Type is #GNUNET_MESSAGE_TYPE_TRANSPORT_FRAGMENT_ACK | ||
498 | */ | ||
499 | struct GNUNET_MessageHeader header; | ||
500 | |||
501 | /** | ||
502 | * Unique ID of the lowest fragment UUID being acknowledged. | ||
503 | */ | ||
504 | uint32_t frag_uuid GNUNET_PACKED; | ||
505 | |||
506 | /** | ||
507 | * Bitfield of up to 64 additional fragments following the | ||
508 | * @e msg_uuid being acknowledged by this message. | ||
509 | */ | ||
510 | uint64_t extra_acks GNUNET_PACKED; | ||
511 | |||
512 | /** | ||
513 | * Original message ID for of the message that all the | ||
514 | * fragments belong to. | ||
515 | */ | ||
516 | struct GNUNET_ShortHashCode msg_uuid; | ||
517 | |||
518 | /** | ||
519 | * How long was the ACK delayed relative to the average time of | ||
520 | * receipt of the fragments being acknowledged? Used to calculate | ||
521 | * the average RTT by taking the receipt time of the ack minus the | ||
522 | * average transmission time of the sender minus this value. | ||
523 | */ | ||
524 | struct GNUNET_TIME_RelativeNBO avg_ack_delay; | ||
525 | |||
526 | /** | ||
527 | * How long until the receiver will stop trying reassembly | ||
528 | * of this message? | ||
529 | */ | ||
530 | struct GNUNET_TIME_RelativeNBO reassembly_timeout; | ||
531 | }; | ||
532 | |||
533 | |||
534 | /** | ||
535 | * Content signed by the initator during DV learning. | 570 | * Content signed by the initator during DV learning. |
536 | * | 571 | * |
537 | * The signature is required to prevent DDoS attacks. A peer sending out this | 572 | * The signature is required to prevent DDoS attacks. A peer sending out this |
@@ -572,7 +607,7 @@ struct DvInitPS | |||
572 | /** | 607 | /** |
573 | * Challenge value used by the initiator to re-identify the path. | 608 | * Challenge value used by the initiator to re-identify the path. |
574 | */ | 609 | */ |
575 | struct GNUNET_ShortHashCode challenge; | 610 | struct ChallengeNonceP challenge; |
576 | }; | 611 | }; |
577 | 612 | ||
578 | 613 | ||
@@ -612,13 +647,13 @@ struct DvHopPS | |||
612 | /** | 647 | /** |
613 | * Challenge value used by the initiator to re-identify the path. | 648 | * Challenge value used by the initiator to re-identify the path. |
614 | */ | 649 | */ |
615 | struct GNUNET_ShortHashCode challenge; | 650 | struct ChallengeNonceP challenge; |
616 | }; | 651 | }; |
617 | 652 | ||
618 | 653 | ||
619 | /** | 654 | /** |
620 | * An entry describing a peer on a path in a | 655 | * An entry describing a peer on a path in a |
621 | * `struct TransportDVLearn` message. | 656 | * `struct TransportDVLearnMessage` message. |
622 | */ | 657 | */ |
623 | struct DVPathEntryP | 658 | struct DVPathEntryP |
624 | { | 659 | { |
@@ -648,7 +683,7 @@ struct DVPathEntryP | |||
648 | * zero, peers that can forward to the initator should always try to | 683 | * zero, peers that can forward to the initator should always try to |
649 | * forward to the initiator. | 684 | * forward to the initiator. |
650 | */ | 685 | */ |
651 | struct TransportDVLearn | 686 | struct TransportDVLearnMessage |
652 | { | 687 | { |
653 | /** | 688 | /** |
654 | * Type is #GNUNET_MESSAGE_TYPE_TRANSPORT_DV_LEARN | 689 | * Type is #GNUNET_MESSAGE_TYPE_TRANSPORT_DV_LEARN |
@@ -692,7 +727,7 @@ struct TransportDVLearn | |||
692 | /** | 727 | /** |
693 | * Challenge value used by the initiator to re-identify the path. | 728 | * Challenge value used by the initiator to re-identify the path. |
694 | */ | 729 | */ |
695 | struct GNUNET_ShortHashCode challenge; | 730 | struct ChallengeNonceP challenge; |
696 | 731 | ||
697 | /* Followed by @e num_hops `struct DVPathEntryP` values, | 732 | /* Followed by @e num_hops `struct DVPathEntryP` values, |
698 | excluding the initiator of the DV trace; the last entry is the | 733 | excluding the initiator of the DV trace; the last entry is the |
@@ -715,7 +750,7 @@ struct TransportDVLearn | |||
715 | * | 750 | * |
716 | * If a peer finds itself still on the list, it must drop the message. | 751 | * If a peer finds itself still on the list, it must drop the message. |
717 | */ | 752 | */ |
718 | struct TransportDVBox | 753 | struct TransportDVBoxMessage |
719 | { | 754 | { |
720 | /** | 755 | /** |
721 | * Type is #GNUNET_MESSAGE_TYPE_TRANSPORT_DV_BOX | 756 | * Type is #GNUNET_MESSAGE_TYPE_TRANSPORT_DV_BOX |
@@ -753,7 +788,7 @@ struct TransportDVBox | |||
753 | * Message send to another peer to validate that it can indeed | 788 | * Message send to another peer to validate that it can indeed |
754 | * receive messages at a particular address. | 789 | * receive messages at a particular address. |
755 | */ | 790 | */ |
756 | struct TransportValidationChallenge | 791 | struct TransportValidationChallengeMessage |
757 | { | 792 | { |
758 | 793 | ||
759 | /** | 794 | /** |
@@ -769,7 +804,7 @@ struct TransportValidationChallenge | |||
769 | /** | 804 | /** |
770 | * Challenge to be signed by the receiving peer. | 805 | * Challenge to be signed by the receiving peer. |
771 | */ | 806 | */ |
772 | struct GNUNET_ShortHashCode challenge; | 807 | struct ChallengeNonceP challenge; |
773 | 808 | ||
774 | /** | 809 | /** |
775 | * Timestamp of the sender, to be copied into the reply | 810 | * Timestamp of the sender, to be copied into the reply |
@@ -800,7 +835,7 @@ struct TransportValidationPS | |||
800 | /** | 835 | /** |
801 | * Challenge signed by the receiving peer. | 836 | * Challenge signed by the receiving peer. |
802 | */ | 837 | */ |
803 | struct GNUNET_ShortHashCode challenge; | 838 | struct ChallengeNonceP challenge; |
804 | }; | 839 | }; |
805 | 840 | ||
806 | 841 | ||
@@ -808,7 +843,7 @@ struct TransportValidationPS | |||
808 | * Message send to a peer to respond to a | 843 | * Message send to a peer to respond to a |
809 | * #GNUNET_MESSAGE_TYPE_ADDRESS_VALIDATION_CHALLENGE | 844 | * #GNUNET_MESSAGE_TYPE_ADDRESS_VALIDATION_CHALLENGE |
810 | */ | 845 | */ |
811 | struct TransportValidationResponse | 846 | struct TransportValidationResponseMessage |
812 | { | 847 | { |
813 | 848 | ||
814 | /** | 849 | /** |
@@ -830,7 +865,7 @@ struct TransportValidationResponse | |||
830 | /** | 865 | /** |
831 | * The challenge that was signed by the receiving peer. | 866 | * The challenge that was signed by the receiving peer. |
832 | */ | 867 | */ |
833 | struct GNUNET_ShortHashCode challenge; | 868 | struct ChallengeNonceP challenge; |
834 | 869 | ||
835 | /** | 870 | /** |
836 | * Original timestamp of the sender (was @code{sender_time}), | 871 | * Original timestamp of the sender (was @code{sender_time}), |
@@ -900,7 +935,7 @@ struct LearnLaunchEntry | |||
900 | /** | 935 | /** |
901 | * Challenge that uniquely identifies this activity. | 936 | * Challenge that uniquely identifies this activity. |
902 | */ | 937 | */ |
903 | struct GNUNET_ShortHashCode challenge; | 938 | struct ChallengeNonceP challenge; |
904 | 939 | ||
905 | /** | 940 | /** |
906 | * When did we transmit the DV learn message (used to calculate RTT) and | 941 | * When did we transmit the DV learn message (used to calculate RTT) and |
@@ -956,17 +991,58 @@ struct EphemeralCacheEntry | |||
956 | 991 | ||
957 | 992 | ||
958 | /** | 993 | /** |
994 | * Information we keep per #GOODPUT_AGING_SLOTS about historic | ||
995 | * (or current) transmission performance. | ||
996 | */ | ||
997 | struct TransmissionHistoryEntry | ||
998 | { | ||
999 | /** | ||
1000 | * Number of bytes actually sent in the interval. | ||
1001 | */ | ||
1002 | uint64_t bytes_sent; | ||
1003 | |||
1004 | /** | ||
1005 | * Number of bytes received and acknowledged by the other peer in | ||
1006 | * the interval. | ||
1007 | */ | ||
1008 | uint64_t bytes_received; | ||
1009 | }; | ||
1010 | |||
1011 | |||
1012 | /** | ||
1013 | * Performance data for a transmission possibility. | ||
1014 | */ | ||
1015 | struct PerformanceData | ||
1016 | { | ||
1017 | /** | ||
1018 | * Weighted average for the RTT. | ||
1019 | */ | ||
1020 | struct GNUNET_TIME_Relative aged_rtt; | ||
1021 | |||
1022 | /** | ||
1023 | * Historic performance data, using a ring buffer of#GOODPUT_AGING_SLOTS | ||
1024 | * entries. | ||
1025 | */ | ||
1026 | struct TransmissionHistoryEntry the[GOODPUT_AGING_SLOTS]; | ||
1027 | |||
1028 | /** | ||
1029 | * What was the last age when we wrote to @e the? Used to clear | ||
1030 | * old entries when the age advances. | ||
1031 | */ | ||
1032 | unsigned int last_age; | ||
1033 | }; | ||
1034 | |||
1035 | |||
1036 | /** | ||
959 | * Client connected to the transport service. | 1037 | * Client connected to the transport service. |
960 | */ | 1038 | */ |
961 | struct TransportClient; | 1039 | struct TransportClient; |
962 | 1040 | ||
963 | |||
964 | /** | 1041 | /** |
965 | * A neighbour that at least one communicator is connected to. | 1042 | * A neighbour that at least one communicator is connected to. |
966 | */ | 1043 | */ |
967 | struct Neighbour; | 1044 | struct Neighbour; |
968 | 1045 | ||
969 | |||
970 | /** | 1046 | /** |
971 | * Entry in our #dv_routes table, representing a (set of) distance | 1047 | * Entry in our #dv_routes table, representing a (set of) distance |
972 | * vector routes to a particular peer. | 1048 | * vector routes to a particular peer. |
@@ -974,6 +1050,118 @@ struct Neighbour; | |||
974 | struct DistanceVector; | 1050 | struct DistanceVector; |
975 | 1051 | ||
976 | /** | 1052 | /** |
1053 | * A queue is a message queue provided by a communicator | ||
1054 | * via which we can reach a particular neighbour. | ||
1055 | */ | ||
1056 | struct Queue; | ||
1057 | |||
1058 | /** | ||
1059 | * Message awaiting transmission. See detailed comments below. | ||
1060 | */ | ||
1061 | struct PendingMessage; | ||
1062 | |||
1063 | /** | ||
1064 | * One possible hop towards a DV target. | ||
1065 | */ | ||
1066 | struct DistanceVectorHop; | ||
1067 | |||
1068 | |||
1069 | /** | ||
1070 | * Data structure kept when we are waiting for an acknowledgement. | ||
1071 | */ | ||
1072 | struct PendingAcknowledgement | ||
1073 | { | ||
1074 | |||
1075 | /** | ||
1076 | * If @e pm is non-NULL, this is the DLL in which this acknowledgement | ||
1077 | * is kept in relation to its pending message. | ||
1078 | */ | ||
1079 | struct PendingAcknowledgement *next_pm; | ||
1080 | |||
1081 | /** | ||
1082 | * If @e pm is non-NULL, this is the DLL in which this acknowledgement | ||
1083 | * is kept in relation to its pending message. | ||
1084 | */ | ||
1085 | struct PendingAcknowledgement *prev_pm; | ||
1086 | |||
1087 | /** | ||
1088 | * If @e queue is non-NULL, this is the DLL in which this acknowledgement | ||
1089 | * is kept in relation to the queue that was used to transmit the | ||
1090 | * @a pm. | ||
1091 | */ | ||
1092 | struct PendingAcknowledgement *next_queue; | ||
1093 | |||
1094 | /** | ||
1095 | * If @e queue is non-NULL, this is the DLL in which this acknowledgement | ||
1096 | * is kept in relation to the queue that was used to transmit the | ||
1097 | * @a pm. | ||
1098 | */ | ||
1099 | struct PendingAcknowledgement *prev_queue; | ||
1100 | |||
1101 | /** | ||
1102 | * If @e dvh is non-NULL, this is the DLL in which this acknowledgement | ||
1103 | * is kept in relation to the DVH that was used to transmit the | ||
1104 | * @a pm. | ||
1105 | */ | ||
1106 | struct PendingAcknowledgement *next_dvh; | ||
1107 | |||
1108 | /** | ||
1109 | * If @e dvh is non-NULL, this is the DLL in which this acknowledgement | ||
1110 | * is kept in relation to the DVH that was used to transmit the | ||
1111 | * @a pm. | ||
1112 | */ | ||
1113 | struct PendingAcknowledgement *prev_dvh; | ||
1114 | |||
1115 | /** | ||
1116 | * Pointers for the DLL of all pending acknowledgements. | ||
1117 | * This list is sorted by @e transmission time. If the list gets too | ||
1118 | * long, the oldest entries are discarded. | ||
1119 | */ | ||
1120 | struct PendingAcknowledgement *next_pa; | ||
1121 | |||
1122 | /** | ||
1123 | * Pointers for the DLL of all pending acknowledgements. | ||
1124 | * This list is sorted by @e transmission time. If the list gets too | ||
1125 | * long, the oldest entries are discarded. | ||
1126 | */ | ||
1127 | struct PendingAcknowledgement *prev_pa; | ||
1128 | |||
1129 | /** | ||
1130 | * Unique identifier for this transmission operation. | ||
1131 | */ | ||
1132 | struct AcknowledgementUUIDP ack_uuid; | ||
1133 | |||
1134 | /** | ||
1135 | * Message that was transmitted, may be NULL if the message was ACKed | ||
1136 | * via another channel. | ||
1137 | */ | ||
1138 | struct PendingMessage *pm; | ||
1139 | |||
1140 | /** | ||
1141 | * Distance vector path chosen for this transmission, NULL if transmission | ||
1142 | * was to a direct neighbour OR if the path was forgotten in the meantime. | ||
1143 | */ | ||
1144 | struct DistanceVectorHop *dvh; | ||
1145 | |||
1146 | /** | ||
1147 | * Queue used for transmission, NULL if the queue has been destroyed | ||
1148 | * (which may happen before we get an acknowledgement). | ||
1149 | */ | ||
1150 | struct Queue *queue; | ||
1151 | |||
1152 | /** | ||
1153 | * Time of the transmission, for RTT calculation. | ||
1154 | */ | ||
1155 | struct GNUNET_TIME_Absolute transmission_time; | ||
1156 | |||
1157 | /** | ||
1158 | * Number of bytes of the original message (to calculate bandwidth). | ||
1159 | */ | ||
1160 | uint16_t message_size; | ||
1161 | }; | ||
1162 | |||
1163 | |||
1164 | /** | ||
977 | * One possible hop towards a DV target. | 1165 | * One possible hop towards a DV target. |
978 | */ | 1166 | */ |
979 | struct DistanceVectorHop | 1167 | struct DistanceVectorHop |
@@ -1000,6 +1188,16 @@ struct DistanceVectorHop | |||
1000 | struct DistanceVectorHop *prev_neighbour; | 1188 | struct DistanceVectorHop *prev_neighbour; |
1001 | 1189 | ||
1002 | /** | 1190 | /** |
1191 | * Head of DLL of PAs that used our @a path. | ||
1192 | */ | ||
1193 | struct PendingAcknowledgement *pa_head; | ||
1194 | |||
1195 | /** | ||
1196 | * Tail of DLL of PAs that used our @a path. | ||
1197 | */ | ||
1198 | struct PendingAcknowledgement *pa_tail; | ||
1199 | |||
1200 | /** | ||
1003 | * What would be the next hop to @e target? | 1201 | * What would be the next hop to @e target? |
1004 | */ | 1202 | */ |
1005 | struct Neighbour *next_hop; | 1203 | struct Neighbour *next_hop; |
@@ -1032,6 +1230,11 @@ struct DistanceVectorHop | |||
1032 | struct GNUNET_TIME_Absolute path_valid_until; | 1230 | struct GNUNET_TIME_Absolute path_valid_until; |
1033 | 1231 | ||
1034 | /** | 1232 | /** |
1233 | * Performance data for this transmission possibility. | ||
1234 | */ | ||
1235 | struct PerformanceData pd; | ||
1236 | |||
1237 | /** | ||
1035 | * Number of hops in total to the `target` (excluding @e next_hop and `target` | 1238 | * Number of hops in total to the `target` (excluding @e next_hop and `target` |
1036 | * itself). Thus 0 still means a distance of 2 hops (to @e next_hop and then | 1239 | * itself). Thus 0 still means a distance of 2 hops (to @e next_hop and then |
1037 | * to `target`). | 1240 | * to `target`). |
@@ -1097,17 +1300,6 @@ struct DistanceVector | |||
1097 | 1300 | ||
1098 | 1301 | ||
1099 | /** | 1302 | /** |
1100 | * A queue is a message queue provided by a communicator | ||
1101 | * via which we can reach a particular neighbour. | ||
1102 | */ | ||
1103 | struct Queue; | ||
1104 | |||
1105 | /** | ||
1106 | * Message awaiting transmission. See detailed comments below. | ||
1107 | */ | ||
1108 | struct PendingMessage; | ||
1109 | |||
1110 | /** | ||
1111 | * Entry identifying transmission in one of our `struct | 1303 | * Entry identifying transmission in one of our `struct |
1112 | * Queue` which still awaits an ACK. This is used to | 1304 | * Queue` which still awaits an ACK. This is used to |
1113 | * ensure we do not overwhelm a communicator and limit the number of | 1305 | * ensure we do not overwhelm a communicator and limit the number of |
@@ -1173,6 +1365,16 @@ struct Queue | |||
1173 | struct Queue *next_client; | 1365 | struct Queue *next_client; |
1174 | 1366 | ||
1175 | /** | 1367 | /** |
1368 | * Head of DLL of PAs that used this queue. | ||
1369 | */ | ||
1370 | struct PendingAcknowledgement *pa_head; | ||
1371 | |||
1372 | /** | ||
1373 | * Tail of DLL of PAs that used this queue. | ||
1374 | */ | ||
1375 | struct PendingAcknowledgement *pa_tail; | ||
1376 | |||
1377 | /** | ||
1176 | * Head of DLL of unacked transmission requests. | 1378 | * Head of DLL of unacked transmission requests. |
1177 | */ | 1379 | */ |
1178 | struct QueueEntry *queue_head; | 1380 | struct QueueEntry *queue_head; |
@@ -1210,11 +1412,6 @@ struct Queue | |||
1210 | struct GNUNET_SCHEDULER_Task *visibility_task; | 1412 | struct GNUNET_SCHEDULER_Task *visibility_task; |
1211 | 1413 | ||
1212 | /** | 1414 | /** |
1213 | * Our current RTT estimate for this queue. | ||
1214 | */ | ||
1215 | struct GNUNET_TIME_Relative rtt; | ||
1216 | |||
1217 | /** | ||
1218 | * How long do *we* consider this @e address to be valid? In the past or | 1415 | * How long do *we* consider this @e address to be valid? In the past or |
1219 | * zero if we have not yet validated it. Can be updated based on | 1416 | * zero if we have not yet validated it. Can be updated based on |
1220 | * challenge-response validations (via address validation logic), or when we | 1417 | * challenge-response validations (via address validation logic), or when we |
@@ -1224,7 +1421,13 @@ struct Queue | |||
1224 | struct GNUNET_TIME_Absolute validated_until; | 1421 | struct GNUNET_TIME_Absolute validated_until; |
1225 | 1422 | ||
1226 | /** | 1423 | /** |
1227 | * Message ID generator for transmissions on this queue. | 1424 | * Performance data for this queue. |
1425 | */ | ||
1426 | struct PerformanceData pd; | ||
1427 | |||
1428 | /** | ||
1429 | * Message ID generator for transmissions on this queue to the | ||
1430 | * communicator. | ||
1228 | */ | 1431 | */ |
1229 | uint64_t mid_gen; | 1432 | uint64_t mid_gen; |
1230 | 1433 | ||
@@ -1282,10 +1485,10 @@ struct ReassemblyContext | |||
1282 | { | 1485 | { |
1283 | 1486 | ||
1284 | /** | 1487 | /** |
1285 | * Original message ID for of the message that all the | 1488 | * Original message ID for of the message that all the fragments |
1286 | * fragments belong to. | 1489 | * belong to. |
1287 | */ | 1490 | */ |
1288 | struct GNUNET_ShortHashCode msg_uuid; | 1491 | struct MessageUUIDP msg_uuid; |
1289 | 1492 | ||
1290 | /** | 1493 | /** |
1291 | * Which neighbour is this context for? | 1494 | * Which neighbour is this context for? |
@@ -1319,36 +1522,12 @@ struct ReassemblyContext | |||
1319 | struct GNUNET_TIME_Absolute reassembly_timeout; | 1522 | struct GNUNET_TIME_Absolute reassembly_timeout; |
1320 | 1523 | ||
1321 | /** | 1524 | /** |
1322 | * Average delay of all acks in @e extra_acks and @e frag_uuid. | ||
1323 | * Should be reset to zero when @e num_acks is set to 0. | ||
1324 | */ | ||
1325 | struct GNUNET_TIME_Relative avg_ack_delay; | ||
1326 | |||
1327 | /** | ||
1328 | * Time we received the last fragment. @e avg_ack_delay must be | 1525 | * Time we received the last fragment. @e avg_ack_delay must be |
1329 | * incremented by now - @e last_frag multiplied by @e num_acks. | 1526 | * incremented by now - @e last_frag multiplied by @e num_acks. |
1330 | */ | 1527 | */ |
1331 | struct GNUNET_TIME_Absolute last_frag; | 1528 | struct GNUNET_TIME_Absolute last_frag; |
1332 | 1529 | ||
1333 | /** | 1530 | /** |
1334 | * Bitfield of up to 64 additional fragments following @e frag_uuid | ||
1335 | * to be acknowledged in the next cummulative ACK. | ||
1336 | */ | ||
1337 | uint64_t extra_acks; | ||
1338 | |||
1339 | /** | ||
1340 | * Unique ID of the lowest fragment UUID to be acknowledged in the | ||
1341 | * next cummulative ACK. Only valid if @e num_acks > 0. | ||
1342 | */ | ||
1343 | uint32_t frag_uuid; | ||
1344 | |||
1345 | /** | ||
1346 | * Number of ACKs we have accumulated so far. Reset to 0 | ||
1347 | * whenever we send a #GNUNET_MESSAGE_TYPE_TRANSPORT_FRAGMENT_ACK. | ||
1348 | */ | ||
1349 | unsigned int num_acks; | ||
1350 | |||
1351 | /** | ||
1352 | * How big is the message we are reassembling in total? | 1531 | * How big is the message we are reassembling in total? |
1353 | */ | 1532 | */ |
1354 | uint16_t msg_size; | 1533 | uint16_t msg_size; |
@@ -1382,7 +1561,7 @@ struct Neighbour | |||
1382 | * reassembly. May be NULL if we currently have no fragments from | 1561 | * reassembly. May be NULL if we currently have no fragments from |
1383 | * this @e pid (lazy initialization). | 1562 | * this @e pid (lazy initialization). |
1384 | */ | 1563 | */ |
1385 | struct GNUNET_CONTAINER_MultiShortmap *reassembly_map; | 1564 | struct GNUNET_CONTAINER_MultiHashMap32 *reassembly_map; |
1386 | 1565 | ||
1387 | /** | 1566 | /** |
1388 | * Heap with `struct ReassemblyContext` structs for fragments under | 1567 | * Heap with `struct ReassemblyContext` structs for fragments under |
@@ -1588,6 +1767,16 @@ struct PendingMessage | |||
1588 | struct PendingMessage *prev_frag; | 1767 | struct PendingMessage *prev_frag; |
1589 | 1768 | ||
1590 | /** | 1769 | /** |
1770 | * Head of DLL of PAs for this pending message. | ||
1771 | */ | ||
1772 | struct PendingAcknowledgement *pa_head; | ||
1773 | |||
1774 | /** | ||
1775 | * Tail of DLL of PAs for this pending message. | ||
1776 | */ | ||
1777 | struct PendingAcknowledgement *pa_tail; | ||
1778 | |||
1779 | /** | ||
1591 | * This message, reliability boxed. Only possibly available if @e pmt is | 1780 | * This message, reliability boxed. Only possibly available if @e pmt is |
1592 | * #PMT_CORE. | 1781 | * #PMT_CORE. |
1593 | */ | 1782 | */ |
@@ -1642,12 +1831,7 @@ struct PendingMessage | |||
1642 | * UUID to use for this message (used for reassembly of fragments, only | 1831 | * UUID to use for this message (used for reassembly of fragments, only |
1643 | * initialized if @e msg_uuid_set is #GNUNET_YES). | 1832 | * initialized if @e msg_uuid_set is #GNUNET_YES). |
1644 | */ | 1833 | */ |
1645 | struct GNUNET_ShortHashCode msg_uuid; | 1834 | struct MessageUUIDP msg_uuid; |
1646 | |||
1647 | /** | ||
1648 | * Counter incremented per generated fragment. | ||
1649 | */ | ||
1650 | uint32_t frag_uuidgen; | ||
1651 | 1835 | ||
1652 | /** | 1836 | /** |
1653 | * Type of the pending message. | 1837 | * Type of the pending message. |
@@ -1674,6 +1858,66 @@ struct PendingMessage | |||
1674 | 1858 | ||
1675 | 1859 | ||
1676 | /** | 1860 | /** |
1861 | * Acknowledgement payload. | ||
1862 | */ | ||
1863 | struct TransportCummulativeAckPayload | ||
1864 | { | ||
1865 | /** | ||
1866 | * When did we receive the message we are ACKing? Used to calculate | ||
1867 | * the delay we introduced by cummulating ACKs. | ||
1868 | */ | ||
1869 | struct GNUNET_TIME_Absolute receive_time; | ||
1870 | |||
1871 | /** | ||
1872 | * UUID of a message being acknowledged. | ||
1873 | */ | ||
1874 | struct AcknowledgementUUIDP ack_uuid; | ||
1875 | }; | ||
1876 | |||
1877 | |||
1878 | /** | ||
1879 | * Data structure in which we track acknowledgements still to | ||
1880 | * be sent to the | ||
1881 | */ | ||
1882 | struct AcknowledgementCummulator | ||
1883 | { | ||
1884 | /** | ||
1885 | * Target peer for which we are accumulating ACKs here. | ||
1886 | */ | ||
1887 | struct GNUNET_PeerIdentity target; | ||
1888 | |||
1889 | /** | ||
1890 | * ACK data being accumulated. Only @e num_acks slots are valid. | ||
1891 | */ | ||
1892 | struct TransportCummulativeAckPayload ack_uuids[MAX_CUMMULATIVE_ACKS]; | ||
1893 | |||
1894 | /** | ||
1895 | * Task scheduled either to transmit the cummulative ACK message, | ||
1896 | * or to clean up this data structure after extended periods of | ||
1897 | * inactivity (if @e num_acks is zero). | ||
1898 | */ | ||
1899 | struct GNUNET_SCHEDULER_Task *task; | ||
1900 | |||
1901 | /** | ||
1902 | * When is @e task run (only used if @e num_acks is non-zero)? | ||
1903 | */ | ||
1904 | struct GNUNET_TIME_Absolute min_transmission_time; | ||
1905 | |||
1906 | /** | ||
1907 | * Counter to produce the `ack_counter` in the `struct | ||
1908 | * TransportReliabilityAckMessage`. Allows the receiver to detect | ||
1909 | * lost ACK messages. Incremented by @e num_acks upon transmission. | ||
1910 | */ | ||
1911 | uint32_t ack_counter; | ||
1912 | |||
1913 | /** | ||
1914 | * Number of entries used in @e ack_uuids. Reset to 0 upon transmission. | ||
1915 | */ | ||
1916 | unsigned int num_acks; | ||
1917 | }; | ||
1918 | |||
1919 | |||
1920 | /** | ||
1677 | * One of the addresses of this peer. | 1921 | * One of the addresses of this peer. |
1678 | */ | 1922 | */ |
1679 | struct AddressListEntry | 1923 | struct AddressListEntry |
@@ -1941,7 +2185,7 @@ struct ValidationState | |||
1941 | * (We must not rotate more often as otherwise we may discard valid answers | 2185 | * (We must not rotate more often as otherwise we may discard valid answers |
1942 | * due to packet losses, latency and reorderings on the network). | 2186 | * due to packet losses, latency and reorderings on the network). |
1943 | */ | 2187 | */ |
1944 | struct GNUNET_ShortHashCode challenge; | 2188 | struct ChallengeNonceP challenge; |
1945 | 2189 | ||
1946 | /** | 2190 | /** |
1947 | * Claimed address of the peer. | 2191 | * Claimed address of the peer. |
@@ -2071,6 +2315,18 @@ static struct GNUNET_CONTAINER_MultiPeerMap *neighbours; | |||
2071 | static struct GNUNET_CONTAINER_MultiPeerMap *backtalkers; | 2315 | static struct GNUNET_CONTAINER_MultiPeerMap *backtalkers; |
2072 | 2316 | ||
2073 | /** | 2317 | /** |
2318 | * Map from PIDs to `struct AcknowledgementCummulator`s. | ||
2319 | * Here we track the cummulative ACKs for transmission. | ||
2320 | */ | ||
2321 | static struct GNUNET_CONTAINER_MultiPeerMap *ack_cummulators; | ||
2322 | |||
2323 | /** | ||
2324 | * Map of pending acknowledgements, mapping `struct AcknowledgementUUID` to | ||
2325 | * a `struct PendingAcknowledgement`. | ||
2326 | */ | ||
2327 | static struct GNUNET_CONTAINER_MultiShortmap *pending_acks; | ||
2328 | |||
2329 | /** | ||
2074 | * Map from PIDs to `struct DistanceVector` entries describing | 2330 | * Map from PIDs to `struct DistanceVector` entries describing |
2075 | * known paths to the peer. | 2331 | * known paths to the peer. |
2076 | */ | 2332 | */ |
@@ -2139,6 +2395,81 @@ static struct GNUNET_SCHEDULER_Task *dvlearn_task; | |||
2139 | */ | 2395 | */ |
2140 | static struct GNUNET_SCHEDULER_Task *validation_task; | 2396 | static struct GNUNET_SCHEDULER_Task *validation_task; |
2141 | 2397 | ||
2398 | /** | ||
2399 | * The most recent PA we have created, head of DLL. | ||
2400 | * The length of the DLL is kept in #pa_count. | ||
2401 | */ | ||
2402 | static struct PendingAcknowledgement *pa_head; | ||
2403 | |||
2404 | /** | ||
2405 | * The oldest PA we have created, tail of DLL. | ||
2406 | * The length of the DLL is kept in #pa_count. | ||
2407 | */ | ||
2408 | static struct PendingAcknowledgement *pa_tail; | ||
2409 | |||
2410 | /** | ||
2411 | * Number of entries in the #pa_head/#pa_tail DLL. Used to | ||
2412 | * limit the size of the data structure. | ||
2413 | */ | ||
2414 | static unsigned int pa_count; | ||
2415 | |||
2416 | |||
2417 | /** | ||
2418 | * Get an offset into the transmission history buffer for `struct | ||
2419 | * PerformanceData`. Note that the caller must perform the required | ||
2420 | * modulo #GOODPUT_AGING_SLOTS operation before indexing into the | ||
2421 | * array! | ||
2422 | * | ||
2423 | * An 'age' lasts 15 minute slots. | ||
2424 | * | ||
2425 | * @return current age of the world | ||
2426 | */ | ||
2427 | static unsigned int | ||
2428 | get_age () | ||
2429 | { | ||
2430 | struct GNUNET_TIME_Absolute now; | ||
2431 | |||
2432 | now = GNUNET_TIME_absolute_get (); | ||
2433 | return now.abs_value_us / GNUNET_TIME_UNIT_MINUTES.rel_value_us / 15; | ||
2434 | } | ||
2435 | |||
2436 | |||
2437 | /** | ||
2438 | * Release @a pa data structure. | ||
2439 | * | ||
2440 | * @param pa data structure to release | ||
2441 | */ | ||
2442 | static void | ||
2443 | free_pending_acknowledgement (struct PendingAcknowledgement *pa) | ||
2444 | { | ||
2445 | struct Queue *q = pa->queue; | ||
2446 | struct PendingMessage *pm = pa->pm; | ||
2447 | struct DistanceVectorHop *dvh = pa->dvh; | ||
2448 | |||
2449 | GNUNET_CONTAINER_MDLL_remove (pa, pa_head, pa_tail, pa); | ||
2450 | pa_count--; | ||
2451 | if (NULL != q) | ||
2452 | { | ||
2453 | GNUNET_CONTAINER_MDLL_remove (queue, q->pa_head, q->pa_tail, pa); | ||
2454 | pa->queue = NULL; | ||
2455 | } | ||
2456 | if (NULL != pm) | ||
2457 | { | ||
2458 | GNUNET_CONTAINER_MDLL_remove (pm, pm->pa_head, pm->pa_tail, pa); | ||
2459 | pa->pm = NULL; | ||
2460 | } | ||
2461 | if (NULL != dvh) | ||
2462 | { | ||
2463 | GNUNET_CONTAINER_MDLL_remove (dvh, dvh->pa_head, dvh->pa_tail, pa); | ||
2464 | pa->queue = NULL; | ||
2465 | } | ||
2466 | GNUNET_assert (GNUNET_YES == | ||
2467 | GNUNET_CONTAINER_multishortmap_remove (pending_acks, | ||
2468 | &pa->ack_uuid.value, | ||
2469 | pa)); | ||
2470 | GNUNET_free (pa); | ||
2471 | } | ||
2472 | |||
2142 | 2473 | ||
2143 | /** | 2474 | /** |
2144 | * Free cached ephemeral key. | 2475 | * Free cached ephemeral key. |
@@ -2235,7 +2566,13 @@ free_distance_vector_hop (struct DistanceVectorHop *dvh) | |||
2235 | { | 2566 | { |
2236 | struct Neighbour *n = dvh->next_hop; | 2567 | struct Neighbour *n = dvh->next_hop; |
2237 | struct DistanceVector *dv = dvh->dv; | 2568 | struct DistanceVector *dv = dvh->dv; |
2569 | struct PendingAcknowledgement *pa; | ||
2238 | 2570 | ||
2571 | while (NULL != (pa = dvh->pa_head)) | ||
2572 | { | ||
2573 | GNUNET_CONTAINER_MDLL_remove (dvh, dvh->pa_head, dvh->pa_tail, pa); | ||
2574 | pa->dvh = NULL; | ||
2575 | } | ||
2239 | GNUNET_CONTAINER_MDLL_remove (neighbour, n->dv_head, n->dv_tail, dvh); | 2576 | GNUNET_CONTAINER_MDLL_remove (neighbour, n->dv_head, n->dv_tail, dvh); |
2240 | GNUNET_CONTAINER_MDLL_remove (dv, dv->dv_head, dv->dv_tail, dvh); | 2577 | GNUNET_CONTAINER_MDLL_remove (dv, dv->dv_head, dv->dv_tail, dvh); |
2241 | GNUNET_free (dvh); | 2578 | GNUNET_free (dvh); |
@@ -2377,9 +2714,9 @@ free_reassembly_context (struct ReassemblyContext *rc) | |||
2377 | 2714 | ||
2378 | GNUNET_assert (rc == GNUNET_CONTAINER_heap_remove_node (rc->hn)); | 2715 | GNUNET_assert (rc == GNUNET_CONTAINER_heap_remove_node (rc->hn)); |
2379 | GNUNET_assert (GNUNET_OK == | 2716 | GNUNET_assert (GNUNET_OK == |
2380 | GNUNET_CONTAINER_multishortmap_remove (n->reassembly_map, | 2717 | GNUNET_CONTAINER_multihashmap32_remove (n->reassembly_map, |
2381 | &rc->msg_uuid, | 2718 | rc->msg_uuid.uuid, |
2382 | rc)); | 2719 | rc)); |
2383 | GNUNET_free (rc); | 2720 | GNUNET_free (rc); |
2384 | } | 2721 | } |
2385 | 2722 | ||
@@ -2423,9 +2760,7 @@ reassembly_cleanup_task (void *cls) | |||
2423 | * @return #GNUNET_OK (continue iteration) | 2760 | * @return #GNUNET_OK (continue iteration) |
2424 | */ | 2761 | */ |
2425 | static int | 2762 | static int |
2426 | free_reassembly_cb (void *cls, | 2763 | free_reassembly_cb (void *cls, uint32_t key, void *value) |
2427 | const struct GNUNET_ShortHashCode *key, | ||
2428 | void *value) | ||
2429 | { | 2764 | { |
2430 | struct ReassemblyContext *rc = value; | 2765 | struct ReassemblyContext *rc = value; |
2431 | 2766 | ||
@@ -2455,10 +2790,10 @@ free_neighbour (struct Neighbour *neighbour) | |||
2455 | GNUNET_SCHEDULER_cancel (neighbour->timeout_task); | 2790 | GNUNET_SCHEDULER_cancel (neighbour->timeout_task); |
2456 | if (NULL != neighbour->reassembly_map) | 2791 | if (NULL != neighbour->reassembly_map) |
2457 | { | 2792 | { |
2458 | GNUNET_CONTAINER_multishortmap_iterate (neighbour->reassembly_map, | 2793 | GNUNET_CONTAINER_multihashmap32_iterate (neighbour->reassembly_map, |
2459 | &free_reassembly_cb, | 2794 | &free_reassembly_cb, |
2460 | NULL); | 2795 | NULL); |
2461 | GNUNET_CONTAINER_multishortmap_destroy (neighbour->reassembly_map); | 2796 | GNUNET_CONTAINER_multihashmap32_destroy (neighbour->reassembly_map); |
2462 | neighbour->reassembly_map = NULL; | 2797 | neighbour->reassembly_map = NULL; |
2463 | GNUNET_CONTAINER_heap_destroy (neighbour->reassembly_heap); | 2798 | GNUNET_CONTAINER_heap_destroy (neighbour->reassembly_heap); |
2464 | neighbour->reassembly_heap = NULL; | 2799 | neighbour->reassembly_heap = NULL; |
@@ -2641,6 +2976,7 @@ free_queue (struct Queue *queue) | |||
2641 | .rtt = GNUNET_TIME_UNIT_FOREVER_REL}; | 2976 | .rtt = GNUNET_TIME_UNIT_FOREVER_REL}; |
2642 | struct QueueEntry *qe; | 2977 | struct QueueEntry *qe; |
2643 | int maxxed; | 2978 | int maxxed; |
2979 | struct PendingAcknowledgement *pa; | ||
2644 | 2980 | ||
2645 | if (NULL != queue->transmit_task) | 2981 | if (NULL != queue->transmit_task) |
2646 | { | 2982 | { |
@@ -2652,6 +2988,12 @@ free_queue (struct Queue *queue) | |||
2652 | GNUNET_SCHEDULER_cancel (queue->visibility_task); | 2988 | GNUNET_SCHEDULER_cancel (queue->visibility_task); |
2653 | queue->visibility_task = NULL; | 2989 | queue->visibility_task = NULL; |
2654 | } | 2990 | } |
2991 | while (NULL != (pa = queue->pa_head)) | ||
2992 | { | ||
2993 | GNUNET_CONTAINER_MDLL_remove (queue, queue->pa_head, queue->pa_tail, pa); | ||
2994 | pa->queue = NULL; | ||
2995 | } | ||
2996 | |||
2655 | GNUNET_CONTAINER_MDLL_remove (neighbour, | 2997 | GNUNET_CONTAINER_MDLL_remove (neighbour, |
2656 | neighbour->queue_head, | 2998 | neighbour->queue_head, |
2657 | neighbour->queue_tail, | 2999 | neighbour->queue_tail, |
@@ -2914,6 +3256,9 @@ check_client_send (void *cls, const struct OutboundMessage *obm) | |||
2914 | 3256 | ||
2915 | /** | 3257 | /** |
2916 | * Free fragment tree below @e root, excluding @e root itself. | 3258 | * Free fragment tree below @e root, excluding @e root itself. |
3259 | * FIXME: this does NOT seem to have the intended semantics | ||
3260 | * based on how this is called. Seems we generally DO expect | ||
3261 | * @a root to be free'ed itself as well! | ||
2917 | * | 3262 | * |
2918 | * @param root root of the tree to free | 3263 | * @param root root of the tree to free |
2919 | */ | 3264 | */ |
@@ -2924,7 +3269,14 @@ free_fragment_tree (struct PendingMessage *root) | |||
2924 | 3269 | ||
2925 | while (NULL != (frag = root->head_frag)) | 3270 | while (NULL != (frag = root->head_frag)) |
2926 | { | 3271 | { |
3272 | struct PendingAcknowledgement *pa; | ||
3273 | |||
2927 | free_fragment_tree (frag); | 3274 | free_fragment_tree (frag); |
3275 | while (NULL != (pa = frag->pa_head)) | ||
3276 | { | ||
3277 | GNUNET_CONTAINER_MDLL_remove (pm, frag->pa_head, frag->pa_tail, pa); | ||
3278 | pa->pm = NULL; | ||
3279 | } | ||
2928 | GNUNET_CONTAINER_MDLL_remove (frag, root->head_frag, root->tail_frag, frag); | 3280 | GNUNET_CONTAINER_MDLL_remove (frag, root->head_frag, root->tail_frag, frag); |
2929 | GNUNET_free (frag); | 3281 | GNUNET_free (frag); |
2930 | } | 3282 | } |
@@ -2943,6 +3295,7 @@ free_pending_message (struct PendingMessage *pm) | |||
2943 | { | 3295 | { |
2944 | struct TransportClient *tc = pm->client; | 3296 | struct TransportClient *tc = pm->client; |
2945 | struct Neighbour *target = pm->target; | 3297 | struct Neighbour *target = pm->target; |
3298 | struct PendingAcknowledgement *pa; | ||
2946 | 3299 | ||
2947 | if (NULL != tc) | 3300 | if (NULL != tc) |
2948 | { | 3301 | { |
@@ -2955,6 +3308,12 @@ free_pending_message (struct PendingMessage *pm) | |||
2955 | target->pending_msg_head, | 3308 | target->pending_msg_head, |
2956 | target->pending_msg_tail, | 3309 | target->pending_msg_tail, |
2957 | pm); | 3310 | pm); |
3311 | while (NULL != (pa = pm->pa_head)) | ||
3312 | { | ||
3313 | GNUNET_CONTAINER_MDLL_remove (pm, pm->pa_head, pm->pa_tail, pa); | ||
3314 | pa->pm = NULL; | ||
3315 | } | ||
3316 | |||
2958 | free_fragment_tree (pm); | 3317 | free_fragment_tree (pm); |
2959 | if (NULL != pm->qe) | 3318 | if (NULL != pm->qe) |
2960 | { | 3319 | { |
@@ -3194,7 +3553,7 @@ check_communicator_backchannel ( | |||
3194 | msize = ntohs (cb->header.size) - sizeof (*cb); | 3553 | msize = ntohs (cb->header.size) - sizeof (*cb); |
3195 | if (UINT16_MAX - msize > | 3554 | if (UINT16_MAX - msize > |
3196 | sizeof (struct TransportBackchannelEncapsulationMessage) + | 3555 | sizeof (struct TransportBackchannelEncapsulationMessage) + |
3197 | sizeof (struct TransportBackchannelRequestPayload)) | 3556 | sizeof (struct TransportBackchannelRequestPayloadP)) |
3198 | { | 3557 | { |
3199 | GNUNET_break (0); | 3558 | GNUNET_break (0); |
3200 | return GNUNET_SYSERR; | 3559 | return GNUNET_SYSERR; |
@@ -3481,10 +3840,10 @@ forward_via_dvh (const struct DistanceVectorHop *dvh, | |||
3481 | enum RouteMessageOptions options) | 3840 | enum RouteMessageOptions options) |
3482 | { | 3841 | { |
3483 | uint16_t mlen = ntohs (payload->size); | 3842 | uint16_t mlen = ntohs (payload->size); |
3484 | char boxram[sizeof (struct TransportDVBox) + | 3843 | char boxram[sizeof (struct TransportDVBoxMessage) + |
3485 | (dvh->distance + 1) * sizeof (struct GNUNET_PeerIdentity) + | 3844 | (dvh->distance + 1) * sizeof (struct GNUNET_PeerIdentity) + |
3486 | mlen] GNUNET_ALIGN; | 3845 | mlen] GNUNET_ALIGN; |
3487 | struct TransportDVBox *box = (struct TransportDVBox *) boxram; | 3846 | struct TransportDVBoxMessage *box = (struct TransportDVBoxMessage *) boxram; |
3488 | struct GNUNET_PeerIdentity *path = (struct GNUNET_PeerIdentity *) &box[1]; | 3847 | struct GNUNET_PeerIdentity *path = (struct GNUNET_PeerIdentity *) &box[1]; |
3489 | 3848 | ||
3490 | box->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_DV_BOX); | 3849 | box->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_DV_BOX); |
@@ -3659,6 +4018,14 @@ struct BackchannelKeyState | |||
3659 | }; | 4018 | }; |
3660 | 4019 | ||
3661 | 4020 | ||
4021 | /** | ||
4022 | * Given the key material in @a km and the initialization vector | ||
4023 | * @a iv, setup the key material for the backchannel in @a key. | ||
4024 | * | ||
4025 | * @param km raw master secret | ||
4026 | * @param iv initialization vector | ||
4027 | * @param key[out] symmetric cipher and HMAC state to generate | ||
4028 | */ | ||
3662 | static void | 4029 | static void |
3663 | bc_setup_key_state_from_km (const struct GNUNET_HashCode *km, | 4030 | bc_setup_key_state_from_km (const struct GNUNET_HashCode *km, |
3664 | const struct GNUNET_ShortHashCode *iv, | 4031 | const struct GNUNET_ShortHashCode *iv, |
@@ -3822,14 +4189,14 @@ handle_communicator_backchannel ( | |||
3822 | struct GNUNET_CRYPTO_EcdhePrivateKey private_key; | 4189 | struct GNUNET_CRYPTO_EcdhePrivateKey private_key; |
3823 | struct GNUNET_TIME_Absolute ephemeral_validity; | 4190 | struct GNUNET_TIME_Absolute ephemeral_validity; |
3824 | struct TransportBackchannelEncapsulationMessage *enc; | 4191 | struct TransportBackchannelEncapsulationMessage *enc; |
3825 | struct TransportBackchannelRequestPayload ppay; | 4192 | struct TransportBackchannelRequestPayloadP ppay; |
3826 | struct BackchannelKeyState key; | 4193 | struct BackchannelKeyState key; |
3827 | char *mpos; | 4194 | char *mpos; |
3828 | uint16_t msize; | 4195 | uint16_t msize; |
3829 | 4196 | ||
3830 | /* encapsulate and encrypt message */ | 4197 | /* encapsulate and encrypt message */ |
3831 | msize = ntohs (cb->header.size) - sizeof (*cb) + | 4198 | msize = ntohs (cb->header.size) - sizeof (*cb) + |
3832 | sizeof (struct TransportBackchannelRequestPayload); | 4199 | sizeof (struct TransportBackchannelRequestPayloadP); |
3833 | enc = GNUNET_malloc (sizeof (*enc) + msize); | 4200 | enc = GNUNET_malloc (sizeof (*enc) + msize); |
3834 | enc->header.type = | 4201 | enc->header.type = |
3835 | htons (GNUNET_MESSAGE_TYPE_TRANSPORT_BACKCHANNEL_ENCAPSULATION); | 4202 | htons (GNUNET_MESSAGE_TYPE_TRANSPORT_BACKCHANNEL_ENCAPSULATION); |
@@ -4140,7 +4507,7 @@ handle_raw_message (void *cls, const struct GNUNET_MessageHeader *mh) | |||
4140 | * @return #GNUNET_YES if message is well-formed | 4507 | * @return #GNUNET_YES if message is well-formed |
4141 | */ | 4508 | */ |
4142 | static int | 4509 | static int |
4143 | check_fragment_box (void *cls, const struct TransportFragmentBox *fb) | 4510 | check_fragment_box (void *cls, const struct TransportFragmentBoxMessage *fb) |
4144 | { | 4511 | { |
4145 | uint16_t size = ntohs (fb->header.size); | 4512 | uint16_t size = ntohs (fb->header.size); |
4146 | uint16_t bsize = size - sizeof (*fb); | 4513 | uint16_t bsize = size - sizeof (*fb); |
@@ -4165,32 +4532,150 @@ check_fragment_box (void *cls, const struct TransportFragmentBox *fb) | |||
4165 | 4532 | ||
4166 | 4533 | ||
4167 | /** | 4534 | /** |
4168 | * Generate a fragment acknowledgement for an @a rc. | 4535 | * Clean up an idle cummulative acknowledgement data structure. |
4169 | * | 4536 | * |
4170 | * @param rc context to generate ACK for, @a rc ACK state is reset | 4537 | * @param cls a `struct AcknowledgementCummulator *` |
4171 | */ | 4538 | */ |
4172 | static void | 4539 | static void |
4173 | send_fragment_ack (struct ReassemblyContext *rc) | 4540 | destroy_ack_cummulator (void *cls) |
4174 | { | 4541 | { |
4175 | struct TransportFragmentAckMessage *ack; | 4542 | struct AcknowledgementCummulator *ac = cls; |
4176 | 4543 | ||
4177 | ack = GNUNET_new (struct TransportFragmentAckMessage); | 4544 | ac->task = NULL; |
4178 | ack->header.size = htons (sizeof (struct TransportFragmentAckMessage)); | 4545 | GNUNET_assert (0 == ac->num_acks); |
4179 | ack->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_FRAGMENT_ACK); | 4546 | GNUNET_assert ( |
4180 | ack->frag_uuid = htonl (rc->frag_uuid); | 4547 | GNUNET_YES == |
4181 | ack->extra_acks = GNUNET_htonll (rc->extra_acks); | 4548 | GNUNET_CONTAINER_multipeermap_remove (ack_cummulators, &ac->target, ac)); |
4182 | ack->msg_uuid = rc->msg_uuid; | 4549 | GNUNET_free (ac); |
4183 | ack->avg_ack_delay = GNUNET_TIME_relative_hton (rc->avg_ack_delay); | 4550 | } |
4184 | if (0 == rc->msg_missing) | 4551 | |
4185 | ack->reassembly_timeout = GNUNET_TIME_relative_hton ( | 4552 | |
4186 | GNUNET_TIME_UNIT_FOREVER_REL); /* signal completion */ | 4553 | /** |
4554 | * Do the transmission of a cummulative acknowledgement now. | ||
4555 | * | ||
4556 | * @param cls a `struct AcknowledgementCummulator *` | ||
4557 | */ | ||
4558 | static void | ||
4559 | transmit_cummulative_ack_cb (void *cls) | ||
4560 | { | ||
4561 | struct AcknowledgementCummulator *ac = cls; | ||
4562 | struct TransportReliabilityAckMessage *ack; | ||
4563 | struct TransportCummulativeAckPayloadP *ap; | ||
4564 | |||
4565 | ac->task = NULL; | ||
4566 | GNUNET_assert (0 < ac->ack_counter); | ||
4567 | ack = GNUNET_malloc (sizeof (*ack) + | ||
4568 | ac->ack_counter * | ||
4569 | sizeof (struct TransportCummulativeAckPayloadP)); | ||
4570 | ack->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_RELIABILITY_ACK); | ||
4571 | ack->header.size = | ||
4572 | htons (sizeof (*ack) + | ||
4573 | ac->ack_counter * sizeof (struct TransportCummulativeAckPayloadP)); | ||
4574 | ack->ack_counter = htonl (ac->ack_counter++); | ||
4575 | ap = (struct TransportCummulativeAckPayloadP *) &ack[1]; | ||
4576 | for (unsigned int i = 0; i < ac->ack_counter; i++) | ||
4577 | { | ||
4578 | ap[i].ack_uuid = ac->ack_uuids[i].ack_uuid; | ||
4579 | ap[i].ack_delay = GNUNET_TIME_relative_hton ( | ||
4580 | GNUNET_TIME_absolute_get_duration (ac->ack_uuids[i].receive_time)); | ||
4581 | } | ||
4582 | route_message (&ac->target, &ack->header, RMO_DV_ALLOWED); | ||
4583 | ac->num_acks = 0; | ||
4584 | ac->task = GNUNET_SCHEDULER_add_delayed (ACK_CUMMULATOR_TIMEOUT, | ||
4585 | &destroy_ack_cummulator, | ||
4586 | ac); | ||
4587 | } | ||
4588 | |||
4589 | |||
4590 | /** | ||
4591 | * Transmit an acknowledgement for @a ack_uuid to @a pid delaying | ||
4592 | * transmission by at most @a ack_delay. | ||
4593 | * | ||
4594 | * @param pid target peer | ||
4595 | * @param ack_uuid UUID to ack | ||
4596 | * @param max_delay how long can the ACK wait | ||
4597 | */ | ||
4598 | static void | ||
4599 | cummulative_ack (const struct GNUNET_PeerIdentity *pid, | ||
4600 | const struct AcknowledgementUUIDP *ack_uuid, | ||
4601 | struct GNUNET_TIME_Absolute max_delay) | ||
4602 | { | ||
4603 | struct AcknowledgementCummulator *ac; | ||
4604 | |||
4605 | ac = GNUNET_CONTAINER_multipeermap_get (ack_cummulators, pid); | ||
4606 | if (NULL == ac) | ||
4607 | { | ||
4608 | ac = GNUNET_new (struct AcknowledgementCummulator); | ||
4609 | ac->target = *pid; | ||
4610 | ac->min_transmission_time = max_delay; | ||
4611 | GNUNET_assert (GNUNET_YES == | ||
4612 | GNUNET_CONTAINER_multipeermap_put ( | ||
4613 | ack_cummulators, | ||
4614 | &ac->target, | ||
4615 | ac, | ||
4616 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); | ||
4617 | } | ||
4187 | else | 4618 | else |
4188 | ack->reassembly_timeout = GNUNET_TIME_relative_hton ( | 4619 | { |
4189 | GNUNET_TIME_absolute_get_remaining (rc->reassembly_timeout)); | 4620 | if (MAX_CUMMULATIVE_ACKS == ac->num_acks) |
4190 | route_message (&rc->neighbour->pid, &ack->header, RMO_DV_ALLOWED); | 4621 | { |
4191 | rc->avg_ack_delay = GNUNET_TIME_UNIT_ZERO; | 4622 | /* must run immediately, ack buffer full! */ |
4192 | rc->num_acks = 0; | 4623 | GNUNET_SCHEDULER_cancel (ac->task); |
4193 | rc->extra_acks = 0LLU; | 4624 | transmit_cummulative_ack_cb (ac); |
4625 | } | ||
4626 | GNUNET_SCHEDULER_cancel (ac->task); | ||
4627 | ac->min_transmission_time = | ||
4628 | GNUNET_TIME_absolute_min (ac->min_transmission_time, max_delay); | ||
4629 | } | ||
4630 | GNUNET_assert (ac->num_acks < MAX_CUMMULATIVE_ACKS); | ||
4631 | ac->ack_uuids[ac->num_acks].receive_time = GNUNET_TIME_absolute_get (); | ||
4632 | ac->ack_uuids[ac->num_acks].ack_uuid = *ack_uuid; | ||
4633 | ac->num_acks++; | ||
4634 | ac->task = GNUNET_SCHEDULER_add_at (ac->min_transmission_time, | ||
4635 | &transmit_cummulative_ack_cb, | ||
4636 | ac); | ||
4637 | } | ||
4638 | |||
4639 | |||
4640 | /** | ||
4641 | * Closure for #find_by_message_uuid. | ||
4642 | */ | ||
4643 | struct FindByMessageUuidContext | ||
4644 | { | ||
4645 | /** | ||
4646 | * UUID to look for. | ||
4647 | */ | ||
4648 | struct MessageUUIDP message_uuid; | ||
4649 | |||
4650 | /** | ||
4651 | * Set to the reassembly context if found. | ||
4652 | */ | ||
4653 | struct ReassemblyContext *rc; | ||
4654 | }; | ||
4655 | |||
4656 | |||
4657 | /** | ||
4658 | * Iterator called to find a reassembly context by the message UUID in the | ||
4659 | * multihashmap32. | ||
4660 | * | ||
4661 | * @param cls a `struct FindByMessageUuidContext` | ||
4662 | * @param key a key (unused) | ||
4663 | * @param value a `struct ReassemblyContext` | ||
4664 | * @return #GNUNET_YES if not found, #GNUNET_NO if found | ||
4665 | */ | ||
4666 | static int | ||
4667 | find_by_message_uuid (void *cls, uint32_t key, void *value) | ||
4668 | { | ||
4669 | struct FindByMessageUuidContext *fc = cls; | ||
4670 | struct ReassemblyContext *rc = value; | ||
4671 | |||
4672 | (void) key; | ||
4673 | if (0 == GNUNET_memcmp (&fc->message_uuid, &rc->msg_uuid)) | ||
4674 | { | ||
4675 | fc->rc = rc; | ||
4676 | return GNUNET_NO; | ||
4677 | } | ||
4678 | return GNUNET_YES; | ||
4194 | } | 4679 | } |
4195 | 4680 | ||
4196 | 4681 | ||
@@ -4202,7 +4687,7 @@ send_fragment_ack (struct ReassemblyContext *rc) | |||
4202 | * @param fb the message that was received | 4687 | * @param fb the message that was received |
4203 | */ | 4688 | */ |
4204 | static void | 4689 | static void |
4205 | handle_fragment_box (void *cls, const struct TransportFragmentBox *fb) | 4690 | handle_fragment_box (void *cls, const struct TransportFragmentBoxMessage *fb) |
4206 | { | 4691 | { |
4207 | struct CommunicatorMessageContext *cmc = cls; | 4692 | struct CommunicatorMessageContext *cmc = cls; |
4208 | struct Neighbour *n; | 4693 | struct Neighbour *n; |
@@ -4211,10 +4696,9 @@ handle_fragment_box (void *cls, const struct TransportFragmentBox *fb) | |||
4211 | uint16_t msize; | 4696 | uint16_t msize; |
4212 | uint16_t fsize; | 4697 | uint16_t fsize; |
4213 | uint16_t frag_off; | 4698 | uint16_t frag_off; |
4214 | uint32_t frag_uuid; | ||
4215 | char *target; | 4699 | char *target; |
4216 | struct GNUNET_TIME_Relative cdelay; | 4700 | struct GNUNET_TIME_Relative cdelay; |
4217 | int ack_now; | 4701 | struct FindByMessageUuidContext fc; |
4218 | 4702 | ||
4219 | n = GNUNET_CONTAINER_multipeermap_get (neighbours, &cmc->im.sender); | 4703 | n = GNUNET_CONTAINER_multipeermap_get (neighbours, &cmc->im.sender); |
4220 | if (NULL == n) | 4704 | if (NULL == n) |
@@ -4228,7 +4712,7 @@ handle_fragment_box (void *cls, const struct TransportFragmentBox *fb) | |||
4228 | } | 4712 | } |
4229 | if (NULL == n->reassembly_map) | 4713 | if (NULL == n->reassembly_map) |
4230 | { | 4714 | { |
4231 | n->reassembly_map = GNUNET_CONTAINER_multishortmap_create (8, GNUNET_YES); | 4715 | n->reassembly_map = GNUNET_CONTAINER_multihashmap32_create (8); |
4232 | n->reassembly_heap = | 4716 | n->reassembly_heap = |
4233 | GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN); | 4717 | GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN); |
4234 | n->reassembly_timeout_task = | 4718 | n->reassembly_timeout_task = |
@@ -4237,8 +4721,13 @@ handle_fragment_box (void *cls, const struct TransportFragmentBox *fb) | |||
4237 | n); | 4721 | n); |
4238 | } | 4722 | } |
4239 | msize = ntohs (fb->msg_size); | 4723 | msize = ntohs (fb->msg_size); |
4240 | rc = GNUNET_CONTAINER_multishortmap_get (n->reassembly_map, &fb->msg_uuid); | 4724 | fc.message_uuid = fb->msg_uuid; |
4241 | if (NULL == rc) | 4725 | fc.rc = NULL; |
4726 | GNUNET_CONTAINER_multihashmap32_get_multiple (n->reassembly_map, | ||
4727 | fb->msg_uuid.uuid, | ||
4728 | &find_by_message_uuid, | ||
4729 | &fc); | ||
4730 | if (NULL == (rc = fc.rc)) | ||
4242 | { | 4731 | { |
4243 | rc = GNUNET_malloc (sizeof (*rc) + msize + /* reassembly payload buffer */ | 4732 | rc = GNUNET_malloc (sizeof (*rc) + msize + /* reassembly payload buffer */ |
4244 | (msize + 7) / 8 * sizeof (uint8_t) /* bitfield */); | 4733 | (msize + 7) / 8 * sizeof (uint8_t) /* bitfield */); |
@@ -4252,11 +4741,11 @@ handle_fragment_box (void *cls, const struct TransportFragmentBox *fb) | |||
4252 | rc, | 4741 | rc, |
4253 | rc->reassembly_timeout.abs_value_us); | 4742 | rc->reassembly_timeout.abs_value_us); |
4254 | GNUNET_assert (GNUNET_OK == | 4743 | GNUNET_assert (GNUNET_OK == |
4255 | GNUNET_CONTAINER_multishortmap_put ( | 4744 | GNUNET_CONTAINER_multihashmap32_put ( |
4256 | n->reassembly_map, | 4745 | n->reassembly_map, |
4257 | &rc->msg_uuid, | 4746 | rc->msg_uuid.uuid, |
4258 | rc, | 4747 | rc, |
4259 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); | 4748 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE)); |
4260 | target = (char *) &rc[1]; | 4749 | target = (char *) &rc[1]; |
4261 | rc->bitfield = (uint8_t *) (target + rc->msg_size); | 4750 | rc->bitfield = (uint8_t *) (target + rc->msg_size); |
4262 | rc->msg_missing = rc->msg_size; | 4751 | rc->msg_missing = rc->msg_size; |
@@ -4274,6 +4763,12 @@ handle_fragment_box (void *cls, const struct TransportFragmentBox *fb) | |||
4274 | 4763 | ||
4275 | /* reassemble */ | 4764 | /* reassemble */ |
4276 | fsize = ntohs (fb->header.size) - sizeof (*fb); | 4765 | fsize = ntohs (fb->header.size) - sizeof (*fb); |
4766 | if (0 == fsize) | ||
4767 | { | ||
4768 | GNUNET_break (0); | ||
4769 | finish_cmc_handling (cmc); | ||
4770 | return; | ||
4771 | } | ||
4277 | frag_off = ntohs (fb->frag_off); | 4772 | frag_off = ntohs (fb->frag_off); |
4278 | memcpy (&target[frag_off], &fb[1], fsize); | 4773 | memcpy (&target[frag_off], &fb[1], fsize); |
4279 | /* update bitfield and msg_missing */ | 4774 | /* update bitfield and msg_missing */ |
@@ -4287,60 +4782,17 @@ handle_fragment_box (void *cls, const struct TransportFragmentBox *fb) | |||
4287 | } | 4782 | } |
4288 | 4783 | ||
4289 | /* Compute cummulative ACK */ | 4784 | /* Compute cummulative ACK */ |
4290 | frag_uuid = ntohl (fb->frag_uuid); | ||
4291 | cdelay = GNUNET_TIME_absolute_get_duration (rc->last_frag); | 4785 | cdelay = GNUNET_TIME_absolute_get_duration (rc->last_frag); |
4292 | cdelay = GNUNET_TIME_relative_multiply (cdelay, rc->num_acks); | 4786 | cdelay = GNUNET_TIME_relative_multiply (cdelay, rc->msg_missing / fsize); |
4787 | if (0 == rc->msg_missing) | ||
4788 | cdelay = GNUNET_TIME_UNIT_ZERO; | ||
4789 | cummulative_ack (&cmc->im.sender, | ||
4790 | &fb->ack_uuid, | ||
4791 | GNUNET_TIME_relative_to_absolute (cdelay)); | ||
4293 | rc->last_frag = GNUNET_TIME_absolute_get (); | 4792 | rc->last_frag = GNUNET_TIME_absolute_get (); |
4294 | rc->avg_ack_delay = GNUNET_TIME_relative_add (rc->avg_ack_delay, cdelay); | ||
4295 | ack_now = GNUNET_NO; | ||
4296 | if (0 == rc->num_acks) | ||
4297 | { | ||
4298 | /* case one: first ack */ | ||
4299 | rc->frag_uuid = frag_uuid; | ||
4300 | rc->extra_acks = 0LLU; | ||
4301 | rc->num_acks = 1; | ||
4302 | } | ||
4303 | else if ((frag_uuid >= rc->frag_uuid) && (frag_uuid <= rc->frag_uuid + 64)) | ||
4304 | { | ||
4305 | /* case two: ack fits after existing min UUID */ | ||
4306 | if ((frag_uuid == rc->frag_uuid) || | ||
4307 | (0 != (rc->extra_acks & (1LLU << (frag_uuid - rc->frag_uuid - 1))))) | ||
4308 | { | ||
4309 | /* duplicate fragment, ack now! */ | ||
4310 | ack_now = GNUNET_YES; | ||
4311 | } | ||
4312 | else | ||
4313 | { | ||
4314 | rc->extra_acks |= (1LLU << (frag_uuid - rc->frag_uuid - 1)); | ||
4315 | rc->num_acks++; | ||
4316 | } | ||
4317 | } | ||
4318 | else if ((rc->frag_uuid > frag_uuid) && | ||
4319 | (((rc->frag_uuid == frag_uuid + 64) && (0 == rc->extra_acks)) || | ||
4320 | ((rc->frag_uuid < frag_uuid + 64) && | ||
4321 | (rc->extra_acks == | ||
4322 | (rc->extra_acks & | ||
4323 | ~((1LLU << (64 - (rc->frag_uuid - frag_uuid))) - 1LLU)))))) | ||
4324 | { | ||
4325 | /* can fit ack by shifting extra acks and starting at | ||
4326 | frag_uid, test above esured that the bits we will | ||
4327 | shift 'extra_acks' by are all zero. */ | ||
4328 | rc->extra_acks <<= (rc->frag_uuid - frag_uuid); | ||
4329 | rc->extra_acks |= (1LLU << (rc->frag_uuid - frag_uuid - 1)); | ||
4330 | rc->frag_uuid = frag_uuid; | ||
4331 | rc->num_acks++; | ||
4332 | } | ||
4333 | if (65 == rc->num_acks) /* OPTIMIZE-FIXME: maybe use smaller threshold? This | ||
4334 | is very aggressive. */ | ||
4335 | ack_now = GNUNET_YES; /* maximum acks received */ | ||
4336 | // FIXME: possibly also ACK based on RTT (but for that we'd need to | ||
4337 | // determine the queue used for the ACK first!) | ||
4338 | |||
4339 | /* is reassembly complete? */ | 4793 | /* is reassembly complete? */ |
4340 | if (0 != rc->msg_missing) | 4794 | if (0 != rc->msg_missing) |
4341 | { | 4795 | { |
4342 | if (ack_now) | ||
4343 | send_fragment_ack (rc); | ||
4344 | finish_cmc_handling (cmc); | 4796 | finish_cmc_handling (cmc); |
4345 | return; | 4797 | return; |
4346 | } | 4798 | } |
@@ -4354,7 +4806,6 @@ handle_fragment_box (void *cls, const struct TransportFragmentBox *fb) | |||
4354 | return; | 4806 | return; |
4355 | } | 4807 | } |
4356 | /* successful reassembly */ | 4808 | /* successful reassembly */ |
4357 | send_fragment_ack (rc); | ||
4358 | demultiplex_with_cmc (cmc, msg); | 4809 | demultiplex_with_cmc (cmc, msg); |
4359 | /* FIXME-OPTIMIZE: really free here? Might be bad if fragments are still | 4810 | /* FIXME-OPTIMIZE: really free here? Might be bad if fragments are still |
4360 | en-route and we forget that we finished this reassembly immediately! | 4811 | en-route and we forget that we finished this reassembly immediately! |
@@ -4365,171 +4816,203 @@ handle_fragment_box (void *cls, const struct TransportFragmentBox *fb) | |||
4365 | 4816 | ||
4366 | 4817 | ||
4367 | /** | 4818 | /** |
4368 | * Check the @a fa against the fragments associated with @a pm. | 4819 | * Communicator gave us a reliability box. Check the message. |
4369 | * If it matches, remove the matching fragments from the transmission | ||
4370 | * list. | ||
4371 | * | 4820 | * |
4372 | * @param pm pending message to check against the ack | 4821 | * @param cls a `struct CommunicatorMessageContext` |
4373 | * @param fa the ack that was received | 4822 | * @param rb the send message that was sent |
4374 | * @return #GNUNET_YES if @a fa matched, #GNUNET_NO if not | 4823 | * @return #GNUNET_YES if message is well-formed |
4375 | */ | 4824 | */ |
4376 | static int | 4825 | static int |
4377 | check_ack_against_pm (struct PendingMessage *pm, | 4826 | check_reliability_box (void *cls, |
4378 | const struct TransportFragmentAckMessage *fa) | 4827 | const struct TransportReliabilityBoxMessage *rb) |
4379 | { | 4828 | { |
4380 | int match; | 4829 | GNUNET_MQ_check_boxed_message (rb); |
4381 | struct PendingMessage *nxt; | 4830 | return GNUNET_YES; |
4382 | uint32_t fs = ntohl (fa->frag_uuid); | ||
4383 | uint64_t xtra = GNUNET_ntohll (fa->extra_acks); | ||
4384 | |||
4385 | match = GNUNET_NO; | ||
4386 | for (struct PendingMessage *frag = pm->head_frag; NULL != frag; frag = nxt) | ||
4387 | { | ||
4388 | const struct TransportFragmentBox *tfb = | ||
4389 | (const struct TransportFragmentBox *) &pm[1]; | ||
4390 | uint32_t fu = ntohl (tfb->frag_uuid); | ||
4391 | |||
4392 | GNUNET_assert (PMT_FRAGMENT_BOX == frag->pmt); | ||
4393 | nxt = frag->next_frag; | ||
4394 | /* Check for exact match or match in the 'xtra' bitmask */ | ||
4395 | if ((fu == fs) || | ||
4396 | ((fu > fs) && (fu <= fs + 64) && (0 != (1LLU << (fu - fs - 1) & xtra)))) | ||
4397 | { | ||
4398 | match = GNUNET_YES; | ||
4399 | free_fragment_tree (frag); | ||
4400 | } | ||
4401 | } | ||
4402 | return match; | ||
4403 | } | 4831 | } |
4404 | 4832 | ||
4405 | 4833 | ||
4406 | /** | 4834 | /** |
4407 | * Communicator gave us a fragment acknowledgement. Process the request. | 4835 | * Communicator gave us a reliability box. Process the request. |
4408 | * | 4836 | * |
4409 | * @param cls a `struct CommunicatorMessageContext` (must call | 4837 | * @param cls a `struct CommunicatorMessageContext` (must call |
4410 | * #finish_cmc_handling() when done) | 4838 | * #finish_cmc_handling() when done) |
4411 | * @param fa the message that was received | 4839 | * @param rb the message that was received |
4412 | */ | 4840 | */ |
4413 | static void | 4841 | static void |
4414 | handle_fragment_ack (void *cls, const struct TransportFragmentAckMessage *fa) | 4842 | handle_reliability_box (void *cls, |
4843 | const struct TransportReliabilityBoxMessage *rb) | ||
4415 | { | 4844 | { |
4416 | struct CommunicatorMessageContext *cmc = cls; | 4845 | struct CommunicatorMessageContext *cmc = cls; |
4417 | struct Neighbour *n; | 4846 | const struct GNUNET_MessageHeader *inbox = |
4418 | int matched; | 4847 | (const struct GNUNET_MessageHeader *) &rb[1]; |
4419 | 4848 | ||
4420 | n = GNUNET_CONTAINER_multipeermap_get (neighbours, &cmc->im.sender); | 4849 | // FIXME: call cummulative_ack(), have ack_countdown influence max_delay! |
4421 | if (NULL == n) | 4850 | (void) (0 == ntohl (rb->ack_countdown)); |
4422 | { | 4851 | /* continue with inner message */ |
4423 | struct GNUNET_SERVICE_Client *client = cmc->tc->client; | 4852 | demultiplex_with_cmc (cmc, inbox); |
4853 | } | ||
4424 | 4854 | ||
4425 | GNUNET_break (0); | 4855 | |
4426 | finish_cmc_handling (cmc); | 4856 | /** |
4427 | GNUNET_SERVICE_client_drop (client); | 4857 | * Check if we have advanced to another age since the last time. If |
4428 | return; | 4858 | * so, purge ancient statistics (more than GOODPUT_AGING_SLOTS before |
4429 | } | 4859 | * the current age) |
4430 | /* FIXME-OPTIMIZE: maybe use another hash map here? */ | 4860 | * |
4431 | matched = GNUNET_NO; | 4861 | * @param pd[in,out] data to update |
4432 | for (struct PendingMessage *pm = n->pending_msg_head; NULL != pm; | 4862 | * @param age current age |
4433 | pm = pm->prev_neighbour) | 4863 | */ |
4434 | { | 4864 | static void |
4435 | if (0 != GNUNET_memcmp (&fa->msg_uuid, &pm->msg_uuid)) | 4865 | update_pd_age (struct PerformanceData *pd, unsigned int age) |
4436 | continue; | 4866 | { |
4437 | matched = GNUNET_YES; | 4867 | unsigned int sage; |
4438 | if (GNUNET_YES == check_ack_against_pm (pm, fa)) | 4868 | |
4439 | { | 4869 | if (age == pd->last_age) |
4440 | struct GNUNET_TIME_Relative avg_ack_delay = | 4870 | return; /* nothing to do */ |
4441 | GNUNET_TIME_relative_ntoh (fa->avg_ack_delay); | 4871 | sage = GNUNET_MAX (pd->last_age, age - 2 * GOODPUT_AGING_SLOTS); |
4442 | // FIXME: update RTT and other reliability data! | 4872 | for (unsigned int i = sage; i <= age - GOODPUT_AGING_SLOTS; i++) |
4443 | // ISSUE: we don't know which of n's queues the message(s) | ||
4444 | // took (and in fact the different messages might have gone | ||
4445 | // over different queues and possibly over multiple). | ||
4446 | // => track queues with PendingMessages, and update RTT only if | ||
4447 | // the queue used is unique? | ||
4448 | // -> how can we get loss rates? | ||
4449 | // -> or, add extra state to Box and ACK to identify queue? | ||
4450 | // IDEA: generate MULTIPLE frag-uuids per fragment and track | ||
4451 | // the queue with the fragment! (-> this logic must | ||
4452 | // be moved into check_ack_against_pm!) | ||
4453 | (void) avg_ack_delay; | ||
4454 | } | ||
4455 | else | ||
4456 | { | ||
4457 | GNUNET_STATISTICS_update (GST_stats, | ||
4458 | "# FRAGMENT_ACKS dropped, no matching fragment", | ||
4459 | 1, | ||
4460 | GNUNET_NO); | ||
4461 | } | ||
4462 | if (NULL == pm->head_frag) | ||
4463 | { | ||
4464 | // if entire message is ACKed, handle that as well. | ||
4465 | // => clean up PM, any post actions? | ||
4466 | free_pending_message (pm); | ||
4467 | } | ||
4468 | else | ||
4469 | { | ||
4470 | struct GNUNET_TIME_Relative reassembly_timeout = | ||
4471 | GNUNET_TIME_relative_ntoh (fa->reassembly_timeout); | ||
4472 | // OPTIMIZE-FIXME: adjust retransmission strategy based on | ||
4473 | // reassembly_timeout! | ||
4474 | (void) reassembly_timeout; | ||
4475 | } | ||
4476 | break; | ||
4477 | } | ||
4478 | if (GNUNET_NO == matched) | ||
4479 | { | 4873 | { |
4480 | GNUNET_STATISTICS_update (GST_stats, | 4874 | struct TransmissionHistoryEntry *the = &pd->the[i % GOODPUT_AGING_SLOTS]; |
4481 | "# FRAGMENT_ACKS dropped, no matching pending message", | 4875 | |
4482 | 1, | 4876 | the->bytes_sent = 0; |
4483 | GNUNET_NO); | 4877 | the->bytes_received = 0; |
4484 | } | 4878 | } |
4485 | finish_cmc_handling (cmc); | 4879 | pd->last_age = age; |
4486 | } | 4880 | } |
4487 | 4881 | ||
4488 | 4882 | ||
4489 | /** | 4883 | /** |
4490 | * Communicator gave us a reliability box. Check the message. | 4884 | * Update @a pd based on the latest @a rtt and the number of bytes |
4885 | * that were confirmed to be successfully transmitted. | ||
4491 | * | 4886 | * |
4492 | * @param cls a `struct CommunicatorMessageContext` | 4887 | * @param pd[in,out] data to update |
4493 | * @param rb the send message that was sent | 4888 | * @param rtt latest round-trip time |
4494 | * @return #GNUNET_YES if message is well-formed | 4889 | * @param bytes_transmitted_ok number of bytes receiver confirmed as received |
4495 | */ | 4890 | */ |
4496 | static int | 4891 | static void |
4497 | check_reliability_box (void *cls, const struct TransportReliabilityBox *rb) | 4892 | update_performance_data (struct PerformanceData *pd, |
4893 | struct GNUNET_TIME_Relative rtt, | ||
4894 | uint16_t bytes_transmitted_ok) | ||
4498 | { | 4895 | { |
4499 | GNUNET_MQ_check_boxed_message (rb); | 4896 | uint64_t nval = rtt.rel_value_us; |
4500 | return GNUNET_YES; | 4897 | uint64_t oval = pd->aged_rtt.rel_value_us; |
4898 | unsigned int age = get_age (); | ||
4899 | struct TransmissionHistoryEntry *the = &pd->the[age % GOODPUT_AGING_SLOTS]; | ||
4900 | |||
4901 | if (oval == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us) | ||
4902 | pd->aged_rtt = rtt; | ||
4903 | else | ||
4904 | pd->aged_rtt.rel_value_us = (nval + 7 * oval) / 8; | ||
4905 | update_pd_age (pd, age); | ||
4906 | the->bytes_received += bytes_transmitted_ok; | ||
4501 | } | 4907 | } |
4502 | 4908 | ||
4503 | 4909 | ||
4504 | /** | 4910 | /** |
4505 | * Communicator gave us a reliability box. Process the request. | 4911 | * We have successfully transmitted data via @a q, update metrics. |
4506 | * | 4912 | * |
4507 | * @param cls a `struct CommunicatorMessageContext` (must call | 4913 | * @param q queue to update |
4508 | * #finish_cmc_handling() when done) | 4914 | * @param rtt round trip time observed |
4509 | * @param rb the message that was received | 4915 | * @param bytes_transmitted_ok number of bytes successfully transmitted |
4510 | */ | 4916 | */ |
4511 | static void | 4917 | static void |
4512 | handle_reliability_box (void *cls, const struct TransportReliabilityBox *rb) | 4918 | update_queue_performance (struct Queue *q, |
4919 | struct GNUNET_TIME_Relative rtt, | ||
4920 | uint16_t bytes_transmitted_ok) | ||
4513 | { | 4921 | { |
4514 | struct CommunicatorMessageContext *cmc = cls; | 4922 | update_performance_data (&q->pd, rtt, bytes_transmitted_ok); |
4515 | const struct GNUNET_MessageHeader *inbox = | 4923 | } |
4516 | (const struct GNUNET_MessageHeader *) &rb[1]; | ||
4517 | 4924 | ||
4518 | if (0 == ntohl (rb->ack_countdown)) | ||
4519 | { | ||
4520 | struct TransportReliabilityAckMessage *ack; | ||
4521 | 4925 | ||
4522 | /* FIXME-OPTIMIZE: implement cummulative ACKs and ack_countdown, | 4926 | /** |
4523 | then setting the avg_ack_delay field below: */ | 4927 | * We have successfully transmitted data via @a dvh, update metrics. |
4524 | ack = GNUNET_malloc (sizeof (*ack) + sizeof (struct GNUNET_ShortHashCode)); | 4928 | * |
4525 | ack->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_RELIABILITY_ACK); | 4929 | * @param dvh distance vector path data to update |
4526 | ack->header.size = | 4930 | * @param rtt round trip time observed |
4527 | htons (sizeof (*ack) + sizeof (struct GNUNET_ShortHashCode)); | 4931 | * @param bytes_transmitted_ok number of bytes successfully transmitted |
4528 | memcpy (&ack[1], &rb->msg_uuid, sizeof (struct GNUNET_ShortHashCode)); | 4932 | */ |
4529 | route_message (&cmc->im.sender, &ack->header, RMO_DV_ALLOWED); | 4933 | static void |
4934 | update_dvh_performance (struct DistanceVectorHop *dvh, | ||
4935 | struct GNUNET_TIME_Relative rtt, | ||
4936 | uint16_t bytes_transmitted_ok) | ||
4937 | { | ||
4938 | update_performance_data (&dvh->pd, rtt, bytes_transmitted_ok); | ||
4939 | } | ||
4940 | |||
4941 | |||
4942 | /** | ||
4943 | * The @a pa was acknowledged, process the acknowledgement. | ||
4944 | * | ||
4945 | * @param pa the pending acknowledgement that was satisfied | ||
4946 | * @param ack_delay artificial delay from cummulative acks created by the other | ||
4947 | * peer | ||
4948 | */ | ||
4949 | static void | ||
4950 | handle_acknowledged (struct PendingAcknowledgement *pa, | ||
4951 | struct GNUNET_TIME_Relative ack_delay) | ||
4952 | { | ||
4953 | struct PendingMessage *pm = pa->pm; | ||
4954 | struct GNUNET_TIME_Relative delay; | ||
4955 | |||
4956 | delay = GNUNET_TIME_absolute_get_duration (pa->transmission_time); | ||
4957 | if (delay.rel_value_us > ack_delay.rel_value_us) | ||
4958 | delay = GNUNET_TIME_UNIT_ZERO; | ||
4959 | else | ||
4960 | delay = GNUNET_TIME_relative_subtract (delay, ack_delay); | ||
4961 | if (NULL != pa->queue) | ||
4962 | update_queue_performance (pa->queue, delay, pa->message_size); | ||
4963 | if (NULL != pa->dvh) | ||
4964 | update_dvh_performance (pa->dvh, delay, pa->message_size); | ||
4965 | if (NULL != pm) | ||
4966 | { | ||
4967 | if (NULL != pm->frag_parent) | ||
4968 | { | ||
4969 | pm = pm->frag_parent; | ||
4970 | free_fragment_tree (pa->pm); | ||
4971 | } | ||
4972 | while ((NULL != pm->frag_parent) && (NULL == pm->head_frag)) | ||
4973 | { | ||
4974 | struct PendingMessage *parent = pm->frag_parent; | ||
4975 | |||
4976 | free_fragment_tree (pm); | ||
4977 | pm = parent; | ||
4978 | } | ||
4979 | if (NULL != pm->head_frag) | ||
4980 | pm = NULL; /* we are done, otherwise free 'pm' below */ | ||
4530 | } | 4981 | } |
4531 | /* continue with inner message */ | 4982 | if (NULL != pm) |
4532 | demultiplex_with_cmc (cmc, inbox); | 4983 | free_pending_message (pm); |
4984 | free_pending_acknowledgement (pa); | ||
4985 | } | ||
4986 | |||
4987 | |||
4988 | /** | ||
4989 | * Communicator gave us a reliability ack. Check it is well-formed. | ||
4990 | * | ||
4991 | * @param cls a `struct CommunicatorMessageContext` (unused) | ||
4992 | * @param ra the message that was received | ||
4993 | * @return #GNUNET_Ok if @a ra is well-formed | ||
4994 | */ | ||
4995 | static int | ||
4996 | check_reliability_ack (void *cls, | ||
4997 | const struct TransportReliabilityAckMessage *ra) | ||
4998 | { | ||
4999 | unsigned int n_acks; | ||
5000 | |||
5001 | (void) cls; | ||
5002 | n_acks = (ntohs (ra->header.size) - sizeof (*ra)) / | ||
5003 | sizeof (struct TransportCummulativeAckPayloadP); | ||
5004 | if (0 == n_acks) | ||
5005 | { | ||
5006 | GNUNET_break_op (0); | ||
5007 | return GNUNET_SYSERR; | ||
5008 | } | ||
5009 | if ((ntohs (ra->header.size) - sizeof (*ra)) != | ||
5010 | n_acks * sizeof (struct TransportCummulativeAckPayloadP)) | ||
5011 | { | ||
5012 | GNUNET_break_op (0); | ||
5013 | return GNUNET_SYSERR; | ||
5014 | } | ||
5015 | return GNUNET_OK; | ||
4533 | } | 5016 | } |
4534 | 5017 | ||
4535 | 5018 | ||
@@ -4545,70 +5028,33 @@ handle_reliability_ack (void *cls, | |||
4545 | const struct TransportReliabilityAckMessage *ra) | 5028 | const struct TransportReliabilityAckMessage *ra) |
4546 | { | 5029 | { |
4547 | struct CommunicatorMessageContext *cmc = cls; | 5030 | struct CommunicatorMessageContext *cmc = cls; |
4548 | struct Neighbour *n; | 5031 | const struct TransportCummulativeAckPayloadP *ack; |
5032 | struct PendingAcknowledgement *pa; | ||
4549 | unsigned int n_acks; | 5033 | unsigned int n_acks; |
4550 | const struct GNUNET_ShortHashCode *msg_uuids; | 5034 | uint32_t ack_counter; |
4551 | struct PendingMessage *nxt; | ||
4552 | int matched; | ||
4553 | 5035 | ||
4554 | n = GNUNET_CONTAINER_multipeermap_get (neighbours, &cmc->im.sender); | ||
4555 | if (NULL == n) | ||
4556 | { | ||
4557 | struct GNUNET_SERVICE_Client *client = cmc->tc->client; | ||
4558 | |||
4559 | GNUNET_break (0); | ||
4560 | finish_cmc_handling (cmc); | ||
4561 | GNUNET_SERVICE_client_drop (client); | ||
4562 | return; | ||
4563 | } | ||
4564 | n_acks = (ntohs (ra->header.size) - sizeof (*ra)) / | 5036 | n_acks = (ntohs (ra->header.size) - sizeof (*ra)) / |
4565 | sizeof (struct GNUNET_ShortHashCode); | 5037 | sizeof (struct TransportCummulativeAckPayloadP); |
4566 | msg_uuids = (const struct GNUNET_ShortHashCode *) &ra[1]; | 5038 | ack = (const struct TransportCummulativeAckPayloadP *) &ra[1]; |
4567 | 5039 | for (unsigned int i = 0; i < n_acks; i++) | |
4568 | /* FIXME-OPTIMIZE: maybe use another hash map here? */ | ||
4569 | matched = GNUNET_NO; | ||
4570 | for (struct PendingMessage *pm = n->pending_msg_head; NULL != pm; pm = nxt) | ||
4571 | { | 5040 | { |
4572 | int in_list; | 5041 | pa = |
4573 | 5042 | GNUNET_CONTAINER_multishortmap_get (pending_acks, &ack[i].ack_uuid.value); | |
4574 | nxt = pm->next_neighbour; | 5043 | if (NULL == pa) |
4575 | in_list = GNUNET_NO; | ||
4576 | for (unsigned int i = 0; i < n_acks; i++) | ||
4577 | { | 5044 | { |
4578 | if (0 != GNUNET_memcmp (&msg_uuids[i], &pm->msg_uuid)) | 5045 | GNUNET_STATISTICS_update ( |
4579 | continue; | 5046 | GST_stats, |
4580 | in_list = GNUNET_YES; | 5047 | "# FRAGMENT_ACKS dropped, no matching pending message", |
4581 | break; | 5048 | 1, |
4582 | } | 5049 | GNUNET_NO); |
4583 | if (GNUNET_NO == in_list) | ||
4584 | continue; | 5050 | continue; |
4585 | |||
4586 | /* this pm was acked! */ | ||
4587 | matched = GNUNET_YES; | ||
4588 | free_pending_message (pm); | ||
4589 | |||
4590 | { | ||
4591 | struct GNUNET_TIME_Relative avg_ack_delay = | ||
4592 | GNUNET_TIME_relative_ntoh (ra->avg_ack_delay); | ||
4593 | // FIXME: update RTT and other reliability data! | ||
4594 | // ISSUE: we don't know which of n's queues the message(s) | ||
4595 | // took (and in fact the different messages might have gone | ||
4596 | // over different queues and possibly over multiple). | ||
4597 | // => track queues with PendingMessages, and update RTT only if | ||
4598 | // the queue used is unique? | ||
4599 | // -> how can we get loss rates? | ||
4600 | // -> or, add extra state to MSG and ACKs to identify queue? | ||
4601 | // -> if we do this, might just do the same for the avg_ack_delay! | ||
4602 | (void) avg_ack_delay; | ||
4603 | } | 5051 | } |
5052 | handle_acknowledged (pa, GNUNET_TIME_relative_ntoh (ack[i].ack_delay)); | ||
4604 | } | 5053 | } |
4605 | if (GNUNET_NO == matched) | 5054 | |
4606 | { | 5055 | ack_counter = htonl (ra->ack_counter); |
4607 | GNUNET_STATISTICS_update (GST_stats, | 5056 | // FIXME: track ACK losses based on ack_counter somewhere! |
4608 | "# FRAGMENT_ACKS dropped, no matching pending message", | 5057 | // (DV and/or Neighbour?) |
4609 | 1, | ||
4610 | GNUNET_NO); | ||
4611 | } | ||
4612 | finish_cmc_handling (cmc); | 5058 | finish_cmc_handling (cmc); |
4613 | } | 5059 | } |
4614 | 5060 | ||
@@ -4629,7 +5075,7 @@ check_backchannel_encapsulation ( | |||
4629 | 5075 | ||
4630 | (void) cls; | 5076 | (void) cls; |
4631 | if ((size - sizeof (*be)) < | 5077 | if ((size - sizeof (*be)) < |
4632 | (sizeof (struct TransportBackchannelRequestPayload) + | 5078 | (sizeof (struct TransportBackchannelRequestPayloadP) + |
4633 | sizeof (struct GNUNET_MessageHeader))) | 5079 | sizeof (struct GNUNET_MessageHeader))) |
4634 | { | 5080 | { |
4635 | GNUNET_break_op (0); | 5081 | GNUNET_break_op (0); |
@@ -4824,7 +5270,8 @@ backtalker_monotime_cb (void *cls, | |||
4824 | 1, | 5270 | 1, |
4825 | GNUNET_NO); | 5271 | GNUNET_NO); |
4826 | b->monotonic_time = mt; | 5272 | b->monotonic_time = mt; |
4827 | /* Setting body_size to 0 prevents call to #forward_backchannel_payload() */ | 5273 | /* Setting body_size to 0 prevents call to #forward_backchannel_payload() |
5274 | */ | ||
4828 | b->body_size = 0; | 5275 | b->body_size = 0; |
4829 | return; | 5276 | return; |
4830 | } | 5277 | } |
@@ -4932,7 +5379,7 @@ handle_backchannel_encapsulation ( | |||
4932 | { | 5379 | { |
4933 | struct Backtalker *b; | 5380 | struct Backtalker *b; |
4934 | struct GNUNET_TIME_Absolute monotime; | 5381 | struct GNUNET_TIME_Absolute monotime; |
4935 | struct TransportBackchannelRequestPayload ppay; | 5382 | struct TransportBackchannelRequestPayloadP ppay; |
4936 | char body[hdr_len - sizeof (ppay)]; | 5383 | char body[hdr_len - sizeof (ppay)]; |
4937 | 5384 | ||
4938 | GNUNET_assert (hdr_len >= | 5385 | GNUNET_assert (hdr_len >= |
@@ -5124,13 +5571,13 @@ activate_core_visible_dv_path (struct DistanceVectorHop *hop) | |||
5124 | * non-first hop is in our neighbour list (returning #GNUNET_SYSERR). | 5571 | * non-first hop is in our neighbour list (returning #GNUNET_SYSERR). |
5125 | * | 5572 | * |
5126 | * @param path the path we learned, path[0] should be us, | 5573 | * @param path the path we learned, path[0] should be us, |
5127 | * and then path contains a valid path from us to `path[path_len-1]` | 5574 | * and then path contains a valid path from us to |
5128 | * path[1] should be a direct neighbour (we should check!) | 5575 | * `path[path_len-1]` path[1] should be a direct neighbour (we should check!) |
5129 | * @param path_len number of entries on the @a path, at least three! | 5576 | * @param path_len number of entries on the @a path, at least three! |
5130 | * @param network_latency how long does the message take from us to | 5577 | * @param network_latency how long does the message take from us to |
5131 | * `path[path_len-1]`? set to "forever" if unknown | 5578 | * `path[path_len-1]`? set to "forever" if unknown |
5132 | * @param path_valid_until how long is this path considered validated? Maybe be | 5579 | * @param path_valid_until how long is this path considered validated? Maybe |
5133 | * zero. | 5580 | * be zero. |
5134 | * @return #GNUNET_YES on success, | 5581 | * @return #GNUNET_YES on success, |
5135 | * #GNUNET_NO if we have better path(s) to the target | 5582 | * #GNUNET_NO if we have better path(s) to the target |
5136 | * #GNUNET_SYSERR if the path is useless and/or invalid | 5583 | * #GNUNET_SYSERR if the path is useless and/or invalid |
@@ -5279,7 +5726,7 @@ learn_dv_path (const struct GNUNET_PeerIdentity *path, | |||
5279 | * @return #GNUNET_YES if message is well-formed | 5726 | * @return #GNUNET_YES if message is well-formed |
5280 | */ | 5727 | */ |
5281 | static int | 5728 | static int |
5282 | check_dv_learn (void *cls, const struct TransportDVLearn *dvl) | 5729 | check_dv_learn (void *cls, const struct TransportDVLearnMessage *dvl) |
5283 | { | 5730 | { |
5284 | uint16_t size = ntohs (dvl->header.size); | 5731 | uint16_t size = ntohs (dvl->header.size); |
5285 | uint16_t num_hops = ntohs (dvl->num_hops); | 5732 | uint16_t num_hops = ntohs (dvl->num_hops); |
@@ -5326,22 +5773,22 @@ check_dv_learn (void *cls, const struct TransportDVLearn *dvl) | |||
5326 | */ | 5773 | */ |
5327 | static void | 5774 | static void |
5328 | forward_dv_learn (const struct GNUNET_PeerIdentity *next_hop, | 5775 | forward_dv_learn (const struct GNUNET_PeerIdentity *next_hop, |
5329 | const struct TransportDVLearn *msg, | 5776 | const struct TransportDVLearnMessage *msg, |
5330 | uint16_t bi_history, | 5777 | uint16_t bi_history, |
5331 | uint16_t nhops, | 5778 | uint16_t nhops, |
5332 | const struct DVPathEntryP *hops, | 5779 | const struct DVPathEntryP *hops, |
5333 | struct GNUNET_TIME_Absolute in_time) | 5780 | struct GNUNET_TIME_Absolute in_time) |
5334 | { | 5781 | { |
5335 | struct DVPathEntryP *dhops; | 5782 | struct DVPathEntryP *dhops; |
5336 | struct TransportDVLearn *fwd; | 5783 | struct TransportDVLearnMessage *fwd; |
5337 | struct GNUNET_TIME_Relative nnd; | 5784 | struct GNUNET_TIME_Relative nnd; |
5338 | 5785 | ||
5339 | /* compute message for forwarding */ | 5786 | /* compute message for forwarding */ |
5340 | GNUNET_assert (nhops < MAX_DV_HOPS_ALLOWED); | 5787 | GNUNET_assert (nhops < MAX_DV_HOPS_ALLOWED); |
5341 | fwd = GNUNET_malloc (sizeof (struct TransportDVLearn) + | 5788 | fwd = GNUNET_malloc (sizeof (struct TransportDVLearnMessage) + |
5342 | (nhops + 1) * sizeof (struct DVPathEntryP)); | 5789 | (nhops + 1) * sizeof (struct DVPathEntryP)); |
5343 | fwd->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_DV_LEARN); | 5790 | fwd->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_DV_LEARN); |
5344 | fwd->header.size = htons (sizeof (struct TransportDVLearn) + | 5791 | fwd->header.size = htons (sizeof (struct TransportDVLearnMessage) + |
5345 | (nhops + 1) * sizeof (struct DVPathEntryP)); | 5792 | (nhops + 1) * sizeof (struct DVPathEntryP)); |
5346 | fwd->num_hops = htons (nhops + 1); | 5793 | fwd->num_hops = htons (nhops + 1); |
5347 | fwd->bidirectional = htons (bi_history); | 5794 | fwd->bidirectional = htons (bi_history); |
@@ -5383,7 +5830,7 @@ forward_dv_learn (const struct GNUNET_PeerIdentity *next_hop, | |||
5383 | static int | 5830 | static int |
5384 | validate_dv_initiator_signature ( | 5831 | validate_dv_initiator_signature ( |
5385 | const struct GNUNET_PeerIdentity *init, | 5832 | const struct GNUNET_PeerIdentity *init, |
5386 | const struct GNUNET_ShortHashCode *challenge, | 5833 | const struct ChallengeNonceP *challenge, |
5387 | const struct GNUNET_CRYPTO_EddsaSignature *init_sig) | 5834 | const struct GNUNET_CRYPTO_EddsaSignature *init_sig) |
5388 | { | 5835 | { |
5389 | struct DvInitPS ip = {.purpose.purpose = htonl ( | 5836 | struct DvInitPS ip = {.purpose.purpose = htonl ( |
@@ -5413,7 +5860,7 @@ validate_dv_initiator_signature ( | |||
5413 | * @param dvl the message that was received | 5860 | * @param dvl the message that was received |
5414 | */ | 5861 | */ |
5415 | static void | 5862 | static void |
5416 | handle_dv_learn (void *cls, const struct TransportDVLearn *dvl) | 5863 | handle_dv_learn (void *cls, const struct TransportDVLearnMessage *dvl) |
5417 | { | 5864 | { |
5418 | struct CommunicatorMessageContext *cmc = cls; | 5865 | struct CommunicatorMessageContext *cmc = cls; |
5419 | enum GNUNET_TRANSPORT_CommunicatorCharacteristics cc; | 5866 | enum GNUNET_TRANSPORT_CommunicatorCharacteristics cc; |
@@ -5459,7 +5906,8 @@ handle_dv_learn (void *cls, const struct TransportDVLearn *dvl) | |||
5459 | finish_cmc_handling (cmc); | 5906 | finish_cmc_handling (cmc); |
5460 | 5907 | ||
5461 | /* OPTIMIZE-FIXME: Technically, we only need to bother checking | 5908 | /* OPTIMIZE-FIXME: Technically, we only need to bother checking |
5462 | the initiator signature if we send the message back to the initiator... */ | 5909 | the initiator signature if we send the message back to the initiator... |
5910 | */ | ||
5463 | if (GNUNET_OK != validate_dv_initiator_signature (&dvl->initiator, | 5911 | if (GNUNET_OK != validate_dv_initiator_signature (&dvl->initiator, |
5464 | &dvl->challenge, | 5912 | &dvl->challenge, |
5465 | &dvl->init_sig)) | 5913 | &dvl->init_sig)) |
@@ -5611,7 +6059,7 @@ handle_dv_learn (void *cls, const struct TransportDVLearn *dvl) | |||
5611 | * @return #GNUNET_YES if message is well-formed | 6059 | * @return #GNUNET_YES if message is well-formed |
5612 | */ | 6060 | */ |
5613 | static int | 6061 | static int |
5614 | check_dv_box (void *cls, const struct TransportDVBox *dvb) | 6062 | check_dv_box (void *cls, const struct TransportDVBoxMessage *dvb) |
5615 | { | 6063 | { |
5616 | uint16_t size = ntohs (dvb->header.size); | 6064 | uint16_t size = ntohs (dvb->header.size); |
5617 | uint16_t num_hops = ntohs (dvb->num_hops); | 6065 | uint16_t num_hops = ntohs (dvb->num_hops); |
@@ -5673,17 +6121,17 @@ forward_dv_box (struct Neighbour *next_hop, | |||
5673 | const void *payload, | 6121 | const void *payload, |
5674 | uint16_t payload_size) | 6122 | uint16_t payload_size) |
5675 | { | 6123 | { |
5676 | struct TransportDVBox *dvb; | 6124 | struct TransportDVBoxMessage *dvb; |
5677 | struct GNUNET_PeerIdentity *dhops; | 6125 | struct GNUNET_PeerIdentity *dhops; |
5678 | 6126 | ||
5679 | GNUNET_assert (UINT16_MAX < sizeof (struct TransportDVBox) + | 6127 | GNUNET_assert (UINT16_MAX < sizeof (struct TransportDVBoxMessage) + |
5680 | sizeof (struct GNUNET_PeerIdentity) * num_hops + | 6128 | sizeof (struct GNUNET_PeerIdentity) * num_hops + |
5681 | payload_size); | 6129 | payload_size); |
5682 | dvb = GNUNET_malloc (sizeof (struct TransportDVBox) + | 6130 | dvb = GNUNET_malloc (sizeof (struct TransportDVBoxMessage) + |
5683 | sizeof (struct GNUNET_PeerIdentity) * num_hops + | 6131 | sizeof (struct GNUNET_PeerIdentity) * num_hops + |
5684 | payload_size); | 6132 | payload_size); |
5685 | dvb->header.size = | 6133 | dvb->header.size = |
5686 | htons (sizeof (struct TransportDVBox) + | 6134 | htons (sizeof (struct TransportDVBoxMessage) + |
5687 | sizeof (struct GNUNET_PeerIdentity) * num_hops + payload_size); | 6135 | sizeof (struct GNUNET_PeerIdentity) * num_hops + payload_size); |
5688 | dvb->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_DV_BOX); | 6136 | dvb->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_DV_BOX); |
5689 | dvb->total_hops = htons (total_hops); | 6137 | dvb->total_hops = htons (total_hops); |
@@ -5704,7 +6152,7 @@ forward_dv_box (struct Neighbour *next_hop, | |||
5704 | * @param dvb the message that was received | 6152 | * @param dvb the message that was received |
5705 | */ | 6153 | */ |
5706 | static void | 6154 | static void |
5707 | handle_dv_box (void *cls, const struct TransportDVBox *dvb) | 6155 | handle_dv_box (void *cls, const struct TransportDVBoxMessage *dvb) |
5708 | { | 6156 | { |
5709 | struct CommunicatorMessageContext *cmc = cls; | 6157 | struct CommunicatorMessageContext *cmc = cls; |
5710 | uint16_t size = ntohs (dvb->header.size) - sizeof (*dvb); | 6158 | uint16_t size = ntohs (dvb->header.size) - sizeof (*dvb); |
@@ -5788,11 +6236,12 @@ check_incoming_msg (void *cls, | |||
5788 | * @param tvc the message that was received | 6236 | * @param tvc the message that was received |
5789 | */ | 6237 | */ |
5790 | static void | 6238 | static void |
5791 | handle_validation_challenge (void *cls, | 6239 | handle_validation_challenge ( |
5792 | const struct TransportValidationChallenge *tvc) | 6240 | void *cls, |
6241 | const struct TransportValidationChallengeMessage *tvc) | ||
5793 | { | 6242 | { |
5794 | struct CommunicatorMessageContext *cmc = cls; | 6243 | struct CommunicatorMessageContext *cmc = cls; |
5795 | struct TransportValidationResponse *tvr; | 6244 | struct TransportValidationResponseMessage *tvr; |
5796 | 6245 | ||
5797 | if (cmc->total_hops > 0) | 6246 | if (cmc->total_hops > 0) |
5798 | { | 6247 | { |
@@ -5801,7 +6250,7 @@ handle_validation_challenge (void *cls, | |||
5801 | finish_cmc_handling (cmc); | 6250 | finish_cmc_handling (cmc); |
5802 | return; | 6251 | return; |
5803 | } | 6252 | } |
5804 | tvr = GNUNET_new (struct TransportValidationResponse); | 6253 | tvr = GNUNET_new (struct TransportValidationResponseMessage); |
5805 | tvr->header.type = | 6254 | tvr->header.type = |
5806 | htons (GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_VALIDATION_RESPONSE); | 6255 | htons (GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_VALIDATION_RESPONSE); |
5807 | tvr->header.size = htons (sizeof (*tvr)); | 6256 | tvr->header.size = htons (sizeof (*tvr)); |
@@ -5835,7 +6284,7 @@ struct CheckKnownChallengeContext | |||
5835 | /** | 6284 | /** |
5836 | * Set to the challenge we are looking for. | 6285 | * Set to the challenge we are looking for. |
5837 | */ | 6286 | */ |
5838 | const struct GNUNET_ShortHashCode *challenge; | 6287 | const struct ChallengeNonceP *challenge; |
5839 | 6288 | ||
5840 | /** | 6289 | /** |
5841 | * Set to a matching validation state, if one was found. | 6290 | * Set to a matching validation state, if one was found. |
@@ -6039,8 +6488,9 @@ update_neighbour_core_visibility (struct Neighbour *n) | |||
6039 | * @param tvr the message that was received | 6488 | * @param tvr the message that was received |
6040 | */ | 6489 | */ |
6041 | static void | 6490 | static void |
6042 | handle_validation_response (void *cls, | 6491 | handle_validation_response ( |
6043 | const struct TransportValidationResponse *tvr) | 6492 | void *cls, |
6493 | const struct TransportValidationResponseMessage *tvr) | ||
6044 | { | 6494 | { |
6045 | struct CommunicatorMessageContext *cmc = cls; | 6495 | struct CommunicatorMessageContext *cmc = cls; |
6046 | struct ValidationState *vs; | 6496 | struct ValidationState *vs; |
@@ -6145,7 +6595,7 @@ handle_validation_response (void *cls, | |||
6145 | return; | 6595 | return; |
6146 | } | 6596 | } |
6147 | q->validated_until = vs->validated_until; | 6597 | q->validated_until = vs->validated_until; |
6148 | q->rtt = vs->validation_rtt; | 6598 | q->pd.aged_rtt = vs->validation_rtt; |
6149 | n = q->neighbour; | 6599 | n = q->neighbour; |
6150 | if (GNUNET_NO != n->core_visible) | 6600 | if (GNUNET_NO != n->core_visible) |
6151 | return; /* nothing changed, we are done here */ | 6601 | return; /* nothing changed, we are done here */ |
@@ -6201,41 +6651,37 @@ demultiplex_with_cmc (struct CommunicatorMessageContext *cmc, | |||
6201 | struct GNUNET_MQ_MessageHandler handlers[] = | 6651 | struct GNUNET_MQ_MessageHandler handlers[] = |
6202 | {GNUNET_MQ_hd_var_size (fragment_box, | 6652 | {GNUNET_MQ_hd_var_size (fragment_box, |
6203 | GNUNET_MESSAGE_TYPE_TRANSPORT_FRAGMENT, | 6653 | GNUNET_MESSAGE_TYPE_TRANSPORT_FRAGMENT, |
6204 | struct TransportFragmentBox, | 6654 | struct TransportFragmentBoxMessage, |
6205 | &cmc), | 6655 | &cmc), |
6206 | GNUNET_MQ_hd_fixed_size (fragment_ack, | ||
6207 | GNUNET_MESSAGE_TYPE_TRANSPORT_FRAGMENT_ACK, | ||
6208 | struct TransportFragmentAckMessage, | ||
6209 | &cmc), | ||
6210 | GNUNET_MQ_hd_var_size (reliability_box, | 6656 | GNUNET_MQ_hd_var_size (reliability_box, |
6211 | GNUNET_MESSAGE_TYPE_TRANSPORT_RELIABILITY_BOX, | 6657 | GNUNET_MESSAGE_TYPE_TRANSPORT_RELIABILITY_BOX, |
6212 | struct TransportReliabilityBox, | 6658 | struct TransportReliabilityBoxMessage, |
6659 | &cmc), | ||
6660 | GNUNET_MQ_hd_var_size (reliability_ack, | ||
6661 | GNUNET_MESSAGE_TYPE_TRANSPORT_RELIABILITY_ACK, | ||
6662 | struct TransportReliabilityAckMessage, | ||
6213 | &cmc), | 6663 | &cmc), |
6214 | GNUNET_MQ_hd_fixed_size (reliability_ack, | ||
6215 | GNUNET_MESSAGE_TYPE_TRANSPORT_RELIABILITY_ACK, | ||
6216 | struct TransportReliabilityAckMessage, | ||
6217 | &cmc), | ||
6218 | GNUNET_MQ_hd_var_size (backchannel_encapsulation, | 6664 | GNUNET_MQ_hd_var_size (backchannel_encapsulation, |
6219 | GNUNET_MESSAGE_TYPE_TRANSPORT_BACKCHANNEL_ENCAPSULATION, | 6665 | GNUNET_MESSAGE_TYPE_TRANSPORT_BACKCHANNEL_ENCAPSULATION, |
6220 | struct TransportBackchannelEncapsulationMessage, | 6666 | struct TransportBackchannelEncapsulationMessage, |
6221 | &cmc), | 6667 | &cmc), |
6222 | GNUNET_MQ_hd_var_size (dv_learn, | 6668 | GNUNET_MQ_hd_var_size (dv_learn, |
6223 | GNUNET_MESSAGE_TYPE_TRANSPORT_DV_LEARN, | 6669 | GNUNET_MESSAGE_TYPE_TRANSPORT_DV_LEARN, |
6224 | struct TransportDVLearn, | 6670 | struct TransportDVLearnMessage, |
6225 | &cmc), | 6671 | &cmc), |
6226 | GNUNET_MQ_hd_var_size (dv_box, | 6672 | GNUNET_MQ_hd_var_size (dv_box, |
6227 | GNUNET_MESSAGE_TYPE_TRANSPORT_DV_BOX, | 6673 | GNUNET_MESSAGE_TYPE_TRANSPORT_DV_BOX, |
6228 | struct TransportDVBox, | 6674 | struct TransportDVBoxMessage, |
6229 | &cmc), | 6675 | &cmc), |
6230 | GNUNET_MQ_hd_fixed_size ( | 6676 | GNUNET_MQ_hd_fixed_size ( |
6231 | validation_challenge, | 6677 | validation_challenge, |
6232 | GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_VALIDATION_CHALLENGE, | 6678 | GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_VALIDATION_CHALLENGE, |
6233 | struct TransportValidationChallenge, | 6679 | struct TransportValidationChallengeMessage, |
6234 | &cmc), | 6680 | &cmc), |
6235 | GNUNET_MQ_hd_fixed_size ( | 6681 | GNUNET_MQ_hd_fixed_size ( |
6236 | validation_response, | 6682 | validation_response, |
6237 | GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_VALIDATION_RESPONSE, | 6683 | GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_VALIDATION_RESPONSE, |
6238 | struct TransportValidationResponse, | 6684 | struct TransportValidationResponseMessage, |
6239 | &cmc), | 6685 | &cmc), |
6240 | GNUNET_MQ_handler_end ()}; | 6686 | GNUNET_MQ_handler_end ()}; |
6241 | int ret; | 6687 | int ret; |
@@ -6315,27 +6761,76 @@ set_pending_message_uuid (struct PendingMessage *pm) | |||
6315 | 6761 | ||
6316 | 6762 | ||
6317 | /** | 6763 | /** |
6764 | * Setup data structure waiting for acknowledgements. | ||
6765 | * | ||
6766 | * @param queue queue the @a pm will be sent over | ||
6767 | * @param dvh path the message will take, may be NULL | ||
6768 | * @param pm the pending message for transmission | ||
6769 | * @return corresponding fresh pending acknowledgement | ||
6770 | */ | ||
6771 | static struct PendingAcknowledgement * | ||
6772 | prepare_pending_acknowledgement (struct Queue *queue, | ||
6773 | struct DistanceVectorHop *dvh, | ||
6774 | struct PendingMessage *pm) | ||
6775 | { | ||
6776 | struct PendingAcknowledgement *pa; | ||
6777 | |||
6778 | pa = GNUNET_new (struct PendingAcknowledgement); | ||
6779 | pa->queue = queue; | ||
6780 | pa->dvh = dvh; | ||
6781 | pa->pm = pm; | ||
6782 | do | ||
6783 | { | ||
6784 | GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE, | ||
6785 | &pa->ack_uuid, | ||
6786 | sizeof (pa->ack_uuid)); | ||
6787 | } while (GNUNET_YES != GNUNET_CONTAINER_multishortmap_put ( | ||
6788 | pending_acks, | ||
6789 | &pa->ack_uuid.value, | ||
6790 | pa, | ||
6791 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); | ||
6792 | GNUNET_CONTAINER_MDLL_insert (queue, queue->pa_head, queue->pa_tail, pa); | ||
6793 | GNUNET_CONTAINER_MDLL_insert (pm, pm->pa_head, pm->pa_tail, pa); | ||
6794 | if (NULL != dvh) | ||
6795 | GNUNET_CONTAINER_MDLL_insert (dvh, dvh->pa_head, dvh->pa_tail, pa); | ||
6796 | pa->transmission_time = GNUNET_TIME_absolute_get (); | ||
6797 | pa->message_size = pm->bytes_msg; | ||
6798 | return pa; | ||
6799 | } | ||
6800 | |||
6801 | |||
6802 | /** | ||
6318 | * Fragment the given @a pm to the given @a mtu. Adds | 6803 | * Fragment the given @a pm to the given @a mtu. Adds |
6319 | * additional fragments to the neighbour as well. If the | 6804 | * additional fragments to the neighbour as well. If the |
6320 | * @a mtu is too small, generates and error for the @a pm | 6805 | * @a mtu is too small, generates and error for the @a pm |
6321 | * and returns NULL. | 6806 | * and returns NULL. |
6322 | * | 6807 | * |
6808 | * @param queue which queue to fragment for | ||
6809 | * @param dvh path the message will take, or NULL | ||
6323 | * @param pm pending message to fragment for transmission | 6810 | * @param pm pending message to fragment for transmission |
6324 | * @param mtu MTU to apply | ||
6325 | * @return new message to transmit | 6811 | * @return new message to transmit |
6326 | */ | 6812 | */ |
6327 | static struct PendingMessage * | 6813 | static struct PendingMessage * |
6328 | fragment_message (struct PendingMessage *pm, uint16_t mtu) | 6814 | fragment_message (struct Queue *queue, |
6815 | struct DistanceVectorHop *dvh, | ||
6816 | struct PendingMessage *pm) | ||
6329 | { | 6817 | { |
6818 | struct PendingAcknowledgement *pa; | ||
6330 | struct PendingMessage *ff; | 6819 | struct PendingMessage *ff; |
6820 | uint16_t mtu; | ||
6331 | 6821 | ||
6822 | pa = prepare_pending_acknowledgement (queue, dvh, pm); | ||
6823 | mtu = (0 == queue->mtu) | ||
6824 | ? UINT16_MAX - sizeof (struct GNUNET_TRANSPORT_SendMessageTo) | ||
6825 | : queue->mtu; | ||
6332 | set_pending_message_uuid (pm); | 6826 | set_pending_message_uuid (pm); |
6333 | 6827 | ||
6334 | /* This invariant is established in #handle_add_queue_message() */ | 6828 | /* This invariant is established in #handle_add_queue_message() */ |
6335 | GNUNET_assert (mtu > sizeof (struct TransportFragmentBox)); | 6829 | GNUNET_assert (mtu > sizeof (struct TransportFragmentBoxMessage)); |
6336 | 6830 | ||
6337 | /* select fragment for transmission, descending the tree if it has | 6831 | /* select fragment for transmission, descending the tree if it has |
6338 | been expanded until we are at a leaf or at a fragment that is small enough | 6832 | been expanded until we are at a leaf or at a fragment that is small |
6833 | enough | ||
6339 | */ | 6834 | */ |
6340 | ff = pm; | 6835 | ff = pm; |
6341 | while (((ff->bytes_msg > mtu) || (pm == ff)) && | 6836 | while (((ff->bytes_msg > mtu) || (pm == ff)) && |
@@ -6348,7 +6843,7 @@ fragment_message (struct PendingMessage *pm, uint16_t mtu) | |||
6348 | { | 6843 | { |
6349 | /* Did not yet calculate all fragments, calculate next fragment */ | 6844 | /* Did not yet calculate all fragments, calculate next fragment */ |
6350 | struct PendingMessage *frag; | 6845 | struct PendingMessage *frag; |
6351 | struct TransportFragmentBox tfb; | 6846 | struct TransportFragmentBoxMessage tfb; |
6352 | const char *orig; | 6847 | const char *orig; |
6353 | char *msg; | 6848 | char *msg; |
6354 | uint16_t fragmax; | 6849 | uint16_t fragmax; |
@@ -6360,26 +6855,28 @@ fragment_message (struct PendingMessage *pm, uint16_t mtu) | |||
6360 | msize = ff->bytes_msg; | 6855 | msize = ff->bytes_msg; |
6361 | if (pm != ff) | 6856 | if (pm != ff) |
6362 | { | 6857 | { |
6363 | const struct TransportFragmentBox *tfbo; | 6858 | const struct TransportFragmentBoxMessage *tfbo; |
6364 | 6859 | ||
6365 | tfbo = (const struct TransportFragmentBox *) orig; | 6860 | tfbo = (const struct TransportFragmentBoxMessage *) orig; |
6366 | orig += sizeof (struct TransportFragmentBox); | 6861 | orig += sizeof (struct TransportFragmentBoxMessage); |
6367 | msize -= sizeof (struct TransportFragmentBox); | 6862 | msize -= sizeof (struct TransportFragmentBoxMessage); |
6368 | xoff = ntohs (tfbo->frag_off); | 6863 | xoff = ntohs (tfbo->frag_off); |
6369 | } | 6864 | } |
6370 | fragmax = mtu - sizeof (struct TransportFragmentBox); | 6865 | fragmax = mtu - sizeof (struct TransportFragmentBoxMessage); |
6371 | fragsize = GNUNET_MIN (msize - ff->frag_off, fragmax); | 6866 | fragsize = GNUNET_MIN (msize - ff->frag_off, fragmax); |
6372 | frag = GNUNET_malloc (sizeof (struct PendingMessage) + | 6867 | frag = |
6373 | sizeof (struct TransportFragmentBox) + fragsize); | 6868 | GNUNET_malloc (sizeof (struct PendingMessage) + |
6869 | sizeof (struct TransportFragmentBoxMessage) + fragsize); | ||
6374 | frag->target = pm->target; | 6870 | frag->target = pm->target; |
6375 | frag->frag_parent = ff; | 6871 | frag->frag_parent = ff; |
6376 | frag->timeout = pm->timeout; | 6872 | frag->timeout = pm->timeout; |
6377 | frag->bytes_msg = sizeof (struct TransportFragmentBox) + fragsize; | 6873 | frag->bytes_msg = sizeof (struct TransportFragmentBoxMessage) + fragsize; |
6378 | frag->pmt = PMT_FRAGMENT_BOX; | 6874 | frag->pmt = PMT_FRAGMENT_BOX; |
6379 | msg = (char *) &frag[1]; | 6875 | msg = (char *) &frag[1]; |
6380 | tfb.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_FRAGMENT); | 6876 | tfb.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_FRAGMENT); |
6381 | tfb.header.size = htons (sizeof (struct TransportFragmentBox) + fragsize); | 6877 | tfb.header.size = |
6382 | tfb.frag_uuid = htonl (pm->frag_uuidgen++); | 6878 | htons (sizeof (struct TransportFragmentBoxMessage) + fragsize); |
6879 | tfb.ack_uuid = pa->ack_uuid; | ||
6383 | tfb.msg_uuid = pm->msg_uuid; | 6880 | tfb.msg_uuid = pm->msg_uuid; |
6384 | tfb.frag_off = htons (ff->frag_off + xoff); | 6881 | tfb.frag_off = htons (ff->frag_off + xoff); |
6385 | tfb.msg_size = htons (pm->bytes_msg); | 6882 | tfb.msg_size = htons (pm->bytes_msg); |
@@ -6410,13 +6907,18 @@ fragment_message (struct PendingMessage *pm, uint16_t mtu) | |||
6410 | * @a pm). If the @a pm is already fragmented or reliability boxed, | 6907 | * @a pm). If the @a pm is already fragmented or reliability boxed, |
6411 | * or itself an ACK, this function simply returns @a pm. | 6908 | * or itself an ACK, this function simply returns @a pm. |
6412 | * | 6909 | * |
6910 | * @param queue which queue to prepare transmission for | ||
6911 | * @param dvh path the message will take, or NULL | ||
6413 | * @param pm pending message to box for transmission over unreliabile queue | 6912 | * @param pm pending message to box for transmission over unreliabile queue |
6414 | * @return new message to transmit | 6913 | * @return new message to transmit |
6415 | */ | 6914 | */ |
6416 | static struct PendingMessage * | 6915 | static struct PendingMessage * |
6417 | reliability_box_message (struct PendingMessage *pm) | 6916 | reliability_box_message (struct Queue *queue, |
6917 | struct DistanceVectorHop *dvh, | ||
6918 | struct PendingMessage *pm) | ||
6418 | { | 6919 | { |
6419 | struct TransportReliabilityBox rbox; | 6920 | struct TransportReliabilityBoxMessage rbox; |
6921 | struct PendingAcknowledgement *pa; | ||
6420 | struct PendingMessage *bpm; | 6922 | struct PendingMessage *bpm; |
6421 | char *msg; | 6923 | char *msg; |
6422 | 6924 | ||
@@ -6433,6 +6935,8 @@ reliability_box_message (struct PendingMessage *pm) | |||
6433 | client_send_response (pm, GNUNET_NO, 0); | 6935 | client_send_response (pm, GNUNET_NO, 0); |
6434 | return NULL; | 6936 | return NULL; |
6435 | } | 6937 | } |
6938 | pa = prepare_pending_acknowledgement (queue, dvh, pm); | ||
6939 | |||
6436 | bpm = GNUNET_malloc (sizeof (struct PendingMessage) + sizeof (rbox) + | 6940 | bpm = GNUNET_malloc (sizeof (struct PendingMessage) + sizeof (rbox) + |
6437 | pm->bytes_msg); | 6941 | pm->bytes_msg); |
6438 | bpm->target = pm->target; | 6942 | bpm->target = pm->target; |
@@ -6445,7 +6949,8 @@ reliability_box_message (struct PendingMessage *pm) | |||
6445 | rbox.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_RELIABILITY_BOX); | 6949 | rbox.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_RELIABILITY_BOX); |
6446 | rbox.header.size = htons (sizeof (rbox) + pm->bytes_msg); | 6950 | rbox.header.size = htons (sizeof (rbox) + pm->bytes_msg); |
6447 | rbox.ack_countdown = htonl (0); // FIXME: implement ACK countdown support | 6951 | rbox.ack_countdown = htonl (0); // FIXME: implement ACK countdown support |
6448 | rbox.msg_uuid = pm->msg_uuid; | 6952 | |
6953 | rbox.ack_uuid = pa->ack_uuid; | ||
6449 | msg = (char *) &bpm[1]; | 6954 | msg = (char *) &bpm[1]; |
6450 | memcpy (msg, &rbox, sizeof (rbox)); | 6955 | memcpy (msg, &rbox, sizeof (rbox)); |
6451 | memcpy (&msg[sizeof (rbox)], &pm[1], pm->bytes_msg); | 6956 | memcpy (&msg[sizeof (rbox)], &pm[1], pm->bytes_msg); |
@@ -6542,7 +7047,7 @@ transmit_on_queue (void *cls) | |||
6542 | return; /* do it later */ | 7047 | return; /* do it later */ |
6543 | overhead = 0; | 7048 | overhead = 0; |
6544 | if (GNUNET_TRANSPORT_CC_RELIABLE != queue->tc->details.communicator.cc) | 7049 | if (GNUNET_TRANSPORT_CC_RELIABLE != queue->tc->details.communicator.cc) |
6545 | overhead += sizeof (struct TransportReliabilityBox); | 7050 | overhead += sizeof (struct TransportReliabilityBoxMessage); |
6546 | s = pm; | 7051 | s = pm; |
6547 | if ( ( (0 != queue->mtu) && | 7052 | if ( ( (0 != queue->mtu) && |
6548 | (pm->bytes_msg + overhead > queue->mtu) ) || | 7053 | (pm->bytes_msg + overhead > queue->mtu) ) || |
@@ -6550,11 +7055,7 @@ transmit_on_queue (void *cls) | |||
6550 | (NULL != pm->head_frag /* fragments already exist, should | 7055 | (NULL != pm->head_frag /* fragments already exist, should |
6551 | respect that even if MTU is 0 for | 7056 | respect that even if MTU is 0 for |
6552 | this queue */) ) | 7057 | this queue */) ) |
6553 | s = fragment_message (s, | 7058 | s = fragment_message (queue, NULL /*FIXME! */, s); |
6554 | (0 == queue->mtu) | ||
6555 | ? UINT16_MAX - | ||
6556 | sizeof (struct GNUNET_TRANSPORT_SendMessageTo) | ||
6557 | : queue->mtu); | ||
6558 | if (NULL == s) | 7059 | if (NULL == s) |
6559 | { | 7060 | { |
6560 | /* Fragmentation failed, try next message... */ | 7061 | /* Fragmentation failed, try next message... */ |
@@ -6562,7 +7063,7 @@ transmit_on_queue (void *cls) | |||
6562 | return; | 7063 | return; |
6563 | } | 7064 | } |
6564 | if (GNUNET_TRANSPORT_CC_RELIABLE != queue->tc->details.communicator.cc) | 7065 | if (GNUNET_TRANSPORT_CC_RELIABLE != queue->tc->details.communicator.cc) |
6565 | s = reliability_box_message (s); | 7066 | s = reliability_box_message (queue, NULL /* FIXME! */, s); |
6566 | if (NULL == s) | 7067 | if (NULL == s) |
6567 | { | 7068 | { |
6568 | /* Reliability boxing failed, try next message... */ | 7069 | /* Reliability boxing failed, try next message... */ |
@@ -6628,7 +7129,8 @@ transmit_on_queue (void *cls) | |||
6628 | message urgency and size when delaying ACKs, etc.) */ | 7129 | message urgency and size when delaying ACKs, etc.) */ |
6629 | update_pm_next_attempt (s, | 7130 | update_pm_next_attempt (s, |
6630 | GNUNET_TIME_relative_to_absolute ( | 7131 | GNUNET_TIME_relative_to_absolute ( |
6631 | GNUNET_TIME_relative_multiply (queue->rtt, 4))); | 7132 | GNUNET_TIME_relative_multiply (queue->pd.aged_rtt, |
7133 | 4))); | ||
6632 | } | 7134 | } |
6633 | 7135 | ||
6634 | /* finally, re-schedule queue transmission task itself */ | 7136 | /* finally, re-schedule queue transmission task itself */ |
@@ -6865,7 +7367,7 @@ notify_client_queues (void *cls, | |||
6865 | for (struct Queue *q = neighbour->queue_head; NULL != q; | 7367 | for (struct Queue *q = neighbour->queue_head; NULL != q; |
6866 | q = q->next_neighbour) | 7368 | q = q->next_neighbour) |
6867 | { | 7369 | { |
6868 | struct MonitorEvent me = {.rtt = q->rtt, | 7370 | struct MonitorEvent me = {.rtt = q->pd.aged_rtt, |
6869 | .cs = q->cs, | 7371 | .cs = q->cs, |
6870 | .num_msg_pending = q->num_msg_pending, | 7372 | .num_msg_pending = q->num_msg_pending, |
6871 | .num_bytes_pending = q->num_bytes_pending}; | 7373 | .num_bytes_pending = q->num_bytes_pending}; |
@@ -6986,7 +7488,7 @@ suggest_to_connect (const struct GNUNET_PeerIdentity *pid, const char *address) | |||
6986 | static void | 7488 | static void |
6987 | validation_transmit_on_queue (struct Queue *q, struct ValidationState *vs) | 7489 | validation_transmit_on_queue (struct Queue *q, struct ValidationState *vs) |
6988 | { | 7490 | { |
6989 | struct TransportValidationChallenge tvc; | 7491 | struct TransportValidationChallengeMessage tvc; |
6990 | 7492 | ||
6991 | vs->last_challenge_use = GNUNET_TIME_absolute_get (); | 7493 | vs->last_challenge_use = GNUNET_TIME_absolute_get (); |
6992 | tvc.header.type = | 7494 | tvc.header.type = |
@@ -7099,7 +7601,7 @@ check_connection_quality (void *cls, | |||
7099 | ctx->q = q; | 7601 | ctx->q = q; |
7100 | /* OPTIMIZE-FIXME: in the future, add reliability / goodput | 7602 | /* OPTIMIZE-FIXME: in the future, add reliability / goodput |
7101 | statistics and consider those as well here? */ | 7603 | statistics and consider those as well here? */ |
7102 | if (q->rtt.rel_value_us < DV_QUALITY_RTT_THRESHOLD.rel_value_us) | 7604 | if (q->pd.aged_rtt.rel_value_us < DV_QUALITY_RTT_THRESHOLD.rel_value_us) |
7103 | do_inc = GNUNET_YES; | 7605 | do_inc = GNUNET_YES; |
7104 | } | 7606 | } |
7105 | if (GNUNET_YES == do_inc) | 7607 | if (GNUNET_YES == do_inc) |
@@ -7124,7 +7626,7 @@ start_dv_learn (void *cls) | |||
7124 | { | 7626 | { |
7125 | struct LearnLaunchEntry *lle; | 7627 | struct LearnLaunchEntry *lle; |
7126 | struct QueueQualityContext qqc; | 7628 | struct QueueQualityContext qqc; |
7127 | struct TransportDVLearn dvl; | 7629 | struct TransportDVLearnMessage dvl; |
7128 | 7630 | ||
7129 | (void) cls; | 7631 | (void) cls; |
7130 | dvlearn_task = NULL; | 7632 | dvlearn_task = NULL; |
@@ -7153,7 +7655,7 @@ start_dv_learn (void *cls) | |||
7153 | lle = lle_tail; | 7655 | lle = lle_tail; |
7154 | GNUNET_assert (GNUNET_YES == | 7656 | GNUNET_assert (GNUNET_YES == |
7155 | GNUNET_CONTAINER_multishortmap_remove (dvlearn_map, | 7657 | GNUNET_CONTAINER_multishortmap_remove (dvlearn_map, |
7156 | &lle->challenge, | 7658 | &lle->challenge.value, |
7157 | lle)); | 7659 | lle)); |
7158 | GNUNET_CONTAINER_DLL_remove (lle_head, lle_tail, lle); | 7660 | GNUNET_CONTAINER_DLL_remove (lle_head, lle_tail, lle); |
7159 | GNUNET_free (lle); | 7661 | GNUNET_free (lle); |
@@ -7167,7 +7669,7 @@ start_dv_learn (void *cls) | |||
7167 | GNUNET_break (GNUNET_YES == | 7669 | GNUNET_break (GNUNET_YES == |
7168 | GNUNET_CONTAINER_multishortmap_put ( | 7670 | GNUNET_CONTAINER_multishortmap_put ( |
7169 | dvlearn_map, | 7671 | dvlearn_map, |
7170 | &lle->challenge, | 7672 | &lle->challenge.value, |
7171 | lle, | 7673 | lle, |
7172 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); | 7674 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); |
7173 | dvl.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_DV_LEARN); | 7675 | dvl.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_DV_LEARN); |
@@ -7255,7 +7757,7 @@ handle_add_queue_message (void *cls, | |||
7255 | const char *addr; | 7757 | const char *addr; |
7256 | uint16_t addr_len; | 7758 | uint16_t addr_len; |
7257 | 7759 | ||
7258 | if (ntohl (aqm->mtu) <= sizeof (struct TransportFragmentBox)) | 7760 | if (ntohl (aqm->mtu) <= sizeof (struct TransportFragmentBoxMessage)) |
7259 | { | 7761 | { |
7260 | /* MTU so small as to be useless for transmissions, | 7762 | /* MTU so small as to be useless for transmissions, |
7261 | required for #fragment_message()! */ | 7763 | required for #fragment_message()! */ |
@@ -7282,7 +7784,7 @@ handle_add_queue_message (void *cls, | |||
7282 | queue = GNUNET_malloc (sizeof (struct Queue) + addr_len); | 7784 | queue = GNUNET_malloc (sizeof (struct Queue) + addr_len); |
7283 | queue->tc = tc; | 7785 | queue->tc = tc; |
7284 | queue->address = (const char *) &queue[1]; | 7786 | queue->address = (const char *) &queue[1]; |
7285 | queue->rtt = GNUNET_TIME_UNIT_FOREVER_REL; | 7787 | queue->pd.aged_rtt = GNUNET_TIME_UNIT_FOREVER_REL; |
7286 | queue->qid = aqm->qid; | 7788 | queue->qid = aqm->qid; |
7287 | queue->mtu = ntohl (aqm->mtu); | 7789 | queue->mtu = ntohl (aqm->mtu); |
7288 | queue->nt = (enum GNUNET_NetworkType) ntohl (aqm->nt); | 7790 | queue->nt = (enum GNUNET_NetworkType) ntohl (aqm->nt); |
@@ -7305,7 +7807,7 @@ handle_add_queue_message (void *cls, | |||
7305 | memcpy (&queue[1], addr, addr_len); | 7807 | memcpy (&queue[1], addr, addr_len); |
7306 | /* notify monitors about new queue */ | 7808 | /* notify monitors about new queue */ |
7307 | { | 7809 | { |
7308 | struct MonitorEvent me = {.rtt = queue->rtt, .cs = queue->cs}; | 7810 | struct MonitorEvent me = {.rtt = queue->pd.aged_rtt, .cs = queue->cs}; |
7309 | 7811 | ||
7310 | notify_monitors (&neighbour->pid, queue->address, queue->nt, &me); | 7812 | notify_monitors (&neighbour->pid, queue->address, queue->nt, &me); |
7311 | } | 7813 | } |
@@ -7361,8 +7863,8 @@ handle_queue_create_ok (void *cls, | |||
7361 | 7863 | ||
7362 | 7864 | ||
7363 | /** | 7865 | /** |
7364 | * Communicator tells us that our request to create a queue failed. This usually | 7866 | * Communicator tells us that our request to create a queue failed. This |
7365 | * indicates that the provided address is simply invalid or that the | 7867 | * usually indicates that the provided address is simply invalid or that the |
7366 | * communicator's resources are exhausted. | 7868 | * communicator's resources are exhausted. |
7367 | * | 7869 | * |
7368 | * @param cls the `struct TransportClient` | 7870 | * @param cls the `struct TransportClient` |
@@ -7655,7 +8157,8 @@ handle_address_consider_verify ( | |||
7655 | (void) cls; | 8157 | (void) cls; |
7656 | // OPTIMIZE-FIXME: checking that we know this address already should | 8158 | // OPTIMIZE-FIXME: checking that we know this address already should |
7657 | // be done BEFORE checking the signature => HELLO API change! | 8159 | // be done BEFORE checking the signature => HELLO API change! |
7658 | // OPTIMIZE-FIXME: pre-check: rate-limit signature verification / validation?! | 8160 | // OPTIMIZE-FIXME: pre-check: rate-limit signature verification / |
8161 | // validation?! | ||
7659 | address = | 8162 | address = |
7660 | GNUNET_HELLO_extract_address (&hdr[1], | 8163 | GNUNET_HELLO_extract_address (&hdr[1], |
7661 | ntohs (hdr->header.size) - sizeof (*hdr), | 8164 | ntohs (hdr->header.size) - sizeof (*hdr), |
@@ -7803,6 +8306,50 @@ free_validation_state_cb (void *cls, | |||
7803 | 8306 | ||
7804 | 8307 | ||
7805 | /** | 8308 | /** |
8309 | * Free pending acknowledgement. | ||
8310 | * | ||
8311 | * @param cls NULL | ||
8312 | * @param key unused | ||
8313 | * @param value a `struct PendingAcknowledgement` | ||
8314 | * @return #GNUNET_OK (always) | ||
8315 | */ | ||
8316 | static int | ||
8317 | free_pending_ack_cb (void *cls, | ||
8318 | const struct GNUNET_ShortHashCode *key, | ||
8319 | void *value) | ||
8320 | { | ||
8321 | struct PendingAcknowledgement *pa = value; | ||
8322 | |||
8323 | (void) cls; | ||
8324 | (void) key; | ||
8325 | free_pending_acknowledgement (pa); | ||
8326 | return GNUNET_OK; | ||
8327 | } | ||
8328 | |||
8329 | |||
8330 | /** | ||
8331 | * Free acknowledgement cummulator. | ||
8332 | * | ||
8333 | * @param cls NULL | ||
8334 | * @param pid unused | ||
8335 | * @param value a `struct AcknowledgementCummulator` | ||
8336 | * @return #GNUNET_OK (always) | ||
8337 | */ | ||
8338 | static int | ||
8339 | free_ack_cummulator_cb (void *cls, | ||
8340 | const struct GNUNET_PeerIdentity *pid, | ||
8341 | void *value) | ||
8342 | { | ||
8343 | struct AcknowledgementCummulator *ac = value; | ||
8344 | |||
8345 | (void) cls; | ||
8346 | (void) pid; | ||
8347 | GNUNET_free (ac); | ||
8348 | return GNUNET_OK; | ||
8349 | } | ||
8350 | |||
8351 | |||
8352 | /** | ||
7806 | * Function called when the service shuts down. Unloads our plugins | 8353 | * Function called when the service shuts down. Unloads our plugins |
7807 | * and cancels pending validations. | 8354 | * and cancels pending validations. |
7808 | * | 8355 | * |
@@ -7835,6 +8382,16 @@ do_shutdown (void *cls) | |||
7835 | GNUNET_free (GST_my_private_key); | 8382 | GNUNET_free (GST_my_private_key); |
7836 | GST_my_private_key = NULL; | 8383 | GST_my_private_key = NULL; |
7837 | } | 8384 | } |
8385 | GNUNET_CONTAINER_multipeermap_iterate (ack_cummulators, | ||
8386 | &free_ack_cummulator_cb, | ||
8387 | NULL); | ||
8388 | GNUNET_CONTAINER_multipeermap_destroy (ack_cummulators); | ||
8389 | ack_cummulators = NULL; | ||
8390 | GNUNET_CONTAINER_multishortmap_iterate (pending_acks, | ||
8391 | &free_pending_ack_cb, | ||
8392 | NULL); | ||
8393 | GNUNET_CONTAINER_multishortmap_destroy (pending_acks); | ||
8394 | pending_acks = NULL; | ||
7838 | GNUNET_CONTAINER_multipeermap_destroy (neighbours); | 8395 | GNUNET_CONTAINER_multipeermap_destroy (neighbours); |
7839 | neighbours = NULL; | 8396 | neighbours = NULL; |
7840 | GNUNET_CONTAINER_multipeermap_iterate (backtalkers, | 8397 | GNUNET_CONTAINER_multipeermap_iterate (backtalkers, |
@@ -7886,6 +8443,8 @@ run (void *cls, | |||
7886 | /* setup globals */ | 8443 | /* setup globals */ |
7887 | GST_cfg = c; | 8444 | GST_cfg = c; |
7888 | backtalkers = GNUNET_CONTAINER_multipeermap_create (16, GNUNET_YES); | 8445 | backtalkers = GNUNET_CONTAINER_multipeermap_create (16, GNUNET_YES); |
8446 | pending_acks = GNUNET_CONTAINER_multishortmap_create (32768, GNUNET_YES); | ||
8447 | ack_cummulators = GNUNET_CONTAINER_multipeermap_create (256, GNUNET_YES); | ||
7889 | neighbours = GNUNET_CONTAINER_multipeermap_create (1024, GNUNET_YES); | 8448 | neighbours = GNUNET_CONTAINER_multipeermap_create (1024, GNUNET_YES); |
7890 | dv_routes = GNUNET_CONTAINER_multipeermap_create (1024, GNUNET_YES); | 8449 | dv_routes = GNUNET_CONTAINER_multipeermap_create (1024, GNUNET_YES); |
7891 | ephemeral_map = GNUNET_CONTAINER_multipeermap_create (32, GNUNET_YES); | 8450 | ephemeral_map = GNUNET_CONTAINER_multipeermap_create (32, GNUNET_YES); |