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