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