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