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