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