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