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