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