implement looping over neighbours to call fwd_dv_learn()
[oweals/gnunet.git] / src / transport / gnunet-service-tng.c
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2010-2016, 2018, 2019 GNUnet e.V.
4
5  GNUnet is free software: you can redistribute it and/or modify it
6  under the terms of the GNU Affero General Public License as published
7  by the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9
10  GNUnet is distributed in the hope that it will be useful, but
11  WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  Affero General Public License for more details.
14
15  You should have received a copy of the GNU Affero General Public License
16  along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
18      SPDX-License-Identifier: AGPL3.0-or-later
19  */
20 /**
21  * @file transport/gnunet-service-tng.c
22  * @brief main for gnunet-service-tng
23  * @author Christian Grothoff
24  *
25  * TODO:
26  * Implement next:
27  * - FIXME: transmit_on_queue: track dvh we may be using and pass it to
28  *   fragment_message() and reliability_box_message() if applicable
29  * - proper use/initialization of timestamps in messages exchanged
30  *   during DV learning
31  * - persistence of monotonic time from DVInit to prevent
32  *   replay attacks using DVInit messages
33  * - dv hop-by-hop signature verification (at least at initiator)
34  * - persistence of monotonic time obtained from other peers
35  *   in PEERSTORE (by message type) -- done for backchannel, needed elsewhere?
36  * - change transport-core API to provide proper flow control in both
37  *   directions, allow multiple messages per peer simultaneously (tag
38  *   confirmations with unique message ID), and replace quota-out with
39  *   proper flow control; specify transmission preferences (latency,
40  *   reliability, etc.) per message!
41  * - add logging
42  *
43  * Later:
44  * - review retransmission logic, right now there is no smartness there!
45  *   => congestion control, flow control, etc
46  *
47  * Optimizations:
48  * - AcknowledgementUUIDPs are overkill with 256 bits (128 would do)
49  *    => Need 128 bit hash map though!
50  * - queue_send_msg and route_message both by API design have to make copies
51  *   of the payload, and route_message on top of that requires a malloc/free.
52  *   Change design to approximate "zero" copy better...
53  * - could avoid copying body of message into each fragment and keep
54  *   fragments as just pointers into the original message and only
55  *   fully build fragments just before transmission (optimization, should
56  *   reduce CPU and memory use)
57  * - if messages are below MTU, consider adding ACKs and other stuff
58  *   (requires planning at receiver, and additional MST-style demultiplex
59  *    at receiver!)
60  * - When we passively learned DV (with unconfirmed freshness), we
61  *   right now add the path to our list but with a zero path_valid_until
62  *   time and only use it for unconfirmed routes.  However, we could consider
63  *   triggering an explicit validation mechansim ourselves, specifically routing
64  *   a challenge-response message over the path (OPTIMIZATION-FIXME).
65  *
66  * Design realizations / discussion:
67  * - communicators do flow control by calling MQ "notify sent"
68  *   when 'ready'. They determine flow implicitly (i.e. TCP blocking)
69  *   or explicitly via backchannel FC ACKs.  As long as the
70  *   channel is not full, they may 'notify sent' even if the other
71  *   peer has not yet confirmed receipt. The other peer confirming
72  *   is _only_ for FC, not for more reliable transmission; reliable
73  *   transmission (i.e. of fragments) is left to _transport_.
74  * - ACKs sent back in uni-directional communicators are done via
75  *   the background channel API; here transport _may_ initially
76  *   broadcast (with bounded # hops) if no path is known;
77  * - transport should _integrate_ DV-routing and build a view of
78  *   the network; then background channel traffic can be
79  *   routed via DV as well as explicit "DV" traffic.
80  * - background channel is also used for ACKs and NAT traversal support
81  * - transport service is responsible for AEAD'ing the background
82  *   channel, timestamps and monotonic time are used against replay
83  *   of old messages -> peerstore needs to be supplied with
84  *   "latest timestamps seen" data
85  * - if transport implements DV, we likely need a 3rd peermap
86  *   in addition to ephemerals and (direct) neighbours
87  *   ==> check if stuff needs to be moved out of "Neighbour"
88  * - transport should encapsualte core-level messages and do its
89  *   own ACKing for RTT/goodput/loss measurements _and_ fragment
90  *   for retransmission
91  */
92 #include "platform.h"
93 #include "gnunet_util_lib.h"
94 #include "gnunet_statistics_service.h"
95 #include "gnunet_transport_monitor_service.h"
96 #include "gnunet_peerstore_service.h"
97 #include "gnunet_hello_lib.h"
98 #include "gnunet_signatures.h"
99 #include "transport.h"
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
106
107 /**
108  * What is the size we assume for a read operation in the
109  * absence of an MTU for the purpose of flow control?
110  */
111 #define IN_PACKET_SIZE_WITHOUT_MTU 128
112
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 /**
120  * Maximum number of peers we select for forwarding DVInit
121  * messages at the same time (excluding initiator).
122  */
123 #define MAX_DV_DISCOVERY_SELECTION 16
124
125 /**
126  * Minimum number of hops we should forward DV learn messages
127  * even if they are NOT useful for us in hope of looping
128  * back to the initiator?
129  *
130  * FIXME: allow initiator some control here instead?
131  */
132 #define MIN_DV_PATH_LENGTH_FOR_INITIATOR 3
133
134 /**
135  * Maximum DV distance allowed ever.
136  */
137 #define MAX_DV_HOPS_ALLOWED 16
138
139 /**
140  * Maximum number of DV learning activities we may
141  * have pending at the same time.
142  */
143 #define MAX_DV_LEARN_PENDING 64
144
145 /**
146  * Maximum number of DV paths we keep simultaneously to the same target.
147  */
148 #define MAX_DV_PATHS_TO_TARGET 3
149
150 /**
151  * If a queue delays the next message by more than this number
152  * of seconds we log a warning. Note: this is for testing,
153  * the value chosen here might be too aggressively low!
154  */
155 #define DELAY_WARN_THRESHOLD \
156   GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5)
157
158 /**
159  * We only consider queues as "quality" connections when
160  * suppressing the generation of DV initiation messages if
161  * the latency of the queue is below this threshold.
162  */
163 #define DV_QUALITY_RTT_THRESHOLD \
164   GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1)
165
166 /**
167  * How long do we consider a DV path valid if we see no
168  * further updates on it? Note: the value chosen here might be too low!
169  */
170 #define DV_PATH_VALIDITY_TIMEOUT \
171   GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5)
172
173 /**
174  * How long do we cache backchannel (struct Backtalker) information
175  * after a backchannel goes inactive?
176  */
177 #define BACKCHANNEL_INACTIVITY_TIMEOUT \
178   GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5)
179
180 /**
181  * How long before paths expire would we like to (re)discover DV paths? Should
182  * be below #DV_PATH_VALIDITY_TIMEOUT.
183  */
184 #define DV_PATH_DISCOVERY_FREQUENCY \
185   GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 4)
186
187 /**
188  * How long are ephemeral keys valid?
189  */
190 #define EPHEMERAL_VALIDITY \
191   GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 4)
192
193 /**
194  * How long do we keep partially reassembled messages around before giving up?
195  */
196 #define REASSEMBLY_EXPIRATION \
197   GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 4)
198
199 /**
200  * What is the fastest rate at which we send challenges *if* we keep learning
201  * an address (gossip, DHT, etc.)?
202  */
203 #define FAST_VALIDATION_CHALLENGE_FREQ \
204   GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 1)
205
206 /**
207  * What is the slowest rate at which we send challenges?
208  */
209 #define MAX_VALIDATION_CHALLENGE_FREQ \
210   GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_DAYS, 1)
211
212 /**
213  * How long until we forget about historic accumulators and thus
214  * reset the ACK counter? Should exceed the maximum time an
215  * active connection experiences without an ACK.
216  */
217 #define ACK_CUMMULATOR_TIMEOUT \
218   GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 4)
219
220 /**
221  * What is the non-randomized base frequency at which we
222  * would initiate DV learn messages?
223  */
224 #define DV_LEARN_BASE_FREQUENCY GNUNET_TIME_UNIT_MINUTES
225
226 /**
227  * How many good connections (confirmed, bi-directional, not DV)
228  * do we need to have to suppress initiating DV learn messages?
229  */
230 #define DV_LEARN_QUALITY_THRESHOLD 100
231
232 /**
233  * When do we forget an invalid address for sure?
234  */
235 #define MAX_ADDRESS_VALID_UNTIL \
236   GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MONTHS, 1)
237
238 /**
239  * How long do we consider an address valid if we just checked?
240  */
241 #define ADDRESS_VALIDATION_LIFETIME \
242   GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 4)
243
244 /**
245  * What is the maximum frequency at which we do address validation?
246  * A random value between 0 and this value is added when scheduling
247  * the #validation_task (both to ensure we do not validate too often,
248  * and to randomize a bit).
249  */
250 #define MIN_DELAY_ADDRESS_VALIDATION GNUNET_TIME_UNIT_MILLISECONDS
251
252 /**
253  * How many network RTTs before an address validation expires should we begin
254  * trying to revalidate? (Note that the RTT used here is the one that we
255  * experienced during the last validation, not necessarily the latest RTT
256  * observed).
257  */
258 #define VALIDATION_RTT_BUFFER_FACTOR 3
259
260 /**
261  * How many messages can we have pending for a given communicator
262  * process before we start to throttle that communicator?
263  *
264  * Used if a communicator might be CPU-bound and cannot handle the traffic.
265  */
266 #define COMMUNICATOR_TOTAL_QUEUE_LIMIT 512
267
268 /**
269  * How many messages can we have pending for a given queue (queue to
270  * a particular peer via a communicator) process before we start to
271  * throttle that queue?
272  */
273 #define QUEUE_LENGTH_LIMIT 32
274
275
276 GNUNET_NETWORK_STRUCT_BEGIN
277
278 /**
279  * Unique identifier we attach to a message.
280  */
281 struct MessageUUIDP
282 {
283   /**
284    * Unique value, generated by incrementing the
285    * `message_uuid_ctr` of `struct Neighbour`.
286    */
287   uint64_t uuid GNUNET_PACKED;
288 };
289
290
291 /**
292  * Unique identifier to map an acknowledgement to a transmission.
293  */
294 struct AcknowledgementUUIDP
295 {
296   /**
297    * The UUID value.  Not actually a hash, but a random value.
298    */
299   struct GNUNET_ShortHashCode value;
300 };
301
302
303 /**
304  * Unique identifier we attach to a message.
305  */
306 struct FragmentUUIDP
307 {
308   /**
309    * Unique value identifying a fragment, in NBO.
310    */
311   uint32_t uuid GNUNET_PACKED;
312 };
313
314
315 /**
316  * Type of a nonce used for challenges.
317  */
318 struct ChallengeNonceP
319 {
320   /**
321    * The value of the nonce.  Note that this is NOT a hash.
322    */
323   struct GNUNET_ShortHashCode value;
324 };
325
326
327 /**
328  * Outer layer of an encapsulated backchannel message.
329  */
330 struct TransportBackchannelEncapsulationMessage
331 {
332   /**
333    * Type is #GNUNET_MESSAGE_TYPE_TRANSPORT_BACKCHANNEL_ENCAPSULATION.
334    */
335   struct GNUNET_MessageHeader header;
336
337   /**
338    * Reserved, always zero.
339    */
340   uint32_t reserved GNUNET_PACKED;
341
342   /**
343    * Target's peer identity (as backchannels may be transmitted
344    * indirectly, or even be broadcast).
345    */
346   struct GNUNET_PeerIdentity target;
347
348   /**
349    * Ephemeral key setup by the sender for @e target, used
350    * to encrypt the payload.
351    */
352   struct GNUNET_CRYPTO_EcdhePublicKey ephemeral_key;
353
354   /**
355    * We use an IV here as the @e ephemeral_key is re-used for
356    * #EPHEMERAL_VALIDITY time to avoid re-signing it all the time.
357    */
358   struct GNUNET_ShortHashCode iv;
359
360   /**
361    * HMAC over the ciphertext of the encrypted, variable-size
362    * body that follows.  Verified via DH of @e target and
363    * @e ephemeral_key
364    */
365   struct GNUNET_HashCode hmac;
366
367   /* Followed by encrypted, variable-size payload */
368 };
369
370
371 /**
372  * Body by which a peer confirms that it is using an ephemeral key.
373  */
374 struct EphemeralConfirmationPS
375 {
376
377   /**
378    * Purpose is #GNUNET_SIGNATURE_PURPOSE_TRANSPORT_EPHEMERAL
379    */
380   struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
381
382   /**
383    * How long is this signature over the ephemeral key valid?
384    *
385    * Note that the receiver MUST IGNORE the absolute time, and only interpret
386    * the value as a mononic time and reject "older" values than the last one
387    * observed.  This is necessary as we do not want to require synchronized
388    * clocks and may not have a bidirectional communication channel.
389    *
390    * Even with this, there is no real guarantee against replay achieved here,
391    * unless the latest timestamp is persisted.  While persistence should be
392    * provided via PEERSTORE, we do not consider the mechanism reliable!  Thus,
393    * communicators must protect against replay attacks when using backchannel
394    * communication!
395    */
396   struct GNUNET_TIME_AbsoluteNBO ephemeral_validity;
397
398   /**
399    * Target's peer identity.
400    */
401   struct GNUNET_PeerIdentity target;
402
403   /**
404    * Ephemeral key setup by the sender for @e target, used
405    * to encrypt the payload.
406    */
407   struct GNUNET_CRYPTO_EcdhePublicKey ephemeral_key;
408 };
409
410
411 /**
412  * Plaintext of the variable-size payload that is encrypted
413  * within a `struct TransportBackchannelEncapsulationMessage`
414  */
415 struct TransportBackchannelRequestPayloadP
416 {
417
418   /**
419    * Sender's peer identity.
420    */
421   struct GNUNET_PeerIdentity sender;
422
423   /**
424    * Signature of the sender over an
425    * #GNUNET_SIGNATURE_PURPOSE_TRANSPORT_EPHEMERAL.
426    */
427   struct GNUNET_CRYPTO_EddsaSignature sender_sig;
428
429   /**
430    * How long is this signature over the ephemeral key valid?
431    *
432    * Note that the receiver MUST IGNORE the absolute time, and only interpret
433    * the value as a mononic time and reject "older" values than the last one
434    * observed.  This is necessary as we do not want to require synchronized
435    * clocks and may not have a bidirectional communication channel.
436    *
437    * Even with this, there is no real guarantee against replay achieved here,
438    * unless the latest timestamp is persisted.  While persistence should be
439    * provided via PEERSTORE, we do not consider the mechanism reliable!  Thus,
440    * communicators must protect against replay attacks when using backchannel
441    * communication!
442    */
443   struct GNUNET_TIME_AbsoluteNBO ephemeral_validity;
444
445   /**
446    * Current monotonic time of the sending transport service.  Used to
447    * detect replayed messages.  Note that the receiver should remember
448    * a list of the recently seen timestamps and only reject messages
449    * if the timestamp is in the list, or the list is "full" and the
450    * timestamp is smaller than the lowest in the list.
451    *
452    * Like the @e ephemeral_validity, the list of timestamps per peer should be
453    * persisted to guard against replays after restarts.
454    */
455   struct GNUNET_TIME_AbsoluteNBO monotonic_time;
456
457   /* Followed by a `struct GNUNET_MessageHeader` with a message
458      for a communicator */
459
460   /* Followed by a 0-termianted string specifying the name of
461      the communicator which is to receive the message */
462 };
463
464
465 /**
466  * Outer layer of an encapsulated unfragmented application message sent
467  * over an unreliable channel.
468  */
469 struct TransportReliabilityBoxMessage
470 {
471   /**
472    * Type is #GNUNET_MESSAGE_TYPE_TRANSPORT_RELIABILITY_BOX
473    */
474   struct GNUNET_MessageHeader header;
475
476   /**
477    * Number of messages still to be sent before a commulative
478    * ACK is requested.  Zero if an ACK is requested immediately.
479    * In NBO.  Note that the receiver may send the ACK faster
480    * if it believes that is reasonable.
481    */
482   uint32_t ack_countdown GNUNET_PACKED;
483
484   /**
485    * Unique ID of the message used for signalling receipt of
486    * messages sent over possibly unreliable channels.  Should
487    * be a random.
488    */
489   struct AcknowledgementUUIDP ack_uuid;
490 };
491
492
493 /**
494  * Acknowledgement payload.
495  */
496 struct TransportCummulativeAckPayloadP
497 {
498   /**
499    * How long was the ACK delayed for generating cummulative ACKs?
500    * Used to calculate the correct network RTT by taking the receipt
501    * time of the ack minus the transmission time of the sender minus
502    * this value.
503    */
504   struct GNUNET_TIME_RelativeNBO ack_delay;
505
506   /**
507    * UUID of a message being acknowledged.
508    */
509   struct AcknowledgementUUIDP ack_uuid;
510 };
511
512
513 /**
514  * Confirmation that the receiver got a
515  * #GNUNET_MESSAGE_TYPE_TRANSPORT_RELIABILITY_BOX. Note that the
516  * confirmation may be transmitted over a completely different queue,
517  * so ACKs are identified by a combination of PID of sender and
518  * message UUID, without the queue playing any role!
519  */
520 struct TransportReliabilityAckMessage
521 {
522   /**
523    * Type is #GNUNET_MESSAGE_TYPE_TRANSPORT_RELIABILITY_ACK
524    */
525   struct GNUNET_MessageHeader header;
526
527   /**
528    * Counter of ACKs transmitted by the sender to us. Incremented
529    * by one for each ACK, used to detect how many ACKs were lost.
530    */
531   uint32_t ack_counter GNUNET_PACKED;
532
533   /* followed by any number of `struct TransportCummulativeAckPayloadP`
534      messages providing ACKs */
535 };
536
537
538 /**
539  * Outer layer of an encapsulated fragmented application message.
540  */
541 struct TransportFragmentBoxMessage
542 {
543   /**
544    * Type is #GNUNET_MESSAGE_TYPE_TRANSPORT_FRAGMENT
545    */
546   struct GNUNET_MessageHeader header;
547
548   /**
549    * Unique ID of this fragment (and fragment transmission!). Will
550    * change even if a fragement is retransmitted to make each
551    * transmission attempt unique! If a client receives a duplicate
552    * fragment (same @e frag_off for same @a msg_uuid, it must send
553    * #GNUNET_MESSAGE_TYPE_TRANSPORT_RELIABILITY_ACK immediately.
554    */
555   struct AcknowledgementUUIDP ack_uuid;
556
557   /**
558    * Original message ID for of the message that all the fragments
559    * belong to.  Must be the same for all fragments.
560    */
561   struct MessageUUIDP msg_uuid;
562
563   /**
564    * Offset of this fragment in the overall message.
565    */
566   uint16_t frag_off GNUNET_PACKED;
567
568   /**
569    * Total size of the message that is being fragmented.
570    */
571   uint16_t msg_size GNUNET_PACKED;
572 };
573
574
575 /**
576  * Content signed by the initator during DV learning.
577  *
578  * The signature is required to prevent DDoS attacks. A peer sending out this
579  * message is potentially generating a lot of traffic that will go back to the
580  * initator, as peers receiving this message will try to let the initiator
581  * know that they got the message.
582  *
583  * Without this signature, an attacker could abuse this mechanism for traffic
584  * amplification, sending a lot of traffic to a peer by putting out this type
585  * of message with the victim's peer identity.
586  *
587  * Even with just a signature, traffic amplification would be possible via
588  * replay attacks. The @e monotonic_time limits such replay attacks, as every
589  * potential amplificator will check the @e monotonic_time and only respond
590  * (at most) once per message.
591  */
592 struct DvInitPS
593 {
594   /**
595    * Purpose is #GNUNET_SIGNATURE_PURPOSE_TRANSPORT_DV_INITIATOR
596    */
597   struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
598
599   /**
600    * Time at the initiator when generating the signature.
601    *
602    * Note that the receiver MUST IGNORE the absolute time, and only interpret
603    * the value as a mononic time and reject "older" values than the last one
604    * observed.  This is necessary as we do not want to require synchronized
605    * clocks and may not have a bidirectional communication channel.
606    *
607    * Even with this, there is no real guarantee against replay achieved here,
608    * unless the latest timestamp is persisted.  Persistence should be
609    * provided via PEERSTORE if possible.
610    */
611   struct GNUNET_TIME_AbsoluteNBO monotonic_time;
612
613   /**
614    * Challenge value used by the initiator to re-identify the path.
615    */
616   struct ChallengeNonceP challenge;
617 };
618
619
620 /**
621  * Content signed by each peer during DV learning.
622  *
623  * This assues the initiator of the DV learning operation that the hop from @e
624  * pred via the signing peer to @e succ actually exists.  This makes it
625  * impossible for an adversary to supply the network with bogus routes.
626  *
627  * The @e challenge is included to provide replay protection for the
628  * initiator. This way, the initiator knows that the hop existed after the
629  * original @e challenge was first transmitted, providing a freshness metric.
630  *
631  * Peers other than the initiator that passively learn paths by observing
632  * these messages do NOT benefit from this. Here, an adversary may indeed
633  * replay old messages.  Thus, passively learned paths should always be
634  * immediately marked as "potentially stale".
635  */
636 struct DvHopPS
637 {
638   /**
639    * Purpose is #GNUNET_SIGNATURE_PURPOSE_TRANSPORT_DV_HOP
640    */
641   struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
642
643   /**
644    * Identity of the previous peer on the path.
645    */
646   struct GNUNET_PeerIdentity pred;
647
648   /**
649    * Identity of the next peer on the path.
650    */
651   struct GNUNET_PeerIdentity succ;
652
653   /**
654    * Challenge value used by the initiator to re-identify the path.
655    */
656   struct ChallengeNonceP challenge;
657 };
658
659
660 /**
661  * An entry describing a peer on a path in a
662  * `struct TransportDVLearnMessage` message.
663  */
664 struct DVPathEntryP
665 {
666   /**
667    * Identity of a peer on the path.
668    */
669   struct GNUNET_PeerIdentity hop;
670
671   /**
672    * Signature of this hop over the path, of purpose
673    * #GNUNET_SIGNATURE_PURPOSE_TRANSPORT_DV_HOP
674    */
675   struct GNUNET_CRYPTO_EddsaSignature hop_sig;
676 };
677
678
679 /**
680  * Internal message used by transport for distance vector learning.
681  * If @e num_hops does not exceed the threshold, peers should append
682  * themselves to the peer list and flood the message (possibly only
683  * to a subset of their neighbours to limit discoverability of the
684  * network topology).  To the extend that the @e bidirectional bits
685  * are set, peers may learn the inverse paths even if they did not
686  * initiate.
687  *
688  * Unless received on a bidirectional queue and @e num_hops just
689  * zero, peers that can forward to the initator should always try to
690  * forward to the initiator.
691  */
692 struct TransportDVLearnMessage
693 {
694   /**
695    * Type is #GNUNET_MESSAGE_TYPE_TRANSPORT_DV_LEARN
696    */
697   struct GNUNET_MessageHeader header;
698
699   /**
700    * Number of hops this messages has travelled, in NBO. Zero if
701    * sent by initiator.
702    */
703   uint16_t num_hops GNUNET_PACKED;
704
705   /**
706    * Bitmask of the last 16 hops indicating whether they are confirmed
707    * available (without DV) in both directions or not, in NBO.  Used
708    * to possibly instantly learn a path in both directions.  Each peer
709    * should shift this value by one to the left, and then set the
710    * lowest bit IF the current sender can be reached from it (without
711    * DV routing).
712    */
713   uint16_t bidirectional GNUNET_PACKED;
714
715   /**
716    * Peers receiving this message and delaying forwarding to other
717    * peers for any reason should increment this value by the non-network
718    * delay created by the peer.
719    */
720   struct GNUNET_TIME_RelativeNBO non_network_delay;
721
722   /**
723    * Signature of this hop over the path, of purpose
724    * #GNUNET_SIGNATURE_PURPOSE_TRANSPORT_DV_INITIATOR
725    */
726   struct GNUNET_CRYPTO_EddsaSignature init_sig;
727
728   /**
729    * Identity of the peer that started this learning activity.
730    */
731   struct GNUNET_PeerIdentity initiator;
732
733   /**
734    * Challenge value used by the initiator to re-identify the path.
735    */
736   struct ChallengeNonceP challenge;
737
738   /* Followed by @e num_hops `struct DVPathEntryP` values,
739      excluding the initiator of the DV trace; the last entry is the
740      current sender; the current peer must not be included. */
741 };
742
743
744 /**
745  * Outer layer of an encapsulated message send over multiple hops.
746  * The path given only includes the identities of the subsequent
747  * peers, i.e. it will be empty if we are the receiver. Each
748  * forwarding peer should scan the list from the end, and if it can,
749  * forward to the respective peer. The list should then be shortened
750  * by all the entries up to and including that peer.  Each hop should
751  * also increment @e total_hops to allow the receiver to get a precise
752  * estimate on the number of hops the message travelled.  Senders must
753  * provide a learned path that thus should work, but intermediaries
754  * know of a shortcut, they are allowed to send the message via that
755  * shortcut.
756  *
757  * If a peer finds itself still on the list, it must drop the message.
758  */
759 struct TransportDVBoxMessage
760 {
761   /**
762    * Type is #GNUNET_MESSAGE_TYPE_TRANSPORT_DV_BOX
763    */
764   struct GNUNET_MessageHeader header;
765
766   /**
767    * Number of total hops this messages travelled. In NBO.
768    * @e origin sets this to zero, to be incremented at
769    * each hop.
770    */
771   uint16_t total_hops GNUNET_PACKED;
772
773   /**
774    * Number of hops this messages includes. In NBO.
775    */
776   uint16_t num_hops GNUNET_PACKED;
777
778   /**
779    * Identity of the peer that originated the message.
780    */
781   struct GNUNET_PeerIdentity origin;
782
783   /* Followed by @e num_hops `struct GNUNET_PeerIdentity` values;
784      excluding the @e origin and the current peer, the last must be
785      the ultimate target; if @e num_hops is zero, the receiver of this
786      message is the ultimate target. */
787
788   /* Followed by the actual message, which itself may be
789      another box, but not a DV_LEARN or DV_BOX message! */
790 };
791
792
793 /**
794  * Message send to another peer to validate that it can indeed
795  * receive messages at a particular address.
796  */
797 struct TransportValidationChallengeMessage
798 {
799
800   /**
801    * Type is #GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_VALIDATION_CHALLENGE
802    */
803   struct GNUNET_MessageHeader header;
804
805   /**
806    * Zero.
807    */
808   uint32_t reserved GNUNET_PACKED;
809
810   /**
811    * Challenge to be signed by the receiving peer.
812    */
813   struct ChallengeNonceP challenge;
814
815   /**
816    * Timestamp of the sender, to be copied into the reply
817    * to allow sender to calculate RTT.
818    */
819   struct GNUNET_TIME_AbsoluteNBO sender_time;
820 };
821
822
823 /**
824  * Message signed by a peer to confirm that it can indeed
825  * receive messages at a particular address.
826  */
827 struct TransportValidationPS
828 {
829
830   /**
831    * Purpose is #GNUNET_SIGNATURE_PURPOSE_TRANSPORT_CHALLENGE
832    */
833   struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
834
835   /**
836    * How long does the sender believe the address on
837    * which the challenge was received to remain valid?
838    */
839   struct GNUNET_TIME_RelativeNBO validity_duration;
840
841   /**
842    * Challenge signed by the receiving peer.
843    */
844   struct ChallengeNonceP challenge;
845 };
846
847
848 /**
849  * Message send to a peer to respond to a
850  * #GNUNET_MESSAGE_TYPE_ADDRESS_VALIDATION_CHALLENGE
851  */
852 struct TransportValidationResponseMessage
853 {
854
855   /**
856    * Type is #GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_VALIDATION_RESPONSE
857    */
858   struct GNUNET_MessageHeader header;
859
860   /**
861    * Zero.
862    */
863   uint32_t reserved GNUNET_PACKED;
864
865   /**
866    * The peer's signature matching the
867    * #GNUNET_SIGNATURE_PURPOSE_TRANSPORT_CHALLENGE purpose.
868    */
869   struct GNUNET_CRYPTO_EddsaSignature signature;
870
871   /**
872    * The challenge that was signed by the receiving peer.
873    */
874   struct ChallengeNonceP challenge;
875
876   /**
877    * Original timestamp of the sender (was @code{sender_time}),
878    * copied into the reply to allow sender to calculate RTT.
879    */
880   struct GNUNET_TIME_AbsoluteNBO origin_time;
881
882   /**
883    * How long does the sender believe this address to remain
884    * valid?
885    */
886   struct GNUNET_TIME_RelativeNBO validity_duration;
887 };
888
889
890 GNUNET_NETWORK_STRUCT_END
891
892
893 /**
894  * What type of client is the `struct TransportClient` about?
895  */
896 enum ClientType
897 {
898   /**
899    * We do not know yet (client is fresh).
900    */
901   CT_NONE = 0,
902
903   /**
904    * Is the CORE service, we need to forward traffic to it.
905    */
906   CT_CORE = 1,
907
908   /**
909    * It is a monitor, forward monitor data.
910    */
911   CT_MONITOR = 2,
912
913   /**
914    * It is a communicator, use for communication.
915    */
916   CT_COMMUNICATOR = 3,
917
918   /**
919    * "Application" telling us where to connect (i.e. TOPOLOGY, DHT or CADET).
920    */
921   CT_APPLICATION = 4
922 };
923
924
925 /**
926  * When did we launch this DV learning activity?
927  */
928 struct LearnLaunchEntry
929 {
930
931   /**
932    * Kept (also) in a DLL sorted by launch time.
933    */
934   struct LearnLaunchEntry *prev;
935
936   /**
937    * Kept (also) in a DLL sorted by launch time.
938    */
939   struct LearnLaunchEntry *next;
940
941   /**
942    * Challenge that uniquely identifies this activity.
943    */
944   struct ChallengeNonceP challenge;
945
946   /**
947    * When did we transmit the DV learn message (used to calculate RTT) and
948    * determine freshness of paths learned via this operation.
949    */
950   struct GNUNET_TIME_Absolute launch_time;
951 };
952
953
954 /**
955  * Entry in our cache of ephemeral keys we currently use.  This way, we only
956  * sign an ephemeral once per @e target, and then can re-use it over multiple
957  * #GNUNET_MESSAGE_TYPE_TRANSPORT_BACKCHANNEL_ENCAPSULATION messages (as
958  * signing is expensive and in some cases we may use backchannel messages a
959  * lot).
960  */
961 struct EphemeralCacheEntry
962 {
963
964   /**
965    * Target's peer identity (we don't re-use ephemerals
966    * to limit linkability of messages).
967    */
968   struct GNUNET_PeerIdentity target;
969
970   /**
971    * Signature affirming @e ephemeral_key of type
972    * #GNUNET_SIGNATURE_PURPOSE_TRANSPORT_EPHEMERAL
973    */
974   struct GNUNET_CRYPTO_EddsaSignature sender_sig;
975
976   /**
977    * How long is @e sender_sig valid
978    */
979   struct GNUNET_TIME_Absolute ephemeral_validity;
980
981   /**
982    * Our ephemeral key.
983    */
984   struct GNUNET_CRYPTO_EcdhePublicKey ephemeral_key;
985
986   /**
987    * Our private ephemeral key.
988    */
989   struct GNUNET_CRYPTO_EcdhePrivateKey private_key;
990
991   /**
992    * Node in the ephemeral cache for this entry.
993    * Used for expiration.
994    */
995   struct GNUNET_CONTAINER_HeapNode *hn;
996 };
997
998
999 /**
1000  * Information we keep per #GOODPUT_AGING_SLOTS about historic
1001  * (or current) transmission performance.
1002  */
1003 struct TransmissionHistoryEntry
1004 {
1005   /**
1006    * Number of bytes actually sent in the interval.
1007    */
1008   uint64_t bytes_sent;
1009
1010   /**
1011    * Number of bytes received and acknowledged by the other peer in
1012    * the interval.
1013    */
1014   uint64_t bytes_received;
1015 };
1016
1017
1018 /**
1019  * Performance data for a transmission possibility.
1020  */
1021 struct PerformanceData
1022 {
1023   /**
1024    * Weighted average for the RTT.
1025    */
1026   struct GNUNET_TIME_Relative aged_rtt;
1027
1028   /**
1029    * Historic performance data, using a ring buffer of#GOODPUT_AGING_SLOTS
1030    * entries.
1031    */
1032   struct TransmissionHistoryEntry the[GOODPUT_AGING_SLOTS];
1033
1034   /**
1035    * What was the last age when we wrote to @e the? Used to clear
1036    * old entries when the age advances.
1037    */
1038   unsigned int last_age;
1039 };
1040
1041
1042 /**
1043  * Client connected to the transport service.
1044  */
1045 struct TransportClient;
1046
1047 /**
1048  * A neighbour that at least one communicator is connected to.
1049  */
1050 struct Neighbour;
1051
1052 /**
1053  * Entry in our #dv_routes table, representing a (set of) distance
1054  * vector routes to a particular peer.
1055  */
1056 struct DistanceVector;
1057
1058 /**
1059  * A queue is a message queue provided by a communicator
1060  * via which we can reach a particular neighbour.
1061  */
1062 struct Queue;
1063
1064 /**
1065  * Message awaiting transmission. See detailed comments below.
1066  */
1067 struct PendingMessage;
1068
1069 /**
1070  * One possible hop towards a DV target.
1071  */
1072 struct DistanceVectorHop;
1073
1074
1075 /**
1076  * Data structure kept when we are waiting for an acknowledgement.
1077  */
1078 struct PendingAcknowledgement
1079 {
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 *next_pm;
1086
1087   /**
1088    * If @e pm is non-NULL, this is the DLL in which this acknowledgement
1089    * is kept in relation to its pending message.
1090    */
1091   struct PendingAcknowledgement *prev_pm;
1092
1093   /**
1094    * If @e queue is non-NULL, this is the DLL in which this acknowledgement
1095    * is kept in relation to the queue that was used to transmit the
1096    * @a pm.
1097    */
1098   struct PendingAcknowledgement *next_queue;
1099
1100   /**
1101    * If @e queue is non-NULL, this is the DLL in which this acknowledgement
1102    * is kept in relation to the queue that was used to transmit the
1103    * @a pm.
1104    */
1105   struct PendingAcknowledgement *prev_queue;
1106
1107   /**
1108    * If @e dvh is non-NULL, this is the DLL in which this acknowledgement
1109    * is kept in relation to the DVH that was used to transmit the
1110    * @a pm.
1111    */
1112   struct PendingAcknowledgement *next_dvh;
1113
1114   /**
1115    * If @e dvh is non-NULL, this is the DLL in which this acknowledgement
1116    * is kept in relation to the DVH that was used to transmit the
1117    * @a pm.
1118    */
1119   struct PendingAcknowledgement *prev_dvh;
1120
1121   /**
1122    * Pointers for the DLL of all pending acknowledgements.
1123    * This list is sorted by @e transmission time.  If the list gets too
1124    * long, the oldest entries are discarded.
1125    */
1126   struct PendingAcknowledgement *next_pa;
1127
1128   /**
1129    * Pointers for the DLL of all pending acknowledgements.
1130    * This list is sorted by @e transmission time.  If the list gets too
1131    * long, the oldest entries are discarded.
1132    */
1133   struct PendingAcknowledgement *prev_pa;
1134
1135   /**
1136    * Unique identifier for this transmission operation.
1137    */
1138   struct AcknowledgementUUIDP ack_uuid;
1139
1140   /**
1141    * Message that was transmitted, may be NULL if the message was ACKed
1142    * via another channel.
1143    */
1144   struct PendingMessage *pm;
1145
1146   /**
1147    * Distance vector path chosen for this transmission, NULL if transmission
1148    * was to a direct neighbour OR if the path was forgotten in the meantime.
1149    */
1150   struct DistanceVectorHop *dvh;
1151
1152   /**
1153    * Queue used for transmission, NULL if the queue has been destroyed
1154    * (which may happen before we get an acknowledgement).
1155    */
1156   struct Queue *queue;
1157
1158   /**
1159    * Time of the transmission, for RTT calculation.
1160    */
1161   struct GNUNET_TIME_Absolute transmission_time;
1162
1163   /**
1164    * Number of bytes of the original message (to calculate bandwidth).
1165    */
1166   uint16_t message_size;
1167 };
1168
1169
1170 /**
1171  * One possible hop towards a DV target.
1172  */
1173 struct DistanceVectorHop
1174 {
1175
1176   /**
1177    * Kept in a MDLL, sorted by @e timeout.
1178    */
1179   struct DistanceVectorHop *next_dv;
1180
1181   /**
1182    * Kept in a MDLL, sorted by @e timeout.
1183    */
1184   struct DistanceVectorHop *prev_dv;
1185
1186   /**
1187    * Kept in a MDLL.
1188    */
1189   struct DistanceVectorHop *next_neighbour;
1190
1191   /**
1192    * Kept in a MDLL.
1193    */
1194   struct DistanceVectorHop *prev_neighbour;
1195
1196   /**
1197    * Head of DLL of PAs that used our @a path.
1198    */
1199   struct PendingAcknowledgement *pa_head;
1200
1201   /**
1202    * Tail of DLL of PAs that used our @a path.
1203    */
1204   struct PendingAcknowledgement *pa_tail;
1205
1206   /**
1207    * What would be the next hop to @e target?
1208    */
1209   struct Neighbour *next_hop;
1210
1211   /**
1212    * Distance vector entry this hop belongs with.
1213    */
1214   struct DistanceVector *dv;
1215
1216   /**
1217    * Array of @e distance hops to the target, excluding @e next_hop.
1218    * NULL if the entire path is us to @e next_hop to `target`. Allocated
1219    * at the end of this struct. Excludes the target itself!
1220    */
1221   const struct GNUNET_PeerIdentity *path;
1222
1223   /**
1224    * At what time do we forget about this path unless we see it again
1225    * while learning?
1226    */
1227   struct GNUNET_TIME_Absolute timeout;
1228
1229   /**
1230    * For how long is the validation of this path considered
1231    * valid?
1232    * Set to ZERO if the path is learned by snooping on DV learn messages
1233    * initiated by other peers, and to the time at which we generated the
1234    * challenge for DV learn operations this peer initiated.
1235    */
1236   struct GNUNET_TIME_Absolute path_valid_until;
1237
1238   /**
1239    * Performance data for this transmission possibility.
1240    */
1241   struct PerformanceData pd;
1242
1243   /**
1244    * Number of hops in total to the `target` (excluding @e next_hop and `target`
1245    * itself). Thus 0 still means a distance of 2 hops (to @e next_hop and then
1246    * to `target`).
1247    */
1248   unsigned int distance;
1249 };
1250
1251
1252 /**
1253  * Entry in our #dv_routes table, representing a (set of) distance
1254  * vector routes to a particular peer.
1255  */
1256 struct DistanceVector
1257 {
1258
1259   /**
1260    * To which peer is this a route?
1261    */
1262   struct GNUNET_PeerIdentity target;
1263
1264   /**
1265    * Known paths to @e target.
1266    */
1267   struct DistanceVectorHop *dv_head;
1268
1269   /**
1270    * Known paths to @e target.
1271    */
1272   struct DistanceVectorHop *dv_tail;
1273
1274   /**
1275    * Task scheduled to purge expired paths from @e dv_head MDLL.
1276    */
1277   struct GNUNET_SCHEDULER_Task *timeout_task;
1278
1279   /**
1280    * Task scheduled to possibly notfiy core that this queue is no longer
1281    * counting as confirmed.  Runs the #core_queue_visibility_check().
1282    */
1283   struct GNUNET_SCHEDULER_Task *visibility_task;
1284
1285   /**
1286    * Quota at which CORE is allowed to transmit to this peer
1287    * (note that the value CORE should actually be told is this
1288    *  value plus the respective value in `struct Neighbour`).
1289    * Should match the sum of the quotas of all of the paths.
1290    *
1291    * FIXME: not yet set, tricky to get right given multiple paths,
1292    *        many of which may be inactive! (=> Idea: measure???)
1293    * FIXME: how do we set this value initially when we tell CORE?
1294    *    Options: start at a minimum value or at literally zero?
1295    *         (=> Current thought: clean would be zero!)
1296    */
1297   struct GNUNET_BANDWIDTH_Value32NBO quota_out;
1298
1299   /**
1300    * Is one of the DV paths in this struct 'confirmed' and thus
1301    * the cause for CORE to see this peer as connected? (Note that
1302    * the same may apply to a `struct Neighbour` at the same time.)
1303    */
1304   int core_visible;
1305 };
1306
1307
1308 /**
1309  * Entry identifying transmission in one of our `struct
1310  * Queue` which still awaits an ACK.  This is used to
1311  * ensure we do not overwhelm a communicator and limit the number of
1312  * messages outstanding per communicator (say in case communicator is
1313  * CPU bound) and per queue (in case bandwidth allocation exceeds
1314  * what the communicator can actually provide towards a particular
1315  * peer/target).
1316  */
1317 struct QueueEntry
1318 {
1319
1320   /**
1321    * Kept as a DLL.
1322    */
1323   struct QueueEntry *next;
1324
1325   /**
1326    * Kept as a DLL.
1327    */
1328   struct QueueEntry *prev;
1329
1330   /**
1331    * Queue this entry is queued with.
1332    */
1333   struct Queue *queue;
1334
1335   /**
1336    * Pending message this entry is for, or NULL for none.
1337    */
1338   struct PendingMessage *pm;
1339
1340   /**
1341    * Message ID used for this message with the queue used for transmission.
1342    */
1343   uint64_t mid;
1344 };
1345
1346
1347 /**
1348  * A queue is a message queue provided by a communicator
1349  * via which we can reach a particular neighbour.
1350  */
1351 struct Queue
1352 {
1353   /**
1354    * Kept in a MDLL.
1355    */
1356   struct Queue *next_neighbour;
1357
1358   /**
1359    * Kept in a MDLL.
1360    */
1361   struct Queue *prev_neighbour;
1362
1363   /**
1364    * Kept in a MDLL.
1365    */
1366   struct Queue *prev_client;
1367
1368   /**
1369    * Kept in a MDLL.
1370    */
1371   struct Queue *next_client;
1372
1373   /**
1374    * Head of DLL of PAs that used this queue.
1375    */
1376   struct PendingAcknowledgement *pa_head;
1377
1378   /**
1379    * Tail of DLL of PAs that used this queue.
1380    */
1381   struct PendingAcknowledgement *pa_tail;
1382
1383   /**
1384    * Head of DLL of unacked transmission requests.
1385    */
1386   struct QueueEntry *queue_head;
1387
1388   /**
1389    * End of DLL of unacked transmission requests.
1390    */
1391   struct QueueEntry *queue_tail;
1392
1393   /**
1394    * Which neighbour is this queue for?
1395    */
1396   struct Neighbour *neighbour;
1397
1398   /**
1399    * Which communicator offers this queue?
1400    */
1401   struct TransportClient *tc;
1402
1403   /**
1404    * Address served by the queue.
1405    */
1406   const char *address;
1407
1408   /**
1409    * Task scheduled for the time when this queue can (likely) transmit the
1410    * next message. Still needs to check with the @e tracker_out to be sure.
1411    */
1412   struct GNUNET_SCHEDULER_Task *transmit_task;
1413
1414   /**
1415    * Task scheduled to possibly notfiy core that this queue is no longer
1416    * counting as confirmed.  Runs the #core_queue_visibility_check().
1417    */
1418   struct GNUNET_SCHEDULER_Task *visibility_task;
1419
1420   /**
1421    * How long do *we* consider this @e address to be valid?  In the past or
1422    * zero if we have not yet validated it.  Can be updated based on
1423    * challenge-response validations (via address validation logic), or when we
1424    * receive ACKs that we can definitively map to transmissions via this
1425    * queue.
1426    */
1427   struct GNUNET_TIME_Absolute validated_until;
1428
1429   /**
1430    * Performance data for this queue.
1431    */
1432   struct PerformanceData pd;
1433
1434   /**
1435    * Message ID generator for transmissions on this queue to the
1436    * communicator.
1437    */
1438   uint64_t mid_gen;
1439
1440   /**
1441    * Unique identifier of this queue with the communicator.
1442    */
1443   uint32_t qid;
1444
1445   /**
1446    * Maximum transmission unit supported by this queue.
1447    */
1448   uint32_t mtu;
1449
1450   /**
1451    * Messages pending.
1452    */
1453   uint32_t num_msg_pending;
1454
1455   /**
1456    * Bytes pending.
1457    */
1458   uint32_t num_bytes_pending;
1459
1460   /**
1461    * Length of the DLL starting at @e queue_head.
1462    */
1463   unsigned int queue_length;
1464
1465   /**
1466    * Network type offered by this queue.
1467    */
1468   enum GNUNET_NetworkType nt;
1469
1470   /**
1471    * Connection status for this queue.
1472    */
1473   enum GNUNET_TRANSPORT_ConnectionStatus cs;
1474
1475   /**
1476    * How much outbound bandwidth do we have available for this queue?
1477    */
1478   struct GNUNET_BANDWIDTH_Tracker tracker_out;
1479
1480   /**
1481    * How much inbound bandwidth do we have available for this queue?
1482    */
1483   struct GNUNET_BANDWIDTH_Tracker tracker_in;
1484 };
1485
1486
1487 /**
1488  * Information we keep for a message that we are reassembling.
1489  */
1490 struct ReassemblyContext
1491 {
1492
1493   /**
1494    * Original message ID for of the message that all the fragments
1495    * belong to.
1496    */
1497   struct MessageUUIDP msg_uuid;
1498
1499   /**
1500    * Which neighbour is this context for?
1501    */
1502   struct Neighbour *neighbour;
1503
1504   /**
1505    * Entry in the reassembly heap (sorted by expiration).
1506    */
1507   struct GNUNET_CONTAINER_HeapNode *hn;
1508
1509   /**
1510    * Bitfield with @e msg_size bits representing the positions
1511    * where we have received fragments.  When we receive a fragment,
1512    * we check the bits in @e bitfield before incrementing @e msg_missing.
1513    *
1514    * Allocated after the reassembled message.
1515    */
1516   uint8_t *bitfield;
1517
1518   /**
1519    * Task for sending ACK. We may send ACKs either because of hitting
1520    * the @e extra_acks limit, or based on time and @e num_acks.  This
1521    * task is for the latter case.
1522    */
1523   struct GNUNET_SCHEDULER_Task *ack_task;
1524
1525   /**
1526    * At what time will we give up reassembly of this message?
1527    */
1528   struct GNUNET_TIME_Absolute reassembly_timeout;
1529
1530   /**
1531    * Time we received the last fragment.  @e avg_ack_delay must be
1532    * incremented by now - @e last_frag multiplied by @e num_acks.
1533    */
1534   struct GNUNET_TIME_Absolute last_frag;
1535
1536   /**
1537    * How big is the message we are reassembling in total?
1538    */
1539   uint16_t msg_size;
1540
1541   /**
1542    * How many bytes of the message are still missing?  Defragmentation
1543    * is complete when @e msg_missing == 0.
1544    */
1545   uint16_t msg_missing;
1546
1547   /* Followed by @e msg_size bytes of the (partially) defragmented original
1548    * message */
1549
1550   /* Followed by @e bitfield data */
1551 };
1552
1553
1554 /**
1555  * A neighbour that at least one communicator is connected to.
1556  */
1557 struct Neighbour
1558 {
1559
1560   /**
1561    * Which peer is this about?
1562    */
1563   struct GNUNET_PeerIdentity pid;
1564
1565   /**
1566    * Map with `struct ReassemblyContext` structs for fragments under
1567    * reassembly. May be NULL if we currently have no fragments from
1568    * this @e pid (lazy initialization).
1569    */
1570   struct GNUNET_CONTAINER_MultiHashMap32 *reassembly_map;
1571
1572   /**
1573    * Heap with `struct ReassemblyContext` structs for fragments under
1574    * reassembly. May be NULL if we currently have no fragments from
1575    * this @e pid (lazy initialization).
1576    */
1577   struct GNUNET_CONTAINER_Heap *reassembly_heap;
1578
1579   /**
1580    * Task to free old entries from the @e reassembly_heap and @e reassembly_map.
1581    */
1582   struct GNUNET_SCHEDULER_Task *reassembly_timeout_task;
1583
1584   /**
1585    * Head of list of messages pending for this neighbour.
1586    */
1587   struct PendingMessage *pending_msg_head;
1588
1589   /**
1590    * Tail of list of messages pending for this neighbour.
1591    */
1592   struct PendingMessage *pending_msg_tail;
1593
1594   /**
1595    * Head of MDLL of DV hops that have this neighbour as next hop. Must be
1596    * purged if this neighbour goes down.
1597    */
1598   struct DistanceVectorHop *dv_head;
1599
1600   /**
1601    * Tail of MDLL of DV hops that have this neighbour as next hop. Must be
1602    * purged if this neighbour goes down.
1603    */
1604   struct DistanceVectorHop *dv_tail;
1605
1606   /**
1607    * Head of DLL of queues to this peer.
1608    */
1609   struct Queue *queue_head;
1610
1611   /**
1612    * Tail of DLL of queues to this peer.
1613    */
1614   struct Queue *queue_tail;
1615
1616   /**
1617    * Task run to cleanup pending messages that have exceeded their timeout.
1618    */
1619   struct GNUNET_SCHEDULER_Task *timeout_task;
1620
1621   /**
1622    * Quota at which CORE is allowed to transmit to this peer
1623    * (note that the value CORE should actually be told is this
1624    *  value plus the respective value in `struct DistanceVector`).
1625    * Should match the sum of the quotas of all of the queues.
1626    *
1627    * FIXME: not yet set, tricky to get right given multiple queues!
1628    *        (=> Idea: measure???)
1629    * FIXME: how do we set this value initially when we tell CORE?
1630    *    Options: start at a minimum value or at literally zero?
1631    *         (=> Current thought: clean would be zero!)
1632    */
1633   struct GNUNET_BANDWIDTH_Value32NBO quota_out;
1634
1635   /**
1636    * What is the earliest timeout of any message in @e pending_msg_tail?
1637    */
1638   struct GNUNET_TIME_Absolute earliest_timeout;
1639
1640   /**
1641    * Do we have a confirmed working queue and are thus visible to
1642    * CORE?
1643    */
1644   int core_visible;
1645 };
1646
1647
1648 /**
1649  * A peer that an application (client) would like us to talk to directly.
1650  */
1651 struct PeerRequest
1652 {
1653
1654   /**
1655    * Which peer is this about?
1656    */
1657   struct GNUNET_PeerIdentity pid;
1658
1659   /**
1660    * Client responsible for the request.
1661    */
1662   struct TransportClient *tc;
1663
1664   /**
1665    * Handle for watching the peerstore for HELLOs for this peer.
1666    */
1667   struct GNUNET_PEERSTORE_WatchContext *wc;
1668
1669   /**
1670    * What kind of performance preference does this @e tc have?
1671    */
1672   enum GNUNET_MQ_PreferenceKind pk;
1673
1674   /**
1675    * How much bandwidth would this @e tc like to see?
1676    */
1677   struct GNUNET_BANDWIDTH_Value32NBO bw;
1678 };
1679
1680
1681 /**
1682  * Types of different pending messages.
1683  */
1684 enum PendingMessageType
1685 {
1686
1687   /**
1688    * Ordinary message received from the CORE service.
1689    */
1690   PMT_CORE = 0,
1691
1692   /**
1693    * Fragment box.
1694    */
1695   PMT_FRAGMENT_BOX = 1,
1696
1697   /**
1698    * Reliability box.
1699    */
1700   PMT_RELIABILITY_BOX = 2,
1701
1702   /**
1703    * Any type of acknowledgement.
1704    */
1705   PMT_ACKNOWLEDGEMENT = 3,
1706
1707   /**
1708    * Control traffic generated by the TRANSPORT service itself.
1709    */
1710   PMT_CONTROL = 4
1711
1712 };
1713
1714
1715 /**
1716  * Transmission request that is awaiting delivery.  The original
1717  * transmission requests from CORE may be too big for some queues.
1718  * In this case, a *tree* of fragments is created.  At each
1719  * level of the tree, fragments are kept in a DLL ordered by which
1720  * fragment should be sent next (at the head).  The tree is searched
1721  * top-down, with the original message at the root.
1722  *
1723  * To select a node for transmission, first it is checked if the
1724  * current node's message fits with the MTU.  If it does not, we
1725  * either calculate the next fragment (based on @e frag_off) from the
1726  * current node, or, if all fragments have already been created,
1727  * descend to the @e head_frag.  Even though the node was already
1728  * fragmented, the fragment may be too big if the fragment was
1729  * generated for a queue with a larger MTU. In this case, the node
1730  * may be fragmented again, thus creating a tree.
1731  *
1732  * When acknowledgements for fragments are received, the tree
1733  * must be pruned, removing those parts that were already
1734  * acknowledged.  When fragments are sent over a reliable
1735  * channel, they can be immediately removed.
1736  *
1737  * If a message is ever fragmented, then the original "full" message
1738  * is never again transmitted (even if it fits below the MTU), and
1739  * only (remaining) fragments are sent.
1740  */
1741 struct PendingMessage
1742 {
1743   /**
1744    * Kept in a MDLL of messages for this @a target.
1745    */
1746   struct PendingMessage *next_neighbour;
1747
1748   /**
1749    * Kept in a MDLL of messages for this @a target.
1750    */
1751   struct PendingMessage *prev_neighbour;
1752
1753   /**
1754    * Kept in a MDLL of messages from this @a client (if @e pmt is #PMT_CORE)
1755    */
1756   struct PendingMessage *next_client;
1757
1758   /**
1759    * Kept in a MDLL of messages from this @a client  (if @e pmt is #PMT_CORE)
1760    */
1761   struct PendingMessage *prev_client;
1762
1763   /**
1764    * Kept in a MDLL of messages from this @a cpm (if @e pmt is
1765    * #PMT_FRAGMENT_BOx)
1766    */
1767   struct PendingMessage *next_frag;
1768
1769   /**
1770    * Kept in a MDLL of messages from this @a cpm  (if @e pmt is
1771    * #PMT_FRAGMENT_BOX)
1772    */
1773   struct PendingMessage *prev_frag;
1774
1775   /**
1776    * Head of DLL of PAs for this pending message.
1777    */
1778   struct PendingAcknowledgement *pa_head;
1779
1780   /**
1781    * Tail of DLL of PAs for this pending message.
1782    */
1783   struct PendingAcknowledgement *pa_tail;
1784
1785   /**
1786    * This message, reliability boxed. Only possibly available if @e pmt is
1787    * #PMT_CORE.
1788    */
1789   struct PendingMessage *bpm;
1790
1791   /**
1792    * Target of the request.
1793    */
1794   struct Neighbour *target;
1795
1796   /**
1797    * Set to non-NULL value if this message is currently being given to a
1798    * communicator and we are awaiting that communicator's acknowledgement.
1799    * Note that we must not retransmit a pending message while we're still
1800    * in the process of giving it to a communicator. If a pending message
1801    * is free'd while this entry is non-NULL, the @e qe reference to us
1802    * should simply be set to NULL.
1803    */
1804   struct QueueEntry *qe;
1805
1806   /**
1807    * Client that issued the transmission request, if @e pmt is #PMT_CORE.
1808    */
1809   struct TransportClient *client;
1810
1811   /**
1812    * Head of a MDLL of fragments created for this core message.
1813    */
1814   struct PendingMessage *head_frag;
1815
1816   /**
1817    * Tail of a MDLL of fragments created for this core message.
1818    */
1819   struct PendingMessage *tail_frag;
1820
1821   /**
1822    * Our parent in the fragmentation tree.
1823    */
1824   struct PendingMessage *frag_parent;
1825
1826   /**
1827    * At what time should we give up on the transmission (and no longer retry)?
1828    */
1829   struct GNUNET_TIME_Absolute timeout;
1830
1831   /**
1832    * What is the earliest time for us to retry transmission of this message?
1833    */
1834   struct GNUNET_TIME_Absolute next_attempt;
1835
1836   /**
1837    * UUID to use for this message (used for reassembly of fragments, only
1838    * initialized if @e msg_uuid_set is #GNUNET_YES).
1839    */
1840   struct MessageUUIDP msg_uuid;
1841
1842   /**
1843    * Type of the pending message.
1844    */
1845   enum PendingMessageType pmt;
1846
1847   /**
1848    * Size of the original message.
1849    */
1850   uint16_t bytes_msg;
1851
1852   /**
1853    * Offset at which we should generate the next fragment.
1854    */
1855   uint16_t frag_off;
1856
1857   /**
1858    * #GNUNET_YES once @e msg_uuid was initialized
1859    */
1860   int16_t msg_uuid_set;
1861
1862   /* Followed by @e bytes_msg to transmit */
1863 };
1864
1865
1866 /**
1867  * Acknowledgement payload.
1868  */
1869 struct TransportCummulativeAckPayload
1870 {
1871   /**
1872    * When did we receive the message we are ACKing?  Used to calculate
1873    * the delay we introduced by cummulating ACKs.
1874    */
1875   struct GNUNET_TIME_Absolute receive_time;
1876
1877   /**
1878    * UUID of a message being acknowledged.
1879    */
1880   struct AcknowledgementUUIDP ack_uuid;
1881 };
1882
1883
1884 /**
1885  * Data structure in which we track acknowledgements still to
1886  * be sent to the
1887  */
1888 struct AcknowledgementCummulator
1889 {
1890   /**
1891    * Target peer for which we are accumulating ACKs here.
1892    */
1893   struct GNUNET_PeerIdentity target;
1894
1895   /**
1896    * ACK data being accumulated.  Only @e num_acks slots are valid.
1897    */
1898   struct TransportCummulativeAckPayload ack_uuids[MAX_CUMMULATIVE_ACKS];
1899
1900   /**
1901    * Task scheduled either to transmit the cummulative ACK message,
1902    * or to clean up this data structure after extended periods of
1903    * inactivity (if @e num_acks is zero).
1904    */
1905   struct GNUNET_SCHEDULER_Task *task;
1906
1907   /**
1908    * When is @e task run (only used if @e num_acks is non-zero)?
1909    */
1910   struct GNUNET_TIME_Absolute min_transmission_time;
1911
1912   /**
1913    * Counter to produce the `ack_counter` in the `struct
1914    * TransportReliabilityAckMessage`.  Allows the receiver to detect
1915    * lost ACK messages.  Incremented by @e num_acks upon transmission.
1916    */
1917   uint32_t ack_counter;
1918
1919   /**
1920    * Number of entries used in @e ack_uuids.  Reset to 0 upon transmission.
1921    */
1922   unsigned int num_acks;
1923 };
1924
1925
1926 /**
1927  * One of the addresses of this peer.
1928  */
1929 struct AddressListEntry
1930 {
1931
1932   /**
1933    * Kept in a DLL.
1934    */
1935   struct AddressListEntry *next;
1936
1937   /**
1938    * Kept in a DLL.
1939    */
1940   struct AddressListEntry *prev;
1941
1942   /**
1943    * Which communicator provides this address?
1944    */
1945   struct TransportClient *tc;
1946
1947   /**
1948    * The actual address.
1949    */
1950   const char *address;
1951
1952   /**
1953    * Current context for storing this address in the peerstore.
1954    */
1955   struct GNUNET_PEERSTORE_StoreContext *sc;
1956
1957   /**
1958    * Task to periodically do @e st operation.
1959    */
1960   struct GNUNET_SCHEDULER_Task *st;
1961
1962   /**
1963    * What is a typical lifetime the communicator expects this
1964    * address to have? (Always from now.)
1965    */
1966   struct GNUNET_TIME_Relative expiration;
1967
1968   /**
1969    * Address identifier used by the communicator.
1970    */
1971   uint32_t aid;
1972
1973   /**
1974    * Network type offered by this address.
1975    */
1976   enum GNUNET_NetworkType nt;
1977 };
1978
1979
1980 /**
1981  * Client connected to the transport service.
1982  */
1983 struct TransportClient
1984 {
1985
1986   /**
1987    * Kept in a DLL.
1988    */
1989   struct TransportClient *next;
1990
1991   /**
1992    * Kept in a DLL.
1993    */
1994   struct TransportClient *prev;
1995
1996   /**
1997    * Handle to the client.
1998    */
1999   struct GNUNET_SERVICE_Client *client;
2000
2001   /**
2002    * Message queue to the client.
2003    */
2004   struct GNUNET_MQ_Handle *mq;
2005
2006   /**
2007    * What type of client is this?
2008    */
2009   enum ClientType type;
2010
2011   union
2012   {
2013
2014     /**
2015      * Information for @e type #CT_CORE.
2016      */
2017     struct
2018     {
2019
2020       /**
2021        * Head of list of messages pending for this client, sorted by
2022        * transmission time ("next_attempt" + possibly internal prioritization).
2023        */
2024       struct PendingMessage *pending_msg_head;
2025
2026       /**
2027        * Tail of list of messages pending for this client.
2028        */
2029       struct PendingMessage *pending_msg_tail;
2030
2031     } core;
2032
2033     /**
2034      * Information for @e type #CT_MONITOR.
2035      */
2036     struct
2037     {
2038
2039       /**
2040        * Peer identity to monitor the addresses of.
2041        * Zero to monitor all neighbours.  Valid if
2042        * @e type is #CT_MONITOR.
2043        */
2044       struct GNUNET_PeerIdentity peer;
2045
2046       /**
2047        * Is this a one-shot monitor?
2048        */
2049       int one_shot;
2050
2051     } monitor;
2052
2053
2054     /**
2055      * Information for @e type #CT_COMMUNICATOR.
2056      */
2057     struct
2058     {
2059       /**
2060        * If @e type is #CT_COMMUNICATOR, this communicator
2061        * supports communicating using these addresses.
2062        */
2063       char *address_prefix;
2064
2065       /**
2066        * Head of DLL of queues offered by this communicator.
2067        */
2068       struct Queue *queue_head;
2069
2070       /**
2071        * Tail of DLL of queues offered by this communicator.
2072        */
2073       struct Queue *queue_tail;
2074
2075       /**
2076        * Head of list of the addresses of this peer offered by this
2077        * communicator.
2078        */
2079       struct AddressListEntry *addr_head;
2080
2081       /**
2082        * Tail of list of the addresses of this peer offered by this
2083        * communicator.
2084        */
2085       struct AddressListEntry *addr_tail;
2086
2087       /**
2088        * Number of queue entries in all queues to this communicator. Used
2089        * throttle sending to a communicator if we see that the communicator
2090        * is globally unable to keep up.
2091        */
2092       unsigned int total_queue_length;
2093
2094       /**
2095        * Characteristics of this communicator.
2096        */
2097       enum GNUNET_TRANSPORT_CommunicatorCharacteristics cc;
2098
2099     } communicator;
2100
2101     /**
2102      * Information for @e type #CT_APPLICATION
2103      */
2104     struct
2105     {
2106
2107       /**
2108        * Map of requests for peers the given client application would like to
2109        * see connections for.  Maps from PIDs to `struct PeerRequest`.
2110        */
2111       struct GNUNET_CONTAINER_MultiPeerMap *requests;
2112
2113     } application;
2114
2115   } details;
2116 };
2117
2118
2119 /**
2120  * State we keep for validation activities.  Each of these
2121  * is both in the #validation_heap and the #validation_map.
2122  */
2123 struct ValidationState
2124 {
2125
2126   /**
2127    * For which peer is @a address to be validated (or possibly valid)?
2128    * Serves as key in the #validation_map.
2129    */
2130   struct GNUNET_PeerIdentity pid;
2131
2132   /**
2133    * How long did the peer claim this @e address to be valid? Capped at
2134    * minimum of #MAX_ADDRESS_VALID_UNTIL relative to the time where we last
2135    * were told about the address and the value claimed by the other peer at
2136    * that time.  May be updated similarly when validation succeeds.
2137    */
2138   struct GNUNET_TIME_Absolute valid_until;
2139
2140   /**
2141    * How long do *we* consider this @e address to be valid?
2142    * In the past or zero if we have not yet validated it.
2143    */
2144   struct GNUNET_TIME_Absolute validated_until;
2145
2146   /**
2147    * When did we FIRST use the current @e challenge in a message?
2148    * Used to sanity-check @code{origin_time} in the response when
2149    * calculating the RTT. If the @code{origin_time} is not in
2150    * the expected range, the response is discarded as malicious.
2151    */
2152   struct GNUNET_TIME_Absolute first_challenge_use;
2153
2154   /**
2155    * When did we LAST use the current @e challenge in a message?
2156    * Used to sanity-check @code{origin_time} in the response when
2157    * calculating the RTT.  If the @code{origin_time} is not in
2158    * the expected range, the response is discarded as malicious.
2159    */
2160   struct GNUNET_TIME_Absolute last_challenge_use;
2161
2162   /**
2163    * Next time we will send the @e challenge to the peer, if this time is past
2164    * @e valid_until, this validation state is released at this time.  If the
2165    * address is valid, @e next_challenge is set to @e validated_until MINUS @e
2166    * validation_delay * #VALIDATION_RTT_BUFFER_FACTOR, such that we will try
2167    * to re-validate before the validity actually expires.
2168    */
2169   struct GNUNET_TIME_Absolute next_challenge;
2170
2171   /**
2172    * Current backoff factor we're applying for sending the @a challenge.
2173    * Reset to 0 if the @a challenge is confirmed upon validation.
2174    * Reduced to minimum of #FAST_VALIDATION_CHALLENGE_FREQ and half of the
2175    * existing value if we receive an unvalidated address again over
2176    * another channel (and thus should consider the information "fresh").
2177    * Maximum is #MAX_VALIDATION_CHALLENGE_FREQ.
2178    */
2179   struct GNUNET_TIME_Relative challenge_backoff;
2180
2181   /**
2182    * Initially set to "forever". Once @e validated_until is set, this value is
2183    * set to the RTT that tells us how long it took to receive the validation.
2184    */
2185   struct GNUNET_TIME_Relative validation_rtt;
2186
2187   /**
2188    * The challenge we sent to the peer to get it to validate the address. Note
2189    * that we rotate the challenge whenever we update @e validated_until to
2190    * avoid attacks where a peer simply replays an old challenge in the future.
2191    * (We must not rotate more often as otherwise we may discard valid answers
2192    * due to packet losses, latency and reorderings on the network).
2193    */
2194   struct ChallengeNonceP challenge;
2195
2196   /**
2197    * Claimed address of the peer.
2198    */
2199   char *address;
2200
2201   /**
2202    * Entry in the #validation_heap, which is sorted by @e next_challenge. The
2203    * heap is used to figure out when the next validation activity should be
2204    * run.
2205    */
2206   struct GNUNET_CONTAINER_HeapNode *hn;
2207
2208   /**
2209    * Handle to a PEERSTORE store operation for this @e address.  NULL if
2210    * no PEERSTORE operation is pending.
2211    */
2212   struct GNUNET_PEERSTORE_StoreContext *sc;
2213
2214   /**
2215    * We are technically ready to send the challenge, but we are waiting for
2216    * the respective queue to become available for transmission.
2217    */
2218   int awaiting_queue;
2219 };
2220
2221
2222 /**
2223  * A Backtalker is a peer sending us backchannel messages. We use this
2224  * struct to detect monotonic time violations, cache ephemeral key
2225  * material (to avoid repeatedly checking signatures), and to synchronize
2226  * monotonic time with the PEERSTORE.
2227  */
2228 struct Backtalker
2229 {
2230   /**
2231    * Peer this is about.
2232    */
2233   struct GNUNET_PeerIdentity pid;
2234
2235   /**
2236    * Last (valid) monotonic time received from this sender.
2237    */
2238   struct GNUNET_TIME_Absolute monotonic_time;
2239
2240   /**
2241    * When will this entry time out?
2242    */
2243   struct GNUNET_TIME_Absolute timeout;
2244
2245   /**
2246    * Last (valid) ephemeral key received from this sender.
2247    */
2248   struct GNUNET_CRYPTO_EcdhePublicKey last_ephemeral;
2249
2250   /**
2251    * Task associated with this backtalker. Can be for timeout,
2252    * or other asynchronous operations.
2253    */
2254   struct GNUNET_SCHEDULER_Task *task;
2255
2256   /**
2257    * Communicator context waiting on this backchannel's @e get, or NULL.
2258    */
2259   struct CommunicatorMessageContext *cmc;
2260
2261   /**
2262    * Handle for an operation to fetch @e monotonic_time information from the
2263    * PEERSTORE, or NULL.
2264    */
2265   struct GNUNET_PEERSTORE_IterateContext *get;
2266
2267   /**
2268    * Handle to a PEERSTORE store operation for this @e pid's @e
2269    * monotonic_time.  NULL if no PEERSTORE operation is pending.
2270    */
2271   struct GNUNET_PEERSTORE_StoreContext *sc;
2272
2273   /**
2274    * Number of bytes of the original message body that follows after this
2275    * struct.
2276    */
2277   size_t body_size;
2278 };
2279
2280
2281 /**
2282  * Head of linked list of all clients to this service.
2283  */
2284 static struct TransportClient *clients_head;
2285
2286 /**
2287  * Tail of linked list of all clients to this service.
2288  */
2289 static struct TransportClient *clients_tail;
2290
2291 /**
2292  * Statistics handle.
2293  */
2294 static struct GNUNET_STATISTICS_Handle *GST_stats;
2295
2296 /**
2297  * Configuration handle.
2298  */
2299 static const struct GNUNET_CONFIGURATION_Handle *GST_cfg;
2300
2301 /**
2302  * Our public key.
2303  */
2304 static struct GNUNET_PeerIdentity GST_my_identity;
2305
2306 /**
2307  * Our private key.
2308  */
2309 static struct GNUNET_CRYPTO_EddsaPrivateKey *GST_my_private_key;
2310
2311 /**
2312  * Map from PIDs to `struct Neighbour` entries.  A peer is
2313  * a neighbour if we have an MQ to it from some communicator.
2314  */
2315 static struct GNUNET_CONTAINER_MultiPeerMap *neighbours;
2316
2317 /**
2318  * Map from PIDs to `struct Backtalker` entries.  A peer is
2319  * a backtalker if it recently send us backchannel messages.
2320  */
2321 static struct GNUNET_CONTAINER_MultiPeerMap *backtalkers;
2322
2323 /**
2324  * Map from PIDs to `struct AcknowledgementCummulator`s.
2325  * Here we track the cummulative ACKs for transmission.
2326  */
2327 static struct GNUNET_CONTAINER_MultiPeerMap *ack_cummulators;
2328
2329 /**
2330  * Map of pending acknowledgements, mapping `struct AcknowledgementUUID` to
2331  * a `struct PendingAcknowledgement`.
2332  */
2333 static struct GNUNET_CONTAINER_MultiShortmap *pending_acks;
2334
2335 /**
2336  * Map from PIDs to `struct DistanceVector` entries describing
2337  * known paths to the peer.
2338  */
2339 static struct GNUNET_CONTAINER_MultiPeerMap *dv_routes;
2340
2341 /**
2342  * Map from PIDs to `struct ValidationState` entries describing
2343  * addresses we are aware of and their validity state.
2344  */
2345 static struct GNUNET_CONTAINER_MultiPeerMap *validation_map;
2346
2347 /**
2348  * Map from challenges to `struct LearnLaunchEntry` values.
2349  */
2350 static struct GNUNET_CONTAINER_MultiShortmap *dvlearn_map;
2351
2352 /**
2353  * Head of a DLL sorted by launch time.
2354  */
2355 static struct LearnLaunchEntry *lle_head;
2356
2357 /**
2358  * Tail of a DLL sorted by launch time.
2359  */
2360 static struct LearnLaunchEntry *lle_tail;
2361
2362 /**
2363  * MIN Heap sorted by "next_challenge" to `struct ValidationState` entries
2364  * sorting addresses we are aware of by when we should next try to (re)validate
2365  * (or expire) them.
2366  */
2367 static struct GNUNET_CONTAINER_Heap *validation_heap;
2368
2369 /**
2370  * Database for peer's HELLOs.
2371  */
2372 static struct GNUNET_PEERSTORE_Handle *peerstore;
2373
2374 /**
2375  * Heap sorting `struct EphemeralCacheEntry` by their
2376  * key/signature validity.
2377  */
2378 static struct GNUNET_CONTAINER_Heap *ephemeral_heap;
2379
2380 /**
2381  * Hash map for looking up `struct EphemeralCacheEntry`s
2382  * by peer identity. (We may have ephemerals in our
2383  * cache for which we do not have a neighbour entry,
2384  * and similar many neighbours may not need ephemerals,
2385  * so we use a second map.)
2386  */
2387 static struct GNUNET_CONTAINER_MultiPeerMap *ephemeral_map;
2388
2389 /**
2390  * Task to free expired ephemerals.
2391  */
2392 static struct GNUNET_SCHEDULER_Task *ephemeral_task;
2393
2394 /**
2395  * Task run to initiate DV learning.
2396  */
2397 static struct GNUNET_SCHEDULER_Task *dvlearn_task;
2398
2399 /**
2400  * Task to run address validation.
2401  */
2402 static struct GNUNET_SCHEDULER_Task *validation_task;
2403
2404 /**
2405  * The most recent PA we have created, head of DLL.
2406  * The length of the DLL is kept in #pa_count.
2407  */
2408 static struct PendingAcknowledgement *pa_head;
2409
2410 /**
2411  * The oldest PA we have created, tail of DLL.
2412  * The length of the DLL is kept in #pa_count.
2413  */
2414 static struct PendingAcknowledgement *pa_tail;
2415
2416 /**
2417  * Number of entries in the #pa_head/#pa_tail DLL.  Used to
2418  * limit the size of the data structure.
2419  */
2420 static unsigned int pa_count;
2421
2422
2423 /**
2424  * Get an offset into the transmission history buffer for `struct
2425  * PerformanceData`.  Note that the caller must perform the required
2426  * modulo #GOODPUT_AGING_SLOTS operation before indexing into the
2427  * array!
2428  *
2429  * An 'age' lasts 15 minute slots.
2430  *
2431  * @return current age of the world
2432  */
2433 static unsigned int
2434 get_age ()
2435 {
2436   struct GNUNET_TIME_Absolute now;
2437
2438   now = GNUNET_TIME_absolute_get ();
2439   return now.abs_value_us / GNUNET_TIME_UNIT_MINUTES.rel_value_us / 15;
2440 }
2441
2442
2443 /**
2444  * Release @a pa data structure.
2445  *
2446  * @param pa data structure to release
2447  */
2448 static void
2449 free_pending_acknowledgement (struct PendingAcknowledgement *pa)
2450 {
2451   struct Queue *q = pa->queue;
2452   struct PendingMessage *pm = pa->pm;
2453   struct DistanceVectorHop *dvh = pa->dvh;
2454
2455   GNUNET_CONTAINER_MDLL_remove (pa, pa_head, pa_tail, pa);
2456   pa_count--;
2457   if (NULL != q)
2458   {
2459     GNUNET_CONTAINER_MDLL_remove (queue, q->pa_head, q->pa_tail, pa);
2460     pa->queue = NULL;
2461   }
2462   if (NULL != pm)
2463   {
2464     GNUNET_CONTAINER_MDLL_remove (pm, pm->pa_head, pm->pa_tail, pa);
2465     pa->pm = NULL;
2466   }
2467   if (NULL != dvh)
2468   {
2469     GNUNET_CONTAINER_MDLL_remove (dvh, dvh->pa_head, dvh->pa_tail, pa);
2470     pa->queue = NULL;
2471   }
2472   GNUNET_assert (GNUNET_YES ==
2473                  GNUNET_CONTAINER_multishortmap_remove (pending_acks,
2474                                                         &pa->ack_uuid.value,
2475                                                         pa));
2476   GNUNET_free (pa);
2477 }
2478
2479
2480 /**
2481  * Free cached ephemeral key.
2482  *
2483  * @param ece cached signature to free
2484  */
2485 static void
2486 free_ephemeral (struct EphemeralCacheEntry *ece)
2487 {
2488   GNUNET_CONTAINER_multipeermap_remove (ephemeral_map, &ece->target, ece);
2489   GNUNET_CONTAINER_heap_remove_node (ece->hn);
2490   GNUNET_free (ece);
2491 }
2492
2493
2494 /**
2495  * Free validation state.
2496  *
2497  * @param vs validation state to free
2498  */
2499 static void
2500 free_validation_state (struct ValidationState *vs)
2501 {
2502   GNUNET_CONTAINER_multipeermap_remove (validation_map, &vs->pid, vs);
2503   GNUNET_CONTAINER_heap_remove_node (vs->hn);
2504   vs->hn = NULL;
2505   if (NULL != vs->sc)
2506   {
2507     GNUNET_PEERSTORE_store_cancel (vs->sc);
2508     vs->sc = NULL;
2509   }
2510   GNUNET_free (vs->address);
2511   GNUNET_free (vs);
2512 }
2513
2514
2515 /**
2516  * Lookup neighbour record for peer @a pid.
2517  *
2518  * @param pid neighbour to look for
2519  * @return NULL if we do not have this peer as a neighbour
2520  */
2521 static struct Neighbour *
2522 lookup_neighbour (const struct GNUNET_PeerIdentity *pid)
2523 {
2524   return GNUNET_CONTAINER_multipeermap_get (neighbours, pid);
2525 }
2526
2527
2528 /**
2529  * Details about what to notify monitors about.
2530  */
2531 struct MonitorEvent
2532 {
2533   /**
2534    * @deprecated To be discussed if we keep these...
2535    */
2536   struct GNUNET_TIME_Absolute last_validation;
2537   struct GNUNET_TIME_Absolute valid_until;
2538   struct GNUNET_TIME_Absolute next_validation;
2539
2540   /**
2541    * Current round-trip time estimate.
2542    */
2543   struct GNUNET_TIME_Relative rtt;
2544
2545   /**
2546    * Connection status.
2547    */
2548   enum GNUNET_TRANSPORT_ConnectionStatus cs;
2549
2550   /**
2551    * Messages pending.
2552    */
2553   uint32_t num_msg_pending;
2554
2555   /**
2556    * Bytes pending.
2557    */
2558   uint32_t num_bytes_pending;
2559 };
2560
2561
2562 /**
2563  * Free a @dvh. Callers MAY want to check if this was the last path to the
2564  * `target`, and if so call #free_dv_route to also free the associated DV
2565  * entry in #dv_routes (if not, the associated scheduler job should eventually
2566  * take care of it).
2567  *
2568  * @param dvh hop to free
2569  */
2570 static void
2571 free_distance_vector_hop (struct DistanceVectorHop *dvh)
2572 {
2573   struct Neighbour *n = dvh->next_hop;
2574   struct DistanceVector *dv = dvh->dv;
2575   struct PendingAcknowledgement *pa;
2576
2577   while (NULL != (pa = dvh->pa_head))
2578   {
2579     GNUNET_CONTAINER_MDLL_remove (dvh, dvh->pa_head, dvh->pa_tail, pa);
2580     pa->dvh = NULL;
2581   }
2582   GNUNET_CONTAINER_MDLL_remove (neighbour, n->dv_head, n->dv_tail, dvh);
2583   GNUNET_CONTAINER_MDLL_remove (dv, dv->dv_head, dv->dv_tail, dvh);
2584   GNUNET_free (dvh);
2585 }
2586
2587
2588 /**
2589  * Free entry in #dv_routes.  First frees all hops to the target, and
2590  * if there are no entries left, frees @a dv as well.
2591  *
2592  * @param dv route to free
2593  */
2594 static void
2595 free_dv_route (struct DistanceVector *dv)
2596 {
2597   struct DistanceVectorHop *dvh;
2598
2599   while (NULL != (dvh = dv->dv_head))
2600     free_distance_vector_hop (dvh);
2601   if (NULL == dv->dv_head)
2602   {
2603     GNUNET_assert (
2604       GNUNET_YES ==
2605       GNUNET_CONTAINER_multipeermap_remove (dv_routes, &dv->target, dv));
2606     if (NULL != dv->visibility_task)
2607       GNUNET_SCHEDULER_cancel (dv->visibility_task);
2608     if (NULL != dv->timeout_task)
2609       GNUNET_SCHEDULER_cancel (dv->timeout_task);
2610     GNUNET_free (dv);
2611   }
2612 }
2613
2614
2615 /**
2616  * Notify monitor @a tc about an event.  That @a tc
2617  * cares about the event has already been checked.
2618  *
2619  * Send @a tc information in @a me about a @a peer's status with
2620  * respect to some @a address to all monitors that care.
2621  *
2622  * @param tc monitor to inform
2623  * @param peer peer the information is about
2624  * @param address address the information is about
2625  * @param nt network type associated with @a address
2626  * @param me detailed information to transmit
2627  */
2628 static void
2629 notify_monitor (struct TransportClient *tc,
2630                 const struct GNUNET_PeerIdentity *peer,
2631                 const char *address,
2632                 enum GNUNET_NetworkType nt,
2633                 const struct MonitorEvent *me)
2634 {
2635   struct GNUNET_MQ_Envelope *env;
2636   struct GNUNET_TRANSPORT_MonitorData *md;
2637   size_t addr_len = strlen (address) + 1;
2638
2639   env = GNUNET_MQ_msg_extra (md,
2640                              addr_len,
2641                              GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_DATA);
2642   md->nt = htonl ((uint32_t) nt);
2643   md->peer = *peer;
2644   md->last_validation = GNUNET_TIME_absolute_hton (me->last_validation);
2645   md->valid_until = GNUNET_TIME_absolute_hton (me->valid_until);
2646   md->next_validation = GNUNET_TIME_absolute_hton (me->next_validation);
2647   md->rtt = GNUNET_TIME_relative_hton (me->rtt);
2648   md->cs = htonl ((uint32_t) me->cs);
2649   md->num_msg_pending = htonl (me->num_msg_pending);
2650   md->num_bytes_pending = htonl (me->num_bytes_pending);
2651   memcpy (&md[1], address, addr_len);
2652   GNUNET_MQ_send (tc->mq, env);
2653 }
2654
2655
2656 /**
2657  * Send information in @a me about a @a peer's status with respect
2658  * to some @a address to all monitors that care.
2659  *
2660  * @param peer peer the information is about
2661  * @param address address the information is about
2662  * @param nt network type associated with @a address
2663  * @param me detailed information to transmit
2664  */
2665 static void
2666 notify_monitors (const struct GNUNET_PeerIdentity *peer,
2667                  const char *address,
2668                  enum GNUNET_NetworkType nt,
2669                  const struct MonitorEvent *me)
2670 {
2671   for (struct TransportClient *tc = clients_head; NULL != tc; tc = tc->next)
2672   {
2673     if (CT_MONITOR != tc->type)
2674       continue;
2675     if (tc->details.monitor.one_shot)
2676       continue;
2677     if ((0 != GNUNET_is_zero (&tc->details.monitor.peer)) &&
2678         (0 != GNUNET_memcmp (&tc->details.monitor.peer, peer)))
2679       continue;
2680     notify_monitor (tc, peer, address, nt, me);
2681   }
2682 }
2683
2684
2685 /**
2686  * Called whenever a client connects.  Allocates our
2687  * data structures associated with that client.
2688  *
2689  * @param cls closure, NULL
2690  * @param client identification of the client
2691  * @param mq message queue for the client
2692  * @return our `struct TransportClient`
2693  */
2694 static void *
2695 client_connect_cb (void *cls,
2696                    struct GNUNET_SERVICE_Client *client,
2697                    struct GNUNET_MQ_Handle *mq)
2698 {
2699   struct TransportClient *tc;
2700
2701   (void) cls;
2702   tc = GNUNET_new (struct TransportClient);
2703   tc->client = client;
2704   tc->mq = mq;
2705   GNUNET_CONTAINER_DLL_insert (clients_head, clients_tail, tc);
2706   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p connected\n", tc);
2707   return tc;
2708 }
2709
2710
2711 /**
2712  * Free @a rc
2713  *
2714  * @param rc data structure to free
2715  */
2716 static void
2717 free_reassembly_context (struct ReassemblyContext *rc)
2718 {
2719   struct Neighbour *n = rc->neighbour;
2720
2721   GNUNET_assert (rc == GNUNET_CONTAINER_heap_remove_node (rc->hn));
2722   GNUNET_assert (GNUNET_OK ==
2723                  GNUNET_CONTAINER_multihashmap32_remove (n->reassembly_map,
2724                                                          rc->msg_uuid.uuid,
2725                                                          rc));
2726   GNUNET_free (rc);
2727 }
2728
2729
2730 /**
2731  * Task run to clean up reassembly context of a neighbour that have expired.
2732  *
2733  * @param cls a `struct Neighbour`
2734  */
2735 static void
2736 reassembly_cleanup_task (void *cls)
2737 {
2738   struct Neighbour *n = cls;
2739   struct ReassemblyContext *rc;
2740
2741   n->reassembly_timeout_task = NULL;
2742   while (NULL != (rc = GNUNET_CONTAINER_heap_peek (n->reassembly_heap)))
2743   {
2744     if (0 == GNUNET_TIME_absolute_get_remaining (rc->reassembly_timeout)
2745                .rel_value_us)
2746     {
2747       free_reassembly_context (rc);
2748       continue;
2749     }
2750     GNUNET_assert (NULL == n->reassembly_timeout_task);
2751     n->reassembly_timeout_task =
2752       GNUNET_SCHEDULER_add_at (rc->reassembly_timeout,
2753                                &reassembly_cleanup_task,
2754                                n);
2755     return;
2756   }
2757 }
2758
2759
2760 /**
2761  * function called to #free_reassembly_context().
2762  *
2763  * @param cls NULL
2764  * @param key unused
2765  * @param value a `struct ReassemblyContext` to free
2766  * @return #GNUNET_OK (continue iteration)
2767  */
2768 static int
2769 free_reassembly_cb (void *cls, uint32_t key, void *value)
2770 {
2771   struct ReassemblyContext *rc = value;
2772
2773   (void) cls;
2774   (void) key;
2775   free_reassembly_context (rc);
2776   return GNUNET_OK;
2777 }
2778
2779
2780 /**
2781  * Release memory used by @a neighbour.
2782  *
2783  * @param neighbour neighbour entry to free
2784  */
2785 static void
2786 free_neighbour (struct Neighbour *neighbour)
2787 {
2788   struct DistanceVectorHop *dvh;
2789
2790   GNUNET_assert (NULL == neighbour->queue_head);
2791   GNUNET_assert (GNUNET_YES ==
2792                  GNUNET_CONTAINER_multipeermap_remove (neighbours,
2793                                                        &neighbour->pid,
2794                                                        neighbour));
2795   if (NULL != neighbour->timeout_task)
2796     GNUNET_SCHEDULER_cancel (neighbour->timeout_task);
2797   if (NULL != neighbour->reassembly_map)
2798   {
2799     GNUNET_CONTAINER_multihashmap32_iterate (neighbour->reassembly_map,
2800                                              &free_reassembly_cb,
2801                                              NULL);
2802     GNUNET_CONTAINER_multihashmap32_destroy (neighbour->reassembly_map);
2803     neighbour->reassembly_map = NULL;
2804     GNUNET_CONTAINER_heap_destroy (neighbour->reassembly_heap);
2805     neighbour->reassembly_heap = NULL;
2806   }
2807   while (NULL != (dvh = neighbour->dv_head))
2808   {
2809     struct DistanceVector *dv = dvh->dv;
2810
2811     free_distance_vector_hop (dvh);
2812     if (NULL == dv->dv_head)
2813       free_dv_route (dv);
2814   }
2815   if (NULL != neighbour->reassembly_timeout_task)
2816     GNUNET_SCHEDULER_cancel (neighbour->reassembly_timeout_task);
2817   GNUNET_free (neighbour);
2818 }
2819
2820
2821 /**
2822  * Send message to CORE clients that we lost a connection.
2823  *
2824  * @param tc client to inform (must be CORE client)
2825  * @param pid peer the connection is for
2826  * @param quota_out current quota for the peer
2827  */
2828 static void
2829 core_send_connect_info (struct TransportClient *tc,
2830                         const struct GNUNET_PeerIdentity *pid,
2831                         struct GNUNET_BANDWIDTH_Value32NBO quota_out)
2832 {
2833   struct GNUNET_MQ_Envelope *env;
2834   struct ConnectInfoMessage *cim;
2835
2836   GNUNET_assert (CT_CORE == tc->type);
2837   env = GNUNET_MQ_msg (cim, GNUNET_MESSAGE_TYPE_TRANSPORT_CONNECT);
2838   cim->quota_out = quota_out;
2839   cim->id = *pid;
2840   GNUNET_MQ_send (tc->mq, env);
2841 }
2842
2843
2844 /**
2845  * Send message to CORE clients that we gained a connection
2846  *
2847  * @param pid peer the queue was for
2848  * @param quota_out current quota for the peer
2849  */
2850 static void
2851 cores_send_connect_info (const struct GNUNET_PeerIdentity *pid,
2852                          struct GNUNET_BANDWIDTH_Value32NBO quota_out)
2853 {
2854   for (struct TransportClient *tc = clients_head; NULL != tc; tc = tc->next)
2855   {
2856     if (CT_CORE != tc->type)
2857       continue;
2858     core_send_connect_info (tc, pid, quota_out);
2859   }
2860 }
2861
2862
2863 /**
2864  * Send message to CORE clients that we lost a connection.
2865  *
2866  * @param pid peer the connection was for
2867  */
2868 static void
2869 cores_send_disconnect_info (const struct GNUNET_PeerIdentity *pid)
2870 {
2871   for (struct TransportClient *tc = clients_head; NULL != tc; tc = tc->next)
2872   {
2873     struct GNUNET_MQ_Envelope *env;
2874     struct DisconnectInfoMessage *dim;
2875
2876     if (CT_CORE != tc->type)
2877       continue;
2878     env = GNUNET_MQ_msg (dim, GNUNET_MESSAGE_TYPE_TRANSPORT_DISCONNECT);
2879     dim->peer = *pid;
2880     GNUNET_MQ_send (tc->mq, env);
2881   }
2882 }
2883
2884
2885 /**
2886  * We believe we are ready to transmit a message on a queue. Double-checks
2887  * with the queue's "tracker_out" and then gives the message to the
2888  * communicator for transmission (updating the tracker, and re-scheduling
2889  * itself if applicable).
2890  *
2891  * @param cls the `struct Queue` to process transmissions for
2892  */
2893 static void
2894 transmit_on_queue (void *cls);
2895
2896
2897 /**
2898  * Schedule next run of #transmit_on_queue().  Does NOTHING if
2899  * we should run immediately or if the message queue is empty.
2900  * Test for no task being added AND queue not being empty to
2901  * transmit immediately afterwards!  This function must only
2902  * be called if the message queue is non-empty!
2903  *
2904  * @param queue the queue to do scheduling for
2905  * @param inside_job set to #GNUNET_YES if called from
2906  *            #transmit_on_queue() itself and NOT setting
2907  *            the task means running immediately
2908  */
2909 static void
2910 schedule_transmit_on_queue (struct Queue *queue, int inside_job)
2911 {
2912   struct Neighbour *n = queue->neighbour;
2913   struct PendingMessage *pm = n->pending_msg_head;
2914   struct GNUNET_TIME_Relative out_delay;
2915   unsigned int wsize;
2916
2917   GNUNET_assert (NULL != pm);
2918   if (queue->tc->details.communicator.total_queue_length >=
2919       COMMUNICATOR_TOTAL_QUEUE_LIMIT)
2920   {
2921     GNUNET_STATISTICS_update (
2922       GST_stats,
2923       "# Transmission throttled due to communicator queue limit",
2924       1,
2925       GNUNET_NO);
2926     return;
2927   }
2928   if (queue->queue_length >= QUEUE_LENGTH_LIMIT)
2929   {
2930     GNUNET_STATISTICS_update (GST_stats,
2931                               "# Transmission throttled due to queue queue limit",
2932                               1,
2933                               GNUNET_NO);
2934     return;
2935   }
2936
2937   wsize = (0 == queue->mtu) ? pm->bytes_msg /* FIXME: add overheads? */
2938                             : queue->mtu;
2939   out_delay = GNUNET_BANDWIDTH_tracker_get_delay (&queue->tracker_out, wsize);
2940   out_delay = GNUNET_TIME_relative_max (GNUNET_TIME_absolute_get_remaining (
2941                                           pm->next_attempt),
2942                                         out_delay);
2943   if ((GNUNET_YES == inside_job) && (0 == out_delay.rel_value_us))
2944     return; /* we should run immediately! */
2945   /* queue has changed since we were scheduled, reschedule again */
2946   queue->transmit_task =
2947     GNUNET_SCHEDULER_add_delayed (out_delay, &transmit_on_queue, queue);
2948   if (out_delay.rel_value_us > DELAY_WARN_THRESHOLD.rel_value_us)
2949     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2950                 "Next transmission on queue `%s' in %s (high delay)\n",
2951                 queue->address,
2952                 GNUNET_STRINGS_relative_time_to_string (out_delay, GNUNET_YES));
2953   else
2954     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2955                 "Next transmission on queue `%s' in %s\n",
2956                 queue->address,
2957                 GNUNET_STRINGS_relative_time_to_string (out_delay, GNUNET_YES));
2958 }
2959
2960
2961 /**
2962  * Check whether the CORE visibility of @a n changed. If so,
2963  * check whether we need to notify CORE.
2964  *
2965  * @param n neighbour to perform the check for
2966  */
2967 static void
2968 update_neighbour_core_visibility (struct Neighbour *n);
2969
2970
2971 /**
2972  * Free @a queue.
2973  *
2974  * @param queue the queue to free
2975  */
2976 static void
2977 free_queue (struct Queue *queue)
2978 {
2979   struct Neighbour *neighbour = queue->neighbour;
2980   struct TransportClient *tc = queue->tc;
2981   struct MonitorEvent me = {.cs = GNUNET_TRANSPORT_CS_DOWN,
2982                             .rtt = GNUNET_TIME_UNIT_FOREVER_REL};
2983   struct QueueEntry *qe;
2984   int maxxed;
2985   struct PendingAcknowledgement *pa;
2986
2987   if (NULL != queue->transmit_task)
2988   {
2989     GNUNET_SCHEDULER_cancel (queue->transmit_task);
2990     queue->transmit_task = NULL;
2991   }
2992   if (NULL != queue->visibility_task)
2993   {
2994     GNUNET_SCHEDULER_cancel (queue->visibility_task);
2995     queue->visibility_task = NULL;
2996   }
2997   while (NULL != (pa = queue->pa_head))
2998   {
2999     GNUNET_CONTAINER_MDLL_remove (queue, queue->pa_head, queue->pa_tail, pa);
3000     pa->queue = NULL;
3001   }
3002
3003   GNUNET_CONTAINER_MDLL_remove (neighbour,
3004                                 neighbour->queue_head,
3005                                 neighbour->queue_tail,
3006                                 queue);
3007   GNUNET_CONTAINER_MDLL_remove (client,
3008                                 tc->details.communicator.queue_head,
3009                                 tc->details.communicator.queue_tail,
3010                                 queue);
3011   maxxed = (COMMUNICATOR_TOTAL_QUEUE_LIMIT >=
3012             tc->details.communicator.total_queue_length);
3013   while (NULL != (qe = queue->queue_head))
3014   {
3015     GNUNET_CONTAINER_DLL_remove (queue->queue_head, queue->queue_tail, qe);
3016     queue->queue_length--;
3017     tc->details.communicator.total_queue_length--;
3018     if (NULL != qe->pm)
3019     {
3020       GNUNET_assert (qe == qe->pm->qe);
3021       qe->pm->qe = NULL;
3022     }
3023     GNUNET_free (qe);
3024   }
3025   GNUNET_assert (0 == queue->queue_length);
3026   if ((maxxed) && (COMMUNICATOR_TOTAL_QUEUE_LIMIT <
3027                    tc->details.communicator.total_queue_length))
3028   {
3029     /* Communicator dropped below threshold, resume all queues */
3030     GNUNET_STATISTICS_update (
3031       GST_stats,
3032       "# Transmission throttled due to communicator queue limit",
3033       -1,
3034       GNUNET_NO);
3035     for (struct Queue *s = tc->details.communicator.queue_head; NULL != s;
3036          s = s->next_client)
3037       schedule_transmit_on_queue (s, GNUNET_NO);
3038   }
3039   notify_monitors (&neighbour->pid, queue->address, queue->nt, &me);
3040   GNUNET_BANDWIDTH_tracker_notification_stop (&queue->tracker_in);
3041   GNUNET_BANDWIDTH_tracker_notification_stop (&queue->tracker_out);
3042   GNUNET_free (queue);
3043
3044   update_neighbour_core_visibility (neighbour);
3045   cores_send_disconnect_info (&neighbour->pid);
3046
3047   if (NULL == neighbour->queue_head)
3048   {
3049     free_neighbour (neighbour);
3050   }
3051 }
3052
3053
3054 /**
3055  * Free @a ale
3056  *
3057  * @param ale address list entry to free
3058  */
3059 static void
3060 free_address_list_entry (struct AddressListEntry *ale)
3061 {
3062   struct TransportClient *tc = ale->tc;
3063
3064   GNUNET_CONTAINER_DLL_remove (tc->details.communicator.addr_head,
3065                                tc->details.communicator.addr_tail,
3066                                ale);
3067   if (NULL != ale->sc)
3068   {
3069     GNUNET_PEERSTORE_store_cancel (ale->sc);
3070     ale->sc = NULL;
3071   }
3072   if (NULL != ale->st)
3073   {
3074     GNUNET_SCHEDULER_cancel (ale->st);
3075     ale->st = NULL;
3076   }
3077   GNUNET_free (ale);
3078 }
3079
3080
3081 /**
3082  * Stop the peer request in @a value.
3083  *
3084  * @param cls a `struct TransportClient` that no longer makes the request
3085  * @param pid the peer's identity
3086  * @param value a `struct PeerRequest`
3087  * @return #GNUNET_YES (always)
3088  */
3089 static int
3090 stop_peer_request (void *cls,
3091                    const struct GNUNET_PeerIdentity *pid,
3092                    void *value)
3093 {
3094   struct TransportClient *tc = cls;
3095   struct PeerRequest *pr = value;
3096
3097   GNUNET_PEERSTORE_watch_cancel (pr->wc);
3098   GNUNET_assert (
3099     GNUNET_YES ==
3100     GNUNET_CONTAINER_multipeermap_remove (tc->details.application.requests,
3101                                           pid,
3102                                           pr));
3103   GNUNET_free (pr);
3104
3105   return GNUNET_OK;
3106 }
3107
3108
3109 /**
3110  * Called whenever a client is disconnected.  Frees our
3111  * resources associated with that client.
3112  *
3113  * @param cls closure, NULL
3114  * @param client identification of the client
3115  * @param app_ctx our `struct TransportClient`
3116  */
3117 static void
3118 client_disconnect_cb (void *cls,
3119                       struct GNUNET_SERVICE_Client *client,
3120                       void *app_ctx)
3121 {
3122   struct TransportClient *tc = app_ctx;
3123
3124   (void) cls;
3125   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3126               "Client %p disconnected, cleaning up.\n",
3127               tc);
3128   GNUNET_CONTAINER_DLL_remove (clients_head, clients_tail, tc);
3129   switch (tc->type)
3130   {
3131   case CT_NONE:
3132     break;
3133   case CT_CORE: {
3134     struct PendingMessage *pm;
3135
3136     while (NULL != (pm = tc->details.core.pending_msg_head))
3137     {
3138       GNUNET_CONTAINER_MDLL_remove (client,
3139                                     tc->details.core.pending_msg_head,
3140                                     tc->details.core.pending_msg_tail,
3141                                     pm);
3142       pm->client = NULL;
3143     }
3144   }
3145   break;
3146   case CT_MONITOR:
3147     break;
3148   case CT_COMMUNICATOR: {
3149     struct Queue *q;
3150     struct AddressListEntry *ale;
3151
3152     while (NULL != (q = tc->details.communicator.queue_head))
3153       free_queue (q);
3154     while (NULL != (ale = tc->details.communicator.addr_head))
3155       free_address_list_entry (ale);
3156     GNUNET_free (tc->details.communicator.address_prefix);
3157   }
3158   break;
3159   case CT_APPLICATION:
3160     GNUNET_CONTAINER_multipeermap_iterate (tc->details.application.requests,
3161                                            &stop_peer_request,
3162                                            tc);
3163     GNUNET_CONTAINER_multipeermap_destroy (tc->details.application.requests);
3164     break;
3165   }
3166   GNUNET_free (tc);
3167 }
3168
3169
3170 /**
3171  * Iterator telling new CORE client about all existing
3172  * connections to peers.
3173  *
3174  * @param cls the new `struct TransportClient`
3175  * @param pid a connected peer
3176  * @param value the `struct Neighbour` with more information
3177  * @return #GNUNET_OK (continue to iterate)
3178  */
3179 static int
3180 notify_client_connect_info (void *cls,
3181                             const struct GNUNET_PeerIdentity *pid,
3182                             void *value)
3183 {
3184   struct TransportClient *tc = cls;
3185   struct Neighbour *neighbour = value;
3186
3187   core_send_connect_info (tc, pid, neighbour->quota_out);
3188   return GNUNET_OK;
3189 }
3190
3191
3192 /**
3193  * Initialize a "CORE" client.  We got a start message from this
3194  * client, so add it to the list of clients for broadcasting of
3195  * inbound messages.
3196  *
3197  * @param cls the client
3198  * @param start the start message that was sent
3199  */
3200 static void
3201 handle_client_start (void *cls, const struct StartMessage *start)
3202 {
3203   struct TransportClient *tc = cls;
3204   uint32_t options;
3205
3206   options = ntohl (start->options);
3207   if ((0 != (1 & options)) &&
3208       (0 != GNUNET_memcmp (&start->self, &GST_my_identity)))
3209   {
3210     /* client thinks this is a different peer, reject */
3211     GNUNET_break (0);
3212     GNUNET_SERVICE_client_drop (tc->client);
3213     return;
3214   }
3215   if (CT_NONE != tc->type)
3216   {
3217     GNUNET_break (0);
3218     GNUNET_SERVICE_client_drop (tc->client);
3219     return;
3220   }
3221   tc->type = CT_CORE;
3222   GNUNET_CONTAINER_multipeermap_iterate (neighbours,
3223                                          &notify_client_connect_info,
3224                                          tc);
3225   GNUNET_SERVICE_client_continue (tc->client);
3226 }
3227
3228
3229 /**
3230  * Client asked for transmission to a peer.  Process the request.
3231  *
3232  * @param cls the client
3233  * @param obm the send message that was sent
3234  */
3235 static int
3236 check_client_send (void *cls, const struct OutboundMessage *obm)
3237 {
3238   struct TransportClient *tc = cls;
3239   uint16_t size;
3240   const struct GNUNET_MessageHeader *obmm;
3241
3242   if (CT_CORE != tc->type)
3243   {
3244     GNUNET_break (0);
3245     return GNUNET_SYSERR;
3246   }
3247   size = ntohs (obm->header.size) - sizeof (struct OutboundMessage);
3248   if (size < sizeof (struct GNUNET_MessageHeader))
3249   {
3250     GNUNET_break (0);
3251     return GNUNET_SYSERR;
3252   }
3253   obmm = (const struct GNUNET_MessageHeader *) &obm[1];
3254   if (size != ntohs (obmm->size))
3255   {
3256     GNUNET_break (0);
3257     return GNUNET_SYSERR;
3258   }
3259   return GNUNET_OK;
3260 }
3261
3262
3263 /**
3264  * Free fragment tree below @e root, excluding @e root itself.
3265  * FIXME: this does NOT seem to have the intended semantics
3266  * based on how this is called. Seems we generally DO expect
3267  * @a root to be free'ed itself as well!
3268  *
3269  * @param root root of the tree to free
3270  */
3271 static void
3272 free_fragment_tree (struct PendingMessage *root)
3273 {
3274   struct PendingMessage *frag;
3275
3276   while (NULL != (frag = root->head_frag))
3277   {
3278     struct PendingAcknowledgement *pa;
3279
3280     free_fragment_tree (frag);
3281     while (NULL != (pa = frag->pa_head))
3282     {
3283       GNUNET_CONTAINER_MDLL_remove (pm, frag->pa_head, frag->pa_tail, pa);
3284       pa->pm = NULL;
3285     }
3286     GNUNET_CONTAINER_MDLL_remove (frag, root->head_frag, root->tail_frag, frag);
3287     GNUNET_free (frag);
3288   }
3289 }
3290
3291
3292 /**
3293  * Release memory associated with @a pm and remove @a pm from associated
3294  * data structures.  @a pm must be a top-level pending message and not
3295  * a fragment in the tree.  The entire tree is freed (if applicable).
3296  *
3297  * @param pm the pending message to free
3298  */
3299 static void
3300 free_pending_message (struct PendingMessage *pm)
3301 {
3302   struct TransportClient *tc = pm->client;
3303   struct Neighbour *target = pm->target;
3304   struct PendingAcknowledgement *pa;
3305
3306   if (NULL != tc)
3307   {
3308     GNUNET_CONTAINER_MDLL_remove (client,
3309                                   tc->details.core.pending_msg_head,
3310                                   tc->details.core.pending_msg_tail,
3311                                   pm);
3312   }
3313   GNUNET_CONTAINER_MDLL_remove (neighbour,
3314                                 target->pending_msg_head,
3315                                 target->pending_msg_tail,
3316                                 pm);
3317   while (NULL != (pa = pm->pa_head))
3318   {
3319     GNUNET_CONTAINER_MDLL_remove (pm, pm->pa_head, pm->pa_tail, pa);
3320     pa->pm = NULL;
3321   }
3322
3323   free_fragment_tree (pm);
3324   if (NULL != pm->qe)
3325   {
3326     GNUNET_assert (pm == pm->qe->pm);
3327     pm->qe->pm = NULL;
3328   }
3329   GNUNET_free_non_null (pm->bpm);
3330   GNUNET_free (pm);
3331 }
3332
3333
3334 /**
3335  * Send a response to the @a pm that we have processed a
3336  * "send" request with status @a success. We
3337  * transmitted @a bytes_physical on the actual wire.
3338  * Sends a confirmation to the "core" client responsible
3339  * for the original request and free's @a pm.
3340  *
3341  * @param pm handle to the original pending message
3342  * @param success status code, #GNUNET_OK on success, #GNUNET_SYSERR
3343  *          for transmission failure
3344  * @param bytes_physical amount of bandwidth consumed
3345  */
3346 static void
3347 client_send_response (struct PendingMessage *pm,
3348                       int success,
3349                       uint32_t bytes_physical)
3350 {
3351   struct TransportClient *tc = pm->client;
3352   struct Neighbour *target = pm->target;
3353   struct GNUNET_MQ_Envelope *env;
3354   struct SendOkMessage *som;
3355
3356   if (NULL != tc)
3357   {
3358     env = GNUNET_MQ_msg (som, GNUNET_MESSAGE_TYPE_TRANSPORT_SEND_OK);
3359     som->success = htonl ((uint32_t) success);
3360     som->bytes_msg = htons (pm->bytes_msg);
3361     som->bytes_physical = htonl (bytes_physical);
3362     som->peer = target->pid;
3363     GNUNET_MQ_send (tc->mq, env);
3364   }
3365   free_pending_message (pm);
3366 }
3367
3368
3369 /**
3370  * Checks the message queue for a neighbour for messages that have timed
3371  * out and purges them.
3372  *
3373  * @param cls a `struct Neighbour`
3374  */
3375 static void
3376 check_queue_timeouts (void *cls)
3377 {
3378   struct Neighbour *n = cls;
3379   struct PendingMessage *pm;
3380   struct GNUNET_TIME_Absolute now;
3381   struct GNUNET_TIME_Absolute earliest_timeout;
3382
3383   n->timeout_task = NULL;
3384   earliest_timeout = GNUNET_TIME_UNIT_FOREVER_ABS;
3385   now = GNUNET_TIME_absolute_get ();
3386   for (struct PendingMessage *pos = n->pending_msg_head; NULL != pos; pos = pm)
3387   {
3388     pm = pos->next_neighbour;
3389     if (pos->timeout.abs_value_us <= now.abs_value_us)
3390     {
3391       GNUNET_STATISTICS_update (GST_stats,
3392                                 "# messages dropped (timeout before confirmation)",
3393                                 1,
3394                                 GNUNET_NO);
3395       client_send_response (pm, GNUNET_NO, 0);
3396       continue;
3397     }
3398     earliest_timeout =
3399       GNUNET_TIME_absolute_min (earliest_timeout, pos->timeout);
3400   }
3401   n->earliest_timeout = earliest_timeout;
3402   if (NULL != n->pending_msg_head)
3403     n->timeout_task =
3404       GNUNET_SCHEDULER_add_at (earliest_timeout, &check_queue_timeouts, n);
3405 }
3406
3407
3408 /**
3409  * Client asked for transmission to a peer.  Process the request.
3410  *
3411  * @param cls the client
3412  * @param obm the send message that was sent
3413  */
3414 static void
3415 handle_client_send (void *cls, const struct OutboundMessage *obm)
3416 {
3417   struct TransportClient *tc = cls;
3418   struct PendingMessage *pm;
3419   const struct GNUNET_MessageHeader *obmm;
3420   struct Neighbour *target;
3421   uint32_t bytes_msg;
3422   int was_empty;
3423
3424   GNUNET_assert (CT_CORE == tc->type);
3425   obmm = (const struct GNUNET_MessageHeader *) &obm[1];
3426   bytes_msg = ntohs (obmm->size);
3427   target = lookup_neighbour (&obm->peer);
3428   if (NULL == target)
3429   {
3430     /* Failure: don't have this peer as a neighbour (anymore).
3431        Might have gone down asynchronously, so this is NOT
3432        a protocol violation by CORE. Still count the event,
3433        as this should be rare. */
3434     struct GNUNET_MQ_Envelope *env;
3435     struct SendOkMessage *som;
3436
3437     env = GNUNET_MQ_msg (som, GNUNET_MESSAGE_TYPE_TRANSPORT_SEND_OK);
3438     som->success = htonl (GNUNET_SYSERR);
3439     som->bytes_msg = htonl (bytes_msg);
3440     som->bytes_physical = htonl (0);
3441     som->peer = obm->peer;
3442     GNUNET_MQ_send (tc->mq, env);
3443     GNUNET_SERVICE_client_continue (tc->client);
3444     GNUNET_STATISTICS_update (GST_stats,
3445                               "# messages dropped (neighbour unknown)",
3446                               1,
3447                               GNUNET_NO);
3448     return;
3449   }
3450   was_empty = (NULL == target->pending_msg_head);
3451   pm = GNUNET_malloc (sizeof (struct PendingMessage) + bytes_msg);
3452   pm->client = tc;
3453   pm->target = target;
3454   pm->bytes_msg = bytes_msg;
3455   pm->timeout =
3456     GNUNET_TIME_relative_to_absolute (GNUNET_TIME_relative_ntoh (obm->timeout));
3457   memcpy (&pm[1], &obm[1], bytes_msg);
3458   GNUNET_CONTAINER_MDLL_insert (neighbour,
3459                                 target->pending_msg_head,
3460                                 target->pending_msg_tail,
3461                                 pm);
3462   GNUNET_CONTAINER_MDLL_insert (client,
3463                                 tc->details.core.pending_msg_head,
3464                                 tc->details.core.pending_msg_tail,
3465                                 pm);
3466   if (target->earliest_timeout.abs_value_us > pm->timeout.abs_value_us)
3467   {
3468     target->earliest_timeout.abs_value_us = pm->timeout.abs_value_us;
3469     if (NULL != target->timeout_task)
3470       GNUNET_SCHEDULER_cancel (target->timeout_task);
3471     target->timeout_task = GNUNET_SCHEDULER_add_at (target->earliest_timeout,
3472                                                     &check_queue_timeouts,
3473                                                     target);
3474   }
3475   if (! was_empty)
3476     return; /* all queues must already be busy */
3477   for (struct Queue *queue = target->queue_head; NULL != queue;
3478        queue = queue->next_neighbour)
3479   {
3480     /* try transmission on any queue that is idle */
3481     if (NULL == queue->transmit_task)
3482       queue->transmit_task =
3483         GNUNET_SCHEDULER_add_now (&transmit_on_queue, queue);
3484   }
3485 }
3486
3487
3488 /**
3489  * Communicator started.  Test message is well-formed.
3490  *
3491  * @param cls the client
3492  * @param cam the send message that was sent
3493  */
3494 static int
3495 check_communicator_available (
3496   void *cls,
3497   const struct GNUNET_TRANSPORT_CommunicatorAvailableMessage *cam)
3498 {
3499   struct TransportClient *tc = cls;
3500   uint16_t size;
3501
3502   if (CT_NONE != tc->type)
3503   {
3504     GNUNET_break (0);
3505     return GNUNET_SYSERR;
3506   }
3507   tc->type = CT_COMMUNICATOR;
3508   size = ntohs (cam->header.size) - sizeof (*cam);
3509   if (0 == size)
3510     return GNUNET_OK; /* receive-only communicator */
3511   GNUNET_MQ_check_zero_termination (cam);
3512   return GNUNET_OK;
3513 }
3514
3515
3516 /**
3517  * Communicator started.  Process the request.
3518  *
3519  * @param cls the client
3520  * @param cam the send message that was sent
3521  */
3522 static void
3523 handle_communicator_available (
3524   void *cls,
3525   const struct GNUNET_TRANSPORT_CommunicatorAvailableMessage *cam)
3526 {
3527   struct TransportClient *tc = cls;
3528   uint16_t size;
3529
3530   size = ntohs (cam->header.size) - sizeof (*cam);
3531   if (0 == size)
3532     return; /* receive-only communicator */
3533   tc->details.communicator.address_prefix =
3534     GNUNET_strdup ((const char *) &cam[1]);
3535   tc->details.communicator.cc =
3536     (enum GNUNET_TRANSPORT_CommunicatorCharacteristics) ntohl (cam->cc);
3537   GNUNET_SERVICE_client_continue (tc->client);
3538 }
3539
3540
3541 /**
3542  * Communicator requests backchannel transmission.  Check the request.
3543  *
3544  * @param cls the client
3545  * @param cb the send message that was sent
3546  * @return #GNUNET_OK if message is well-formed
3547  */
3548 static int
3549 check_communicator_backchannel (
3550   void *cls,
3551   const struct GNUNET_TRANSPORT_CommunicatorBackchannel *cb)
3552 {
3553   const struct GNUNET_MessageHeader *inbox;
3554   const char *is;
3555   uint16_t msize;
3556   uint16_t isize;
3557
3558   (void) cls;
3559   msize = ntohs (cb->header.size) - sizeof (*cb);
3560   if (UINT16_MAX - msize >
3561       sizeof (struct TransportBackchannelEncapsulationMessage) +
3562         sizeof (struct TransportBackchannelRequestPayloadP))
3563   {
3564     GNUNET_break (0);
3565     return GNUNET_SYSERR;
3566   }
3567   inbox = (const struct GNUNET_MessageHeader *) &cb[1];
3568   isize = ntohs (inbox->size);
3569   if (isize >= msize)
3570   {
3571     GNUNET_break (0);
3572     return GNUNET_SYSERR;
3573   }
3574   is = (const char *) inbox;
3575   is += isize;
3576   msize -= isize;
3577   GNUNET_assert (msize > 0);
3578   if ('\0' != is[msize - 1])
3579   {
3580     GNUNET_break (0);
3581     return GNUNET_SYSERR;
3582   }
3583   return GNUNET_OK;
3584 }
3585
3586
3587 /**
3588  * Remove memory used by expired ephemeral keys.
3589  *
3590  * @param cls NULL
3591  */
3592 static void
3593 expire_ephemerals (void *cls)
3594 {
3595   struct EphemeralCacheEntry *ece;
3596
3597   (void) cls;
3598   ephemeral_task = NULL;
3599   while (NULL != (ece = GNUNET_CONTAINER_heap_peek (ephemeral_heap)))
3600   {
3601     if (0 == GNUNET_TIME_absolute_get_remaining (ece->ephemeral_validity)
3602                .rel_value_us)
3603     {
3604       free_ephemeral (ece);
3605       continue;
3606     }
3607     ephemeral_task = GNUNET_SCHEDULER_add_at (ece->ephemeral_validity,
3608                                               &expire_ephemerals,
3609                                               NULL);
3610     return;
3611   }
3612 }
3613
3614
3615 /**
3616  * Lookup ephemeral key in our #ephemeral_map. If no valid one exists, generate
3617  * one, cache it and return it.
3618  *
3619  * @param pid peer to look up ephemeral for
3620  * @param private_key[out] set to the private key
3621  * @param ephemeral_key[out] set to the key
3622  * @param ephemeral_sender_sig[out] set to the signature
3623  * @param ephemeral_validity[out] set to the validity expiration time
3624  */
3625 static void
3626 lookup_ephemeral (const struct GNUNET_PeerIdentity *pid,
3627                   struct GNUNET_CRYPTO_EcdhePrivateKey *private_key,
3628                   struct GNUNET_CRYPTO_EcdhePublicKey *ephemeral_key,
3629                   struct GNUNET_CRYPTO_EddsaSignature *ephemeral_sender_sig,
3630                   struct GNUNET_TIME_Absolute *ephemeral_validity)
3631 {
3632   struct EphemeralCacheEntry *ece;
3633   struct EphemeralConfirmationPS ec;
3634
3635   ece = GNUNET_CONTAINER_multipeermap_get (ephemeral_map, pid);
3636   if ((NULL != ece) &&
3637       (0 == GNUNET_TIME_absolute_get_remaining (ece->ephemeral_validity)
3638               .rel_value_us))
3639   {
3640     free_ephemeral (ece);
3641     ece = NULL;
3642   }
3643   if (NULL == ece)
3644   {
3645     ece = GNUNET_new (struct EphemeralCacheEntry);
3646     ece->target = *pid;
3647     ece->ephemeral_validity =
3648       GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get_monotonic (GST_cfg),
3649                                 EPHEMERAL_VALIDITY);
3650     GNUNET_assert (GNUNET_OK ==
3651                    GNUNET_CRYPTO_ecdhe_key_create2 (&ece->private_key));
3652     GNUNET_CRYPTO_ecdhe_key_get_public (&ece->private_key, &ece->ephemeral_key);
3653     ec.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_EPHEMERAL);
3654     ec.purpose.size = htonl (sizeof (ec));
3655     ec.target = *pid;
3656     ec.ephemeral_key = ece->ephemeral_key;
3657     GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_eddsa_sign (GST_my_private_key,
3658                                                           &ec.purpose,
3659                                                           &ece->sender_sig));
3660     ece->hn =
3661       GNUNET_CONTAINER_heap_insert (ephemeral_heap,
3662                                     ece,
3663                                     ece->ephemeral_validity.abs_value_us);
3664     GNUNET_assert (GNUNET_OK ==
3665                    GNUNET_CONTAINER_multipeermap_put (
3666                      ephemeral_map,
3667                      &ece->target,
3668                      ece,
3669                      GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
3670     if (NULL == ephemeral_task)
3671       ephemeral_task = GNUNET_SCHEDULER_add_at (ece->ephemeral_validity,
3672                                                 &expire_ephemerals,
3673                                                 NULL);
3674   }
3675   *private_key = ece->private_key;
3676   *ephemeral_key = ece->ephemeral_key;
3677   *ephemeral_sender_sig = ece->sender_sig;
3678   *ephemeral_validity = ece->ephemeral_validity;
3679 }
3680
3681
3682 /**
3683  * Send the control message @a payload on @a queue.
3684  *
3685  * @param queue the queue to use for transmission
3686  * @param pm pending message to update once transmission is done, may be NULL!
3687  * @param payload the payload to send (encapsulated in a
3688  *        #GNUNET_MESSAGE_TYPE_TRANSPORT_SEND_MSG).
3689  * @param payload_size number of bytes in @a payload
3690  */
3691 static void
3692 queue_send_msg (struct Queue *queue,
3693                 struct PendingMessage *pm,
3694                 const void *payload,
3695                 size_t payload_size)
3696 {
3697   struct Neighbour *n = queue->neighbour;
3698   struct GNUNET_TRANSPORT_SendMessageTo *smt;
3699   struct GNUNET_MQ_Envelope *env;
3700
3701   env = GNUNET_MQ_msg_extra (smt,
3702                              payload_size,
3703                              GNUNET_MESSAGE_TYPE_TRANSPORT_SEND_MSG);
3704   smt->qid = queue->qid;
3705   smt->mid = queue->mid_gen;
3706   smt->receiver = n->pid;
3707   memcpy (&smt[1], payload, payload_size);
3708   {
3709     /* Pass the env to the communicator of queue for transmission. */
3710     struct QueueEntry *qe;
3711
3712     qe = GNUNET_new (struct QueueEntry);
3713     qe->mid = queue->mid_gen++;
3714     qe->queue = queue;
3715     if (NULL != pm)
3716     {
3717       qe->pm = pm;
3718       GNUNET_assert (NULL == pm->qe);
3719       pm->qe = qe;
3720     }
3721     GNUNET_CONTAINER_DLL_insert (queue->queue_head, queue->queue_tail, qe);
3722     GNUNET_assert (CT_COMMUNICATOR == queue->tc->type);
3723     queue->queue_length++;
3724     queue->tc->details.communicator.total_queue_length++;
3725     GNUNET_MQ_send (queue->tc->mq, env);
3726   }
3727 }
3728
3729
3730 /**
3731  * Which transmission options are allowable for transmission?
3732  * Interpreted bit-wise!
3733  */
3734 enum RouteMessageOptions
3735 {
3736   /**
3737    * Only confirmed, non-DV direct neighbours.
3738    */
3739   RMO_NONE = 0,
3740
3741   /**
3742    * We are allowed to use DV routing for this @a hdr
3743    */
3744   RMO_DV_ALLOWED = 1,
3745
3746   /**
3747    * We are allowed to use unconfirmed queues or DV routes for this message
3748    */
3749   RMO_UNCONFIRMED_ALLOWED = 2,
3750
3751   /**
3752    * Reliable and unreliable, DV and non-DV are all acceptable.
3753    */
3754   RMO_ANYTHING_GOES = (RMO_DV_ALLOWED | RMO_UNCONFIRMED_ALLOWED),
3755
3756   /**
3757    * If we have multiple choices, it is OK to send this message
3758    * over multiple channels at the same time to improve loss tolerance.
3759    * (We do at most 2 transmissions.)
3760    */
3761   RMO_REDUNDANT = 4
3762 };
3763
3764
3765 /**
3766  * Pick a queue of @a n under constraints @a options and schedule
3767  * transmission of @a hdr.
3768  *
3769  * @param n neighbour to send to
3770  * @param hdr message to send as payload
3771  * @param options whether queues must be confirmed or not,
3772  *        and whether we may pick multiple (2) queues
3773  */
3774 static void
3775 route_via_neighbour (const struct Neighbour *n,
3776                      const struct GNUNET_MessageHeader *hdr,
3777                      enum RouteMessageOptions options)
3778 {
3779   struct GNUNET_TIME_Absolute now;
3780   unsigned int candidates;
3781   unsigned int sel1;
3782   unsigned int sel2;
3783
3784   /* Pick one or two 'random' queues from n (under constraints of options) */
3785   now = GNUNET_TIME_absolute_get ();
3786   /* FIXME-OPTIMIZE: give queues 'weights' and pick proportional to
3787      weight in the future; weight could be assigned by observed
3788      bandwidth (note: not sure if we should do this for this type
3789      of control traffic though). */
3790   candidates = 0;
3791   for (struct Queue *pos = n->queue_head; NULL != pos;
3792        pos = pos->next_neighbour)
3793   {
3794     /* Count the queue with the visibility task in all cases, as
3795        otherwise we may end up with no queues just because the
3796        time for the visibility task just expired but the scheduler
3797        just ran this task first */
3798     if ((0 == (options & RMO_UNCONFIRMED_ALLOWED)) ||
3799         (pos->validated_until.abs_value_us > now.abs_value_us) ||
3800         (NULL != pos->visibility_task))
3801       candidates++;
3802   }
3803   if (0 == candidates)
3804   {
3805     /* Given that we above check for pos->visibility task,
3806        this should be strictly impossible. */
3807     GNUNET_break (0);
3808     return;
3809   }
3810   sel1 = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, candidates);
3811   if (0 == (options & RMO_REDUNDANT))
3812     sel2 = candidates; /* picks none! */
3813   else
3814     sel2 = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, candidates);
3815   candidates = 0;
3816   for (struct Queue *pos = n->queue_head; NULL != pos;
3817        pos = pos->next_neighbour)
3818   {
3819     /* Count the queue with the visibility task in all cases, as
3820        otherwise we may end up with no queues just because the
3821        time for the visibility task just expired but the scheduler
3822        just ran this task first */
3823     if ((pos->validated_until.abs_value_us > now.abs_value_us) ||
3824         (NULL != pos->visibility_task))
3825     {
3826       if ((sel1 == candidates) || (sel2 == candidates))
3827         queue_send_msg (pos, NULL, hdr, ntohs (hdr->size));
3828       candidates++;
3829     }
3830   }
3831 }
3832
3833
3834 /**
3835  * Given a distance vector path @a dvh route @a payload to
3836  * the ultimate destination respecting @a options.
3837  * Sets up the boxed message and queues it at the next hop.
3838  *
3839  * @param dvh choice of the path for the message
3840  * @param payload body to transmit
3841  * @param options options to use for control
3842  */
3843 static void
3844 forward_via_dvh (const struct DistanceVectorHop *dvh,
3845                  const struct GNUNET_MessageHeader *payload,
3846                  enum RouteMessageOptions options)
3847 {
3848   uint16_t mlen = ntohs (payload->size);
3849   char boxram[sizeof (struct TransportDVBoxMessage) +
3850               (dvh->distance + 1) * sizeof (struct GNUNET_PeerIdentity) +
3851               mlen] GNUNET_ALIGN;
3852   struct TransportDVBoxMessage *box = (struct TransportDVBoxMessage *) boxram;
3853   struct GNUNET_PeerIdentity *path = (struct GNUNET_PeerIdentity *) &box[1];
3854
3855   box->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_DV_BOX);
3856   box->header.size = htons (sizeof (boxram));
3857   box->total_hops = htons (0);
3858   box->num_hops = htons (dvh->distance + 1);
3859   box->origin = GST_my_identity;
3860   memcpy (path, dvh->path, dvh->distance * sizeof (struct GNUNET_PeerIdentity));
3861   path[dvh->distance] = dvh->dv->target;
3862   memcpy (&path[dvh->distance + 1], payload, mlen);
3863   route_via_neighbour (dvh->next_hop, &box->header, options);
3864 }
3865
3866
3867 /**
3868  * Pick a path of @a dv under constraints @a options and schedule
3869  * transmission of @a hdr.
3870  *
3871  * @param n neighbour to send to
3872  * @param hdr message to send as payload
3873  * @param options whether path must be confirmed or not
3874  *        and whether we may pick multiple (2) paths
3875  */
3876 static void
3877 route_via_dv (const struct DistanceVector *dv,
3878               const struct GNUNET_MessageHeader *hdr,
3879               enum RouteMessageOptions options)
3880 {
3881   struct DistanceVectorHop *h1;
3882   struct DistanceVectorHop *h2;
3883   uint64_t num_dv;
3884   uint64_t choice1;
3885   uint64_t choice2;
3886
3887   /* Pick random vectors, but weighted by distance, giving more weight
3888      to shorter vectors */
3889   num_dv = 0;
3890   for (struct DistanceVectorHop *pos = dv->dv_head; NULL != pos;
3891        pos = pos->next_dv)
3892   {
3893     if ((0 == (options & RMO_UNCONFIRMED_ALLOWED)) &&
3894         (GNUNET_TIME_absolute_get_remaining (pos->path_valid_until)
3895            .rel_value_us == 0))
3896       continue; /* pos unconfirmed and confirmed required */
3897     num_dv += MAX_DV_HOPS_ALLOWED - pos->distance;
3898   }
3899   if (0 == num_dv)
3900   {
3901     GNUNET_break (0);
3902     return;
3903   }
3904   choice1 = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, num_dv);
3905   choice2 = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, num_dv);
3906   num_dv = 0;
3907   h1 = NULL;
3908   h2 = NULL;
3909   for (struct DistanceVectorHop *pos = dv->dv_head; NULL != pos;
3910        pos = pos->next_dv)
3911   {
3912     uint32_t delta = MAX_DV_HOPS_ALLOWED - pos->distance;
3913
3914     if ((0 == (options & RMO_UNCONFIRMED_ALLOWED)) &&
3915         (GNUNET_TIME_absolute_get_remaining (pos->path_valid_until)
3916            .rel_value_us == 0))
3917       continue; /* pos unconfirmed and confirmed required */
3918     if ((num_dv <= choice1) && (num_dv + delta > choice1))
3919       h1 = pos;
3920     if ((num_dv <= choice2) && (num_dv + delta > choice2))
3921       h2 = pos;
3922     num_dv += delta;
3923   }
3924   forward_via_dvh (h1, hdr, options & (~RMO_REDUNDANT));
3925   if (0 == (options & RMO_REDUNDANT))
3926     forward_via_dvh (h2, hdr, options & (~RMO_REDUNDANT));
3927 }
3928
3929
3930 /**
3931  * We need to transmit @a hdr to @a target.  If necessary, this may
3932  * involve DV routing.
3933  *
3934  * @param target peer to receive @a hdr
3935  * @param hdr header of the message to route and #GNUNET_free()
3936  * @param options which transmission channels are allowed
3937  */
3938 static void
3939 route_message (const struct GNUNET_PeerIdentity *target,
3940                struct GNUNET_MessageHeader *hdr,
3941                enum RouteMessageOptions options)
3942 {
3943   struct Neighbour *n;
3944   struct DistanceVector *dv;
3945
3946   n = GNUNET_CONTAINER_multipeermap_get (neighbours, target);
3947   dv = (0 != (options & RMO_DV_ALLOWED))
3948          ? GNUNET_CONTAINER_multipeermap_get (dv_routes, target)
3949          : NULL;
3950   if (0 == (options & RMO_UNCONFIRMED_ALLOWED))
3951   {
3952     /* if confirmed is required, and we do not have anything
3953        confirmed, drop respective options */
3954     if ((NULL != n) && (GNUNET_NO == n->core_visible))
3955       n = NULL;
3956     if ((NULL != dv) && (GNUNET_NO == dv->core_visible))
3957       dv = NULL;
3958   }
3959   if ((NULL == n) && (NULL == dv))
3960   {
3961     GNUNET_STATISTICS_update (GST_stats,
3962                               "# Messages dropped in routing: no acceptable method",
3963                               1,
3964                               GNUNET_NO);
3965     GNUNET_free (hdr);
3966     return;
3967   }
3968   /* If both dv and n are possible and we must choose:
3969      flip a coin for the choice between the two; for now 50/50 */
3970   if ((NULL != n) && (NULL != dv) && (0 == (options & RMO_REDUNDANT)))
3971   {
3972     if (0 == GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 2))
3973       n = NULL;
3974     else
3975       dv = NULL;
3976   }
3977   if ((NULL != n) && (NULL != dv))
3978     options &= ~RMO_REDUNDANT; /* We will do one DV and one direct, that's
3979                                   enough for redunancy, so clear the flag. */
3980   if (NULL != n)
3981   {
3982     route_via_neighbour (n, hdr, options);
3983   }
3984   if (NULL != dv)
3985   {
3986     route_via_dv (dv, hdr, options);
3987   }
3988   GNUNET_free (hdr);
3989 }
3990
3991
3992 /**
3993  * Structure of the key material used to encrypt backchannel messages.
3994  */
3995 struct BackchannelKeyState
3996 {
3997   /**
3998    * State of our block cipher.
3999    */
4000   gcry_cipher_hd_t cipher;
4001
4002   /**
4003    * Actual key material.
4004    */
4005   struct
4006   {
4007
4008     /**
4009      * Key used for HMAC calculations (via #GNUNET_CRYPTO_hmac()).
4010      */
4011     struct GNUNET_CRYPTO_AuthKey hmac_key;
4012
4013     /**
4014      * Symmetric key to use for encryption.
4015      */
4016     char aes_key[256 / 8];
4017
4018     /**
4019      * Counter value to use during setup.
4020      */
4021     char aes_ctr[128 / 8];
4022
4023   } material;
4024 };
4025
4026
4027 /**
4028  * Given the key material in @a km and the initialization vector
4029  * @a iv, setup the key material for the backchannel in @a key.
4030  *
4031  * @param km raw master secret
4032  * @param iv initialization vector
4033  * @param key[out] symmetric cipher and HMAC state to generate
4034  */
4035 static void
4036 bc_setup_key_state_from_km (const struct GNUNET_HashCode *km,
4037                             const struct GNUNET_ShortHashCode *iv,
4038                             struct BackchannelKeyState *key)
4039 {
4040   /* must match #dh_key_derive_eph_pub */
4041   GNUNET_assert (GNUNET_YES ==
4042                  GNUNET_CRYPTO_kdf (&key->material,
4043                                     sizeof (key->material),
4044                                     "transport-backchannel-key",
4045                                     strlen ("transport-backchannel-key"),
4046                                     &km,
4047                                     sizeof (km),
4048                                     iv,
4049                                     sizeof (*iv)));
4050   gcry_cipher_open (&key->cipher,
4051                     GCRY_CIPHER_AES256 /* low level: go for speed */,
4052                     GCRY_CIPHER_MODE_CTR,
4053                     0 /* flags */);
4054   gcry_cipher_setkey (key->cipher,
4055                       &key->material.aes_key,
4056                       sizeof (key->material.aes_key));
4057   gcry_cipher_setctr (key->cipher,
4058                       &key->material.aes_ctr,
4059                       sizeof (key->material.aes_ctr));
4060 }
4061
4062
4063 /**
4064  * Derive backchannel encryption key material from @a priv_ephemeral
4065  * and @a target and @a iv.
4066  *
4067  * @param priv_ephemeral ephemeral private key to use
4068  * @param target the target peer to encrypt to
4069  * @param iv unique IV to use
4070  * @param key[out] set to the key material
4071  */
4072 static void
4073 dh_key_derive_eph_pid (
4074   const struct GNUNET_CRYPTO_EcdhePrivateKey *priv_ephemeral,
4075   const struct GNUNET_PeerIdentity *target,
4076   const struct GNUNET_ShortHashCode *iv,
4077   struct BackchannelKeyState *key)
4078 {
4079   struct GNUNET_HashCode km;
4080
4081   GNUNET_assert (GNUNET_YES == GNUNET_CRYPTO_ecdh_eddsa (priv_ephemeral,
4082                                                          &target->public_key,
4083                                                          &km));
4084   bc_setup_key_state_from_km (&km, iv, key);
4085 }
4086
4087
4088 /**
4089  * Derive backchannel encryption key material from #GST_my_private_key
4090  * and @a pub_ephemeral and @a iv.
4091  *
4092  * @param priv_ephemeral ephemeral private key to use
4093  * @param target the target peer to encrypt to
4094  * @param iv unique IV to use
4095  * @param key[out] set to the key material
4096  */
4097 static void
4098 dh_key_derive_eph_pub (const struct GNUNET_CRYPTO_EcdhePublicKey *pub_ephemeral,
4099                        const struct GNUNET_ShortHashCode *iv,
4100                        struct BackchannelKeyState *key)
4101 {
4102   struct GNUNET_HashCode km;
4103
4104   GNUNET_assert (GNUNET_YES == GNUNET_CRYPTO_eddsa_ecdh (GST_my_private_key,
4105                                                          pub_ephemeral,
4106                                                          &km));
4107   bc_setup_key_state_from_km (&km, iv, key);
4108 }
4109
4110
4111 /**
4112  * Do HMAC calculation for backchannel messages over @a data using key
4113  * material from @a key.
4114  *
4115  * @param key key material (from DH)
4116  * @param hmac[out] set to the HMAC
4117  * @param data data to perform HMAC calculation over
4118  * @param data_size number of bytes in @a data
4119  */
4120 static void
4121 bc_hmac (const struct BackchannelKeyState *key,
4122          struct GNUNET_HashCode *hmac,
4123          const void *data,
4124          size_t data_size)
4125 {
4126   GNUNET_CRYPTO_hmac (&key->material.hmac_key, data, data_size, hmac);
4127 }
4128
4129
4130 /**
4131  * Perform backchannel encryption using symmetric secret in @a key
4132  * to encrypt data from @a in to @a dst.
4133  *
4134  * @param key[in,out] key material to use
4135  * @param dst where to write the result
4136  * @param in input data to encrypt (plaintext)
4137  * @param in_size number of bytes of input in @a in and available at @a dst
4138  */
4139 static void
4140 bc_encrypt (struct BackchannelKeyState *key,
4141             const void *in,
4142             void *dst,
4143             size_t in_size)
4144 {
4145   GNUNET_assert (0 ==
4146                  gcry_cipher_encrypt (key->cipher, dst, in_size, in, in_size));
4147 }
4148
4149
4150 /**
4151  * Perform backchannel encryption using symmetric secret in @a key
4152  * to encrypt data from @a in to @a dst.
4153  *
4154  * @param key[in,out] key material to use
4155  * @param ciph cipher text to decrypt
4156  * @param out[out] output data to generate (plaintext)
4157  * @param out_size number of bytes of input in @a ciph and available in @a out
4158  */
4159 static void
4160 bc_decrypt (struct BackchannelKeyState *key,
4161             void *out,
4162             const void *ciph,
4163             size_t out_size)
4164 {
4165   GNUNET_assert (
4166     0 == gcry_cipher_decrypt (key->cipher, out, out_size, ciph, out_size));
4167 }
4168
4169
4170 /**
4171  * Clean up key material in @a key.
4172  *
4173  * @param key key material to clean up (memory must not be free'd!)
4174  */
4175 static void
4176 bc_key_clean (struct BackchannelKeyState *key)
4177 {
4178   gcry_cipher_close (key->cipher);
4179   GNUNET_CRYPTO_zero_keys (&key->material, sizeof (key->material));
4180 }
4181
4182
4183 /**
4184  * Communicator requests backchannel transmission.  Process the request.
4185  *
4186  * @param cls the client
4187  * @param cb the send message that was sent
4188  */
4189 static void
4190 handle_communicator_backchannel (
4191   void *cls,
4192   const struct GNUNET_TRANSPORT_CommunicatorBackchannel *cb)
4193 {
4194   struct TransportClient *tc = cls;
4195   struct GNUNET_CRYPTO_EcdhePrivateKey private_key;
4196   struct GNUNET_TIME_Absolute ephemeral_validity;
4197   struct TransportBackchannelEncapsulationMessage *enc;
4198   struct TransportBackchannelRequestPayloadP ppay;
4199   struct BackchannelKeyState key;
4200   char *mpos;
4201   uint16_t msize;
4202
4203   /* encapsulate and encrypt message */
4204   msize = ntohs (cb->header.size) - sizeof (*cb) +
4205           sizeof (struct TransportBackchannelRequestPayloadP);
4206   enc = GNUNET_malloc (sizeof (*enc) + msize);
4207   enc->header.type =
4208     htons (GNUNET_MESSAGE_TYPE_TRANSPORT_BACKCHANNEL_ENCAPSULATION);
4209   enc->header.size = htons (sizeof (*enc) + msize);
4210   enc->target = cb->pid;
4211   lookup_ephemeral (&cb->pid,
4212                     &private_key,
4213                     &enc->ephemeral_key,
4214                     &ppay.sender_sig,
4215                     &ephemeral_validity);
4216   GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE,
4217                               &enc->iv,
4218                               sizeof (enc->iv));
4219   dh_key_derive_eph_pid (&private_key, &cb->pid, &enc->iv, &key);
4220   ppay.ephemeral_validity = GNUNET_TIME_absolute_hton (ephemeral_validity);
4221   ppay.monotonic_time =
4222     GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get_monotonic (GST_cfg));
4223   mpos = (char *) &enc[1];
4224   bc_encrypt (&key, &ppay, mpos, sizeof (ppay));
4225   bc_encrypt (&key,
4226               &cb[1],
4227               &mpos[sizeof (ppay)],
4228               ntohs (cb->header.size) - sizeof (*cb));
4229   bc_hmac (&key,
4230            &enc->hmac,
4231            mpos,
4232            sizeof (ppay) + ntohs (cb->header.size) - sizeof (*cb));
4233   bc_key_clean (&key);
4234   route_message (&cb->pid, &enc->header, RMO_DV_ALLOWED);
4235   GNUNET_SERVICE_client_continue (tc->client);
4236 }
4237
4238
4239 /**
4240  * Address of our peer added.  Test message is well-formed.
4241  *
4242  * @param cls the client
4243  * @param aam the send message that was sent
4244  * @return #GNUNET_OK if message is well-formed
4245  */
4246 static int
4247 check_add_address (void *cls,
4248                    const struct GNUNET_TRANSPORT_AddAddressMessage *aam)
4249 {
4250   struct TransportClient *tc = cls;
4251
4252   if (CT_COMMUNICATOR != tc->type)
4253   {
4254     GNUNET_break (0);
4255     return GNUNET_SYSERR;
4256   }
4257   GNUNET_MQ_check_zero_termination (aam);
4258   return GNUNET_OK;
4259 }
4260
4261
4262 /**
4263  * Ask peerstore to store our address.
4264  *
4265  * @param cls an `struct AddressListEntry *`
4266  */
4267 static void
4268 store_pi (void *cls);
4269
4270
4271 /**
4272  * Function called when peerstore is done storing our address.
4273  *
4274  * @param cls a `struct AddressListEntry`
4275  * @param success #GNUNET_YES if peerstore was successful
4276  */
4277 static void
4278 peerstore_store_own_cb (void *cls, int success)
4279 {
4280   struct AddressListEntry *ale = cls;
4281
4282   ale->sc = NULL;
4283   if (GNUNET_YES != success)
4284     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
4285                 "Failed to store our own address `%s' in peerstore!\n",
4286                 ale->address);
4287   /* refresh period is 1/4 of expiration time, that should be plenty
4288      without being excessive. */
4289   ale->st =
4290     GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_divide (ale->expiration,
4291                                                                4ULL),
4292                                   &store_pi,
4293                                   ale);
4294 }
4295
4296
4297 /**
4298  * Ask peerstore to store our address.
4299  *
4300  * @param cls an `struct AddressListEntry *`
4301  */
4302 static void
4303 store_pi (void *cls)
4304 {
4305   struct AddressListEntry *ale = cls;
4306   void *addr;
4307   size_t addr_len;
4308   struct GNUNET_TIME_Absolute expiration;
4309
4310   ale->st = NULL;
4311   expiration = GNUNET_TIME_relative_to_absolute (ale->expiration);
4312   GNUNET_HELLO_sign_address (ale->address,
4313                              ale->nt,
4314                              expiration,
4315                              GST_my_private_key,
4316                              &addr,
4317                              &addr_len);
4318   ale->sc = GNUNET_PEERSTORE_store (peerstore,
4319                                     "transport",
4320                                     &GST_my_identity,
4321                                     GNUNET_PEERSTORE_TRANSPORT_HELLO_KEY,
4322                                     addr,
4323                                     addr_len,
4324                                     expiration,
4325                                     GNUNET_PEERSTORE_STOREOPTION_MULTIPLE,
4326                                     &peerstore_store_own_cb,
4327                                     ale);
4328   GNUNET_free (addr);
4329   if (NULL == ale->sc)
4330   {
4331     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
4332                 "Failed to store our address `%s' with peerstore\n",
4333                 ale->address);
4334     ale->st =
4335       GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, &store_pi, ale);
4336   }
4337 }
4338
4339
4340 /**
4341  * Address of our peer added.  Process the request.
4342  *
4343  * @param cls the client
4344  * @param aam the send message that was sent
4345  */
4346 static void
4347 handle_add_address (void *cls,
4348                     const struct GNUNET_TRANSPORT_AddAddressMessage *aam)
4349 {
4350   struct TransportClient *tc = cls;
4351   struct AddressListEntry *ale;
4352   size_t slen;
4353
4354   slen = ntohs (aam->header.size) - sizeof (*aam);
4355   ale = GNUNET_malloc (sizeof (struct AddressListEntry) + slen);
4356   ale->tc = tc;
4357   ale->address = (const char *) &ale[1];
4358   ale->expiration = GNUNET_TIME_relative_ntoh (aam->expiration);
4359   ale->aid = aam->aid;
4360   ale->nt = (enum GNUNET_NetworkType) ntohl (aam->nt);
4361   memcpy (&ale[1], &aam[1], slen);
4362   GNUNET_CONTAINER_DLL_insert (tc->details.communicator.addr_head,
4363                                tc->details.communicator.addr_tail,
4364                                ale);
4365   ale->st = GNUNET_SCHEDULER_add_now (&store_pi, ale);
4366   GNUNET_SERVICE_client_continue (tc->client);
4367 }
4368
4369
4370 /**
4371  * Address of our peer deleted.  Process the request.
4372  *
4373  * @param cls the client
4374  * @param dam the send message that was sent
4375  */
4376 static void
4377 handle_del_address (void *cls,
4378                     const struct GNUNET_TRANSPORT_DelAddressMessage *dam)
4379 {
4380   struct TransportClient *tc = cls;
4381
4382   if (CT_COMMUNICATOR != tc->type)
4383   {
4384     GNUNET_break (0);
4385     GNUNET_SERVICE_client_drop (tc->client);
4386     return;
4387   }
4388   for (struct AddressListEntry *ale = tc->details.communicator.addr_head;
4389        NULL != ale;
4390        ale = ale->next)
4391   {
4392     if (dam->aid != ale->aid)
4393       continue;
4394     GNUNET_assert (ale->tc == tc);
4395     free_address_list_entry (ale);
4396     GNUNET_SERVICE_client_continue (tc->client);
4397   }
4398   GNUNET_break (0);
4399   GNUNET_SERVICE_client_drop (tc->client);
4400 }
4401
4402
4403 /**
4404  * Context from #handle_incoming_msg().  Closure for many
4405  * message handlers below.
4406  */
4407 struct CommunicatorMessageContext
4408 {
4409   /**
4410    * Which communicator provided us with the message.
4411    */
4412   struct TransportClient *tc;
4413
4414   /**
4415    * Additional information for flow control and about the sender.
4416    */
4417   struct GNUNET_TRANSPORT_IncomingMessage im;
4418
4419   /**
4420    * Number of hops the message has travelled (if DV-routed).
4421    * FIXME: make use of this in ACK handling!
4422    */
4423   uint16_t total_hops;
4424 };
4425
4426
4427 /**
4428  * Given an inbound message @a msg from a communicator @a cmc,
4429  * demultiplex it based on the type calling the right handler.
4430  *
4431  * @param cmc context for demultiplexing
4432  * @param msg message to demultiplex
4433  */
4434 static void
4435 demultiplex_with_cmc (struct CommunicatorMessageContext *cmc,
4436                       const struct GNUNET_MessageHeader *msg);
4437
4438
4439 /**
4440  * Send ACK to communicator (if requested) and free @a cmc.
4441  *
4442  * @param cmc context for which we are done handling the message
4443  */
4444 static void
4445 finish_cmc_handling (struct CommunicatorMessageContext *cmc)
4446 {
4447   if (0 != ntohl (cmc->im.fc_on))
4448   {
4449     /* send ACK when done to communicator for flow control! */
4450     struct GNUNET_MQ_Envelope *env;
4451     struct GNUNET_TRANSPORT_IncomingMessageAck *ack;
4452
4453     env = GNUNET_MQ_msg (ack, GNUNET_MESSAGE_TYPE_TRANSPORT_INCOMING_MSG_ACK);
4454     ack->reserved = htonl (0);
4455     ack->fc_id = cmc->im.fc_id;
4456     ack->sender = cmc->im.sender;
4457     GNUNET_MQ_send (cmc->tc->mq, env);
4458   }
4459   GNUNET_SERVICE_client_continue (cmc->tc->client);
4460   GNUNET_free (cmc);
4461 }
4462
4463
4464 /**
4465  * Communicator gave us an unencapsulated message to pass as-is to
4466  * CORE.  Process the request.
4467  *
4468  * @param cls a `struct CommunicatorMessageContext` (must call
4469  * #finish_cmc_handling() when done)
4470  * @param mh the message that was received
4471  */
4472 static void
4473 handle_raw_message (void *cls, const struct GNUNET_MessageHeader *mh)
4474 {
4475   struct CommunicatorMessageContext *cmc = cls;
4476   uint16_t size = ntohs (mh->size);
4477
4478   if ((size > UINT16_MAX - sizeof (struct InboundMessage)) ||
4479       (size < sizeof (struct GNUNET_MessageHeader)))
4480   {
4481     struct GNUNET_SERVICE_Client *client = cmc->tc->client;
4482
4483     GNUNET_break (0);
4484     finish_cmc_handling (cmc);
4485     GNUNET_SERVICE_client_drop (client);
4486     return;
4487   }
4488   /* Forward to all CORE clients */
4489   for (struct TransportClient *tc = clients_head; NULL != tc; tc = tc->next)
4490   {
4491     struct GNUNET_MQ_Envelope *env;
4492     struct InboundMessage *im;
4493
4494     if (CT_CORE != tc->type)
4495       continue;
4496     env = GNUNET_MQ_msg_extra (im, size, GNUNET_MESSAGE_TYPE_TRANSPORT_RECV);
4497     im->peer = cmc->im.sender;
4498     memcpy (&im[1], mh, size);
4499     GNUNET_MQ_send (tc->mq, env);
4500   }
4501   /* FIXME: consider doing this _only_ once the message
4502      was drained from the CORE MQs to extend flow control to CORE!
4503      (basically, increment counter in cmc, decrement on MQ send continuation! */
4504   finish_cmc_handling (cmc);
4505 }
4506
4507
4508 /**
4509  * Communicator gave us a fragment box.  Check the message.
4510  *
4511  * @param cls a `struct CommunicatorMessageContext`
4512  * @param fb the send message that was sent
4513  * @return #GNUNET_YES if message is well-formed
4514  */
4515 static int
4516 check_fragment_box (void *cls, const struct TransportFragmentBoxMessage *fb)
4517 {
4518   uint16_t size = ntohs (fb->header.size);
4519   uint16_t bsize = size - sizeof (*fb);
4520
4521   if (0 == bsize)
4522   {
4523     GNUNET_break_op (0);
4524     return GNUNET_SYSERR;
4525   }
4526   if (bsize + ntohs (fb->frag_off) > ntohs (fb->msg_size))
4527   {
4528     GNUNET_break_op (0);
4529     return GNUNET_SYSERR;
4530   }
4531   if (ntohs (fb->frag_off) >= ntohs (fb->msg_size))
4532   {
4533     GNUNET_break_op (0);
4534     return GNUNET_SYSERR;
4535   }
4536   return GNUNET_YES;
4537 }
4538
4539
4540 /**
4541  * Clean up an idle cummulative acknowledgement data structure.
4542  *
4543  * @param cls a `struct AcknowledgementCummulator *`
4544  */
4545 static void
4546 destroy_ack_cummulator (void *cls)
4547 {
4548   struct AcknowledgementCummulator *ac = cls;
4549
4550   ac->task = NULL;
4551   GNUNET_assert (0 == ac->num_acks);
4552   GNUNET_assert (
4553     GNUNET_YES ==
4554     GNUNET_CONTAINER_multipeermap_remove (ack_cummulators, &ac->target, ac));
4555   GNUNET_free (ac);
4556 }
4557
4558
4559 /**
4560  * Do the transmission of a cummulative acknowledgement now.
4561  *
4562  * @param cls a `struct AcknowledgementCummulator *`
4563  */
4564 static void
4565 transmit_cummulative_ack_cb (void *cls)
4566 {
4567   struct AcknowledgementCummulator *ac = cls;
4568   struct TransportReliabilityAckMessage *ack;
4569   struct TransportCummulativeAckPayloadP *ap;
4570
4571   ac->task = NULL;
4572   GNUNET_assert (0 < ac->ack_counter);
4573   ack = GNUNET_malloc (sizeof (*ack) +
4574                        ac->ack_counter *
4575                          sizeof (struct TransportCummulativeAckPayloadP));
4576   ack->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_RELIABILITY_ACK);
4577   ack->header.size =
4578     htons (sizeof (*ack) +
4579            ac->ack_counter * sizeof (struct TransportCummulativeAckPayloadP));
4580   ack->ack_counter = htonl (ac->ack_counter++);
4581   ap = (struct TransportCummulativeAckPayloadP *) &ack[1];
4582   for (unsigned int i = 0; i < ac->ack_counter; i++)
4583   {
4584     ap[i].ack_uuid = ac->ack_uuids[i].ack_uuid;
4585     ap[i].ack_delay = GNUNET_TIME_relative_hton (
4586       GNUNET_TIME_absolute_get_duration (ac->ack_uuids[i].receive_time));
4587   }
4588   route_message (&ac->target, &ack->header, RMO_DV_ALLOWED);
4589   ac->num_acks = 0;
4590   ac->task = GNUNET_SCHEDULER_add_delayed (ACK_CUMMULATOR_TIMEOUT,
4591                                            &destroy_ack_cummulator,
4592                                            ac);
4593 }
4594
4595
4596 /**
4597  * Transmit an acknowledgement for @a ack_uuid to @a pid delaying
4598  * transmission by at most @a ack_delay.
4599  *
4600  * @param pid target peer
4601  * @param ack_uuid UUID to ack
4602  * @param max_delay how long can the ACK wait
4603  */
4604 static void
4605 cummulative_ack (const struct GNUNET_PeerIdentity *pid,
4606                  const struct AcknowledgementUUIDP *ack_uuid,
4607                  struct GNUNET_TIME_Absolute max_delay)
4608 {
4609   struct AcknowledgementCummulator *ac;
4610
4611   ac = GNUNET_CONTAINER_multipeermap_get (ack_cummulators, pid);
4612   if (NULL == ac)
4613   {
4614     ac = GNUNET_new (struct AcknowledgementCummulator);
4615     ac->target = *pid;
4616     ac->min_transmission_time = max_delay;
4617     GNUNET_assert (GNUNET_YES ==
4618                    GNUNET_CONTAINER_multipeermap_put (
4619                      ack_cummulators,
4620                      &ac->target,
4621                      ac,
4622                      GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
4623   }
4624   else
4625   {
4626     if (MAX_CUMMULATIVE_ACKS == ac->num_acks)
4627     {
4628       /* must run immediately, ack buffer full! */
4629       GNUNET_SCHEDULER_cancel (ac->task);
4630       transmit_cummulative_ack_cb (ac);
4631     }
4632     GNUNET_SCHEDULER_cancel (ac->task);
4633     ac->min_transmission_time =
4634       GNUNET_TIME_absolute_min (ac->min_transmission_time, max_delay);
4635   }
4636   GNUNET_assert (ac->num_acks < MAX_CUMMULATIVE_ACKS);
4637   ac->ack_uuids[ac->num_acks].receive_time = GNUNET_TIME_absolute_get ();
4638   ac->ack_uuids[ac->num_acks].ack_uuid = *ack_uuid;
4639   ac->num_acks++;
4640   ac->task = GNUNET_SCHEDULER_add_at (ac->min_transmission_time,
4641                                       &transmit_cummulative_ack_cb,
4642                                       ac);
4643 }
4644
4645
4646 /**
4647  * Closure for #find_by_message_uuid.
4648  */
4649 struct FindByMessageUuidContext
4650 {
4651   /**
4652    * UUID to look for.
4653    */
4654   struct MessageUUIDP message_uuid;
4655
4656   /**
4657    * Set to the reassembly context if found.
4658    */
4659   struct ReassemblyContext *rc;
4660 };
4661
4662
4663 /**
4664  * Iterator called to find a reassembly context by the message UUID in the
4665  * multihashmap32.
4666  *
4667  * @param cls a `struct FindByMessageUuidContext`
4668  * @param key a key (unused)
4669  * @param value a `struct ReassemblyContext`
4670  * @return #GNUNET_YES if not found, #GNUNET_NO if found
4671  */
4672 static int
4673 find_by_message_uuid (void *cls, uint32_t key, void *value)
4674 {
4675   struct FindByMessageUuidContext *fc = cls;
4676   struct ReassemblyContext *rc = value;
4677
4678   (void) key;
4679   if (0 == GNUNET_memcmp (&fc->message_uuid, &rc->msg_uuid))
4680   {
4681     fc->rc = rc;
4682     return GNUNET_NO;
4683   }
4684   return GNUNET_YES;
4685 }
4686
4687
4688 /**
4689  * Communicator gave us a fragment.  Process the request.
4690  *
4691  * @param cls a `struct CommunicatorMessageContext` (must call
4692  * #finish_cmc_handling() when done)
4693  * @param fb the message that was received
4694  */
4695 static void
4696 handle_fragment_box (void *cls, const struct TransportFragmentBoxMessage *fb)
4697 {
4698   struct CommunicatorMessageContext *cmc = cls;
4699   struct Neighbour *n;
4700   struct ReassemblyContext *rc;
4701   const struct GNUNET_MessageHeader *msg;
4702   uint16_t msize;
4703   uint16_t fsize;
4704   uint16_t frag_off;
4705   char *target;
4706   struct GNUNET_TIME_Relative cdelay;
4707   struct FindByMessageUuidContext fc;
4708
4709   n = GNUNET_CONTAINER_multipeermap_get (neighbours, &cmc->im.sender);
4710   if (NULL == n)
4711   {
4712     struct GNUNET_SERVICE_Client *client = cmc->tc->client;
4713
4714     GNUNET_break (0);
4715     finish_cmc_handling (cmc);
4716     GNUNET_SERVICE_client_drop (client);
4717     return;
4718   }
4719   if (NULL == n->reassembly_map)
4720   {
4721     n->reassembly_map = GNUNET_CONTAINER_multihashmap32_create (8);
4722     n->reassembly_heap =
4723       GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
4724     n->reassembly_timeout_task =
4725       GNUNET_SCHEDULER_add_delayed (REASSEMBLY_EXPIRATION,
4726                                     &reassembly_cleanup_task,
4727                                     n);
4728   }
4729   msize = ntohs (fb->msg_size);
4730   fc.message_uuid = fb->msg_uuid;
4731   fc.rc = NULL;
4732   GNUNET_CONTAINER_multihashmap32_get_multiple (n->reassembly_map,
4733                                                 fb->msg_uuid.uuid,
4734                                                 &find_by_message_uuid,
4735                                                 &fc);
4736   if (NULL == (rc = fc.rc))
4737   {
4738     rc = GNUNET_malloc (sizeof (*rc) + msize + /* reassembly payload buffer */
4739                         (msize + 7) / 8 * sizeof (uint8_t) /* bitfield */);
4740     rc->msg_uuid = fb->msg_uuid;
4741     rc->neighbour = n;
4742     rc->msg_size = msize;
4743     rc->reassembly_timeout =
4744       GNUNET_TIME_relative_to_absolute (REASSEMBLY_EXPIRATION);
4745     rc->last_frag = GNUNET_TIME_absolute_get ();
4746     rc->hn = GNUNET_CONTAINER_heap_insert (n->reassembly_heap,
4747                                            rc,
4748                                            rc->reassembly_timeout.abs_value_us);
4749     GNUNET_assert (GNUNET_OK ==
4750                    GNUNET_CONTAINER_multihashmap32_put (
4751                      n->reassembly_map,
4752                      rc->msg_uuid.uuid,
4753                      rc,
4754                      GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE));
4755     target = (char *) &rc[1];
4756     rc->bitfield = (uint8_t *) (target + rc->msg_size);
4757     rc->msg_missing = rc->msg_size;
4758   }
4759   else
4760   {
4761     target = (char *) &rc[1];
4762   }
4763   if (msize != rc->msg_size)
4764   {
4765     GNUNET_break (0);
4766     finish_cmc_handling (cmc);
4767     return;
4768   }
4769
4770   /* reassemble */
4771   fsize = ntohs (fb->header.size) - sizeof (*fb);
4772   if (0 == fsize)
4773   {
4774     GNUNET_break (0);
4775     finish_cmc_handling (cmc);
4776     return;
4777   }
4778   frag_off = ntohs (fb->frag_off);
4779   memcpy (&target[frag_off], &fb[1], fsize);
4780   /* update bitfield and msg_missing */
4781   for (unsigned int i = frag_off; i < frag_off + fsize; i++)
4782   {
4783     if (0 == (rc->bitfield[i / 8] & (1 << (i % 8))))
4784     {
4785       rc->bitfield[i / 8] |= (1 << (i % 8));
4786       rc->msg_missing--;
4787     }
4788   }
4789
4790   /* Compute cummulative ACK */
4791   cdelay = GNUNET_TIME_absolute_get_duration (rc->last_frag);
4792   cdelay = GNUNET_TIME_relative_multiply (cdelay, rc->msg_missing / fsize);
4793   if (0 == rc->msg_missing)
4794     cdelay = GNUNET_TIME_UNIT_ZERO;
4795   cummulative_ack (&cmc->im.sender,
4796                    &fb->ack_uuid,
4797                    GNUNET_TIME_relative_to_absolute (cdelay));
4798   rc->last_frag = GNUNET_TIME_absolute_get ();
4799   /* is reassembly complete? */
4800   if (0 != rc->msg_missing)
4801   {
4802     finish_cmc_handling (cmc);
4803     return;
4804   }
4805   /* reassembly is complete, verify result */
4806   msg = (const struct GNUNET_MessageHeader *) &rc[1];
4807   if (ntohs (msg->size) != rc->msg_size)
4808   {
4809     GNUNET_break (0);
4810     free_reassembly_context (rc);
4811     finish_cmc_handling (cmc);
4812     return;
4813   }
4814   /* successful reassembly */
4815   demultiplex_with_cmc (cmc, msg);
4816   /* FIXME-OPTIMIZE: really free here? Might be bad if fragments are still
4817      en-route and we forget that we finished this reassembly immediately!
4818      -> keep around until timeout?
4819      -> shorten timeout based on ACK? */
4820   free_reassembly_context (rc);
4821 }
4822
4823
4824 /**
4825  * Communicator gave us a reliability box.  Check the message.
4826  *
4827  * @param cls a `struct CommunicatorMessageContext`
4828  * @param rb the send message that was sent
4829  * @return #GNUNET_YES if message is well-formed
4830  */
4831 static int
4832 check_reliability_box (void *cls,
4833                        const struct TransportReliabilityBoxMessage *rb)
4834 {
4835   GNUNET_MQ_check_boxed_message (rb);
4836   return GNUNET_YES;
4837 }
4838
4839
4840 /**
4841  * Communicator gave us a reliability box.  Process the request.
4842  *
4843  * @param cls a `struct CommunicatorMessageContext` (must call
4844  * #finish_cmc_handling() when done)
4845  * @param rb the message that was received
4846  */
4847 static void
4848 handle_reliability_box (void *cls,
4849                         const struct TransportReliabilityBoxMessage *rb)
4850 {
4851   struct CommunicatorMessageContext *cmc = cls;
4852   const struct GNUNET_MessageHeader *inbox =
4853     (const struct GNUNET_MessageHeader *) &rb[1];
4854
4855   // FIXME: call cummulative_ack(), have ack_countdown influence max_delay!
4856   (void) (0 == ntohl (rb->ack_countdown));
4857   /* continue with inner message */
4858   demultiplex_with_cmc (cmc, inbox);
4859 }
4860
4861
4862 /**
4863  * Check if we have advanced to another age since the last time.  If
4864  * so, purge ancient statistics (more than GOODPUT_AGING_SLOTS before
4865  * the current age)
4866  *
4867  * @param pd[in,out] data to update
4868  * @param age current age
4869  */
4870 static void
4871 update_pd_age (struct PerformanceData *pd, unsigned int age)
4872 {
4873   unsigned int sage;
4874
4875   if (age == pd->last_age)
4876     return; /* nothing to do */
4877   sage = GNUNET_MAX (pd->last_age, age - 2 * GOODPUT_AGING_SLOTS);
4878   for (unsigned int i = sage; i <= age - GOODPUT_AGING_SLOTS; i++)
4879   {
4880     struct TransmissionHistoryEntry *the = &pd->the[i % GOODPUT_AGING_SLOTS];
4881
4882     the->bytes_sent = 0;
4883     the->bytes_received = 0;
4884   }
4885   pd->last_age = age;
4886 }
4887
4888
4889 /**
4890  * Update @a pd based on the latest @a rtt and the number of bytes
4891  * that were confirmed to be successfully transmitted.
4892  *
4893  * @param pd[in,out] data to update
4894  * @param rtt latest round-trip time
4895  * @param bytes_transmitted_ok number of bytes receiver confirmed as received
4896  */
4897 static void
4898 update_performance_data (struct PerformanceData *pd,
4899                          struct GNUNET_TIME_Relative rtt,
4900                          uint16_t bytes_transmitted_ok)
4901 {
4902   uint64_t nval = rtt.rel_value_us;
4903   uint64_t oval = pd->aged_rtt.rel_value_us;
4904   unsigned int age = get_age ();
4905   struct TransmissionHistoryEntry *the = &pd->the[age % GOODPUT_AGING_SLOTS];
4906
4907   if (oval == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us)
4908     pd->aged_rtt = rtt;
4909   else
4910     pd->aged_rtt.rel_value_us = (nval + 7 * oval) / 8;
4911   update_pd_age (pd, age);
4912   the->bytes_received += bytes_transmitted_ok;
4913 }
4914
4915
4916 /**
4917  * We have successfully transmitted data via @a q, update metrics.
4918  *
4919  * @param q queue to update
4920  * @param rtt round trip time observed
4921  * @param bytes_transmitted_ok number of bytes successfully transmitted
4922  */
4923 static void
4924 update_queue_performance (struct Queue *q,
4925                           struct GNUNET_TIME_Relative rtt,
4926                           uint16_t bytes_transmitted_ok)
4927 {
4928   update_performance_data (&q->pd, rtt, bytes_transmitted_ok);
4929 }
4930
4931
4932 /**
4933  * We have successfully transmitted data via @a dvh, update metrics.
4934  *
4935  * @param dvh distance vector path data to update
4936  * @param rtt round trip time observed
4937  * @param bytes_transmitted_ok number of bytes successfully transmitted
4938  */
4939 static void
4940 update_dvh_performance (struct DistanceVectorHop *dvh,
4941                         struct GNUNET_TIME_Relative rtt,
4942                         uint16_t bytes_transmitted_ok)
4943 {
4944   update_performance_data (&dvh->pd, rtt, bytes_transmitted_ok);
4945 }
4946
4947
4948 /**
4949  * The @a pa was acknowledged, process the acknowledgement.
4950  *
4951  * @param pa the pending acknowledgement that was satisfied
4952  * @param ack_delay artificial delay from cummulative acks created by the other
4953  * peer
4954  */
4955 static void
4956 handle_acknowledged (struct PendingAcknowledgement *pa,
4957                      struct GNUNET_TIME_Relative ack_delay)
4958 {
4959   struct PendingMessage *pm = pa->pm;
4960   struct GNUNET_TIME_Relative delay;
4961
4962   delay = GNUNET_TIME_absolute_get_duration (pa->transmission_time);
4963   if (delay.rel_value_us > ack_delay.rel_value_us)
4964     delay = GNUNET_TIME_UNIT_ZERO;
4965   else
4966     delay = GNUNET_TIME_relative_subtract (delay, ack_delay);
4967   if (NULL != pa->queue)
4968     update_queue_performance (pa->queue, delay, pa->message_size);
4969   if (NULL != pa->dvh)
4970     update_dvh_performance (pa->dvh, delay, pa->message_size);
4971   if (NULL != pm)
4972   {
4973     if (NULL != pm->frag_parent)
4974     {
4975       pm = pm->frag_parent;
4976       free_fragment_tree (pa->pm);
4977     }
4978     while ((NULL != pm->frag_parent) && (NULL == pm->head_frag))
4979     {
4980       struct PendingMessage *parent = pm->frag_parent;
4981
4982       free_fragment_tree (pm);
4983       pm = parent;
4984     }
4985     if (NULL != pm->head_frag)
4986       pm = NULL; /* we are done, otherwise free 'pm' below */
4987   }
4988   if (NULL != pm)
4989     free_pending_message (pm);
4990   free_pending_acknowledgement (pa);
4991 }
4992
4993
4994 /**
4995  * Communicator gave us a reliability ack.  Check it is well-formed.
4996  *
4997  * @param cls a `struct CommunicatorMessageContext` (unused)
4998  * @param ra the message that was received
4999  * @return #GNUNET_Ok if @a ra is well-formed
5000  */
5001 static int
5002 check_reliability_ack (void *cls,
5003                        const struct TransportReliabilityAckMessage *ra)
5004 {
5005   unsigned int n_acks;
5006
5007   (void) cls;
5008   n_acks = (ntohs (ra->header.size) - sizeof (*ra)) /
5009            sizeof (struct TransportCummulativeAckPayloadP);
5010   if (0 == n_acks)
5011   {
5012     GNUNET_break_op (0);
5013     return GNUNET_SYSERR;
5014   }
5015   if ((ntohs (ra->header.size) - sizeof (*ra)) !=
5016       n_acks * sizeof (struct TransportCummulativeAckPayloadP))
5017   {
5018     GNUNET_break_op (0);
5019     return GNUNET_SYSERR;
5020   }
5021   return GNUNET_OK;
5022 }
5023
5024
5025 /**
5026  * Communicator gave us a reliability ack.  Process the request.
5027  *
5028  * @param cls a `struct CommunicatorMessageContext` (must call
5029  * #finish_cmc_handling() when done)
5030  * @param ra the message that was received
5031  */
5032 static void
5033 handle_reliability_ack (void *cls,
5034                         const struct TransportReliabilityAckMessage *ra)
5035 {
5036   struct CommunicatorMessageContext *cmc = cls;
5037   const struct TransportCummulativeAckPayloadP *ack;
5038   struct PendingAcknowledgement *pa;
5039   unsigned int n_acks;
5040   uint32_t ack_counter;
5041
5042   n_acks = (ntohs (ra->header.size) - sizeof (*ra)) /
5043            sizeof (struct TransportCummulativeAckPayloadP);
5044   ack = (const struct TransportCummulativeAckPayloadP *) &ra[1];
5045   for (unsigned int i = 0; i < n_acks; i++)
5046   {
5047     pa =
5048       GNUNET_CONTAINER_multishortmap_get (pending_acks, &ack[i].ack_uuid.value);
5049     if (NULL == pa)
5050     {
5051       GNUNET_STATISTICS_update (
5052         GST_stats,
5053         "# FRAGMENT_ACKS dropped, no matching pending message",
5054         1,
5055         GNUNET_NO);
5056       continue;
5057     }
5058     handle_acknowledged (pa, GNUNET_TIME_relative_ntoh (ack[i].ack_delay));
5059   }
5060
5061   ack_counter = htonl (ra->ack_counter);
5062   // FIXME: track ACK losses based on ack_counter somewhere!
5063   // (DV and/or Neighbour?)
5064   finish_cmc_handling (cmc);
5065 }
5066
5067
5068 /**
5069  * Communicator gave us a backchannel encapsulation.  Check the message.
5070  *
5071  * @param cls a `struct CommunicatorMessageContext`
5072  * @param be the send message that was sent
5073  * @return #GNUNET_YES if message is well-formed
5074  */
5075 static int
5076 check_backchannel_encapsulation (
5077   void *cls,
5078   const struct TransportBackchannelEncapsulationMessage *be)
5079 {
5080   uint16_t size = ntohs (be->header.size);
5081
5082   (void) cls;
5083   if ((size - sizeof (*be)) <
5084       (sizeof (struct TransportBackchannelRequestPayloadP) +
5085        sizeof (struct GNUNET_MessageHeader)))
5086   {
5087     GNUNET_break_op (0);
5088     return GNUNET_SYSERR;
5089   }
5090   return GNUNET_YES;
5091 }
5092
5093
5094 /**
5095  * We received the plaintext @a msg from backtalker @a b. Forward
5096  * it to the respective communicator.
5097  *
5098  * @param b a backtalker
5099  * @param msg a message, consisting of a `struct GNUNET_MessageHeader`
5100  *        followed by the target name of the communicator
5101  * @param msg_size number of bytes in @a msg
5102  */
5103 static void
5104 forward_backchannel_payload (struct Backtalker *b,
5105                              const void *msg,
5106                              size_t msg_size)
5107 {
5108   struct GNUNET_TRANSPORT_CommunicatorBackchannelIncoming *cbi;
5109   struct GNUNET_MQ_Envelope *env;
5110   struct TransportClient *tc;
5111   const struct GNUNET_MessageHeader *mh;
5112   const char *target_communicator;
5113   uint16_t mhs;
5114
5115   /* Determine target_communicator and check @a msg is well-formed */
5116   mh = msg;
5117   mhs = ntohs (mh->size);
5118   if (mhs <= msg_size)
5119   {
5120     GNUNET_break_op (0);
5121     return;
5122   }
5123   target_communicator = &((const char *) msg)[ntohs (mh->size)];
5124   if ('\0' != target_communicator[msg_size - mhs - 1])
5125   {
5126     GNUNET_break_op (0);
5127     return;
5128   }
5129   /* Find client providing this communicator */
5130   for (tc = clients_head; NULL != tc; tc = tc->next)
5131     if ((CT_COMMUNICATOR == tc->type) &&
5132         (0 ==
5133          strcmp (tc->details.communicator.address_prefix, target_communicator)))
5134       break;
5135   if (NULL == tc)
5136   {
5137     char *stastr;
5138
5139     GNUNET_asprintf (
5140       &stastr,
5141       "# Backchannel message dropped: target communicator `%s' unknown",
5142       target_communicator);
5143     GNUNET_STATISTICS_update (GST_stats, stastr, 1, GNUNET_NO);
5144     GNUNET_free (stastr);
5145     return;
5146   }
5147   /* Finally, deliver backchannel message to communicator */
5148   env = GNUNET_MQ_msg_extra (
5149     cbi,
5150     msg_size,
5151     GNUNET_MESSAGE_TYPE_TRANSPORT_COMMUNICATOR_BACKCHANNEL_INCOMING);
5152   cbi->pid = b->pid;
5153   memcpy (&cbi[1], msg, msg_size);
5154   GNUNET_MQ_send (tc->mq, env);
5155 }
5156
5157
5158 /**
5159  * Free data structures associated with @a b.
5160  *
5161  * @param b data structure to release
5162  */
5163 static void
5164 free_backtalker (struct Backtalker *b)
5165 {
5166   if (NULL != b->get)
5167   {
5168     GNUNET_PEERSTORE_iterate_cancel (b->get);
5169     b->get = NULL;
5170     GNUNET_assert (NULL != b->cmc);
5171     finish_cmc_handling (b->cmc);
5172     b->cmc = NULL;
5173   }
5174   if (NULL != b->task)
5175   {
5176     GNUNET_SCHEDULER_cancel (b->task);
5177     b->task = NULL;
5178   }
5179   if (NULL != b->sc)
5180   {
5181     GNUNET_PEERSTORE_store_cancel (b->sc);
5182     b->sc = NULL;
5183   }
5184   GNUNET_assert (
5185     GNUNET_YES ==
5186     GNUNET_CONTAINER_multipeermap_remove (backtalkers, &b->pid, b));
5187   GNUNET_free (b);
5188 }
5189
5190
5191 /**
5192  * Callback to free backtalker records.
5193  *
5194  * @param cls NULL
5195  * @param pid unused
5196  * @param value a `struct Backtalker`
5197  * @return #GNUNET_OK (always)
5198  */
5199 static int
5200 free_backtalker_cb (void *cls,
5201                     const struct GNUNET_PeerIdentity *pid,
5202                     void *value)
5203 {
5204   struct Backtalker *b = value;
5205
5206   (void) cls;
5207   (void) pid;
5208   free_backtalker (b);
5209   return GNUNET_OK;
5210 }
5211
5212
5213 /**
5214  * Function called when it is time to clean up a backtalker.
5215  *
5216  * @param cls a `struct Backtalker`
5217  */
5218 static void
5219 backtalker_timeout_cb (void *cls)
5220 {
5221   struct Backtalker *b = cls;
5222
5223   b->task = NULL;
5224   if (0 != GNUNET_TIME_absolute_get_remaining (b->timeout).rel_value_us)
5225   {
5226     b->task = GNUNET_SCHEDULER_add_at (b->timeout, &backtalker_timeout_cb, b);
5227     return;
5228   }
5229   GNUNET_assert (NULL == b->sc);
5230   free_backtalker (b);
5231 }
5232
5233
5234 /**
5235  * Function called with the monotonic time of a backtalker
5236  * by PEERSTORE. Updates the time and continues processing.
5237  *
5238  * @param cls a `struct Backtalker`
5239  * @param record the information found, NULL for the last call
5240  * @param emsg error message
5241  */
5242 static void
5243 backtalker_monotime_cb (void *cls,
5244                         const struct GNUNET_PEERSTORE_Record *record,
5245                         const char *emsg)
5246 {
5247   struct Backtalker *b = cls;
5248   struct GNUNET_TIME_AbsoluteNBO *mtbe;
5249   struct GNUNET_TIME_Absolute mt;
5250
5251   (void) emsg;
5252   if (NULL == record)
5253   {
5254     /* we're done with #backtalker_monotime_cb() invocations,
5255        continue normal processing */
5256     b->get = NULL;
5257     GNUNET_assert (NULL != b->cmc);
5258     finish_cmc_handling (b->cmc);
5259     b->cmc = NULL;
5260     if (0 != b->body_size)
5261       forward_backchannel_payload (b, &b[1], b->body_size);
5262     return;
5263   }
5264   if (sizeof (*mtbe) != record->value_size)
5265   {
5266     GNUNET_break (0);
5267     return;
5268   }
5269   mtbe = record->value;
5270   mt = GNUNET_TIME_absolute_ntoh (*mtbe);
5271   if (mt.abs_value_us > b->monotonic_time.abs_value_us)
5272   {
5273     GNUNET_STATISTICS_update (
5274       GST_stats,
5275       "# Backchannel messages dropped: monotonic time not increasing",
5276       1,
5277       GNUNET_NO);
5278     b->monotonic_time = mt;
5279     /* Setting body_size to 0 prevents call to #forward_backchannel_payload()
5280      */
5281     b->body_size = 0;
5282     return;
5283   }
5284 }
5285
5286
5287 /**
5288  * Function called by PEERSTORE when the store operation of
5289  * a backtalker's monotonic time is complete.
5290  *
5291  * @param cls the `struct Backtalker`
5292  * @param success #GNUNET_OK on success
5293  */
5294 static void
5295 backtalker_monotime_store_cb (void *cls, int success)
5296 {
5297   struct Backtalker *b = cls;
5298
5299   if (GNUNET_OK != success)
5300   {
5301     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
5302                 "Failed to store backtalker's monotonic time in PEERSTORE!\n");
5303   }
5304   b->sc = NULL;
5305   b->task = GNUNET_SCHEDULER_add_at (b->timeout, &backtalker_timeout_cb, b);
5306 }
5307
5308
5309 /**
5310  * The backtalker @a b monotonic time changed. Update PEERSTORE.
5311  *
5312  * @param b a backtalker with updated monotonic time
5313  */
5314 static void
5315 update_backtalker_monotime (struct Backtalker *b)
5316 {
5317   struct GNUNET_TIME_AbsoluteNBO mtbe;
5318
5319   if (NULL != b->sc)
5320   {
5321     GNUNET_PEERSTORE_store_cancel (b->sc);
5322     b->sc = NULL;
5323   }
5324   else
5325   {
5326     GNUNET_SCHEDULER_cancel (b->task);
5327     b->task = NULL;
5328   }
5329   mtbe = GNUNET_TIME_absolute_hton (b->monotonic_time);
5330   b->sc =
5331     GNUNET_PEERSTORE_store (peerstore,
5332                             "transport",
5333                             &b->pid,
5334                             GNUNET_PEERSTORE_TRANSPORT_BACKCHANNEL_MONOTIME,
5335                             &mtbe,
5336                             sizeof (mtbe),
5337                             GNUNET_TIME_UNIT_FOREVER_ABS,
5338                             GNUNET_PEERSTORE_STOREOPTION_REPLACE,
5339                             &backtalker_monotime_store_cb,
5340                             b);
5341 }
5342
5343
5344 /**
5345  * Communicator gave us a backchannel encapsulation.  Process the request.
5346  * (We are not the origin of the backchannel here, the communicator simply
5347  * received a backchannel message and we are expected to forward it.)
5348  *
5349  * @param cls a `struct CommunicatorMessageContext` (must call
5350  * #finish_cmc_handling() when done)
5351  * @param be the message that was received
5352  */
5353 static void
5354 handle_backchannel_encapsulation (
5355   void *cls,
5356   const struct TransportBackchannelEncapsulationMessage *be)
5357 {
5358   struct CommunicatorMessageContext *cmc = cls;
5359   struct BackchannelKeyState key;
5360   struct GNUNET_HashCode hmac;
5361   const char *hdr;
5362   size_t hdr_len;
5363
5364   if (0 != GNUNET_memcmp (&be->target, &GST_my_identity))
5365   {
5366     /* not for me, try to route to target */
5367     route_message (&be->target,
5368                    GNUNET_copy_message (&be->header),
5369                    RMO_DV_ALLOWED);
5370     finish_cmc_handling (cmc);
5371     return;
5372   }
5373   dh_key_derive_eph_pub (&be->ephemeral_key, &be->iv, &key);
5374   hdr = (const char *) &be[1];
5375   hdr_len = ntohs (be->header.size) - sizeof (*be);
5376   bc_hmac (&key, &hmac, hdr, hdr_len);
5377   if (0 != GNUNET_memcmp (&hmac, &be->hmac))
5378   {
5379     /* HMAC missmatch, disard! */
5380     GNUNET_break_op (0);
5381     finish_cmc_handling (cmc);
5382     return;
5383   }
5384   /* begin actual decryption */
5385   {
5386     struct Backtalker *b;
5387     struct GNUNET_TIME_Absolute monotime;
5388     struct TransportBackchannelRequestPayloadP ppay;
5389     char body[hdr_len - sizeof (ppay)];
5390
5391     GNUNET_assert (hdr_len >=
5392                    sizeof (ppay) + sizeof (struct GNUNET_MessageHeader));
5393     bc_decrypt (&key, &ppay, hdr, sizeof (ppay));
5394     bc_decrypt (&key, &body, &hdr[sizeof (ppay)], hdr_len - sizeof (ppay));
5395     bc_key_clean (&key);
5396     monotime = GNUNET_TIME_absolute_ntoh (ppay.monotonic_time);
5397     b = GNUNET_CONTAINER_multipeermap_get (backtalkers, &ppay.sender);
5398     if ((NULL != b) && (monotime.abs_value_us < b->monotonic_time.abs_value_us))
5399     {
5400       GNUNET_STATISTICS_update (
5401         GST_stats,
5402         "# Backchannel messages dropped: monotonic time not increasing",
5403         1,
5404         GNUNET_NO);
5405       finish_cmc_handling (cmc);
5406       return;
5407     }
5408     if ((NULL == b) ||
5409         (0 != GNUNET_memcmp (&b->last_ephemeral, &be->ephemeral_key)))
5410     {
5411       /* Check signature */
5412       struct EphemeralConfirmationPS ec;
5413
5414       ec.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_EPHEMERAL);
5415       ec.purpose.size = htonl (sizeof (ec));
5416       ec.target = GST_my_identity;
5417       ec.ephemeral_key = be->ephemeral_key;
5418       if (
5419         GNUNET_OK !=
5420         GNUNET_CRYPTO_eddsa_verify (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_EPHEMERAL,
5421                                     &ec.purpose,
5422                                     &ppay.sender_sig,
5423                                     &ppay.sender.public_key))
5424       {
5425         /* Signature invalid, disard! */
5426         GNUNET_break_op (0);
5427         finish_cmc_handling (cmc);
5428         return;
5429       }
5430     }
5431     if (NULL != b)
5432     {
5433       /* update key cache and mono time */
5434       b->last_ephemeral = be->ephemeral_key;
5435       b->monotonic_time = monotime;
5436       update_backtalker_monotime (b);
5437       forward_backchannel_payload (b, body, sizeof (body));
5438       b->timeout =
5439         GNUNET_TIME_relative_to_absolute (BACKCHANNEL_INACTIVITY_TIMEOUT);
5440       finish_cmc_handling (cmc);
5441       return;
5442     }
5443     /* setup data structure to cache signature AND check
5444        monotonic time with PEERSTORE before forwarding backchannel payload */
5445     b = GNUNET_malloc (sizeof (struct Backtalker) + sizeof (body));
5446     b->pid = ppay.sender;
5447     b->body_size = sizeof (body);
5448     memcpy (&b[1], body, sizeof (body));
5449     GNUNET_assert (GNUNET_YES ==
5450                    GNUNET_CONTAINER_multipeermap_put (
5451                      backtalkers,
5452                      &b->pid,
5453                      b,
5454                      GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
5455     b->monotonic_time = monotime; /* NOTE: to be checked still! */
5456     b->cmc = cmc;
5457     b->timeout =
5458       GNUNET_TIME_relative_to_absolute (BACKCHANNEL_INACTIVITY_TIMEOUT);
5459     b->task = GNUNET_SCHEDULER_add_at (b->timeout, &backtalker_timeout_cb, b);
5460     b->get =
5461       GNUNET_PEERSTORE_iterate (peerstore,
5462                                 "transport",
5463                                 &b->pid,
5464                                 GNUNET_PEERSTORE_TRANSPORT_BACKCHANNEL_MONOTIME,
5465                                 &backtalker_monotime_cb,
5466                                 b);
5467   }
5468 }
5469
5470
5471 /**
5472  * Task called when we should check if any of the DV paths
5473  * we have learned to a target are due for garbage collection.
5474  *
5475  * Collects stale paths, and possibly frees the entire DV
5476  * entry if no paths are left. Otherwise re-schedules itself.
5477  *
5478  * @param cls a `struct DistanceVector`
5479  */
5480 static void
5481 path_cleanup_cb (void *cls)
5482 {
5483   struct DistanceVector *dv = cls;
5484   struct DistanceVectorHop *pos;
5485
5486   dv->timeout_task = NULL;
5487   while (NULL != (pos = dv->dv_head))
5488   {
5489     GNUNET_assert (dv == pos->dv);
5490     if (GNUNET_TIME_absolute_get_remaining (pos->timeout).rel_value_us > 0)
5491       break;
5492     free_distance_vector_hop (pos);
5493   }
5494   if (NULL == pos)
5495   {
5496     free_dv_route (dv);
5497     return;
5498   }
5499   dv->timeout_task =
5500     GNUNET_SCHEDULER_add_at (pos->timeout, &path_cleanup_cb, dv);
5501 }
5502
5503 /**
5504  * Task run to check whether the hops of the @a cls still
5505  * are validated, or if we need to core about disconnection.
5506  *
5507  * @param cls a `struct DistanceVector` (with core_visible set!)
5508  */
5509 static void
5510 check_dv_path_down (void *cls)
5511 {
5512   struct DistanceVector *dv = cls;
5513   struct Neighbour *n;
5514
5515   dv->visibility_task = NULL;
5516   GNUNET_assert (GNUNET_YES == dv->core_visible);
5517   for (struct DistanceVectorHop *pos = dv->dv_head; NULL != pos;
5518        pos = pos->next_dv)
5519   {
5520     if (0 <
5521         GNUNET_TIME_absolute_get_remaining (pos->path_valid_until).rel_value_us)
5522     {
5523       dv->visibility_task = GNUNET_SCHEDULER_add_at (pos->path_valid_until,
5524                                                      &check_dv_path_down,
5525                                                      dv);
5526       return;
5527     }
5528   }
5529   /* all paths invalid, make dv core-invisible */
5530   dv->core_visible = GNUNET_NO;
5531   n = GNUNET_CONTAINER_multipeermap_get (neighbours, &dv->target);
5532   if ((NULL != n) && (GNUNET_YES == n->core_visible))
5533     return; /* no need to tell core, connection still up! */
5534   cores_send_disconnect_info (&dv->target);
5535 }
5536
5537
5538 /**
5539  * The @a hop is a validated path to the respective target
5540  * peer and we should tell core about it -- and schedule
5541  * a job to revoke the state.
5542  *
5543  * @param hop a path to some peer that is the reason for activation
5544  */
5545 static void
5546 activate_core_visible_dv_path (struct DistanceVectorHop *hop)
5547 {
5548   struct DistanceVector *dv = hop->dv;
5549   struct Neighbour *n;
5550
5551   GNUNET_assert (GNUNET_NO == dv->core_visible);
5552   GNUNET_assert (NULL == dv->visibility_task);
5553
5554   dv->core_visible = GNUNET_YES;
5555   dv->visibility_task =
5556     GNUNET_SCHEDULER_add_at (hop->path_valid_until, &check_dv_path_down, dv);
5557   n = GNUNET_CONTAINER_multipeermap_get (neighbours, &dv->target);
5558   if ((NULL != n) && (GNUNET_YES == n->core_visible))
5559     return; /* no need to tell core, connection already up! */
5560   cores_send_connect_info (&dv->target,
5561                            (NULL != n)
5562                              ? GNUNET_BANDWIDTH_value_sum (n->quota_out,
5563                                                            dv->quota_out)
5564                              : dv->quota_out);
5565 }
5566
5567
5568 /**
5569  * We have learned a @a path through the network to some other peer, add it to
5570  * our DV data structure (returning #GNUNET_YES on success).
5571  *
5572  * We do not add paths if we have a sufficient number of shorter
5573  * paths to this target already (returning #GNUNET_NO).
5574  *
5575  * We also do not add problematic paths, like those where we lack the first
5576  * hop in our neighbour list (i.e. due to a topology change) or where some
5577  * non-first hop is in our neighbour list (returning #GNUNET_SYSERR).
5578  *
5579  * @param path the path we learned, path[0] should be us,
5580  *             and then path contains a valid path from us to
5581  * `path[path_len-1]` path[1] should be a direct neighbour (we should check!)
5582  * @param path_len number of entries on the @a path, at least three!
5583  * @param network_latency how long does the message take from us to
5584  * `path[path_len-1]`? set to "forever" if unknown
5585  * @param path_valid_until how long is this path considered validated? Maybe
5586  * be zero.
5587  * @return #GNUNET_YES on success,
5588  *         #GNUNET_NO if we have better path(s) to the target
5589  *         #GNUNET_SYSERR if the path is useless and/or invalid
5590  *                         (i.e. path[1] not a direct neighbour
5591  *                        or path[i+1] is a direct neighbour for i>0)
5592  */
5593 static int
5594 learn_dv_path (const struct GNUNET_PeerIdentity *path,
5595                unsigned int path_len,
5596                struct GNUNET_TIME_Relative network_latency,
5597                struct GNUNET_TIME_Absolute path_valid_until)
5598 {
5599   struct DistanceVectorHop *hop;
5600   struct DistanceVector *dv;
5601   struct Neighbour *next_hop;
5602   unsigned int shorter_distance;
5603
5604   if (path_len < 3)
5605   {
5606     /* what a boring path! not allowed! */
5607     GNUNET_break (0);
5608     return GNUNET_SYSERR;
5609   }
5610   GNUNET_assert (0 == GNUNET_memcmp (&GST_my_identity, &path[0]));
5611   next_hop = GNUNET_CONTAINER_multipeermap_get (neighbours, &path[1]);
5612   if (NULL == next_hop)
5613   {
5614     /* next hop must be a neighbour, otherwise this whole thing is useless! */
5615     GNUNET_break (0);
5616     return GNUNET_SYSERR;
5617   }
5618   for (unsigned int i = 2; i < path_len; i++)
5619     if (NULL != GNUNET_CONTAINER_multipeermap_get (neighbours, &path[i]))
5620     {
5621       /* Useless path, we have a direct connection to some hop
5622          in the middle of the path, so this one doesn't even
5623          seem terribly useful for redundancy */
5624       return GNUNET_SYSERR;
5625     }
5626   dv = GNUNET_CONTAINER_multipeermap_get (dv_routes, &path[path_len - 1]);
5627   if (NULL == dv)
5628   {
5629     dv = GNUNET_new (struct DistanceVector);
5630     dv->target = path[path_len - 1];
5631     dv->timeout_task = GNUNET_SCHEDULER_add_delayed (DV_PATH_VALIDITY_TIMEOUT,
5632                                                      &path_cleanup_cb,
5633                                                      dv);
5634     GNUNET_assert (GNUNET_OK ==
5635                    GNUNET_CONTAINER_multipeermap_put (
5636                      dv_routes,
5637                      &dv->target,
5638                      dv,
5639                      GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
5640   }
5641   /* Check if we have this path already! */
5642   shorter_distance = 0;
5643   for (struct DistanceVectorHop *pos = dv->dv_head; NULL != pos;
5644        pos = pos->next_dv)
5645   {
5646     if (pos->distance < path_len - 2)
5647       shorter_distance++;
5648     /* Note that the distances in 'pos' excludes us (path[0]) and
5649        the next_hop (path[1]), so we need to subtract two
5650        and check next_hop explicitly */
5651     if ((pos->distance == path_len - 2) && (pos->next_hop == next_hop))
5652     {
5653       int match = GNUNET_YES;
5654
5655       for (unsigned int i = 0; i < pos->distance; i++)
5656       {
5657         if (0 != GNUNET_memcmp (&pos->path[i], &path[i + 2]))
5658         {
5659           match = GNUNET_NO;
5660           break;
5661         }
5662       }
5663       if (GNUNET_YES == match)
5664       {
5665         struct GNUNET_TIME_Relative last_timeout;
5666
5667         /* Re-discovered known path, update timeout */
5668         GNUNET_STATISTICS_update (GST_stats,
5669                                   "# Known DV path refreshed",
5670                                   1,
5671                                   GNUNET_NO);
5672         last_timeout = GNUNET_TIME_absolute_get_remaining (pos->timeout);
5673         pos->timeout =
5674           GNUNET_TIME_relative_to_absolute (DV_PATH_VALIDITY_TIMEOUT);
5675         pos->path_valid_until =
5676           GNUNET_TIME_absolute_max (pos->path_valid_until, path_valid_until);
5677         GNUNET_CONTAINER_MDLL_remove (dv, dv->dv_head, dv->dv_tail, pos);
5678         GNUNET_CONTAINER_MDLL_insert (dv, dv->dv_head, dv->dv_tail, pos);
5679         if ((GNUNET_NO == dv->core_visible) &&
5680             (0 < GNUNET_TIME_absolute_get_remaining (path_valid_until)
5681                    .rel_value_us))
5682           activate_core_visible_dv_path (pos);
5683         if (last_timeout.rel_value_us <
5684             GNUNET_TIME_relative_subtract (DV_PATH_VALIDITY_TIMEOUT,
5685                                            DV_PATH_DISCOVERY_FREQUENCY)
5686               .rel_value_us)
5687         {
5688           /* Some peer send DV learn messages too often, we are learning
5689              the same path faster than it would be useful; do not forward! */
5690           return GNUNET_NO;
5691         }
5692         return GNUNET_YES;
5693       }
5694     }
5695   }
5696   /* Count how many shorter paths we have (incl. direct
5697      neighbours) before simply giving up on this one! */
5698   if (shorter_distance >= MAX_DV_PATHS_TO_TARGET)
5699   {
5700     /* We have a shorter path already! */
5701     return GNUNET_NO;
5702   }
5703   /* create new DV path entry */
5704   hop = GNUNET_malloc (sizeof (struct DistanceVectorHop) +
5705                        sizeof (struct GNUNET_PeerIdentity) * (path_len - 2));
5706   hop->next_hop = next_hop;
5707   hop->dv = dv;
5708   hop->path = (const struct GNUNET_PeerIdentity *) &hop[1];
5709   memcpy (&hop[1],
5710           &path[2],
5711           sizeof (struct GNUNET_PeerIdentity) * (path_len - 2));
5712   hop->timeout = GNUNET_TIME_relative_to_absolute (DV_PATH_VALIDITY_TIMEOUT);
5713   hop->path_valid_until = path_valid_until;
5714   hop->distance = path_len - 2;
5715   GNUNET_CONTAINER_MDLL_insert (dv, dv->dv_head, dv->dv_tail, hop);
5716   GNUNET_CONTAINER_MDLL_insert (neighbour,
5717                                 next_hop->dv_head,
5718                                 next_hop->dv_tail,
5719                                 hop);
5720   if ((GNUNET_NO == dv->core_visible) &&
5721       (0 < GNUNET_TIME_absolute_get_remaining (path_valid_until).rel_value_us))
5722     activate_core_visible_dv_path (hop);
5723   return GNUNET_YES;
5724 }
5725
5726
5727 /**
5728  * Communicator gave us a DV learn message.  Check the message.
5729  *
5730  * @param cls a `struct CommunicatorMessageContext`
5731  * @param dvl the send message that was sent
5732  * @return #GNUNET_YES if message is well-formed
5733  */
5734 static int
5735 check_dv_learn (void *cls, const struct TransportDVLearnMessage *dvl)
5736 {
5737   uint16_t size = ntohs (dvl->header.size);
5738   uint16_t num_hops = ntohs (dvl->num_hops);
5739   const struct DVPathEntryP *hops = (const struct DVPathEntryP *) &dvl[1];
5740
5741   (void) cls;
5742   if (size != sizeof (*dvl) + num_hops * sizeof (struct DVPathEntryP))
5743   {
5744     GNUNET_break_op (0);
5745     return GNUNET_SYSERR;
5746   }
5747   if (num_hops > MAX_DV_HOPS_ALLOWED)
5748   {
5749     GNUNET_break_op (0);
5750     return GNUNET_SYSERR;
5751   }
5752   for (unsigned int i = 0; i < num_hops; i++)
5753   {
5754     if (0 == GNUNET_memcmp (&dvl->initiator, &hops[i].hop))
5755     {
5756       GNUNET_break_op (0);
5757       return GNUNET_SYSERR;
5758     }
5759     if (0 == GNUNET_memcmp (&GST_my_identity, &hops[i].hop))
5760     {
5761       GNUNET_break_op (0);
5762       return GNUNET_SYSERR;
5763     }
5764   }
5765   return GNUNET_YES;
5766 }
5767
5768
5769 /**
5770  * Build and forward a DV learn message to @a next_hop.
5771  *
5772  * @param next_hop peer to send the message to
5773  * @param msg message received
5774  * @param bi_history bitmask specifying hops on path that were bidirectional
5775  * @param nhops length of the @a hops array
5776  * @param hops path the message traversed so far
5777  * @param in_time when did we receive the message, used to calculate network
5778  * delay
5779  */
5780 static void
5781 forward_dv_learn (const struct GNUNET_PeerIdentity *next_hop,
5782                   const struct TransportDVLearnMessage *msg,
5783                   uint16_t bi_history,
5784                   uint16_t nhops,
5785                   const struct DVPathEntryP *hops,
5786                   struct GNUNET_TIME_Absolute in_time)
5787 {
5788   struct DVPathEntryP *dhops;
5789   struct TransportDVLearnMessage *fwd;
5790   struct GNUNET_TIME_Relative nnd;
5791
5792   /* compute message for forwarding */
5793   GNUNET_assert (nhops < MAX_DV_HOPS_ALLOWED);
5794   fwd = GNUNET_malloc (sizeof (struct TransportDVLearnMessage) +
5795                        (nhops + 1) * sizeof (struct DVPathEntryP));
5796   fwd->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_DV_LEARN);
5797   fwd->header.size = htons (sizeof (struct TransportDVLearnMessage) +
5798                             (nhops + 1) * sizeof (struct DVPathEntryP));
5799   fwd->num_hops = htons (nhops + 1);
5800   fwd->bidirectional = htons (bi_history);
5801   nnd = GNUNET_TIME_relative_add (GNUNET_TIME_absolute_get_duration (in_time),
5802                                   GNUNET_TIME_relative_ntoh (
5803                                     msg->non_network_delay));
5804   fwd->non_network_delay = GNUNET_TIME_relative_hton (nnd);
5805   fwd->init_sig = msg->init_sig;
5806   fwd->initiator = msg->initiator;
5807   fwd->challenge = msg->challenge;
5808   dhops = (struct DVPathEntryP *) &fwd[1];
5809   GNUNET_memcpy (dhops, hops, sizeof (struct DVPathEntryP) * nhops);
5810   dhops[nhops].hop = GST_my_identity;
5811   {
5812     struct DvHopPS dhp = {.purpose.purpose =
5813                             htonl (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_DV_HOP),
5814                           .purpose.size = htonl (sizeof (dhp)),
5815                           .pred = dhops[nhops - 1].hop,
5816                           .succ = *next_hop,
5817                           .challenge = msg->challenge};
5818
5819     GNUNET_assert (GNUNET_OK ==
5820                    GNUNET_CRYPTO_eddsa_sign (GST_my_private_key,
5821                                              &dhp.purpose,
5822                                              &dhops[nhops].hop_sig));
5823   }
5824   route_message (next_hop, &fwd->header, RMO_UNCONFIRMED_ALLOWED);
5825 }
5826
5827
5828 /**
5829  * Check signature of type #GNUNET_SIGNATURE_PURPOSE_TRANSPORT_DV_INITIATOR
5830  *
5831  * @param init the signer
5832  * @param challenge the challenge that was signed
5833  * @param init_sig signature presumably by @a init
5834  * @return #GNUNET_OK if the signature is valid
5835  */
5836 static int
5837 validate_dv_initiator_signature (
5838   const struct GNUNET_PeerIdentity *init,
5839   const struct ChallengeNonceP *challenge,
5840   const struct GNUNET_CRYPTO_EddsaSignature *init_sig)
5841 {
5842   struct DvInitPS ip = {.purpose.purpose = htonl (
5843                           GNUNET_SIGNATURE_PURPOSE_TRANSPORT_DV_INITIATOR),
5844                         .purpose.size = htonl (sizeof (ip)),
5845                         .challenge = *challenge};
5846
5847   if (
5848     GNUNET_OK !=
5849     GNUNET_CRYPTO_eddsa_verify (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_DV_INITIATOR,
5850                                 &ip.purpose,
5851                                 init_sig,
5852                                 &init->public_key))
5853   {
5854     GNUNET_break_op (0);
5855     return GNUNET_SYSERR;
5856   }
5857   return GNUNET_OK;
5858 }
5859
5860
5861 /**
5862  * Closure for #dv_neighbour_selection and #dv_neighbour_transmission.
5863  */
5864 struct NeighbourSelectionContext
5865 {
5866   /**
5867    * Original message we received.
5868    */
5869   const struct TransportDVLearnMessage *dvl;
5870
5871   /**
5872    * The hops taken.
5873    */
5874   const struct DVPathEntryP *hops;
5875
5876   /**
5877    * Time we received the message.
5878    */
5879   struct GNUNET_TIME_Absolute in_time;
5880
5881   /**
5882    * Offsets of the selected peers.
5883    */
5884   uint32_t selections[MAX_DV_DISCOVERY_SELECTION];
5885
5886   /**
5887    * Number of peers eligible for selection.
5888    */
5889   unsigned int num_eligible;
5890
5891   /**
5892    * Number of peers that were selected for forwarding.
5893    */
5894   unsigned int num_selections;
5895
5896   /**
5897    * Number of hops in @e hops
5898    */
5899   uint16_t nhops;
5900
5901   /**
5902    * Bitmap of bidirectional connections encountered.
5903    */
5904   uint16_t bi_history;
5905 };
5906
5907
5908 /**
5909  * Function called for each neighbour during #handle_dv_learn.
5910  *
5911  * @param cls a `struct NeighbourSelectionContext *`
5912  * @param pid identity of the peer
5913  * @param value a `struct Neighbour`
5914  * @return #GNUNET_YES (always)
5915  */
5916 static int
5917 dv_neighbour_selection (void *cls,
5918                         const struct GNUNET_PeerIdentity *pid,
5919                         void *value)
5920 {
5921   struct NeighbourSelectionContext *nsc = cls;
5922
5923   (void) value;
5924   if (0 == GNUNET_memcmp (pid, &nsc->dvl->initiator))
5925     return GNUNET_YES; /* skip initiator */
5926   for (unsigned int i = 0; i < nsc->nhops; i++)
5927     if (0 == GNUNET_memcmp (pid, &nsc->hops[i].hop))
5928       return GNUNET_YES; /* skip peers on path */
5929   nsc->num_eligible++;
5930   return GNUNET_YES;
5931 }
5932
5933
5934 /**
5935  * Function called for each neighbour during #handle_dv_learn.
5936  * We call #forward_dv_learn() on the neighbour(s) selected
5937  * during #dv_neighbour_selection().
5938  *
5939  * @param cls a `struct NeighbourSelectionContext *`
5940  * @param pid identity of the peer
5941  * @param value a `struct Neighbour`
5942  * @return #GNUNET_YES (always)
5943  */
5944 static int
5945 dv_neighbour_transmission (void *cls,
5946                            const struct GNUNET_PeerIdentity *pid,
5947                            void *value)
5948 {
5949   struct NeighbourSelectionContext *nsc = cls;
5950
5951   (void) value;
5952   if (0 == GNUNET_memcmp (pid, &nsc->dvl->initiator))
5953     return GNUNET_YES; /* skip initiator */
5954   for (unsigned int i = 0; i < nsc->nhops; i++)
5955     if (0 == GNUNET_memcmp (pid, &nsc->hops[i].hop))
5956       return GNUNET_YES; /* skip peers on path */
5957   for (unsigned int i = 0; i < nsc->num_selections; i++)
5958   {
5959     if (nsc->selections[i] == nsc->num_eligible)
5960     {
5961       forward_dv_learn (pid,
5962                         nsc->dvl,
5963                         nsc->bi_history,
5964                         nsc->nhops,
5965                         nsc->hops,
5966                         nsc->in_time);
5967       break;
5968     }
5969   }
5970   nsc->num_eligible++;
5971   return GNUNET_YES;
5972 }
5973
5974
5975 /**
5976  * Computes the number of neighbours we should forward a DVInit
5977  * message to given that it has so far taken @a hops_taken hops
5978  * though the network and that the number of neighbours we have
5979  * in total is @a neighbour_count, out of which @a eligible_count
5980  * are not yet on the path.
5981  *
5982  * NOTE: technically we might want to include NSE in the formula to
5983  * get a better grip on the overall network size. However, for now
5984  * using NSE here would create a dependency issue in the build system.
5985  * => Left for later, hardcoded to 50 for now.
5986  *
5987  * The goal of the fomula is that we want to reach a total of LOG(NSE)
5988  * peers via DV (`target_total`).  We want the reach to be spread out
5989  * over various distances to the origin, with a bias towards shorter
5990  * distances.
5991  *
5992  * We make the strong assumption that the network topology looks
5993  * "similar" at other hops, in particular the @a neighbour_count
5994  * should be comparable at other hops.
5995  *
5996  * If the local neighbourhood is densely connected, we expect that @a
5997  * eligible_count is close to @a neighbour_count minus @a hops_taken
5998  * as a lot of the path is already known. In that case, we should
5999  * forward to few(er) peers to try to find a path out of the
6000  * neighbourhood. OTOH, if @a eligible_count is close to @a
6001  * neighbour_count, we should forward to many peers as we are either
6002  * still close to the origin (i.e.  @a hops_taken is small) or because
6003  * we managed to get beyond a local cluster.  We express this as
6004  * the `boost_factor` using the square of the fraction of eligible
6005  * neighbours (so if only 50% are eligible, we boost by 1/4, but if
6006  * 99% are eligible, the 'boost' will be almost 1).
6007  *
6008  * Second, the more hops we have taken, the larger the problem of an
6009  * exponential traffic explosion gets.  So we take the `target_total`,
6010  * and compute our degree such that at each distance d 2^{-d} peers
6011  * are selected (corrected by the `boost_factor`).
6012  *
6013  * @param hops_taken number of hops DVInit has travelled so far
6014  * @param neighbour_count number of neighbours we have in total
6015  * @param eligible_count number of neighbours we could in
6016  *        theory forward to
6017  */
6018 static unsigned int
6019 calculate_fork_degree (unsigned int hops_taken,
6020                        unsigned int neighbour_count,
6021                        unsigned int eligible_count)
6022 {
6023   double target_total = 50.0; /* FIXME: use LOG(NSE)? */
6024   double eligible_ratio =
6025     ((double) eligible_count) / ((double) neighbour_count);
6026   double boost_factor = eligible_ratio * eligible_ratio;
6027   unsigned int rnd;
6028   double left;
6029
6030   if (hops_taken >= 64)
6031     return 0; /* precaution given bitshift below */
6032   for (unsigned int i = 1; i < hops_taken; i++)
6033   {
6034     /* For each hop, subtract the expected number of targets
6035        reached at distance d (so what remains divided by 2^d) */
6036     target_total -= (target_total * boost_factor / (1LLU << i));
6037   }
6038   rnd =
6039     (unsigned int) floor (target_total * boost_factor / (1LLU << hops_taken));
6040   /* round up or down probabilistically depending on how close we were
6041      when floor()ing to rnd */
6042   left = target_total - (double) rnd;
6043   if (UINT32_MAX * left >
6044       GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, UINT32_MAX))
6045     rnd++; /* round up */
6046   return rnd;
6047 }
6048
6049
6050 /**
6051  * Communicator gave us a DV learn message.  Process the request.
6052  *
6053  * @param cls a `struct CommunicatorMessageContext` (must call
6054  * #finish_cmc_handling() when done)
6055  * @param dvl the message that was received
6056  */
6057 static void
6058 handle_dv_learn (void *cls, const struct TransportDVLearnMessage *dvl)
6059 {
6060   struct CommunicatorMessageContext *cmc = cls;
6061   enum GNUNET_TRANSPORT_CommunicatorCharacteristics cc;
6062   int bi_hop;
6063   uint16_t nhops;
6064   uint16_t bi_history;
6065   const struct DVPathEntryP *hops;
6066   int do_fwd;
6067   int did_initiator;
6068   struct GNUNET_TIME_Absolute in_time;
6069
6070   nhops = ntohs (dvl->bidirectional); /* 0 = sender is initiator */
6071   bi_history = ntohs (dvl->bidirectional);
6072   hops = (const struct DVPathEntryP *) &dvl[1];
6073   if (0 == nhops)
6074   {
6075     /* sanity check */
6076     if (0 != GNUNET_memcmp (&dvl->initiator, &cmc->im.sender))
6077     {
6078       GNUNET_break (0);
6079       finish_cmc_handling (cmc);
6080       return;
6081     }
6082   }
6083   else
6084   {
6085     /* sanity check */
6086     if (0 != GNUNET_memcmp (&hops[nhops - 1].hop, &cmc->im.sender))
6087     {
6088       GNUNET_break (0);
6089       finish_cmc_handling (cmc);
6090       return;
6091     }
6092   }
6093
6094   GNUNET_assert (CT_COMMUNICATOR == cmc->tc->type);
6095   cc = cmc->tc->details.communicator.cc;
6096   bi_hop = (GNUNET_TRANSPORT_CC_RELIABLE ==
6097             cc); // FIXME: add bi-directional flag to cc?
6098   in_time = GNUNET_TIME_absolute_get ();
6099
6100   /* continue communicator here, everything else can happen asynchronous! */
6101   finish_cmc_handling (cmc);
6102
6103   /* OPTIMIZE-FIXME: Technically, we only need to bother checking
6104      the initiator signature if we send the message back to the initiator...
6105    */
6106   if (GNUNET_OK != validate_dv_initiator_signature (&dvl->initiator,
6107                                                     &dvl->challenge,
6108                                                     &dvl->init_sig))
6109   {
6110     GNUNET_break_op (0);
6111     return;
6112   }
6113   // FIXME: asynchronously (!) verify hop-by-hop signatures!
6114   // => if signature verification load too high, implement random drop
6115   // strategy!?
6116
6117   do_fwd = GNUNET_YES;
6118   if (0 == GNUNET_memcmp (&GST_my_identity, &dvl->initiator))
6119   {
6120     struct GNUNET_PeerIdentity path[nhops + 1];
6121     struct GNUNET_TIME_Relative host_latency_sum;
6122     struct GNUNET_TIME_Relative latency;
6123     struct GNUNET_TIME_Relative network_latency;
6124
6125     /* We initiated this, learn the forward path! */
6126     path[0] = GST_my_identity;
6127     path[1] = hops[0].hop;
6128     host_latency_sum = GNUNET_TIME_relative_ntoh (dvl->non_network_delay);
6129
6130     // Need also something to lookup initiation time
6131     // to compute RTT! -> add RTT argument here?
6132     latency = GNUNET_TIME_UNIT_FOREVER_REL; // FIXME: initialize properly
6133     // (based on dvl->challenge, we can identify time of origin!)
6134
6135     network_latency = GNUNET_TIME_relative_subtract (latency, host_latency_sum);
6136     /* assumption: latency on all links is the same */
6137     network_latency = GNUNET_TIME_relative_divide (network_latency, nhops);
6138
6139     for (unsigned int i = 2; i <= nhops; i++)
6140     {
6141       struct GNUNET_TIME_Relative ilat;
6142
6143       /* assumption: linear latency increase per hop */
6144       ilat = GNUNET_TIME_relative_multiply (network_latency, i);
6145       path[i] = hops[i - 1].hop;
6146       learn_dv_path (path,
6147                      i,
6148                      ilat,
6149                      GNUNET_TIME_relative_to_absolute (
6150                        ADDRESS_VALIDATION_LIFETIME));
6151     }
6152     /* as we initiated, do not forward again (would be circular!) */
6153     do_fwd = GNUNET_NO;
6154     return;
6155   }
6156   else if (bi_hop)
6157   {
6158     /* last hop was bi-directional, we could learn something here! */
6159     struct GNUNET_PeerIdentity path[nhops + 2];
6160
6161     path[0] = GST_my_identity;
6162     path[1] = hops[nhops - 1].hop; /* direct neighbour == predecessor! */
6163     for (unsigned int i = 0; i < nhops; i++)
6164     {
6165       int iret;
6166
6167       if (0 == (bi_history & (1 << i)))
6168         break; /* i-th hop not bi-directional, stop learning! */
6169       if (i == nhops)
6170       {
6171         path[i + 2] = dvl->initiator;
6172       }
6173       else
6174       {
6175         path[i + 2] = hops[nhops - i - 2].hop;
6176       }
6177
6178       iret = learn_dv_path (path,
6179                             i + 2,
6180                             GNUNET_TIME_UNIT_FOREVER_REL,
6181                             GNUNET_TIME_UNIT_ZERO_ABS);
6182       if (GNUNET_SYSERR == iret)
6183       {
6184         /* path invalid or too long to be interesting for US, thus should also
6185            not be interesting to our neighbours, cut path when forwarding to
6186            'i' hops, except of course for the one that goes back to the
6187            initiator */
6188         GNUNET_STATISTICS_update (GST_stats,
6189                                   "# DV learn not forwarded due invalidity of path",
6190                                   1,
6191                                   GNUNET_NO);
6192         do_fwd = GNUNET_NO;
6193         break;
6194       }
6195       if ((GNUNET_NO == iret) && (nhops == i + 1))
6196       {
6197         /* we have better paths, and this is the longest target,
6198            so there cannot be anything interesting later */
6199         GNUNET_STATISTICS_update (GST_stats,
6200                                   "# DV learn not forwarded, got better paths",
6201                                   1,
6202                                   GNUNET_NO);
6203         do_fwd = GNUNET_NO;
6204         break;
6205       }
6206     }
6207   }
6208
6209   if (MAX_DV_HOPS_ALLOWED == nhops)
6210   {
6211     /* At limit, we're out of here! */
6212     finish_cmc_handling (cmc);
6213     return;
6214   }
6215
6216   /* Forward to initiator, if path non-trivial and possible */
6217   bi_history = (bi_history << 1) | (bi_hop ? 1 : 0);
6218   did_initiator = GNUNET_NO;
6219   if ((1 < nhops) &&
6220       (GNUNET_YES ==
6221        GNUNET_CONTAINER_multipeermap_contains (neighbours, &dvl->initiator)))
6222   {
6223     /* send back to origin! */
6224     forward_dv_learn (&dvl->initiator, dvl, bi_history, nhops, hops, in_time);
6225     did_initiator = GNUNET_YES;
6226   }
6227   /* We forward under two conditions: either we still learned something
6228      ourselves (do_fwd), or the path was darn short and thus the initiator is
6229      likely to still be very interested in this (and we did NOT already
6230      send it back to the initiator) */
6231   if ((do_fwd) || ((nhops < MIN_DV_PATH_LENGTH_FOR_INITIATOR) &&
6232                    (GNUNET_NO == did_initiator)))
6233   {
6234     /* Pick random neighbours that are not yet on the path */
6235     struct NeighbourSelectionContext nsc;
6236     unsigned int n_cnt;
6237
6238     n_cnt = GNUNET_CONTAINER_multipeermap_size (neighbours);
6239     nsc.nhops = nhops;
6240     nsc.dvl = dvl;
6241     nsc.bi_history = bi_history;
6242     nsc.hops = hops;
6243     nsc.in_time = in_time;
6244     nsc.num_eligible = 0;
6245     GNUNET_CONTAINER_multipeermap_iterate (neighbours,
6246                                            &dv_neighbour_selection,
6247                                            &nsc);
6248     if (0 == nsc.num_eligible)
6249       return; /* done here, cannot forward to anyone else */
6250     nsc.num_selections = calculate_fork_degree (nhops, n_cnt, nsc.num_eligible);
6251     nsc.num_selections =
6252       GNUNET_MIN (MAX_DV_DISCOVERY_SELECTION, nsc.num_selections);
6253     for (unsigned int i = 0; i < nsc.num_selections; i++)
6254       nsc.selections[i] =
6255         (nsc.num_selections == n_cnt)
6256           ? i /* all were selected, avoid collisions by chance */
6257           : GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, n_cnt);
6258     nsc.num_eligible = 0;
6259     GNUNET_CONTAINER_multipeermap_iterate (neighbours,
6260                                            &dv_neighbour_transmission,
6261                                            &nsc);
6262   }
6263 }
6264
6265
6266 /**
6267  * Communicator gave us a DV box.  Check the message.
6268  *
6269  * @param cls a `struct CommunicatorMessageContext`
6270  * @param dvb the send message that was sent
6271  * @return #GNUNET_YES if message is well-formed
6272  */
6273 static int
6274 check_dv_box (void *cls, const struct TransportDVBoxMessage *dvb)
6275 {
6276   uint16_t size = ntohs (dvb->header.size);
6277   uint16_t num_hops = ntohs (dvb->num_hops);
6278   const struct GNUNET_PeerIdentity *hops =
6279     (const struct GNUNET_PeerIdentity *) &dvb[1];
6280   const struct GNUNET_MessageHeader *inbox =
6281     (const struct GNUNET_MessageHeader *) &hops[num_hops];
6282   uint16_t isize;
6283   uint16_t itype;
6284
6285   (void) cls;
6286   if (size < sizeof (*dvb) + num_hops * sizeof (struct GNUNET_PeerIdentity) +
6287                sizeof (struct GNUNET_MessageHeader))
6288   {
6289     GNUNET_break_op (0);
6290     return GNUNET_SYSERR;
6291   }
6292   isize = ntohs (inbox->size);
6293   if (size !=
6294       sizeof (*dvb) + num_hops * sizeof (struct GNUNET_PeerIdentity) + isize)
6295   {
6296     GNUNET_break_op (0);
6297     return GNUNET_SYSERR;
6298   }
6299   itype = ntohs (inbox->type);
6300   if ((GNUNET_MESSAGE_TYPE_TRANSPORT_DV_BOX == itype) ||
6301       (GNUNET_MESSAGE_TYPE_TRANSPORT_DV_LEARN == itype))
6302   {
6303     GNUNET_break_op (0);
6304     return GNUNET_SYSERR;
6305   }
6306   if (0 == GNUNET_memcmp (&dvb->origin, &GST_my_identity))
6307   {
6308     GNUNET_break_op (0);
6309     return GNUNET_SYSERR;
6310   }
6311   return GNUNET_YES;
6312 }
6313
6314
6315 /**
6316  * Create a DV Box message and queue it for transmission to
6317  * @ea next_hop.
6318  *
6319  * @param next_hop peer to receive the message next
6320  * @param total_hops how many hops did the message take so far
6321  * @param num_hops length of the @a hops array
6322  * @param origin origin of the message
6323  * @param hops next peer(s) to the destination, including destination
6324  * @param payload payload of the box
6325  * @param payload_size number of bytes in @a payload
6326  */
6327 static void
6328 forward_dv_box (struct Neighbour *next_hop,
6329                 uint16_t total_hops,
6330                 uint16_t num_hops,
6331                 const struct GNUNET_PeerIdentity *origin,
6332                 const struct GNUNET_PeerIdentity *hops,
6333                 const void *payload,
6334                 uint16_t payload_size)
6335 {
6336   struct TransportDVBoxMessage *dvb;
6337   struct GNUNET_PeerIdentity *dhops;
6338
6339   GNUNET_assert (UINT16_MAX < sizeof (struct TransportDVBoxMessage) +
6340                                 sizeof (struct GNUNET_PeerIdentity) * num_hops +
6341                                 payload_size);
6342   dvb = GNUNET_malloc (sizeof (struct TransportDVBoxMessage) +
6343                        sizeof (struct GNUNET_PeerIdentity) * num_hops +
6344                        payload_size);
6345   dvb->header.size =
6346     htons (sizeof (struct TransportDVBoxMessage) +
6347            sizeof (struct GNUNET_PeerIdentity) * num_hops + payload_size);
6348   dvb->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_DV_BOX);
6349   dvb->total_hops = htons (total_hops);
6350   dvb->num_hops = htons (num_hops);
6351   dvb->origin = *origin;
6352   dhops = (struct GNUNET_PeerIdentity *) &dvb[1];
6353   memcpy (dhops, hops, num_hops * sizeof (struct GNUNET_PeerIdentity));
6354   memcpy (&dhops[num_hops], payload, payload_size);
6355   route_message (&next_hop->pid, &dvb->header, RMO_NONE);
6356 }
6357
6358
6359 /**
6360  * Communicator gave us a DV box.  Process the request.
6361  *
6362  * @param cls a `struct CommunicatorMessageContext` (must call
6363  * #finish_cmc_handling() when done)
6364  * @param dvb the message that was received
6365  */
6366 static void
6367 handle_dv_box (void *cls, const struct TransportDVBoxMessage *dvb)
6368 {
6369   struct CommunicatorMessageContext *cmc = cls;
6370   uint16_t size = ntohs (dvb->header.size) - sizeof (*dvb);
6371   uint16_t num_hops = ntohs (dvb->num_hops);
6372   const struct GNUNET_PeerIdentity *hops =
6373     (const struct GNUNET_PeerIdentity *) &dvb[1];
6374   const struct GNUNET_MessageHeader *inbox =
6375     (const struct GNUNET_MessageHeader *) &hops[num_hops];
6376
6377   if (num_hops > 0)
6378   {
6379     /* We're trying from the end of the hops array, as we may be
6380        able to find a shortcut unknown to the origin that way */
6381     for (int i = num_hops - 1; i >= 0; i--)
6382     {
6383       struct Neighbour *n;
6384
6385       if (0 == GNUNET_memcmp (&hops[i], &GST_my_identity))
6386       {
6387         GNUNET_break_op (0);
6388         finish_cmc_handling (cmc);
6389         return;
6390       }
6391       n = GNUNET_CONTAINER_multipeermap_get (neighbours, &hops[i]);
6392       if (NULL == n)
6393         continue;
6394       forward_dv_box (n,
6395                       ntohs (dvb->total_hops) + 1,
6396                       num_hops - i - 1, /* number of hops left */
6397                       &dvb->origin,
6398                       &hops[i + 1], /* remaining hops */
6399                       (const void *) &dvb[1],
6400                       size);
6401       finish_cmc_handling (cmc);
6402       return;
6403     }
6404     /* Woopsie, next hop not in neighbours, drop! */
6405     GNUNET_STATISTICS_update (GST_stats,
6406                               "# DV Boxes dropped: next hop unknown",
6407                               1,
6408                               GNUNET_NO);
6409     finish_cmc_handling (cmc);
6410     return;
6411   }
6412   /* We are the target. Unbox and handle message. */
6413   cmc->im.sender = dvb->origin;
6414   cmc->total_hops = ntohs (dvb->total_hops);
6415   demultiplex_with_cmc (cmc, inbox);
6416 }
6417
6418
6419 /**
6420  * Client notified us about transmission from a peer.  Process the request.
6421  *
6422  * @param cls a `struct TransportClient` which sent us the message
6423  * @param obm the send message that was sent
6424  * @return #GNUNET_YES if message is well-formed
6425  */
6426 static int
6427 check_incoming_msg (void *cls,
6428                     const struct GNUNET_TRANSPORT_IncomingMessage *im)
6429 {
6430   struct TransportClient *tc = cls;
6431
6432   if (CT_COMMUNICATOR != tc->type)
6433   {
6434     GNUNET_break (0);
6435     return GNUNET_SYSERR;
6436   }
6437   GNUNET_MQ_check_boxed_message (im);
6438   return GNUNET_OK;
6439 }
6440
6441
6442 /**
6443  * Communicator gave us a transport address validation challenge.  Process the
6444  * request.
6445  *
6446  * @param cls a `struct CommunicatorMessageContext` (must call
6447  * #finish_cmc_handling() when done)
6448  * @param tvc the message that was received
6449  */
6450 static void
6451 handle_validation_challenge (
6452   void *cls,
6453   const struct TransportValidationChallengeMessage *tvc)
6454 {
6455   struct CommunicatorMessageContext *cmc = cls;
6456   struct TransportValidationResponseMessage *tvr;
6457
6458   if (cmc->total_hops > 0)
6459   {
6460     /* DV routing is not allowed for validation challenges! */
6461     GNUNET_break_op (0);
6462     finish_cmc_handling (cmc);
6463     return;
6464   }
6465   tvr = GNUNET_new (struct TransportValidationResponseMessage);
6466   tvr->header.type =
6467     htons (GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_VALIDATION_RESPONSE);
6468   tvr->header.size = htons (sizeof (*tvr));
6469   tvr->challenge = tvc->challenge;
6470   tvr->origin_time = tvc->sender_time;
6471   tvr->validity_duration = cmc->im.expected_address_validity;
6472   {
6473     /* create signature */
6474     struct TransportValidationPS tvp =
6475       {.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_CHALLENGE),
6476        .purpose.size = htonl (sizeof (tvp)),
6477        .validity_duration = tvr->validity_duration,
6478        .challenge = tvc->challenge};
6479
6480     GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_eddsa_sign (GST_my_private_key,
6481                                                           &tvp.purpose,
6482                                                           &tvr->signature));
6483   }
6484   route_message (&cmc->im.sender,
6485                  &tvr->header,
6486                  RMO_ANYTHING_GOES | RMO_REDUNDANT);
6487   finish_cmc_handling (cmc);
6488 }
6489
6490
6491 /**
6492  * Closure for #check_known_challenge.
6493  */
6494 struct CheckKnownChallengeContext
6495 {
6496   /**
6497    * Set to the challenge we are looking for.
6498    */
6499   const struct ChallengeNonceP *challenge;
6500
6501   /**
6502    * Set to a matching validation state, if one was found.
6503    */
6504   struct ValidationState *vs;
6505 };
6506
6507
6508 /**
6509  * Test if the validation state in @a value matches the
6510  * challenge from @a cls.
6511  *
6512  * @param cls a `struct CheckKnownChallengeContext`
6513  * @param pid unused (must match though)
6514  * @param value a `struct ValidationState`
6515  * @return #GNUNET_OK if not matching, #GNUNET_NO if match found
6516  */
6517 static int
6518 check_known_challenge (void *cls,
6519                        const struct GNUNET_PeerIdentity *pid,
6520                        void *value)
6521 {
6522   struct CheckKnownChallengeContext *ckac = cls;
6523   struct ValidationState *vs = value;
6524
6525   (void) pid;
6526   if (0 != GNUNET_memcmp (&vs->challenge, ckac->challenge))
6527     return GNUNET_OK;
6528   ckac->vs = vs;
6529   return GNUNET_NO;
6530 }
6531
6532
6533 /**
6534  * Function called when peerstore is done storing a
6535  * validated address.
6536  *
6537  * @param cls a `struct ValidationState`
6538  * @param success #GNUNET_YES on success
6539  */
6540 static void
6541 peerstore_store_validation_cb (void *cls, int success)
6542 {
6543   struct ValidationState *vs = cls;
6544
6545   vs->sc = NULL;
6546   if (GNUNET_YES == success)
6547     return;
6548   GNUNET_STATISTICS_update (GST_stats,
6549                             "# Peerstore failed to store foreign address",
6550                             1,
6551                             GNUNET_NO);
6552 }
6553
6554
6555 /**
6556  * Task run periodically to validate some address based on #validation_heap.
6557  *
6558  * @param cls NULL
6559  */
6560 static void
6561 validation_start_cb (void *cls);
6562
6563
6564 /**
6565  * Set the time for next_challenge of @a vs to @a new_time.
6566  * Updates the heap and if necessary reschedules the job.
6567  *
6568  * @param vs validation state to update
6569  * @param new_time new time for revalidation
6570  */
6571 static void
6572 update_next_challenge_time (struct ValidationState *vs,
6573                             struct GNUNET_TIME_Absolute new_time)
6574 {
6575   struct GNUNET_TIME_Relative delta;
6576
6577   if (new_time.abs_value_us == vs->next_challenge.abs_value_us)
6578     return; /* be lazy */
6579   vs->next_challenge = new_time;
6580   if (NULL == vs->hn)
6581     vs->hn =
6582       GNUNET_CONTAINER_heap_insert (validation_heap, vs, new_time.abs_value_us);
6583   else
6584     GNUNET_CONTAINER_heap_update_cost (vs->hn, new_time.abs_value_us);
6585   if ((vs != GNUNET_CONTAINER_heap_peek (validation_heap)) &&
6586       (NULL != validation_task))
6587     return;
6588   if (NULL != validation_task)
6589     GNUNET_SCHEDULER_cancel (validation_task);
6590   /* randomize a bit */
6591   delta.rel_value_us =
6592     GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK,
6593                               MIN_DELAY_ADDRESS_VALIDATION.rel_value_us);
6594   new_time = GNUNET_TIME_absolute_add (new_time, delta);
6595   validation_task =
6596     GNUNET_SCHEDULER_add_at (new_time, &validation_start_cb, NULL);
6597 }
6598
6599
6600 /**
6601  * Find the queue matching @a pid and @a address.
6602  *
6603  * @param pid peer the queue must go to
6604  * @param address address the queue must use
6605  * @return NULL if no such queue exists
6606  */
6607 static struct Queue *
6608 find_queue (const struct GNUNET_PeerIdentity *pid, const char *address)
6609 {
6610   struct Neighbour *n;
6611
6612   n = GNUNET_CONTAINER_multipeermap_get (neighbours, pid);
6613   if (NULL == n)
6614     return NULL;
6615   for (struct Queue *pos = n->queue_head; NULL != pos;
6616        pos = pos->next_neighbour)
6617   {
6618     if (0 == strcmp (pos->address, address))
6619       return pos;
6620   }
6621   return NULL;
6622 }
6623
6624
6625 /**
6626  * Task run periodically to check whether the validity of the given queue has
6627  * run its course. If so, finds either another queue to take over, or clears
6628  * the neighbour's `core_visible` flag. In the latter case, gives DV routes a
6629  * chance to take over, and if that fails, notifies CORE about the disconnect.
6630  *
6631  * @param cls a `struct Queue`
6632  */
6633 static void
6634 core_queue_visibility_check (void *cls)
6635 {
6636   struct Queue *q = cls;
6637
6638   q->visibility_task = NULL;
6639   if (0 != GNUNET_TIME_absolute_get_remaining (q->validated_until).rel_value_us)
6640   {
6641     q->visibility_task = GNUNET_SCHEDULER_add_at (q->validated_until,
6642                                                   &core_queue_visibility_check,
6643                                                   q);
6644     return;
6645   }
6646   update_neighbour_core_visibility (q->neighbour);
6647 }
6648
6649
6650 /**
6651  * Check whether the CORE visibility of @a n should change.  Finds either a
6652  * queue to preserve the visibility, or clears the neighbour's `core_visible`
6653  * flag. In the latter case, gives DV routes a chance to take over, and if
6654  * that fails, notifies CORE about the disconnect.  If so, check whether we
6655  * need to notify CORE.
6656  *
6657  * @param n neighbour to perform the check for
6658  */
6659 static void
6660 update_neighbour_core_visibility (struct Neighbour *n)
6661 {
6662   struct DistanceVector *dv;
6663
6664   GNUNET_assert (GNUNET_YES == n->core_visible);
6665   /* Check if _any_ queue of this neighbour is still valid, if so, schedule
6666      the #core_queue_visibility_check() task for that queue */
6667   for (struct Queue *q = n->queue_head; NULL != q; q = q->next_neighbour)
6668   {
6669     if (0 !=
6670         GNUNET_TIME_absolute_get_remaining (q->validated_until).rel_value_us)
6671     {
6672       /* found a valid queue, use this one */
6673       q->visibility_task =
6674         GNUNET_SCHEDULER_add_at (q->validated_until,
6675                                  &core_queue_visibility_check,
6676                                  q);
6677       return;
6678     }
6679   }
6680   n->core_visible = GNUNET_NO;
6681
6682   /* Check if _any_ DV route to this neighbour is currently
6683      valid, if so, do NOT tell core about the loss of direct
6684      connectivity (DV still counts!) */
6685   dv = GNUNET_CONTAINER_multipeermap_get (dv_routes, &n->pid);
6686   if (GNUNET_YES == dv->core_visible)
6687     return;
6688   /* Nothing works anymore, need to tell CORE about the loss of
6689      connectivity! */
6690   cores_send_disconnect_info (&n->pid);
6691 }
6692
6693
6694 /**
6695  * Communicator gave us a transport address validation response.  Process the
6696  * request.
6697  *
6698  * @param cls a `struct CommunicatorMessageContext` (must call
6699  * #finish_cmc_handling() when done)
6700  * @param tvr the message that was received
6701  */
6702 static void
6703 handle_validation_response (
6704   void *cls,
6705   const struct TransportValidationResponseMessage *tvr)
6706 {
6707   struct CommunicatorMessageContext *cmc = cls;
6708   struct ValidationState *vs;
6709   struct CheckKnownChallengeContext ckac = {.challenge = &tvr->challenge,
6710                                             .vs = NULL};
6711   struct GNUNET_TIME_Absolute origin_time;
6712   struct Queue *q;
6713   struct DistanceVector *dv;
6714   struct Neighbour *n;
6715
6716   /* check this is one of our challenges */
6717   (void) GNUNET_CONTAINER_multipeermap_get_multiple (validation_map,
6718                                                      &cmc->im.sender,
6719                                                      &check_known_challenge,
6720                                                      &ckac);
6721   if (NULL == (vs = ckac.vs))
6722   {
6723     /* This can happen simply if we 'forgot' the challenge by now,
6724        i.e. because we received the validation response twice */
6725     GNUNET_STATISTICS_update (GST_stats,
6726                               "# Validations dropped, challenge unknown",
6727                               1,
6728                               GNUNET_NO);
6729     finish_cmc_handling (cmc);
6730     return;
6731   }
6732
6733   /* sanity check on origin time */
6734   origin_time = GNUNET_TIME_absolute_ntoh (tvr->origin_time);
6735   if ((origin_time.abs_value_us < vs->first_challenge_use.abs_value_us) ||
6736       (origin_time.abs_value_us > vs->last_challenge_use.abs_value_us))
6737   {
6738     GNUNET_break_op (0);
6739     finish_cmc_handling (cmc);
6740     return;
6741   }
6742
6743   {
6744     /* check signature */
6745     struct TransportValidationPS tvp =
6746       {.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_CHALLENGE),
6747        .purpose.size = htonl (sizeof (tvp)),
6748        .validity_duration = tvr->validity_duration,
6749        .challenge = tvr->challenge};
6750
6751     if (
6752       GNUNET_OK !=
6753       GNUNET_CRYPTO_eddsa_verify (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_CHALLENGE,
6754                                   &tvp.purpose,
6755                                   &tvr->signature,
6756                                   &cmc->im.sender.public_key))
6757     {
6758       GNUNET_break_op (0);
6759       finish_cmc_handling (cmc);
6760       return;
6761     }
6762   }
6763
6764   /* validity is capped by our willingness to keep track of the
6765      validation entry and the maximum the other peer allows */
6766   vs->valid_until = GNUNET_TIME_relative_to_absolute (
6767     GNUNET_TIME_relative_min (GNUNET_TIME_relative_ntoh (
6768                                 tvr->validity_duration),
6769                               MAX_ADDRESS_VALID_UNTIL));
6770   vs->validated_until =
6771     GNUNET_TIME_absolute_min (vs->valid_until,
6772                               GNUNET_TIME_relative_to_absolute (
6773                                 ADDRESS_VALIDATION_LIFETIME));
6774   vs->validation_rtt = GNUNET_TIME_absolute_get_duration (origin_time);
6775   vs->challenge_backoff = GNUNET_TIME_UNIT_ZERO;
6776   GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE,
6777                               &vs->challenge,
6778                               sizeof (vs->challenge));
6779   vs->first_challenge_use = GNUNET_TIME_absolute_subtract (
6780     vs->validated_until,
6781     GNUNET_TIME_relative_multiply (vs->validation_rtt,
6782                                    VALIDATION_RTT_BUFFER_FACTOR));
6783   vs->last_challenge_use =
6784     GNUNET_TIME_UNIT_ZERO_ABS; /* challenge was not yet used */
6785   update_next_challenge_time (vs, vs->first_challenge_use);
6786   vs->sc = GNUNET_PEERSTORE_store (peerstore,
6787                                    "transport",
6788                                    &cmc->im.sender,
6789                                    GNUNET_PEERSTORE_TRANSPORT_URLADDRESS_KEY,
6790                                    vs->address,
6791                                    strlen (vs->address) + 1,
6792                                    vs->valid_until,
6793                                    GNUNET_PEERSTORE_STOREOPTION_MULTIPLE,
6794                                    &peerstore_store_validation_cb,
6795                                    vs);
6796   finish_cmc_handling (cmc);
6797
6798   /* Finally, we now possibly have a confirmed (!) working queue,
6799      update queue status (if queue still is around) */
6800   q = find_queue (&vs->pid, vs->address);
6801   if (NULL == q)
6802   {
6803     GNUNET_STATISTICS_update (GST_stats,
6804                               "# Queues lost at time of successful validation",
6805                               1,
6806                               GNUNET_NO);
6807     return;
6808   }
6809   q->validated_until = vs->validated_until;
6810   q->pd.aged_rtt = vs->validation_rtt;
6811   n = q->neighbour;
6812   if (GNUNET_NO != n->core_visible)
6813     return; /* nothing changed, we are done here */
6814   n->core_visible = GNUNET_YES;
6815   q->visibility_task = GNUNET_SCHEDULER_add_at (q->validated_until,
6816                                                 &core_queue_visibility_check,
6817                                                 q);
6818   /* Check if _any_ DV route to this neighbour is
6819      currently valid, if so, do NOT tell core anything! */
6820   dv = GNUNET_CONTAINER_multipeermap_get (dv_routes, &n->pid);
6821   if ((NULL != dv) && (GNUNET_YES == dv->core_visible))
6822     return; /* nothing changed, done */
6823   /* We lacked a confirmed connection to the neighbour
6824      before, so tell CORE about it (finally!) */
6825   cores_send_connect_info (&n->pid,
6826                            (NULL != dv)
6827                              ? GNUNET_BANDWIDTH_value_sum (dv->quota_out,
6828                                                            n->quota_out)
6829                              : n->quota_out);
6830 }
6831
6832
6833 /**
6834  * Incoming meessage.  Process the request.
6835  *
6836  * @param im the send message that was received
6837  */
6838 static void
6839 handle_incoming_msg (void *cls,
6840                      const struct GNUNET_TRANSPORT_IncomingMessage *im)
6841 {
6842   struct TransportClient *tc = cls;
6843   struct CommunicatorMessageContext *cmc =
6844     GNUNET_new (struct CommunicatorMessageContext);
6845
6846   cmc->tc = tc;
6847   cmc->im = *im;
6848   demultiplex_with_cmc (cmc, (const struct GNUNET_MessageHeader *) &im[1]);
6849 }
6850
6851
6852 /**
6853  * Given an inbound message @a msg from a communicator @a cmc,
6854  * demultiplex it based on the type calling the right handler.
6855  *
6856  * @param cmc context for demultiplexing
6857  * @param msg message to demultiplex
6858  */
6859 static void
6860 demultiplex_with_cmc (struct CommunicatorMessageContext *cmc,
6861                       const struct GNUNET_MessageHeader *msg)
6862 {
6863   struct GNUNET_MQ_MessageHandler handlers[] =
6864     {GNUNET_MQ_hd_var_size (fragment_box,
6865                             GNUNET_MESSAGE_TYPE_TRANSPORT_FRAGMENT,
6866                             struct TransportFragmentBoxMessage,
6867                             &cmc),
6868      GNUNET_MQ_hd_var_size (reliability_box,
6869                             GNUNET_MESSAGE_TYPE_TRANSPORT_RELIABILITY_BOX,
6870                             struct TransportReliabilityBoxMessage,
6871                             &cmc),
6872      GNUNET_MQ_hd_var_size (reliability_ack,
6873                             GNUNET_MESSAGE_TYPE_TRANSPORT_RELIABILITY_ACK,
6874                             struct TransportReliabilityAckMessage,
6875                             &cmc),
6876      GNUNET_MQ_hd_var_size (backchannel_encapsulation,
6877                             GNUNET_MESSAGE_TYPE_TRANSPORT_BACKCHANNEL_ENCAPSULATION,
6878                             struct TransportBackchannelEncapsulationMessage,
6879                             &cmc),
6880      GNUNET_MQ_hd_var_size (dv_learn,
6881                             GNUNET_MESSAGE_TYPE_TRANSPORT_DV_LEARN,
6882                             struct TransportDVLearnMessage,
6883                             &cmc),
6884      GNUNET_MQ_hd_var_size (dv_box,
6885                             GNUNET_MESSAGE_TYPE_TRANSPORT_DV_BOX,
6886                             struct TransportDVBoxMessage,
6887                             &cmc),
6888      GNUNET_MQ_hd_fixed_size (
6889        validation_challenge,
6890        GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_VALIDATION_CHALLENGE,
6891        struct TransportValidationChallengeMessage,
6892        &cmc),
6893      GNUNET_MQ_hd_fixed_size (
6894        validation_response,
6895        GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_VALIDATION_RESPONSE,
6896        struct TransportValidationResponseMessage,
6897        &cmc),
6898      GNUNET_MQ_handler_end ()};
6899   int ret;
6900
6901   ret = GNUNET_MQ_handle_message (handlers, msg);
6902   if (GNUNET_SYSERR == ret)
6903   {
6904     GNUNET_break (0);
6905     GNUNET_SERVICE_client_drop (cmc->tc->client);
6906     GNUNET_free (cmc);
6907     return;
6908   }
6909   if (GNUNET_NO == ret)
6910   {
6911     /* unencapsulated 'raw' message */
6912     handle_raw_message (&cmc, msg);
6913   }
6914 }
6915
6916
6917 /**
6918  * New queue became available.  Check message.
6919  *
6920  * @param cls the client
6921  * @param aqm the send message that was sent
6922  */
6923 static int
6924 check_add_queue_message (void *cls,
6925                          const struct GNUNET_TRANSPORT_AddQueueMessage *aqm)
6926 {
6927   struct TransportClient *tc = cls;
6928
6929   if (CT_COMMUNICATOR != tc->type)
6930   {
6931     GNUNET_break (0);
6932     return GNUNET_SYSERR;
6933   }
6934   GNUNET_MQ_check_zero_termination (aqm);
6935   return GNUNET_OK;
6936 }
6937
6938
6939 /**
6940  * Bandwidth tracker informs us that the delay until we should receive
6941  * more has changed.
6942  *
6943  * @param cls a `struct Queue` for which the delay changed
6944  */
6945 static void
6946 tracker_update_in_cb (void *cls)
6947 {
6948   struct Queue *queue = cls;
6949   struct GNUNET_TIME_Relative in_delay;
6950   unsigned int rsize;
6951
6952   rsize = (0 == queue->mtu) ? IN_PACKET_SIZE_WITHOUT_MTU : queue->mtu;
6953   in_delay = GNUNET_BANDWIDTH_tracker_get_delay (&queue->tracker_in, rsize);
6954   // FIXME: how exactly do we do inbound flow control?
6955 }
6956
6957
6958 /**
6959  * If necessary, generates the UUID for a @a pm
6960  *
6961  * @param pm pending message to generate UUID for.
6962  */
6963 static void
6964 set_pending_message_uuid (struct PendingMessage *pm)
6965 {
6966   if (pm->msg_uuid_set)
6967     return;
6968   GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE,
6969                               &pm->msg_uuid,
6970                               sizeof (pm->msg_uuid));
6971   pm->msg_uuid_set = GNUNET_YES;
6972 }
6973
6974
6975 /**
6976  * Setup data structure waiting for acknowledgements.
6977  *
6978  * @param queue queue the @a pm will be sent over
6979  * @param dvh path the message will take, may be NULL
6980  * @param pm the pending message for transmission
6981  * @return corresponding fresh pending acknowledgement
6982  */
6983 static struct PendingAcknowledgement *
6984 prepare_pending_acknowledgement (struct Queue *queue,
6985                                  struct DistanceVectorHop *dvh,
6986                                  struct PendingMessage *pm)
6987 {
6988   struct PendingAcknowledgement *pa;
6989
6990   pa = GNUNET_new (struct PendingAcknowledgement);
6991   pa->queue = queue;
6992   pa->dvh = dvh;
6993   pa->pm = pm;
6994   do
6995   {
6996     GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE,
6997                                 &pa->ack_uuid,
6998                                 sizeof (pa->ack_uuid));
6999   } while (GNUNET_YES != GNUNET_CONTAINER_multishortmap_put (
7000                            pending_acks,
7001                            &pa->ack_uuid.value,
7002                            pa,
7003                            GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
7004   GNUNET_CONTAINER_MDLL_insert (queue, queue->pa_head, queue->pa_tail, pa);
7005   GNUNET_CONTAINER_MDLL_insert (pm, pm->pa_head, pm->pa_tail, pa);
7006   if (NULL != dvh)
7007     GNUNET_CONTAINER_MDLL_insert (dvh, dvh->pa_head, dvh->pa_tail, pa);
7008   pa->transmission_time = GNUNET_TIME_absolute_get ();
7009   pa->message_size = pm->bytes_msg;
7010   return pa;
7011 }
7012
7013
7014 /**
7015  * Fragment the given @a pm to the given @a mtu.  Adds
7016  * additional fragments to the neighbour as well. If the
7017  * @a mtu is too small, generates and error for the @a pm
7018  * and returns NULL.
7019  *
7020  * @param queue which queue to fragment for
7021  * @param dvh path the message will take, or NULL
7022  * @param pm pending message to fragment for transmission
7023  * @return new message to transmit
7024  */
7025 static struct PendingMessage *
7026 fragment_message (struct Queue *queue,
7027                   struct DistanceVectorHop *dvh,
7028                   struct PendingMessage *pm)
7029 {
7030   struct PendingAcknowledgement *pa;
7031   struct PendingMessage *ff;
7032   uint16_t mtu;
7033
7034   pa = prepare_pending_acknowledgement (queue, dvh, pm);
7035   mtu = (0 == queue->mtu)
7036           ? UINT16_MAX - sizeof (struct GNUNET_TRANSPORT_SendMessageTo)
7037           : queue->mtu;
7038   set_pending_message_uuid (pm);
7039
7040   /* This invariant is established in #handle_add_queue_message() */
7041   GNUNET_assert (mtu > sizeof (struct TransportFragmentBoxMessage));
7042
7043   /* select fragment for transmission, descending the tree if it has
7044      been expanded until we are at a leaf or at a fragment that is small
7045      enough
7046    */
7047   ff = pm;
7048   while (((ff->bytes_msg > mtu) || (pm == ff)) &&
7049          (ff->frag_off == ff->bytes_msg) && (NULL != ff->head_frag))
7050   {
7051     ff = ff->head_frag; /* descent into fragmented fragments */
7052   }
7053
7054   if (((ff->bytes_msg > mtu) || (pm == ff)) && (pm->frag_off < pm->bytes_msg))
7055   {
7056     /* Did not yet calculate all fragments, calculate next fragment */
7057     struct PendingMessage *frag;
7058     struct TransportFragmentBoxMessage tfb;
7059     const char *orig;
7060     char *msg;
7061     uint16_t fragmax;
7062     uint16_t fragsize;
7063     uint16_t msize;
7064     uint16_t xoff = 0;
7065
7066     orig = (const char *) &ff[1];
7067     msize = ff->bytes_msg;
7068     if (pm != ff)
7069     {
7070       const struct TransportFragmentBoxMessage *tfbo;
7071
7072       tfbo = (const struct TransportFragmentBoxMessage *) orig;
7073       orig += sizeof (struct TransportFragmentBoxMessage);
7074       msize -= sizeof (struct TransportFragmentBoxMessage);
7075       xoff = ntohs (tfbo->frag_off);
7076     }
7077     fragmax = mtu - sizeof (struct TransportFragmentBoxMessage);
7078     fragsize = GNUNET_MIN (msize - ff->frag_off, fragmax);
7079     frag =
7080       GNUNET_malloc (sizeof (struct PendingMessage) +
7081                      sizeof (struct TransportFragmentBoxMessage) + fragsize);
7082     frag->target = pm->target;
7083     frag->frag_parent = ff;
7084     frag->timeout = pm->timeout;
7085     frag->bytes_msg = sizeof (struct TransportFragmentBoxMessage) + fragsize;
7086     frag->pmt = PMT_FRAGMENT_BOX;
7087     msg = (char *) &frag[1];
7088     tfb.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_FRAGMENT);
7089     tfb.header.size =
7090       htons (sizeof (struct TransportFragmentBoxMessage) + fragsize);
7091     tfb.ack_uuid = pa->ack_uuid;
7092     tfb.msg_uuid = pm->msg_uuid;
7093     tfb.frag_off = htons (ff->frag_off + xoff);
7094     tfb.msg_size = htons (pm->bytes_msg);
7095     memcpy (msg, &tfb, sizeof (tfb));
7096     memcpy (&msg[sizeof (tfb)], &orig[ff->frag_off], fragsize);
7097     GNUNET_CONTAINER_MDLL_insert (frag, ff->head_frag, ff->tail_frag, frag);
7098     ff->frag_off += fragsize;
7099     ff = frag;
7100   }
7101
7102   /* Move head to the tail and return it */
7103   GNUNET_CONTAINER_MDLL_remove (frag,
7104                                 ff->frag_parent->head_frag,
7105                                 ff->frag_parent->tail_frag,
7106                                 ff);
7107   GNUNET_CONTAINER_MDLL_insert_tail (frag,
7108                                      ff->frag_parent->head_frag,
7109                                      ff->frag_parent->tail_frag,
7110                                      ff);
7111   return ff;
7112 }
7113
7114
7115 /**
7116  * Reliability-box the given @a pm. On error (can there be any), NULL
7117  * may be returned, otherwise the "replacement" for @a pm (which
7118  * should then be added to the respective neighbour's queue instead of
7119  * @a pm).  If the @a pm is already fragmented or reliability boxed,
7120  * or itself an ACK, this function simply returns @a pm.
7121  *
7122  * @param queue which queue to prepare transmission for
7123  * @param dvh path the message will take, or NULL
7124  * @param pm pending message to box for transmission over unreliabile queue
7125  * @return new message to transmit
7126  */
7127 static struct PendingMessage *
7128 reliability_box_message (struct Queue *queue,
7129                          struct DistanceVectorHop *dvh,
7130                          struct PendingMessage *pm)
7131 {
7132   struct TransportReliabilityBoxMessage rbox;
7133   struct PendingAcknowledgement *pa;
7134   struct PendingMessage *bpm;
7135   char *msg;
7136
7137   if (PMT_CORE != pm->pmt)
7138     return pm; /* already fragmented or reliability boxed, or control message:
7139                   do nothing */
7140   if (NULL != pm->bpm)
7141     return pm->bpm; /* already computed earlier: do nothing */
7142   GNUNET_assert (NULL == pm->head_frag);
7143   if (pm->bytes_msg + sizeof (rbox) > UINT16_MAX)
7144   {
7145     /* failed hard */
7146     GNUNET_break (0);
7147     client_send_response (pm, GNUNET_NO, 0);
7148     return NULL;
7149   }
7150   pa = prepare_pending_acknowledgement (queue, dvh, pm);
7151
7152   bpm = GNUNET_malloc (sizeof (struct PendingMessage) + sizeof (rbox) +
7153                        pm->bytes_msg);
7154   bpm->target = pm->target;
7155   bpm->frag_parent = pm;
7156   GNUNET_CONTAINER_MDLL_insert (frag, pm->head_frag, pm->tail_frag, bpm);
7157   bpm->timeout = pm->timeout;
7158   bpm->pmt = PMT_RELIABILITY_BOX;
7159   bpm->bytes_msg = pm->bytes_msg + sizeof (rbox);
7160   set_pending_message_uuid (bpm);
7161   rbox.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_RELIABILITY_BOX);
7162   rbox.header.size = htons (sizeof (rbox) + pm->bytes_msg);
7163   rbox.ack_countdown = htonl (0); // FIXME: implement ACK countdown support
7164
7165   rbox.ack_uuid = pa->ack_uuid;
7166   msg = (char *) &bpm[1];
7167   memcpy (msg, &rbox, sizeof (rbox));
7168   memcpy (&msg[sizeof (rbox)], &pm[1], pm->bytes_msg);
7169   pm->bpm = bpm;
7170   return bpm;
7171 }
7172
7173
7174 /**
7175  * Change the value of the `next_attempt` field of @a pm
7176  * to @a next_attempt and re-order @a pm in the transmission
7177  * list as required by the new timestmap.
7178  *
7179  * @param pm a pending message to update
7180  * @param next_attempt timestamp to use
7181  */
7182 static void
7183 update_pm_next_attempt (struct PendingMessage *pm,
7184                         struct GNUNET_TIME_Absolute next_attempt)
7185 {
7186   struct Neighbour *neighbour = pm->target;
7187
7188   pm->next_attempt = next_attempt;
7189   if (NULL == pm->frag_parent)
7190   {
7191     struct PendingMessage *pos;
7192
7193     /* re-insert sort in neighbour list */
7194     GNUNET_CONTAINER_MDLL_remove (neighbour,
7195                                   neighbour->pending_msg_head,
7196                                   neighbour->pending_msg_tail,
7197                                   pm);
7198     pos = neighbour->pending_msg_tail;
7199     while ((NULL != pos) &&
7200            (next_attempt.abs_value_us > pos->next_attempt.abs_value_us))
7201       pos = pos->prev_neighbour;
7202     GNUNET_CONTAINER_MDLL_insert_after (neighbour,
7203                                         neighbour->pending_msg_head,
7204                                         neighbour->pending_msg_tail,
7205                                         pos,
7206                                         pm);
7207   }
7208   else
7209   {
7210     /* re-insert sort in fragment list */
7211     struct PendingMessage *fp = pm->frag_parent;
7212     struct PendingMessage *pos;
7213
7214     GNUNET_CONTAINER_MDLL_remove (frag, fp->head_frag, fp->tail_frag, pm);
7215     pos = fp->tail_frag;
7216     while ((NULL != pos) &&
7217            (next_attempt.abs_value_us > pos->next_attempt.abs_value_us))
7218       pos = pos->prev_frag;
7219     GNUNET_CONTAINER_MDLL_insert_after (frag,
7220                                         fp->head_frag,
7221                                         fp->tail_frag,
7222                                         pos,
7223                                         pm);
7224   }
7225 }
7226
7227
7228 /**
7229  * We believe we are ready to transmit a message on a queue. Double-checks
7230  * with the queue's "tracker_out" and then gives the message to the
7231  * communicator for transmission (updating the tracker, and re-scheduling
7232  * itself if applicable).
7233  *
7234  * @param cls the `struct Queue` to process transmissions for
7235  */
7236 static void
7237 transmit_on_queue (void *cls)
7238 {
7239   struct Queue *queue = cls;
7240   struct Neighbour *n = queue->neighbour;
7241   struct PendingMessage *pm;
7242   struct PendingMessage *s;
7243   uint32_t overhead;
7244
7245   queue->transmit_task = NULL;
7246   if (NULL == (pm = n->pending_msg_head))
7247   {
7248     /* no message pending, nothing to do here! */
7249     return;
7250   }
7251   if (NULL != pm->qe)
7252   {
7253     /* message still pending with communciator!
7254        LOGGING-FIXME: Use stats? logging? Should this not be rare? */
7255     return;
7256   }
7257   schedule_transmit_on_queue (queue, GNUNET_YES);
7258   if (NULL != queue->transmit_task)
7259     return; /* do it later */
7260   overhead = 0;
7261   if (GNUNET_TRANSPORT_CC_RELIABLE != queue->tc->details.communicator.cc)
7262     overhead += sizeof (struct TransportReliabilityBoxMessage);
7263   s = pm;
7264   if ( ( (0 != queue->mtu) &&
7265          (pm->bytes_msg + overhead > queue->mtu) ) ||
7266        (pm->bytes_msg > UINT16_MAX - sizeof (struct GNUNET_TRANSPORT_SendMessageTo)) ||
7267        (NULL != pm->head_frag /* fragments already exist, should
7268                                  respect that even if MTU is 0 for
7269                                  this queue */) )
7270     s = fragment_message (queue, NULL /*FIXME! */, s);
7271   if (NULL == s)
7272   {
7273     /* Fragmentation failed, try next message... */
7274     schedule_transmit_on_queue (queue, GNUNET_NO);
7275     return;
7276   }
7277   if (GNUNET_TRANSPORT_CC_RELIABLE != queue->tc->details.communicator.cc)
7278     s = reliability_box_message (queue, NULL /* FIXME! */, s);
7279   if (NULL == s)
7280   {
7281     /* Reliability boxing failed, try next message... */
7282     schedule_transmit_on_queue (queue, GNUNET_NO);
7283     return;
7284   }
7285
7286   /* Pass 's' for transission to the communicator */
7287   queue_send_msg (queue, s, &s[1], s->bytes_msg);
7288   // FIXME: do something similar to the logic below
7289   // in defragmentation / reliability ACK handling!
7290
7291   /* Check if this transmission somehow conclusively finished handing 'pm'
7292      even without any explicit ACKs */
7293   if ((PMT_CORE == s->pmt) &&
7294       (GNUNET_TRANSPORT_CC_RELIABLE == queue->tc->details.communicator.cc))
7295   {
7296     /* Full message sent, and over reliabile channel */
7297     client_send_response (pm, GNUNET_YES, pm->bytes_msg);
7298   }
7299   else if ((GNUNET_TRANSPORT_CC_RELIABLE ==
7300             queue->tc->details.communicator.cc) &&
7301            (PMT_FRAGMENT_BOX == s->pmt))
7302   {
7303     struct PendingMessage *pos;
7304
7305     /* Fragment sent over reliabile channel */
7306     free_fragment_tree (s);
7307     pos = s->frag_parent;
7308     GNUNET_CONTAINER_MDLL_remove (frag, pos->head_frag, pos->tail_frag, s);
7309     GNUNET_free (s);
7310     /* check if subtree is done */
7311     while ((NULL == pos->head_frag) && (pos->frag_off == pos->bytes_msg) &&
7312            (pos != pm))
7313     {
7314       s = pos;
7315       pos = s->frag_parent;
7316       GNUNET_CONTAINER_MDLL_remove (frag, pos->head_frag, pos->tail_frag, s);
7317       GNUNET_free (s);
7318     }
7319
7320     /* Was this the last applicable fragmment? */
7321     if ((NULL == pm->head_frag) && (pm->frag_off == pm->bytes_msg))
7322       client_send_response (
7323         pm,
7324         GNUNET_YES,
7325         pm->bytes_msg /* FIXME: calculate and add overheads! */);
7326   }
7327   else if (PMT_CORE != pm->pmt)
7328   {
7329     /* This was an acknowledgement of some type, always free */
7330     free_pending_message (pm);
7331   }
7332   else
7333   {
7334     /* Message not finished, waiting for acknowledgement.
7335        Update time by which we might retransmit 's' based on queue
7336        characteristics (i.e. RTT); it takes one RTT for the message to
7337        arrive and the ACK to come back in the best case; but the other
7338        side is allowed to delay ACKs by 2 RTTs, so we use 4 RTT before
7339        retransmitting.  Note that in the future this heuristic should
7340        likely be improved further (measure RTT stability, consider
7341        message urgency and size when delaying ACKs, etc.) */
7342     update_pm_next_attempt (s,
7343                             GNUNET_TIME_relative_to_absolute (
7344                               GNUNET_TIME_relative_multiply (queue->pd.aged_rtt,
7345                                                              4)));
7346   }
7347
7348   /* finally, re-schedule queue transmission task itself */
7349   schedule_transmit_on_queue (queue, GNUNET_NO);
7350 }
7351
7352
7353 /**
7354  * Bandwidth tracker informs us that the delay until we
7355  * can transmit again changed.
7356  *
7357  * @param cls a `struct Queue` for which the delay changed
7358  */
7359 static void
7360 tracker_update_out_cb (void *cls)
7361 {
7362   struct Queue *queue = cls;
7363   struct Neighbour *n = queue->neighbour;
7364
7365   if (NULL == n->pending_msg_head)
7366   {
7367     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
7368                 "Bandwidth allocation updated for empty transmission queue `%s'\n",
7369                 queue->address);
7370     return; /* no message pending, nothing to do here! */
7371   }
7372   GNUNET_SCHEDULER_cancel (queue->transmit_task);
7373   queue->transmit_task = NULL;
7374   schedule_transmit_on_queue (queue, GNUNET_NO);
7375 }
7376
7377
7378 /**
7379  * Bandwidth tracker informs us that excessive outbound bandwidth was
7380  * allocated which is not being used.
7381  *
7382  * @param cls a `struct Queue` for which the excess was noted
7383  */
7384 static void
7385 tracker_excess_out_cb (void *cls)
7386 {
7387   (void) cls;
7388
7389   /* FIXME: trigger excess bandwidth report to core? Right now,
7390      this is done internally within transport_api2_core already,
7391      but we probably want to change the logic and trigger it
7392      from here via a message instead! */
7393   /* TODO: maybe inform someone at this point? */
7394   GNUNET_STATISTICS_update (GST_stats,
7395                             "# Excess outbound bandwidth reported",
7396                             1,
7397                             GNUNET_NO);
7398 }
7399
7400
7401 /**
7402  * Bandwidth tracker informs us that excessive inbound bandwidth was allocated
7403  * which is not being used.
7404  *
7405  * @param cls a `struct Queue` for which the excess was noted
7406  */
7407 static void
7408 tracker_excess_in_cb (void *cls)
7409 {
7410   (void) cls;
7411
7412   /* TODO: maybe inform somone at this point? */
7413   GNUNET_STATISTICS_update (GST_stats,
7414                             "# Excess inbound bandwidth reported",
7415                             1,
7416                             GNUNET_NO);
7417 }
7418
7419
7420 /**
7421  * Queue to a peer went down.  Process the request.
7422  *
7423  * @param cls the client
7424  * @param dqm the send message that was sent
7425  */
7426 static void
7427 handle_del_queue_message (void *cls,
7428                           const struct GNUNET_TRANSPORT_DelQueueMessage *dqm)
7429 {
7430   struct TransportClient *tc = cls;
7431
7432   if (CT_COMMUNICATOR != tc->type)
7433   {
7434     GNUNET_break (0);
7435     GNUNET_SERVICE_client_drop (tc->client);
7436     return;
7437   }
7438   for (struct Queue *queue = tc->details.communicator.queue_head; NULL != queue;
7439        queue = queue->next_client)
7440   {
7441     struct Neighbour *neighbour = queue->neighbour;
7442
7443     if ((dqm->qid != queue->qid) ||
7444         (0 != GNUNET_memcmp (&dqm->receiver, &neighbour->pid)))
7445       continue;
7446     free_queue (queue);
7447     GNUNET_SERVICE_client_continue (tc->client);
7448     return;
7449   }
7450   GNUNET_break (0);
7451   GNUNET_SERVICE_client_drop (tc->client);
7452 }
7453
7454
7455 /**
7456  * Message was transmitted.  Process the request.
7457  *
7458  * @param cls the client
7459  * @param sma the send message that was sent
7460  */
7461 static void
7462 handle_send_message_ack (void *cls,
7463                          const struct GNUNET_TRANSPORT_SendMessageToAck *sma)
7464 {
7465   struct TransportClient *tc = cls;
7466   struct QueueEntry *qe;
7467   struct PendingMessage *pm;
7468
7469   if (CT_COMMUNICATOR != tc->type)
7470   {
7471     GNUNET_break (0);
7472     GNUNET_SERVICE_client_drop (tc->client);
7473     return;
7474   }
7475
7476   /* find our queue entry matching the ACK */
7477   qe = NULL;
7478   for (struct Queue *queue = tc->details.communicator.queue_head; NULL != queue;
7479        queue = queue->next_client)
7480   {
7481     if (0 != GNUNET_memcmp (&queue->neighbour->pid, &sma->receiver))
7482       continue;
7483     for (struct QueueEntry *qep = queue->queue_head; NULL != qep;
7484          qep = qep->next)
7485     {
7486       if (qep->mid != sma->mid)
7487         continue;
7488       qe = qep;
7489       break;
7490     }
7491     break;
7492   }
7493   if (NULL == qe)
7494   {
7495     /* this should never happen */
7496     GNUNET_break (0);
7497     GNUNET_SERVICE_client_drop (tc->client);
7498     return;
7499   }
7500   GNUNET_CONTAINER_DLL_remove (qe->queue->queue_head,
7501                                qe->queue->queue_tail,
7502                                qe);
7503   qe->queue->queue_length--;
7504   tc->details.communicator.total_queue_length--;
7505   GNUNET_SERVICE_client_continue (tc->client);
7506
7507   /* if applicable, resume transmissions that waited on ACK */
7508   if (COMMUNICATOR_TOTAL_QUEUE_LIMIT - 1 ==
7509       tc->details.communicator.total_queue_length)
7510   {
7511     /* Communicator dropped below threshold, resume all queues
7512        incident with this client! */
7513     GNUNET_STATISTICS_update (
7514       GST_stats,
7515       "# Transmission throttled due to communicator queue limit",
7516       -1,
7517       GNUNET_NO);
7518     for (struct Queue *queue = tc->details.communicator.queue_head;
7519          NULL != queue;
7520          queue = queue->next_client)
7521       schedule_transmit_on_queue (queue, GNUNET_NO);
7522   }
7523   else if (QUEUE_LENGTH_LIMIT - 1 == qe->queue->queue_length)
7524   {
7525     /* queue dropped below threshold; only resume this one queue */
7526     GNUNET_STATISTICS_update (GST_stats,
7527                               "# Transmission throttled due to queue queue limit",
7528                               -1,
7529                               GNUNET_NO);
7530     schedule_transmit_on_queue (qe->queue, GNUNET_NO);
7531   }
7532
7533   if (NULL != (pm = qe->pm))
7534   {
7535     struct Neighbour *n;
7536
7537     GNUNET_assert (qe == pm->qe);
7538     pm->qe = NULL;
7539     /* If waiting for this communicator may have blocked transmission
7540        of pm on other queues for this neighbour, force schedule
7541        transmit on queue for queues of the neighbour */
7542     n = pm->target;
7543     if (n->pending_msg_head == pm)
7544     {
7545       for (struct Queue *queue = n->queue_head; NULL != queue;
7546            queue = queue->next_neighbour)
7547         schedule_transmit_on_queue (queue, GNUNET_NO);
7548     }
7549     if (GNUNET_OK != ntohl (sma->status))
7550     {
7551       GNUNET_log (
7552         GNUNET_ERROR_TYPE_INFO,
7553         "Queue failed in transmission, will try retransmission immediately\n");
7554       update_pm_next_attempt (pm, GNUNET_TIME_UNIT_ZERO_ABS);
7555     }
7556   }
7557   GNUNET_free (qe);
7558 }
7559
7560
7561 /**
7562  * Iterator telling new MONITOR client about all existing
7563  * queues to peers.
7564  *
7565  * @param cls the new `struct TransportClient`
7566  * @param pid a connected peer
7567  * @param value the `struct Neighbour` with more information
7568  * @return #GNUNET_OK (continue to iterate)
7569  */
7570 static int
7571 notify_client_queues (void *cls,
7572                       const struct GNUNET_PeerIdentity *pid,
7573                       void *value)
7574 {
7575   struct TransportClient *tc = cls;
7576   struct Neighbour *neighbour = value;
7577
7578   GNUNET_assert (CT_MONITOR == tc->type);
7579   for (struct Queue *q = neighbour->queue_head; NULL != q;
7580        q = q->next_neighbour)
7581   {
7582     struct MonitorEvent me = {.rtt = q->pd.aged_rtt,
7583                               .cs = q->cs,
7584                               .num_msg_pending = q->num_msg_pending,
7585                               .num_bytes_pending = q->num_bytes_pending};
7586
7587     notify_monitor (tc, pid, q->address, q->nt, &me);
7588   }
7589   return GNUNET_OK;
7590 }
7591
7592
7593 /**
7594  * Initialize a monitor client.
7595  *
7596  * @param cls the client
7597  * @param start the start message that was sent
7598  */
7599 static void
7600 handle_monitor_start (void *cls,
7601                       const struct GNUNET_TRANSPORT_MonitorStart *start)
7602 {
7603   struct TransportClient *tc = cls;
7604
7605   if (CT_NONE != tc->type)
7606   {
7607     GNUNET_break (0);
7608     GNUNET_SERVICE_client_drop (tc->client);
7609     return;
7610   }
7611   tc->type = CT_MONITOR;
7612   tc->details.monitor.peer = start->peer;
7613   tc->details.monitor.one_shot = ntohl (start->one_shot);
7614   GNUNET_CONTAINER_multipeermap_iterate (neighbours, &notify_client_queues, tc);
7615   GNUNET_SERVICE_client_mark_monitor (tc->client);
7616   GNUNET_SERVICE_client_continue (tc->client);
7617 }
7618
7619
7620 /**
7621  * Find transport client providing communication service
7622  * for the protocol @a prefix.
7623  *
7624  * @param prefix communicator name
7625  * @return NULL if no such transport client is available
7626  */
7627 static struct TransportClient *
7628 lookup_communicator (const char *prefix)
7629 {
7630   for (struct TransportClient *tc = clients_head; NULL != tc; tc = tc->next)
7631   {
7632     if (CT_COMMUNICATOR != tc->type)
7633       continue;
7634     if (0 == strcmp (prefix, tc->details.communicator.address_prefix))
7635       return tc;
7636   }
7637   GNUNET_log (
7638     GNUNET_ERROR_TYPE_WARNING,
7639     "Somone suggested use of communicator for `%s', but we do not have such a communicator!\n",
7640     prefix);
7641   return NULL;
7642 }
7643
7644
7645 /**
7646  * Signature of a function called with a communicator @a address of a peer
7647  * @a pid that an application wants us to connect to.
7648  *
7649  * @param pid target peer
7650  * @param address the address to try
7651  */
7652 static void
7653 suggest_to_connect (const struct GNUNET_PeerIdentity *pid, const char *address)
7654 {
7655   static uint32_t idgen;
7656   struct TransportClient *tc;
7657   char *prefix;
7658   struct GNUNET_TRANSPORT_CreateQueue *cqm;
7659   struct GNUNET_MQ_Envelope *env;
7660   size_t alen;
7661
7662   prefix = GNUNET_HELLO_address_to_prefix (address);
7663   if (NULL == prefix)
7664   {
7665     GNUNET_break (0); /* We got an invalid address!? */
7666     return;
7667   }
7668   tc = lookup_communicator (prefix);
7669   if (NULL == tc)
7670   {
7671     GNUNET_STATISTICS_update (GST_stats,
7672                               "# Suggestions ignored due to missing communicator",
7673                               1,
7674                               GNUNET_NO);
7675     return;
7676   }
7677   /* forward suggestion for queue creation to communicator */
7678   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
7679               "Request #%u for `%s' communicator to create queue to `%s'\n",
7680               (unsigned int) idgen,
7681               prefix,
7682               address);
7683   alen = strlen (address) + 1;
7684   env =
7685     GNUNET_MQ_msg_extra (cqm, alen, GNUNET_MESSAGE_TYPE_TRANSPORT_QUEUE_CREATE);
7686   cqm->request_id = htonl (idgen++);
7687   cqm->receiver = *pid;
7688   memcpy (&cqm[1], address, alen);
7689   GNUNET_MQ_send (tc->mq, env);
7690 }
7691
7692
7693 /**
7694  * The queue @a q (which matches the peer and address in @a vs) is
7695  * ready for queueing. We should now queue the validation request.
7696  *
7697  * @param q queue to send on
7698  * @param vs state to derive validation challenge from
7699  */
7700 static void
7701 validation_transmit_on_queue (struct Queue *q, struct ValidationState *vs)
7702 {
7703   struct TransportValidationChallengeMessage tvc;
7704
7705   vs->last_challenge_use = GNUNET_TIME_absolute_get ();
7706   tvc.header.type =
7707     htons (GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_VALIDATION_CHALLENGE);
7708   tvc.header.size = htons (sizeof (tvc));
7709   tvc.reserved = htonl (0);
7710   tvc.challenge = vs->challenge;
7711   tvc.sender_time = GNUNET_TIME_absolute_hton (vs->last_challenge_use);
7712   queue_send_msg (q, NULL, &tvc, sizeof (tvc));
7713 }
7714
7715
7716 /**
7717  * Task run periodically to validate some address based on #validation_heap.
7718  *
7719  * @param cls NULL
7720  */
7721 static void
7722 validation_start_cb (void *cls)
7723 {
7724   struct ValidationState *vs;
7725   struct Queue *q;
7726
7727   (void) cls;
7728   validation_task = NULL;
7729   vs = GNUNET_CONTAINER_heap_peek (validation_heap);
7730   /* drop validations past their expiration */
7731   while (
7732     (NULL != vs) &&
7733     (0 == GNUNET_TIME_absolute_get_remaining (vs->valid_until).rel_value_us))
7734   {
7735     free_validation_state (vs);
7736     vs = GNUNET_CONTAINER_heap_peek (validation_heap);
7737   }
7738   if (NULL == vs)
7739     return; /* woopsie, no more addresses known, should only
7740                happen if we're really a lonely peer */
7741   q = find_queue (&vs->pid, vs->address);
7742   if (NULL == q)
7743   {
7744     vs->awaiting_queue = GNUNET_YES;
7745     suggest_to_connect (&vs->pid, vs->address);
7746   }
7747   else
7748     validation_transmit_on_queue (q, vs);
7749   /* Finally, reschedule next attempt */
7750   vs->challenge_backoff =
7751     GNUNET_TIME_randomized_backoff (vs->challenge_backoff,
7752                                     MAX_VALIDATION_CHALLENGE_FREQ);
7753   update_next_challenge_time (vs,
7754                               GNUNET_TIME_relative_to_absolute (
7755                                 vs->challenge_backoff));
7756 }
7757
7758
7759 /**
7760  * Closure for #check_connection_quality.
7761  */
7762 struct QueueQualityContext
7763 {
7764   /**
7765    * Set to the @e k'th queue encountered.
7766    */
7767   struct Queue *q;
7768
7769   /**
7770    * Set to the number of quality queues encountered.
7771    */
7772   unsigned int quality_count;
7773
7774   /**
7775    * Set to the total number of queues encountered.
7776    */
7777   unsigned int num_queues;
7778
7779   /**
7780    * Decremented for each queue, for selection of the
7781    * k-th queue in @e q.
7782    */
7783   unsigned int k;
7784 };
7785
7786
7787 /**
7788  * Check whether any queue to the given neighbour is
7789  * of a good "quality" and if so, increment the counter.
7790  * Also counts the total number of queues, and returns
7791  * the k-th queue found.
7792  *
7793  * @param cls a `struct QueueQualityContext *` with counters
7794  * @param pid peer this is about
7795  * @param value a `struct Neighbour`
7796  * @return #GNUNET_OK (continue to iterate)
7797  */
7798 static int
7799 check_connection_quality (void *cls,
7800                           const struct GNUNET_PeerIdentity *pid,
7801                           void *value)
7802 {
7803   struct QueueQualityContext *ctx = cls;
7804   struct Neighbour *n = value;
7805   int do_inc;
7806
7807   (void) pid;
7808   do_inc = GNUNET_NO;
7809   for (struct Queue *q = n->queue_head; NULL != q; q = q->next_neighbour)
7810   {
7811     ctx->num_queues++;
7812     if (0 == ctx->k--)
7813       ctx->q = q;
7814     /* OPTIMIZE-FIXME: in the future, add reliability / goodput
7815        statistics and consider those as well here? */
7816     if (q->pd.aged_rtt.rel_value_us < DV_QUALITY_RTT_THRESHOLD.rel_value_us)
7817       do_inc = GNUNET_YES;
7818   }
7819   if (GNUNET_YES == do_inc)
7820     ctx->quality_count++;
7821   return GNUNET_OK;
7822 }
7823
7824
7825 /**
7826  * Task run when we CONSIDER initiating a DV learn
7827  * process. We first check that sending out a message is
7828  * even possible (queues exist), then that it is desirable
7829  * (if not, reschedule the task for later), and finally
7830  * we may then begin the job.  If there are too many
7831  * entries in the #dvlearn_map, we purge the oldest entry
7832  * using #lle_tail.
7833  *
7834  * @param cls NULL
7835  */
7836 static void
7837 start_dv_learn (void *cls)
7838 {
7839   struct LearnLaunchEntry *lle;
7840   struct QueueQualityContext qqc;
7841   struct TransportDVLearnMessage dvl;
7842
7843   (void) cls;
7844   dvlearn_task = NULL;
7845   if (0 == GNUNET_CONTAINER_multipeermap_size (neighbours))
7846     return; /* lost all connectivity, cannot do learning */
7847   qqc.quality_count = 0;
7848   qqc.num_queues = 0;
7849   GNUNET_CONTAINER_multipeermap_iterate (neighbours,
7850                                          &check_connection_quality,
7851                                          &qqc);
7852   if (qqc.quality_count > DV_LEARN_QUALITY_THRESHOLD)
7853   {
7854     struct GNUNET_TIME_Relative delay;
7855     unsigned int factor;
7856
7857     /* scale our retries by how far we are above the threshold */
7858     factor = qqc.quality_count / DV_LEARN_QUALITY_THRESHOLD;
7859     delay = GNUNET_TIME_relative_multiply (DV_LEARN_BASE_FREQUENCY, factor);
7860     dvlearn_task = GNUNET_SCHEDULER_add_delayed (delay, &start_dv_learn, NULL);
7861     return;
7862   }
7863   /* remove old entries in #dvlearn_map if it has grown too big */
7864   while (MAX_DV_LEARN_PENDING >=
7865          GNUNET_CONTAINER_multishortmap_size (dvlearn_map))
7866   {
7867     lle = lle_tail;
7868     GNUNET_assert (GNUNET_YES ==
7869                    GNUNET_CONTAINER_multishortmap_remove (dvlearn_map,
7870                                                           &lle->challenge.value,
7871                                                           lle));
7872     GNUNET_CONTAINER_DLL_remove (lle_head, lle_tail, lle);
7873     GNUNET_free (lle);
7874   }
7875   /* setup data structure for learning */
7876   lle = GNUNET_new (struct LearnLaunchEntry);
7877   GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE,
7878                               &lle->challenge,
7879                               sizeof (lle->challenge));
7880   GNUNET_CONTAINER_DLL_insert (lle_head, lle_tail, lle);
7881   GNUNET_break (GNUNET_YES ==
7882                 GNUNET_CONTAINER_multishortmap_put (
7883                   dvlearn_map,
7884                   &lle->challenge.value,
7885                   lle,
7886                   GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
7887   dvl.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_DV_LEARN);
7888   dvl.header.size = htons (sizeof (dvl));
7889   dvl.num_hops = htons (0);
7890   dvl.bidirectional = htons (0);
7891   dvl.non_network_delay = GNUNET_TIME_relative_hton (GNUNET_TIME_UNIT_ZERO);
7892   {
7893     struct DvInitPS dvip = {.purpose.purpose = htonl (
7894                               GNUNET_SIGNATURE_PURPOSE_TRANSPORT_DV_INITIATOR),
7895                             .purpose.size = htonl (sizeof (dvip)),
7896                             .challenge = lle->challenge};
7897
7898     GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_eddsa_sign (GST_my_private_key,
7899                                                           &dvip.purpose,
7900                                                           &dvl.init_sig));
7901   }
7902   dvl.initiator = GST_my_identity;
7903   dvl.challenge = lle->challenge;
7904
7905   qqc.quality_count = 0;
7906   qqc.k = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, qqc.num_queues);
7907   qqc.num_queues = 0;
7908   qqc.q = NULL;
7909   GNUNET_CONTAINER_multipeermap_iterate (neighbours,
7910                                          &check_connection_quality,
7911                                          &qqc);
7912   GNUNET_assert (NULL != qqc.q);
7913
7914   /* Do this as close to transmission time as possible! */
7915   lle->launch_time = GNUNET_TIME_absolute_get ();
7916
7917   queue_send_msg (qqc.q, NULL, &dvl, sizeof (dvl));
7918   /* reschedule this job, randomizing the time it runs (but no
7919      actual backoff!) */
7920   dvlearn_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_randomize (
7921                                                  DV_LEARN_BASE_FREQUENCY),
7922                                                &start_dv_learn,
7923                                                NULL);
7924 }
7925
7926
7927 /**
7928  * A new queue has been created, check if any address validation
7929  * requests have been waiting for it.
7930  *
7931  * @param cls a `struct Queue`
7932  * @param pid peer concerned (unused)
7933  * @param value a `struct ValidationState`
7934  * @return #GNUNET_NO if a match was found and we can stop looking
7935  */
7936 static int
7937 check_validation_request_pending (void *cls,
7938                                   const struct GNUNET_PeerIdentity *pid,
7939                                   void *value)
7940 {
7941   struct Queue *q = cls;
7942   struct ValidationState *vs = value;
7943
7944   (void) pid;
7945   if ((GNUNET_YES == vs->awaiting_queue) &&
7946       (0 == strcmp (vs->address, q->address)))
7947   {
7948     vs->awaiting_queue = GNUNET_NO;
7949     validation_transmit_on_queue (q, vs);
7950     return GNUNET_NO;
7951   }
7952   return GNUNET_OK;
7953 }
7954
7955
7956 /**
7957  * New queue became available.  Process the request.
7958  *
7959  * @param cls the client
7960  * @param aqm the send message that was sent
7961  */
7962 static void
7963 handle_add_queue_message (void *cls,
7964                           const struct GNUNET_TRANSPORT_AddQueueMessage *aqm)
7965 {
7966   struct TransportClient *tc = cls;
7967   struct Queue *queue;
7968   struct Neighbour *neighbour;
7969   const char *addr;
7970   uint16_t addr_len;
7971
7972   if (ntohl (aqm->mtu) <= sizeof (struct TransportFragmentBoxMessage))
7973   {
7974     /* MTU so small as to be useless for transmissions,
7975        required for #fragment_message()! */
7976     GNUNET_break_op (0);
7977     GNUNET_SERVICE_client_drop (tc->client);
7978     return;
7979   }
7980   neighbour = lookup_neighbour (&aqm->receiver);
7981   if (NULL == neighbour)
7982   {
7983     neighbour = GNUNET_new (struct Neighbour);
7984     neighbour->earliest_timeout = GNUNET_TIME_UNIT_FOREVER_ABS;
7985     neighbour->pid = aqm->receiver;
7986     GNUNET_assert (GNUNET_OK ==
7987                    GNUNET_CONTAINER_multipeermap_put (
7988                      neighbours,
7989                      &neighbour->pid,
7990                      neighbour,
7991                      GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
7992   }
7993   addr_len = ntohs (aqm->header.size) - sizeof (*aqm);
7994   addr = (const char *) &aqm[1];
7995
7996   queue = GNUNET_malloc (sizeof (struct Queue) + addr_len);
7997   queue->tc = tc;
7998   queue->address = (const char *) &queue[1];
7999   queue->pd.aged_rtt = GNUNET_TIME_UNIT_FOREVER_REL;
8000   queue->qid = aqm->qid;
8001   queue->mtu = ntohl (aqm->mtu);
8002   queue->nt = (enum GNUNET_NetworkType) ntohl (aqm->nt);
8003   queue->cs = (enum GNUNET_TRANSPORT_ConnectionStatus) ntohl (aqm->cs);
8004   queue->neighbour = neighbour;
8005   GNUNET_BANDWIDTH_tracker_init2 (&queue->tracker_in,
8006                                   &tracker_update_in_cb,
8007                                   queue,
8008                                   GNUNET_BANDWIDTH_ZERO,
8009                                   GNUNET_CONSTANTS_MAX_BANDWIDTH_CARRY_S,
8010                                   &tracker_excess_in_cb,
8011                                   queue);
8012   GNUNET_BANDWIDTH_tracker_init2 (&queue->tracker_out,
8013                                   &tracker_update_out_cb,
8014                                   queue,
8015                                   GNUNET_BANDWIDTH_ZERO,
8016                                   GNUNET_CONSTANTS_MAX_BANDWIDTH_CARRY_S,
8017                                   &tracker_excess_out_cb,
8018                                   queue);
8019   memcpy (&queue[1], addr, addr_len);
8020   /* notify monitors about new queue */
8021   {
8022     struct MonitorEvent me = {.rtt = queue->pd.aged_rtt, .cs = queue->cs};
8023
8024     notify_monitors (&neighbour->pid, queue->address, queue->nt, &me);
8025   }
8026   GNUNET_CONTAINER_MDLL_insert (neighbour,
8027                                 neighbour->queue_head,
8028                                 neighbour->queue_tail,
8029                                 queue);
8030   GNUNET_CONTAINER_MDLL_insert (client,
8031                                 tc->details.communicator.queue_head,
8032                                 tc->details.communicator.queue_tail,
8033                                 queue);
8034   /* check if valdiations are waiting for the queue */
8035   (void)
8036     GNUNET_CONTAINER_multipeermap_get_multiple (validation_map,
8037                                                 &aqm->receiver,
8038                                                 &check_validation_request_pending,
8039                                                 queue);
8040   /* might be our first queue, try launching DV learning */
8041   if (NULL == dvlearn_task)
8042     dvlearn_task = GNUNET_SCHEDULER_add_now (&start_dv_learn, NULL);
8043   GNUNET_SERVICE_client_continue (tc->client);
8044 }
8045
8046
8047 /**
8048  * Communicator tells us that our request to create a queue "worked", that
8049  * is setting up the queue is now in process.
8050  *
8051  * @param cls the `struct TransportClient`
8052  * @param cqr confirmation message
8053  */
8054 static void
8055 handle_queue_create_ok (void *cls,
8056                         const struct GNUNET_TRANSPORT_CreateQueueResponse *cqr)
8057 {
8058   struct TransportClient *tc = cls;
8059
8060   if (CT_COMMUNICATOR != tc->type)
8061   {
8062     GNUNET_break (0);
8063     GNUNET_SERVICE_client_drop (tc->client);
8064     return;
8065   }
8066   GNUNET_STATISTICS_update (GST_stats,
8067                             "# Suggestions succeeded at communicator",
8068                             1,
8069                             GNUNET_NO);
8070   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
8071               "Request #%u for communicator to create queue succeeded\n",
8072               (unsigned int) ntohs (cqr->request_id));
8073   GNUNET_SERVICE_client_continue (tc->client);
8074 }
8075
8076
8077 /**
8078  * Communicator tells us that our request to create a queue failed. This
8079  * usually indicates that the provided address is simply invalid or that the
8080  * communicator's resources are exhausted.
8081  *
8082  * @param cls the `struct TransportClient`
8083  * @param cqr failure message
8084  */
8085 static void
8086 handle_queue_create_fail (
8087   void *cls,
8088   const struct GNUNET_TRANSPORT_CreateQueueResponse *cqr)
8089 {
8090   struct TransportClient *tc = cls;
8091
8092   if (CT_COMMUNICATOR != tc->type)
8093   {
8094     GNUNET_break (0);
8095     GNUNET_SERVICE_client_drop (tc->client);
8096     return;
8097   }
8098   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
8099               "Request #%u for communicator to create queue failed\n",
8100               (unsigned int) ntohs (cqr->request_id));
8101   GNUNET_STATISTICS_update (GST_stats,
8102                             "# Suggestions failed in queue creation at communicator",
8103                             1,
8104                             GNUNET_NO);
8105   GNUNET_SERVICE_client_continue (tc->client);
8106 }
8107
8108
8109 /**
8110  * We have received a `struct ExpressPreferenceMessage` from an application
8111  * client.
8112  *
8113  * @param cls handle to the client
8114  * @param msg the start message
8115  */
8116 static void
8117 handle_suggest_cancel (void *cls, const struct ExpressPreferenceMessage *msg)
8118 {
8119   struct TransportClient *tc = cls;
8120   struct PeerRequest *pr;
8121
8122   if (CT_APPLICATION != tc->type)
8123   {
8124     GNUNET_break (0);
8125     GNUNET_SERVICE_client_drop (tc->client);
8126     return;
8127   }
8128   pr = GNUNET_CONTAINER_multipeermap_get (tc->details.application.requests,
8129                                           &msg->peer);
8130   if (NULL == pr)
8131   {
8132     GNUNET_break (0);
8133     GNUNET_SERVICE_client_drop (tc->client);
8134     return;
8135   }
8136   (void) stop_peer_request (tc, &pr->pid, pr);
8137   GNUNET_SERVICE_client_continue (tc->client);
8138 }
8139
8140
8141 /**
8142  * Check #GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_CONSIDER_VERIFY
8143  * messages. We do nothing here, real verification is done later.
8144  *
8145  * @param cls a `struct TransportClient *`
8146  * @param msg message to verify
8147  * @return #GNUNET_OK
8148  */
8149 static int
8150 check_address_consider_verify (
8151   void *cls,
8152   const struct GNUNET_TRANSPORT_AddressToVerify *hdr)
8153 {
8154   (void) cls;
8155   (void) hdr;
8156   return GNUNET_OK;
8157 }
8158
8159
8160 /**
8161  * Closure for #check_known_address.
8162  */
8163 struct CheckKnownAddressContext
8164 {
8165   /**
8166    * Set to the address we are looking for.
8167    */
8168   const char *address;
8169
8170   /**
8171    * Set to a matching validation state, if one was found.
8172    */
8173   struct ValidationState *vs;
8174 };
8175
8176
8177 /**
8178  * Test if the validation state in @a value matches the
8179  * address from @a cls.
8180  *
8181  * @param cls a `struct CheckKnownAddressContext`
8182  * @param pid unused (must match though)
8183  * @param value a `struct ValidationState`
8184  * @return #GNUNET_OK if not matching, #GNUNET_NO if match found
8185  */
8186 static int
8187 check_known_address (void *cls,
8188                      const struct GNUNET_PeerIdentity *pid,
8189                      void *value)
8190 {
8191   struct CheckKnownAddressContext *ckac = cls;
8192   struct ValidationState *vs = value;
8193
8194   (void) pid;
8195   if (0 != strcmp (vs->address, ckac->address))
8196     return GNUNET_OK;
8197   ckac->vs = vs;
8198   return GNUNET_NO;
8199 }
8200
8201
8202 /**
8203  * Start address validation.
8204  *
8205  * @param pid peer the @a address is for
8206  * @param address an address to reach @a pid (presumably)
8207  * @param expiration when did @a pid claim @a address will become invalid
8208  */
8209 static void
8210 start_address_validation (const struct GNUNET_PeerIdentity *pid,
8211                           const char *address,
8212                           struct GNUNET_TIME_Absolute expiration)
8213 {
8214   struct GNUNET_TIME_Absolute now;
8215   struct ValidationState *vs;
8216   struct CheckKnownAddressContext ckac = {.address = address, .vs = NULL};
8217
8218   if (0 == GNUNET_TIME_absolute_get_remaining (expiration).rel_value_us)
8219     return; /* expired */
8220   (void) GNUNET_CONTAINER_multipeermap_get_multiple (validation_map,
8221                                                      pid,
8222                                                      &check_known_address,
8223                                                      &ckac);
8224   if (NULL != (vs = ckac.vs))
8225   {
8226     /* if 'vs' is not currently valid, we need to speed up retrying the
8227      * validation */
8228     if (vs->validated_until.abs_value_us < vs->next_challenge.abs_value_us)
8229     {
8230       /* reduce backoff as we got a fresh advertisement */
8231       vs->challenge_backoff =
8232         GNUNET_TIME_relative_min (FAST_VALIDATION_CHALLENGE_FREQ,
8233                                   GNUNET_TIME_relative_divide (vs->challenge_backoff,
8234                                                                2));
8235       update_next_challenge_time (vs,
8236                                   GNUNET_TIME_relative_to_absolute (
8237                                     vs->challenge_backoff));
8238     }
8239     return;
8240   }
8241   now = GNUNET_TIME_absolute_get ();
8242   vs = GNUNET_new (struct ValidationState);
8243   vs->pid = *pid;
8244   vs->valid_until = expiration;
8245   vs->first_challenge_use = now;
8246   vs->validation_rtt = GNUNET_TIME_UNIT_FOREVER_REL;
8247   GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE,
8248                               &vs->challenge,
8249                               sizeof (vs->challenge));
8250   vs->address = GNUNET_strdup (address);
8251   GNUNET_assert (GNUNET_YES ==
8252                  GNUNET_CONTAINER_multipeermap_put (
8253                    validation_map,
8254                    &vs->pid,
8255                    vs,
8256                    GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
8257   update_next_challenge_time (vs, now);
8258 }
8259
8260
8261 /**
8262  * Function called by PEERSTORE for each matching record.
8263  *
8264  * @param cls closure
8265  * @param record peerstore record information
8266  * @param emsg error message, or NULL if no errors
8267  */
8268 static void
8269 handle_hello (void *cls,
8270               const struct GNUNET_PEERSTORE_Record *record,
8271               const char *emsg)
8272 {
8273   struct PeerRequest *pr = cls;
8274   const char *val;
8275
8276   if (NULL != emsg)
8277   {
8278     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
8279                 "Got failure from PEERSTORE: %s\n",
8280                 emsg);
8281     return;
8282   }
8283   val = record->value;
8284   if ((0 == record->value_size) || ('\0' != val[record->value_size - 1]))
8285   {
8286     GNUNET_break (0);
8287     return;
8288   }
8289   start_address_validation (&pr->pid,
8290                             (const char *) record->value,
8291                             record->expiry);
8292 }
8293
8294
8295 /**
8296  * We have received a `struct ExpressPreferenceMessage` from an application
8297  * client.
8298  *
8299  * @param cls handle to the client
8300  * @param msg the start message
8301  */
8302 static void
8303 handle_suggest (void *cls, const struct ExpressPreferenceMessage *msg)
8304 {
8305   struct TransportClient *tc = cls;
8306   struct PeerRequest *pr;
8307
8308   if (CT_NONE == tc->type)
8309   {
8310     tc->type = CT_APPLICATION;
8311     tc->details.application.requests =
8312       GNUNET_CONTAINER_multipeermap_create (16, GNUNET_YES);
8313   }
8314   if (CT_APPLICATION != tc->type)
8315   {
8316     GNUNET_break (0);
8317     GNUNET_SERVICE_client_drop (tc->client);
8318     return;
8319   }
8320   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
8321               "Client suggested we talk to %s with preference %d at rate %u\n",
8322               GNUNET_i2s (&msg->peer),
8323               (int) ntohl (msg->pk),
8324               (int) ntohl (msg->bw.value__));
8325   pr = GNUNET_new (struct PeerRequest);
8326   pr->tc = tc;
8327   pr->pid = msg->peer;
8328   pr->bw = msg->bw;
8329   pr->pk = (enum GNUNET_MQ_PreferenceKind) ntohl (msg->pk);
8330   if (GNUNET_YES != GNUNET_CONTAINER_multipeermap_put (
8331                       tc->details.application.requests,
8332                       &pr->pid,
8333                       pr,
8334                       GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
8335   {
8336     GNUNET_break (0);
8337     GNUNET_free (pr);
8338     GNUNET_SERVICE_client_drop (tc->client);
8339     return;
8340   }
8341   pr->wc = GNUNET_PEERSTORE_watch (peerstore,
8342                                    "transport",
8343                                    &pr->pid,
8344                                    GNUNET_PEERSTORE_TRANSPORT_URLADDRESS_KEY,
8345                                    &handle_hello,
8346                                    pr);
8347   GNUNET_SERVICE_client_continue (tc->client);
8348 }
8349
8350
8351 /**
8352  * Given another peers address, consider checking it for validity
8353  * and then adding it to the Peerstore.
8354  *
8355  * @param cls a `struct TransportClient`
8356  * @param hdr message containing the raw address data and
8357  *        signature in the body, see #GNUNET_HELLO_extract_address()
8358  */
8359 static void
8360 handle_address_consider_verify (
8361   void *cls,
8362   const struct GNUNET_TRANSPORT_AddressToVerify *hdr)
8363 {
8364   struct TransportClient *tc = cls;
8365   char *address;
8366   enum GNUNET_NetworkType nt;
8367   struct GNUNET_TIME_Absolute expiration;
8368
8369   (void) cls;
8370   // OPTIMIZE-FIXME: checking that we know this address already should
8371   //        be done BEFORE checking the signature => HELLO API change!
8372   // OPTIMIZE-FIXME: pre-check: rate-limit signature verification /
8373   // validation?!
8374   address =
8375     GNUNET_HELLO_extract_address (&hdr[1],
8376                                   ntohs (hdr->header.size) - sizeof (*hdr),
8377                                   &hdr->peer,
8378                                   &nt,
8379                                   &expiration);
8380   if (NULL == address)
8381   {
8382     GNUNET_break_op (0);
8383     return;
8384   }
8385   start_address_validation (&hdr->peer, address, expiration);
8386   GNUNET_free (address);
8387   GNUNET_SERVICE_client_continue (tc->client);
8388 }
8389
8390
8391 /**
8392  * Check #GNUNET_MESSAGE_TYPE_TRANSPORT_REQUEST_HELLO_VALIDATION
8393  * messages.
8394  *
8395  * @param cls a `struct TransportClient *`
8396  * @param m message to verify
8397  * @return #GNUNET_OK on success
8398  */
8399 static int
8400 check_request_hello_validation (void *cls,
8401                                 const struct RequestHelloValidationMessage *m)
8402 {
8403   (void) cls;
8404   GNUNET_MQ_check_zero_termination (m);
8405   return GNUNET_OK;
8406 }
8407
8408
8409 /**
8410  * A client encountered an address of another peer. Consider validating it,
8411  * and if validation succeeds, persist it to PEERSTORE.
8412  *
8413  * @param cls a `struct TransportClient *`
8414  * @param m message to verify
8415  */
8416 static void
8417 handle_request_hello_validation (void *cls,
8418                                  const struct RequestHelloValidationMessage *m)
8419 {
8420   struct TransportClient *tc = cls;
8421
8422   start_address_validation (&m->peer,
8423                             (const char *) &m[1],
8424                             GNUNET_TIME_absolute_ntoh (m->expiration));
8425   GNUNET_SERVICE_client_continue (tc->client);
8426 }
8427
8428
8429 /**
8430  * Free neighbour entry.
8431  *
8432  * @param cls NULL
8433  * @param pid unused
8434  * @param value a `struct Neighbour`
8435  * @return #GNUNET_OK (always)
8436  */
8437 static int
8438 free_neighbour_cb (void *cls,
8439                    const struct GNUNET_PeerIdentity *pid,
8440                    void *value)
8441 {
8442   struct Neighbour *neighbour = value;
8443
8444   (void) cls;
8445   (void) pid;
8446   GNUNET_break (0); // should this ever happen?
8447   free_neighbour (neighbour);
8448
8449   return GNUNET_OK;
8450 }
8451
8452
8453 /**
8454  * Free DV route entry.
8455  *
8456  * @param cls NULL
8457  * @param pid unused
8458  * @param value a `struct DistanceVector`
8459  * @return #GNUNET_OK (always)
8460  */
8461 static int
8462 free_dv_routes_cb (void *cls,
8463                    const struct GNUNET_PeerIdentity *pid,
8464                    void *value)
8465 {
8466   struct DistanceVector *dv = value;
8467
8468   (void) cls;
8469   (void) pid;
8470   free_dv_route (dv);
8471
8472   return GNUNET_OK;
8473 }
8474
8475
8476 /**
8477  * Free ephemeral entry.
8478  *
8479  * @param cls NULL
8480  * @param pid unused
8481  * @param value a `struct EphemeralCacheEntry`
8482  * @return #GNUNET_OK (always)
8483  */
8484 static int
8485 free_ephemeral_cb (void *cls,
8486                    const struct GNUNET_PeerIdentity *pid,
8487                    void *value)
8488 {
8489   struct EphemeralCacheEntry *ece = value;
8490
8491   (void) cls;
8492   (void) pid;
8493   free_ephemeral (ece);
8494   return GNUNET_OK;
8495 }
8496
8497
8498 /**
8499  * Free validation state.
8500  *
8501  * @param cls NULL
8502  * @param pid unused
8503  * @param value a `struct ValidationState`
8504  * @return #GNUNET_OK (always)
8505  */
8506 static int
8507 free_validation_state_cb (void *cls,
8508                           const struct GNUNET_PeerIdentity *pid,
8509                           void *value)
8510 {
8511   struct ValidationState *vs = value;
8512
8513   (void) cls;
8514   (void) pid;
8515   free_validation_state (vs);
8516   return GNUNET_OK;
8517 }
8518
8519
8520 /**
8521  * Free pending acknowledgement.
8522  *
8523  * @param cls NULL
8524  * @param key unused
8525  * @param value a `struct PendingAcknowledgement`
8526  * @return #GNUNET_OK (always)
8527  */
8528 static int
8529 free_pending_ack_cb (void *cls,
8530                      const struct GNUNET_ShortHashCode *key,
8531                      void *value)
8532 {
8533   struct PendingAcknowledgement *pa = value;
8534
8535   (void) cls;
8536   (void) key;
8537   free_pending_acknowledgement (pa);
8538   return GNUNET_OK;
8539 }
8540
8541
8542 /**
8543  * Free acknowledgement cummulator.
8544  *
8545  * @param cls NULL
8546  * @param pid unused
8547  * @param value a `struct AcknowledgementCummulator`
8548  * @return #GNUNET_OK (always)
8549  */
8550 static int
8551 free_ack_cummulator_cb (void *cls,
8552                         const struct GNUNET_PeerIdentity *pid,
8553                         void *value)
8554 {
8555   struct AcknowledgementCummulator *ac = value;
8556
8557   (void) cls;
8558   (void) pid;
8559   GNUNET_free (ac);
8560   return GNUNET_OK;
8561 }
8562
8563
8564 /**
8565  * Function called when the service shuts down.  Unloads our plugins
8566  * and cancels pending validations.
8567  *
8568  * @param cls closure, unused
8569  */
8570 static void
8571 do_shutdown (void *cls)
8572 {
8573   struct LearnLaunchEntry *lle;
8574   (void) cls;
8575
8576   if (NULL != ephemeral_task)
8577   {
8578     GNUNET_SCHEDULER_cancel (ephemeral_task);
8579     ephemeral_task = NULL;
8580   }
8581   GNUNET_CONTAINER_multipeermap_iterate (neighbours, &free_neighbour_cb, NULL);
8582   if (NULL != peerstore)
8583   {
8584     GNUNET_PEERSTORE_disconnect (peerstore, GNUNET_NO);
8585     peerstore = NULL;
8586   }
8587   if (NULL != GST_stats)
8588   {
8589     GNUNET_STATISTICS_destroy (GST_stats, GNUNET_NO);
8590     GST_stats = NULL;
8591   }
8592   if (NULL != GST_my_private_key)
8593   {
8594     GNUNET_free (GST_my_private_key);
8595     GST_my_private_key = NULL;
8596   }
8597   GNUNET_CONTAINER_multipeermap_iterate (ack_cummulators,
8598                                          &free_ack_cummulator_cb,
8599                                          NULL);
8600   GNUNET_CONTAINER_multipeermap_destroy (ack_cummulators);
8601   ack_cummulators = NULL;
8602   GNUNET_CONTAINER_multishortmap_iterate (pending_acks,
8603                                           &free_pending_ack_cb,
8604                                           NULL);
8605   GNUNET_CONTAINER_multishortmap_destroy (pending_acks);
8606   pending_acks = NULL;
8607   GNUNET_CONTAINER_multipeermap_destroy (neighbours);
8608   neighbours = NULL;
8609   GNUNET_CONTAINER_multipeermap_iterate (backtalkers,
8610                                          &free_backtalker_cb,
8611                                          NULL);
8612   GNUNET_CONTAINER_multipeermap_destroy (backtalkers);
8613   backtalkers = NULL;
8614   GNUNET_CONTAINER_multipeermap_iterate (validation_map,
8615                                          &free_validation_state_cb,
8616                                          NULL);
8617   GNUNET_CONTAINER_multipeermap_destroy (validation_map);
8618   validation_map = NULL;
8619   while (NULL != (lle = lle_head))
8620   {
8621     GNUNET_CONTAINER_DLL_remove (lle_head, lle_tail, lle);
8622     GNUNET_free (lle);
8623   }
8624   GNUNET_CONTAINER_multishortmap_destroy (dvlearn_map);
8625   dvlearn_map = NULL;
8626   GNUNET_CONTAINER_heap_destroy (validation_heap);
8627   validation_heap = NULL;
8628   GNUNET_CONTAINER_multipeermap_iterate (dv_routes, &free_dv_routes_cb, NULL);
8629   GNUNET_CONTAINER_multipeermap_destroy (dv_routes);
8630   dv_routes = NULL;
8631   GNUNET_CONTAINER_multipeermap_iterate (ephemeral_map,
8632                                          &free_ephemeral_cb,
8633                                          NULL);
8634   GNUNET_CONTAINER_multipeermap_destroy (ephemeral_map);
8635   ephemeral_map = NULL;
8636   GNUNET_CONTAINER_heap_destroy (ephemeral_heap);
8637   ephemeral_heap = NULL;
8638 }
8639
8640
8641 /**
8642  * Initiate transport service.
8643  *
8644  * @param cls closure
8645  * @param c configuration to use
8646  * @param service the initialized service
8647  */
8648 static void
8649 run (void *cls,
8650      const struct GNUNET_CONFIGURATION_Handle *c,
8651      struct GNUNET_SERVICE_Handle *service)
8652 {
8653   (void) cls;
8654   (void) service;
8655   /* setup globals */
8656   GST_cfg = c;
8657   backtalkers = GNUNET_CONTAINER_multipeermap_create (16, GNUNET_YES);
8658   pending_acks = GNUNET_CONTAINER_multishortmap_create (32768, GNUNET_YES);
8659   ack_cummulators = GNUNET_CONTAINER_multipeermap_create (256, GNUNET_YES);
8660   neighbours = GNUNET_CONTAINER_multipeermap_create (1024, GNUNET_YES);
8661   dv_routes = GNUNET_CONTAINER_multipeermap_create (1024, GNUNET_YES);
8662   ephemeral_map = GNUNET_CONTAINER_multipeermap_create (32, GNUNET_YES);
8663   ephemeral_heap =
8664     GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
8665   dvlearn_map = GNUNET_CONTAINER_multishortmap_create (2 * MAX_DV_LEARN_PENDING,
8666                                                        GNUNET_YES);
8667   validation_map = GNUNET_CONTAINER_multipeermap_create (1024, GNUNET_YES);
8668   validation_heap =
8669     GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
8670   GST_my_private_key =
8671     GNUNET_CRYPTO_eddsa_key_create_from_configuration (GST_cfg);
8672   if (NULL == GST_my_private_key)
8673   {
8674     GNUNET_log (
8675       GNUNET_ERROR_TYPE_ERROR,
8676       _ (
8677         "Transport service is lacking key configuration settings. Exiting.\n"));
8678     GNUNET_SCHEDULER_shutdown ();
8679     return;
8680   }
8681   GNUNET_CRYPTO_eddsa_key_get_public (GST_my_private_key,
8682                                       &GST_my_identity.public_key);
8683   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
8684               "My identity is `%s'\n",
8685               GNUNET_i2s_full (&GST_my_identity));
8686   GST_stats = GNUNET_STATISTICS_create ("transport", GST_cfg);
8687   GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL);
8688   peerstore = GNUNET_PEERSTORE_connect (GST_cfg);
8689   if (NULL == peerstore)
8690   {
8691     GNUNET_break (0);
8692     GNUNET_SCHEDULER_shutdown ();
8693     return;
8694   }
8695 }
8696
8697
8698 /**
8699  * Define "main" method using service macro.
8700  */
8701 GNUNET_SERVICE_MAIN (
8702   "transport",
8703   GNUNET_SERVICE_OPTION_SOFT_SHUTDOWN,
8704   &run,
8705   &client_connect_cb,
8706   &client_disconnect_cb,
8707   NULL,
8708   /* communication with applications */
8709   GNUNET_MQ_hd_fixed_size (suggest,
8710                            GNUNET_MESSAGE_TYPE_TRANSPORT_SUGGEST,
8711                            struct ExpressPreferenceMessage,
8712                            NULL),
8713   GNUNET_MQ_hd_fixed_size (suggest_cancel,
8714                            GNUNET_MESSAGE_TYPE_TRANSPORT_SUGGEST_CANCEL,
8715                            struct ExpressPreferenceMessage,
8716                            NULL),
8717   GNUNET_MQ_hd_var_size (request_hello_validation,
8718                          GNUNET_MESSAGE_TYPE_TRANSPORT_REQUEST_HELLO_VALIDATION,
8719                          struct RequestHelloValidationMessage,
8720                          NULL),
8721   /* communication with core */
8722   GNUNET_MQ_hd_fixed_size (client_start,
8723                            GNUNET_MESSAGE_TYPE_TRANSPORT_START,
8724                            struct StartMessage,
8725                            NULL),
8726   GNUNET_MQ_hd_var_size (client_send,
8727                          GNUNET_MESSAGE_TYPE_TRANSPORT_SEND,
8728                          struct OutboundMessage,
8729                          NULL),
8730   /* communication with communicators */
8731   GNUNET_MQ_hd_var_size (communicator_available,
8732                          GNUNET_MESSAGE_TYPE_TRANSPORT_NEW_COMMUNICATOR,
8733                          struct GNUNET_TRANSPORT_CommunicatorAvailableMessage,
8734                          NULL),
8735   GNUNET_MQ_hd_var_size (communicator_backchannel,
8736                          GNUNET_MESSAGE_TYPE_TRANSPORT_COMMUNICATOR_BACKCHANNEL,
8737                          struct GNUNET_TRANSPORT_CommunicatorBackchannel,
8738                          NULL),
8739   GNUNET_MQ_hd_var_size (add_address,
8740                          GNUNET_MESSAGE_TYPE_TRANSPORT_ADD_ADDRESS,
8741                          struct GNUNET_TRANSPORT_AddAddressMessage,
8742                          NULL),
8743   GNUNET_MQ_hd_fixed_size (del_address,
8744                            GNUNET_MESSAGE_TYPE_TRANSPORT_DEL_ADDRESS,
8745                            struct GNUNET_TRANSPORT_DelAddressMessage,
8746                            NULL),
8747   GNUNET_MQ_hd_var_size (incoming_msg,
8748                          GNUNET_MESSAGE_TYPE_TRANSPORT_INCOMING_MSG,
8749                          struct GNUNET_TRANSPORT_IncomingMessage,
8750                          NULL),
8751   GNUNET_MQ_hd_fixed_size (queue_create_ok,
8752                            GNUNET_MESSAGE_TYPE_TRANSPORT_QUEUE_CREATE_OK,
8753                            struct GNUNET_TRANSPORT_CreateQueueResponse,
8754                            NULL),
8755   GNUNET_MQ_hd_fixed_size (queue_create_fail,
8756                            GNUNET_MESSAGE_TYPE_TRANSPORT_QUEUE_CREATE_FAIL,
8757                            struct GNUNET_TRANSPORT_CreateQueueResponse,
8758                            NULL),
8759   GNUNET_MQ_hd_var_size (add_queue_message,
8760                          GNUNET_MESSAGE_TYPE_TRANSPORT_QUEUE_SETUP,
8761                          struct GNUNET_TRANSPORT_AddQueueMessage,
8762                          NULL),
8763   GNUNET_MQ_hd_var_size (address_consider_verify,
8764                          GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_CONSIDER_VERIFY,
8765                          struct GNUNET_TRANSPORT_AddressToVerify,
8766                          NULL),
8767   GNUNET_MQ_hd_fixed_size (del_queue_message,
8768                            GNUNET_MESSAGE_TYPE_TRANSPORT_QUEUE_TEARDOWN,
8769                            struct GNUNET_TRANSPORT_DelQueueMessage,
8770                            NULL),
8771   GNUNET_MQ_hd_fixed_size (send_message_ack,
8772                            GNUNET_MESSAGE_TYPE_TRANSPORT_SEND_MSG_ACK,
8773                            struct GNUNET_TRANSPORT_SendMessageToAck,
8774                            NULL),
8775   /* communication with monitors */
8776   GNUNET_MQ_hd_fixed_size (monitor_start,
8777                            GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_START,
8778                            struct GNUNET_TRANSPORT_MonitorStart,
8779                            NULL),
8780   GNUNET_MQ_handler_end ());
8781
8782
8783 /* end of file gnunet-service-transport.c */