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