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