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