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