work on DV data structures
[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  * - figure out how to transmit (selective) ACKs in case of uni-directional
27  *   communicators (with/without core? DV-only?) When do we use ACKs?
28  *   => communicators use selective ACKs for flow control
29  *   => transport uses message-level ACKs for RTT, fragment confirmation
30  *   => integrate DV into transport, use neither core nor communicators
31  *      but rather give communicators transport-encapsulated messages
32  *      (which could be core-data, background-channel traffic, or
33  *       transport-to-transport traffic)
34  *
35  * Implement next:
36  * - DV data structures:
37  *   + initiation of DV learn (incl. RTT measurement logic!)
38  *     - security considerations? add signatures to routes? initiator signature?
39  *   + using DV routes!
40  *     - handling of DV-boxed messages that need to be forwarded
41  *     - route_message implementation, including using DV data structures
42  *       (but not when routing certain message types, like DV learn,
43  *        MUST pay attention to content here -- or pass extra flags?)
44  * - ACK handling / retransmission
45  * - track RTT, distance, loss, etc.
46  * - backchannel message encryption & decryption
47  *
48  * Later:
49  * - change transport-core API to provide proper flow control in both
50  *   directions, allow multiple messages per peer simultaneously (tag
51  *   confirmations with unique message ID), and replace quota-out with
52  *   proper flow control;
53  * - if messages are below MTU, consider adding ACKs and other stuff
54  *   (requires planning at receiver, and additional MST-style demultiplex
55  *    at receiver!)
56  * - could avoid copying body of message into each fragment and keep
57  *   fragments as just pointers into the original message and only
58  *   fully build fragments just before transmission (optimization, should
59  *   reduce CPU and memory use)
60  *
61  * Design realizations / discussion:
62  * - communicators do flow control by calling MQ "notify sent"
63  *   when 'ready'. They determine flow implicitly (i.e. TCP blocking)
64  *   or explicitly via backchannel FC ACKs.  As long as the
65  *   channel is not full, they may 'notify sent' even if the other
66  *   peer has not yet confirmed receipt. The other peer confirming
67  *   is _only_ for FC, not for more reliable transmission; reliable
68  *   transmission (i.e. of fragments) is left to _transport_.
69  * - ACKs sent back in uni-directional communicators are done via
70  *   the background channel API; here transport _may_ initially
71  *   broadcast (with bounded # hops) if no path is known;
72  * - transport should _integrate_ DV-routing and build a view of
73  *   the network; then background channel traffic can be
74  *   routed via DV as well as explicit "DV" traffic.
75  * - background channel is also used for ACKs and NAT traversal support
76  * - transport service is responsible for AEAD'ing the background
77  *   channel, timestamps and monotonic time are used against replay
78  *   of old messages -> peerstore needs to be supplied with
79  *   "latest timestamps seen" data
80  * - if transport implements DV, we likely need a 3rd peermap
81  *   in addition to ephemerals and (direct) neighbours
82  *   ==> check if stuff needs to be moved out of "Neighbour"
83  * - transport should encapsualte core-level messages and do its
84  *   own ACKing for RTT/goodput/loss measurements _and_ fragment
85  *   for retransmission
86  */
87 #include "platform.h"
88 #include "gnunet_util_lib.h"
89 #include "gnunet_statistics_service.h"
90 #include "gnunet_transport_monitor_service.h"
91 #include "gnunet_peerstore_service.h"
92 #include "gnunet_hello_lib.h"
93 #include "gnunet_signatures.h"
94 #include "transport.h"
95
96
97 /**
98  * What is the size we assume for a read operation in the
99  * absence of an MTU for the purpose of flow control?
100  */
101 #define IN_PACKET_SIZE_WITHOUT_MTU 128
102
103 /**
104  * Minimum number of hops we should forward DV learn messages
105  * even if they are NOT useful for us in hope of looping
106  * back to the initiator?
107  *
108  * FIXME: allow initiator some control here instead?
109  */
110 #define MIN_DV_PATH_LENGTH_FOR_INITIATOR 3
111
112 /**
113  * Maximum DV distance allowed ever.
114  */
115 #define MAX_DV_HOPS_ALLOWED 16
116
117 /**
118  * Maximum number of DV paths we keep simultaneously to the same target.
119  */
120 #define MAX_DV_PATHS_TO_TARGET 3
121
122 /**
123  * If a queue delays the next message by more than this number
124  * of seconds we log a warning. Note: this is for testing,
125  * the value chosen here might be too aggressively low!
126  */
127 #define DELAY_WARN_THRESHOLD GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5)
128
129 /**
130  * How long do we consider a DV path valid if we see no
131  * further updates on it? Note: the value chosen here might be too low!
132  */
133 #define DV_PATH_VALIDITY_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5)
134
135 /**
136  * How long before paths expire would we like to (re)discover DV paths? Should
137  * be below #DV_PATH_VALIDITY_TIMEOUT.
138  */
139 #define DV_PATH_DISCOVERY_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 4)
140
141 /**
142  * How long are ephemeral keys valid?
143  */
144 #define EPHEMERAL_VALIDITY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 4)
145
146 /**
147  * How long do we keep partially reassembled messages around before giving up?
148  */
149 #define REASSEMBLY_EXPIRATION GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 4)
150
151 /**
152  * What is the fastest rate at which we send challenges *if* we keep learning
153  * an address (gossip, DHT, etc.)?
154  */
155 #define FAST_VALIDATION_CHALLENGE_FREQ GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 1)
156
157 /**
158  * What is the slowest rate at which we send challenges?
159  */
160 #define MAX_VALIDATION_CHALLENGE_FREQ GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_DAYS, 1)
161
162 /**
163  * When do we forget an invalid address for sure?
164  */
165 #define MAX_ADDRESS_VALID_UNTIL GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MONTHS, 1)
166 /**
167  * How long do we consider an address valid if we just checked?
168  */
169 #define ADDRESS_VALIDATION_LIFETIME GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 4)
170
171 /**
172  * What is the maximum frequency at which we do address validation?
173  * A random value between 0 and this value is added when scheduling
174  * the #validation_task (both to ensure we do not validate too often,
175  * and to randomize a bit).
176  */
177 #define MIN_DELAY_ADDRESS_VALIDATION GNUNET_TIME_UNIT_MILLISECONDS
178
179 /**
180  * How many network RTTs before an address validation expires should we begin
181  * trying to revalidate? (Note that the RTT used here is the one that we
182  * experienced during the last validation, not necessarily the latest RTT
183  * observed).
184  */
185 #define VALIDATION_RTT_BUFFER_FACTOR 3
186
187 /**
188  * How many messages can we have pending for a given communicator
189  * process before we start to throttle that communicator?
190  *
191  * Used if a communicator might be CPU-bound and cannot handle the traffic.
192  */
193 #define COMMUNICATOR_TOTAL_QUEUE_LIMIT 512
194
195 /**
196  * How many messages can we have pending for a given queue (queue to
197  * a particular peer via a communicator) process before we start to
198  * throttle that queue?
199  */
200 #define QUEUE_LENGTH_LIMIT 32
201
202
203 GNUNET_NETWORK_STRUCT_BEGIN
204
205 /**
206  * Outer layer of an encapsulated backchannel message.
207  */
208 struct TransportBackchannelEncapsulationMessage
209 {
210   /**
211    * Type is #GNUNET_MESSAGE_TYPE_TRANSPORT_BACKCHANNEL_ENCAPSULATION.
212    */
213   struct GNUNET_MessageHeader header;
214
215   /**
216    * Distance the backchannel message has traveled, to be updated at
217    * each hop.  Used to bound the number of hops in case a backchannel
218    * message is broadcast and thus travels without routing
219    * information (during initial backchannel discovery).
220    */
221   uint32_t distance;
222
223   /**
224    * Target's peer identity (as backchannels may be transmitted
225    * indirectly, or even be broadcast).
226    */
227   struct GNUNET_PeerIdentity target;
228
229   /**
230    * Ephemeral key setup by the sender for @e target, used
231    * to encrypt the payload.
232    */
233   struct GNUNET_CRYPTO_EcdhePublicKey ephemeral_key;
234
235   // FIXME: probably should add random IV here as well,
236   // especially if we re-use ephemeral keys!
237
238   /**
239    * HMAC over the ciphertext of the encrypted, variable-size
240    * body that follows.  Verified via DH of @e target and
241    * @e ephemeral_key
242    */
243   struct GNUNET_HashCode hmac;
244
245   /* Followed by encrypted, variable-size payload */
246 };
247
248
249 /**
250  * Body by which a peer confirms that it is using an ephemeral key.
251  */
252 struct EphemeralConfirmation
253 {
254
255   /**
256    * Purpose is #GNUNET_SIGNATURE_PURPOSE_TRANSPORT_EPHEMERAL
257    */
258   struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
259
260   /**
261    * How long is this signature over the ephemeral key valid?
262    * Note that the receiver MUST IGNORE the absolute time, and
263    * only interpret the value as a mononic time and reject
264    * "older" values than the last one observed.  Even with this,
265    * there is no real guarantee against replay achieved here,
266    * as the latest timestamp is not persisted.  This is
267    * necessary as we do not want to require synchronized
268    * clocks and may not have a bidirectional communication
269    * channel.  Communicators must protect against replay
270    * attacks when using backchannel communication!
271    */
272   struct GNUNET_TIME_AbsoluteNBO ephemeral_validity;
273
274   /**
275    * Target's peer identity.
276    */
277   struct GNUNET_PeerIdentity target;
278
279   /**
280    * Ephemeral key setup by the sender for @e target, used
281    * to encrypt the payload.
282    */
283   struct GNUNET_CRYPTO_EcdhePublicKey ephemeral_key;
284
285 };
286
287
288 /**
289  * Plaintext of the variable-size payload that is encrypted
290  * within a `struct TransportBackchannelEncapsulationMessage`
291  */
292 struct TransportBackchannelRequestPayload
293 {
294
295   /**
296    * Sender's peer identity.
297    */
298   struct GNUNET_PeerIdentity sender;
299
300   /**
301    * Signature of the sender over an
302    * #GNUNET_SIGNATURE_PURPOSE_TRANSPORT_EPHEMERAL.
303    */
304   struct GNUNET_CRYPTO_EddsaSignature sender_sig;
305
306   /**
307    * How long is this signature over the ephemeral key
308    * valid?
309    */
310   struct GNUNET_TIME_AbsoluteNBO ephemeral_validity;
311
312   /**
313    * Current monotonic time of the sending transport service.  Used to
314    * detect replayed messages.  Note that the receiver should remember
315    * a list of the recently seen timestamps and only reject messages
316    * if the timestamp is in the list, or the list is "full" and the
317    * timestamp is smaller than the lowest in the list.  This list of
318    * timestamps per peer should be persisted to guard against replays
319    * after restarts.
320    */
321   struct GNUNET_TIME_AbsoluteNBO monotonic_time;
322
323   /* Followed by a `struct GNUNET_MessageHeader` with a message
324      for a communicator */
325
326   /* Followed by a 0-termianted string specifying the name of
327      the communicator which is to receive the message */
328
329 };
330
331
332 /**
333  * Outer layer of an encapsulated unfragmented application message sent
334  * over an unreliable channel.
335  */
336 struct TransportReliabilityBox
337 {
338   /**
339    * Type is #GNUNET_MESSAGE_TYPE_TRANSPORT_RELIABILITY_BOX
340    */
341   struct GNUNET_MessageHeader header;
342
343   /**
344    * Number of messages still to be sent before a commulative
345    * ACK is requested.  Zero if an ACK is requested immediately.
346    * In NBO.  Note that the receiver may send the ACK faster
347    * if it believes that is reasonable.
348    */
349   uint32_t ack_countdown GNUNET_PACKED;
350
351   /**
352    * Unique ID of the message used for signalling receipt of
353    * messages sent over possibly unreliable channels.  Should
354    * be a random.
355    */
356   struct GNUNET_ShortHashCode msg_uuid;
357 };
358
359
360 /**
361  * Confirmation that the receiver got a
362  * #GNUNET_MESSAGE_TYPE_TRANSPORT_RELIABILITY_BOX. Note that the
363  * confirmation may be transmitted over a completely different queue,
364  * so ACKs are identified by a combination of PID of sender and
365  * message UUID, without the queue playing any role!
366  */
367 struct TransportReliabilityAckMessage
368 {
369   /**
370    * Type is #GNUNET_MESSAGE_TYPE_TRANSPORT_RELIABILITY_ACK
371    */
372   struct GNUNET_MessageHeader header;
373
374   /**
375    * Reserved. Zero.
376    */
377   uint32_t reserved GNUNET_PACKED;
378
379   /**
380    * How long was the ACK delayed relative to the average time of
381    * receipt of the messages being acknowledged?  Used to calculate
382    * the average RTT by taking the receipt time of the ack minus the
383    * average transmission time of the sender minus this value.
384    */
385   struct GNUNET_TIME_RelativeNBO avg_ack_delay;
386
387   /* followed by any number of `struct GNUNET_ShortHashCode`
388      messages providing ACKs */
389 };
390
391
392 /**
393  * Outer layer of an encapsulated fragmented application message.
394  */
395 struct TransportFragmentBox
396 {
397   /**
398    * Type is #GNUNET_MESSAGE_TYPE_TRANSPORT_FRAGMENT
399    */
400   struct GNUNET_MessageHeader header;
401
402   /**
403    * Unique ID of this fragment (and fragment transmission!). Will
404    * change even if a fragement is retransmitted to make each
405    * transmission attempt unique! Should be incremented by one for
406    * each fragment transmission. If a client receives a duplicate
407    * fragment (same @e frag_off), it must send
408    * #GNUNET_MESSAGE_TYPE_TRANSPORT_FRAGMENT_ACK immediately.
409    */
410   uint32_t frag_uuid GNUNET_PACKED;
411
412   /**
413    * Original message ID for of the message that all the1
414    * fragments belong to.  Must be the same for all fragments.
415    */
416   struct GNUNET_ShortHashCode msg_uuid;
417
418   /**
419    * Offset of this fragment in the overall message.
420    */
421   uint16_t frag_off GNUNET_PACKED;
422
423   /**
424    * Total size of the message that is being fragmented.
425    */
426   uint16_t msg_size GNUNET_PACKED;
427
428 };
429
430
431 /**
432  * Outer layer of an fragmented application message sent over a queue
433  * with finite MTU.  When a #GNUNET_MESSAGE_TYPE_TRANSPORT_FRAGMENT is
434  * received, the receiver has two RTTs or 64 further fragments with
435  * the same basic message time to send an acknowledgement, possibly
436  * acknowledging up to 65 fragments in one ACK.  ACKs must also be
437  * sent immediately once all fragments were sent.
438  */
439 struct TransportFragmentAckMessage
440 {
441   /**
442    * Type is #GNUNET_MESSAGE_TYPE_TRANSPORT_FRAGMENT_ACK
443    */
444   struct GNUNET_MessageHeader header;
445
446   /**
447    * Unique ID of the lowest fragment UUID being acknowledged.
448    */
449   uint32_t frag_uuid GNUNET_PACKED;
450
451   /**
452    * Bitfield of up to 64 additional fragments following the
453    * @e msg_uuid being acknowledged by this message.
454    */
455   uint64_t extra_acks GNUNET_PACKED;
456
457   /**
458    * Original message ID for of the message that all the
459    * fragments belong to.
460    */
461   struct GNUNET_ShortHashCode msg_uuid;
462
463   /**
464    * How long was the ACK delayed relative to the average time of
465    * receipt of the fragments being acknowledged?  Used to calculate
466    * the average RTT by taking the receipt time of the ack minus the
467    * average transmission time of the sender minus this value.
468    */
469   struct GNUNET_TIME_RelativeNBO avg_ack_delay;
470
471   /**
472    * How long until the receiver will stop trying reassembly
473    * of this message?
474    */
475   struct GNUNET_TIME_RelativeNBO reassembly_timeout;
476 };
477
478
479 /**
480  * Content signed by each peer during DV learning.
481  */
482 struct DvInitPS
483 {
484   /**
485    * Purpose is #GNUNET_SIGNATURE_PURPOSE_TRANSPORT_DV_INITIATOR
486    */
487   struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
488
489   /**
490    * Challenge value used by the initiator to re-identify the path.
491    */
492   struct GNUNET_ShortHashCode challenge;
493
494 };
495
496
497 /**
498  * Content signed by each peer during DV learning.
499  */
500 struct DvHopPS
501 {
502   /**
503    * Purpose is #GNUNET_SIGNATURE_PURPOSE_TRANSPORT_DV_HOP
504    */
505   struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
506
507   /**
508    * Identity of the previous peer on the path.
509    */
510   struct GNUNET_PeerIdentity pred;
511
512   /**
513    * Identity of the next peer on the path.
514    */
515   struct GNUNET_PeerIdentity succ;
516
517   /**
518    * Challenge value used by the initiator to re-identify the path.
519    */
520   struct GNUNET_ShortHashCode challenge;
521
522 };
523
524
525 /**
526  * An entry describing a peer on a path in a
527  * `struct TransportDVLearn` message.
528  */
529 struct DVPathEntryP
530 {
531   /**
532    * Identity of a peer on the path.
533    */
534   struct GNUNET_PeerIdentity hop;
535
536   /**
537    * Signature of this hop over the path, of purpose
538    * #GNUNET_SIGNATURE_PURPOSE_TRANSPORT_DV_HOP
539    */
540   struct GNUNET_CRYPTO_EddsaSignature hop_sig;
541
542 };
543
544
545 /**
546  * Internal message used by transport for distance vector learning.
547  * If @e num_hops does not exceed the threshold, peers should append
548  * themselves to the peer list and flood the message (possibly only
549  * to a subset of their neighbours to limit discoverability of the
550  * network topology).  To the extend that the @e bidirectional bits
551  * are set, peers may learn the inverse paths even if they did not
552  * initiate.
553  *
554  * Unless received on a bidirectional queue and @e num_hops just
555  * zero, peers that can forward to the initator should always try to
556  * forward to the initiator.
557  */
558 struct TransportDVLearn
559 {
560   /**
561    * Type is #GNUNET_MESSAGE_TYPE_TRANSPORT_DV_LEARN
562    */
563   struct GNUNET_MessageHeader header;
564
565   /**
566    * Number of hops this messages has travelled, in NBO. Zero if
567    * sent by initiator.
568    */
569   uint16_t num_hops GNUNET_PACKED;
570
571   /**
572    * Bitmask of the last 16 hops indicating whether they are confirmed
573    * available (without DV) in both directions or not, in NBO.  Used
574    * to possibly instantly learn a path in both directions.  Each peer
575    * should shift this value by one to the left, and then set the
576    * lowest bit IF the current sender can be reached from it (without
577    * DV routing).
578    */
579   uint16_t bidirectional GNUNET_PACKED;
580
581   /**
582    * Peers receiving this message and delaying forwarding to other
583    * peers for any reason should increment this value by the non-network
584    * delay created by the peer.
585    */
586   struct GNUNET_TIME_RelativeNBO non_network_delay;
587
588   /**
589    * Signature of this hop over the path, of purpose
590    * #GNUNET_SIGNATURE_PURPOSE_TRANSPORT_DV_INITIATOR
591    */
592   struct GNUNET_CRYPTO_EddsaSignature init_sig;
593
594   /**
595    * Identity of the peer that started this learning activity.
596    */
597   struct GNUNET_PeerIdentity initiator;
598
599   /**
600    * Challenge value used by the initiator to re-identify the path.
601    */
602   struct GNUNET_ShortHashCode challenge;
603
604   /* Followed by @e num_hops `struct DVPathEntryP` values,
605      excluding the initiator of the DV trace; the last entry is the
606      current sender; the current peer must not be included. */
607
608 };
609
610
611 /**
612  * Outer layer of an encapsulated message send over multiple hops.
613  * The path given only includes the identities of the subsequent
614  * peers, i.e. it will be empty if we are the receiver. Each
615  * forwarding peer should scan the list from the end, and if it can,
616  * forward to the respective peer. The list should then be shortened
617  * by all the entries up to and including that peer.  Each hop should
618  * also increment @e total_hops to allow the receiver to get a precise
619  * estimate on the number of hops the message travelled.  Senders must
620  * provide a learned path that thus should work, but intermediaries
621  * know of a shortcut, they are allowed to send the message via that
622  * shortcut.
623  *
624  * If a peer finds itself still on the list, it must drop the message.
625  */
626 struct TransportDVBox
627 {
628   /**
629    * Type is #GNUNET_MESSAGE_TYPE_TRANSPORT_DV_BOX
630    */
631   struct GNUNET_MessageHeader header;
632
633   /**
634    * Number of total hops this messages travelled. In NBO.
635    * @e origin sets this to zero, to be incremented at
636    * each hop.
637    */
638   uint16_t total_hops GNUNET_PACKED;
639
640   /**
641    * Number of hops this messages includes. In NBO.
642    */
643   uint16_t num_hops GNUNET_PACKED;
644
645   /**
646    * Identity of the peer that originated the message.
647    */
648   struct GNUNET_PeerIdentity origin;
649
650   /* Followed by @e num_hops `struct GNUNET_PeerIdentity` values;
651      excluding the @e origin and the current peer, the last must be
652      the ultimate target; if @e num_hops is zero, the receiver of this
653      message is the ultimate target. */
654
655   /* Followed by the actual message, which itself may be
656      another box, but not a DV_LEARN or DV_BOX message! */
657 };
658
659
660 /**
661  * Message send to another peer to validate that it can indeed
662  * receive messages at a particular address.
663  */
664 struct TransportValidationChallenge
665 {
666
667   /**
668    * Type is #GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_VALIDATION_CHALLENGE
669    */
670   struct GNUNET_MessageHeader header;
671
672   /**
673    * Zero.
674    */
675   uint32_t reserved GNUNET_PACKED;
676
677   /**
678    * Challenge to be signed by the receiving peer.
679    */
680   struct GNUNET_ShortHashCode challenge;
681
682   /**
683    * Timestamp of the sender, to be copied into the reply
684    * to allow sender to calculate RTT.
685    */
686   struct GNUNET_TIME_AbsoluteNBO sender_time;
687 };
688
689
690 /**
691  * Message signed by a peer to confirm that it can indeed
692  * receive messages at a particular address.
693  */
694 struct TransportValidationPS
695 {
696
697   /**
698    * Purpose is #GNUNET_SIGNATURE_PURPOSE_TRANSPORT_CHALLENGE
699    */
700   struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
701
702   /**
703    * How long does the sender believe the address on
704    * which the challenge was received to remain valid?
705    */
706   struct GNUNET_TIME_RelativeNBO validity_duration;
707
708   /**
709    * Challenge signed by the receiving peer.
710    */
711   struct GNUNET_ShortHashCode challenge;
712
713 };
714
715
716 /**
717  * Message send to a peer to respond to a
718  * #GNUNET_MESSAGE_TYPE_ADDRESS_VALIDATION_CHALLENGE
719  */
720 struct TransportValidationResponse
721 {
722
723   /**
724    * Type is #GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_VALIDATION_RESPONSE
725    */
726   struct GNUNET_MessageHeader header;
727
728   /**
729    * Zero.
730    */
731   uint32_t reserved GNUNET_PACKED;
732
733   /**
734    * The peer's signature matching the
735    * #GNUNET_SIGNATURE_PURPOSE_TRANSPORT_CHALLENGE purpose.
736    */
737   struct GNUNET_CRYPTO_EddsaSignature signature;
738
739   /**
740    * The challenge that was signed by the receiving peer.
741    */
742   struct GNUNET_ShortHashCode challenge;
743
744   /**
745    * Original timestamp of the sender (was @code{sender_time}),
746    * copied into the reply to allow sender to calculate RTT.
747    */
748   struct GNUNET_TIME_AbsoluteNBO origin_time;
749
750   /**
751    * How long does the sender believe this address to remain
752    * valid?
753    */
754   struct GNUNET_TIME_RelativeNBO validity_duration;
755 };
756
757
758
759 GNUNET_NETWORK_STRUCT_END
760
761
762 /**
763  * What type of client is the `struct TransportClient` about?
764  */
765 enum ClientType
766 {
767   /**
768    * We do not know yet (client is fresh).
769    */
770   CT_NONE = 0,
771
772   /**
773    * Is the CORE service, we need to forward traffic to it.
774    */
775   CT_CORE = 1,
776
777   /**
778    * It is a monitor, forward monitor data.
779    */
780   CT_MONITOR = 2,
781
782   /**
783    * It is a communicator, use for communication.
784    */
785   CT_COMMUNICATOR = 3,
786
787   /**
788    * "Application" telling us where to connect (i.e. TOPOLOGY, DHT or CADET).
789    */
790   CT_APPLICATION = 4
791 };
792
793
794 /**
795  * Entry in our cache of ephemeral keys we currently use.
796  * This way, we only sign an ephemeral once per @e target,
797  * and then can re-use it over multiple
798  * #GNUNET_MESSAGE_TYPE_TRANSPORT_BACKCHANNEL_ENCAPSULATION
799  * messages (as signing is expensive).
800  */
801 struct EphemeralCacheEntry
802 {
803
804   /**
805    * Target's peer identity (we don't re-use ephemerals
806    * to limit linkability of messages).
807    */
808   struct GNUNET_PeerIdentity target;
809
810   /**
811    * Signature affirming @e ephemeral_key of type
812    * #GNUNET_SIGNATURE_PURPOSE_TRANSPORT_EPHEMERAL
813    */
814   struct GNUNET_CRYPTO_EddsaSignature sender_sig;
815
816   /**
817    * How long is @e sender_sig valid
818    */
819   struct GNUNET_TIME_Absolute ephemeral_validity;
820
821   /**
822    * Our ephemeral key.
823    */
824   struct GNUNET_CRYPTO_EcdhePublicKey ephemeral_key;
825
826   /**
827    * Our private ephemeral key.
828    */
829   struct GNUNET_CRYPTO_EcdhePrivateKey private_key;
830
831   /**
832    * Node in the ephemeral cache for this entry.
833    * Used for expiration.
834    */
835   struct GNUNET_CONTAINER_HeapNode *hn;
836 };
837
838
839 /**
840  * Client connected to the transport service.
841  */
842 struct TransportClient;
843
844
845 /**
846  * A neighbour that at least one communicator is connected to.
847  */
848 struct Neighbour;
849
850
851 /**
852  * Entry in our #dv_routes table, representing a (set of) distance
853  * vector routes to a particular peer.
854  */
855 struct DistanceVector;
856
857 /**
858  * One possible hop towards a DV target.
859  */
860 struct DistanceVectorHop
861 {
862
863   /**
864    * Kept in a MDLL, sorted by @e timeout.
865    */
866   struct DistanceVectorHop *next_dv;
867
868   /**
869    * Kept in a MDLL, sorted by @e timeout.
870    */
871   struct DistanceVectorHop *prev_dv;
872
873   /**
874    * Kept in a MDLL.
875    */
876   struct DistanceVectorHop *next_neighbour;
877
878   /**
879    * Kept in a MDLL.
880    */
881   struct DistanceVectorHop *prev_neighbour;
882
883   /**
884    * What would be the next hop to @e target?
885    */
886   struct Neighbour *next_hop;
887
888   /**
889    * Distance vector entry this hop belongs with.
890    */
891   struct DistanceVector *dv;
892
893   /**
894    * Array of @e distance hops to the target, excluding @e next_hop.
895    * NULL if the entire path is us to @e next_hop to `target`. Allocated
896    * at the end of this struct.
897    */
898   const struct GNUNET_PeerIdentity *path;
899
900   /**
901    * At what time do we forget about this path unless we see it again
902    * while learning?
903    */
904   struct GNUNET_TIME_Absolute timeout;
905
906   /**
907    * How many hops in total to the `target` (excluding @e next_hop and `target` itself),
908    * thus 0 still means a distance of 2 hops (to @e next_hop and then to `target`)?
909    */
910   unsigned int distance;
911 };
912
913
914 /**
915  * Entry in our #dv_routes table, representing a (set of) distance
916  * vector routes to a particular peer.
917  */
918 struct DistanceVector
919 {
920
921   /**
922    * To which peer is this a route?
923    */
924   struct GNUNET_PeerIdentity target;
925
926   /**
927    * Known paths to @e target.
928    */
929   struct DistanceVectorHop *dv_head;
930
931   /**
932    * Known paths to @e target.
933    */
934   struct DistanceVectorHop *dv_tail;
935
936   /**
937    * Task scheduled to purge expired paths from @e dv_head MDLL.
938    */
939   struct GNUNET_SCHEDULER_Task *timeout_task;
940 };
941
942
943 /**
944  * A queue is a message queue provided by a communicator
945  * via which we can reach a particular neighbour.
946  */
947 struct Queue;
948
949
950 /**
951  * Entry identifying transmission in one of our `struct
952  * Queue` which still awaits an ACK.  This is used to
953  * ensure we do not overwhelm a communicator and limit the number of
954  * messages outstanding per communicator (say in case communicator is
955  * CPU bound) and per queue (in case bandwidth allocation exceeds
956  * what the communicator can actually provide towards a particular
957  * peer/target).
958  */
959 struct QueueEntry
960 {
961
962   /**
963    * Kept as a DLL.
964    */
965   struct QueueEntry *next;
966
967   /**
968    * Kept as a DLL.
969    */
970   struct QueueEntry *prev;
971
972   /**
973    * Queue this entry is queued with.
974    */
975   struct Queue *queue;
976
977   /**
978    * Message ID used for this message with the queue used for transmission.
979    */
980   uint64_t mid;
981 };
982
983
984 /**
985  * A queue is a message queue provided by a communicator
986  * via which we can reach a particular neighbour.
987  */
988 struct Queue
989 {
990   /**
991    * Kept in a MDLL.
992    */
993   struct Queue *next_neighbour;
994
995   /**
996    * Kept in a MDLL.
997    */
998   struct Queue *prev_neighbour;
999
1000   /**
1001    * Kept in a MDLL.
1002    */
1003   struct Queue *prev_client;
1004
1005   /**
1006    * Kept in a MDLL.
1007    */
1008   struct Queue *next_client;
1009
1010   /**
1011    * Head of DLL of unacked transmission requests.
1012    */
1013   struct QueueEntry *queue_head;
1014
1015   /**
1016    * End of DLL of unacked transmission requests.
1017    */
1018   struct QueueEntry *queue_tail;
1019
1020   /**
1021    * Which neighbour is this queue for?
1022    */
1023   struct Neighbour *neighbour;
1024
1025   /**
1026    * Which communicator offers this queue?
1027    */
1028   struct TransportClient *tc;
1029
1030   /**
1031    * Address served by the queue.
1032    */
1033   const char *address;
1034
1035   /**
1036    * Task scheduled for the time when this queue can (likely) transmit the
1037    * next message. Still needs to check with the @e tracker_out to be sure.
1038    */
1039   struct GNUNET_SCHEDULER_Task *transmit_task;
1040
1041   /**
1042    * Our current RTT estimate for this queue.
1043    */
1044   struct GNUNET_TIME_Relative rtt;
1045
1046   /**
1047    * Message ID generator for transmissions on this queue.
1048    */
1049   uint64_t mid_gen;
1050
1051   /**
1052    * Unique identifier of this queue with the communicator.
1053    */
1054   uint32_t qid;
1055
1056   /**
1057    * Maximum transmission unit supported by this queue.
1058    */
1059   uint32_t mtu;
1060
1061   /**
1062    * Distance to the target of this queue.
1063    */
1064   uint32_t distance;
1065
1066   /**
1067    * Messages pending.
1068    */
1069   uint32_t num_msg_pending;
1070
1071   /**
1072    * Bytes pending.
1073    */
1074   uint32_t num_bytes_pending;
1075
1076   /**
1077    * Length of the DLL starting at @e queue_head.
1078    */
1079   unsigned int queue_length;
1080
1081   /**
1082    * Network type offered by this queue.
1083    */
1084   enum GNUNET_NetworkType nt;
1085
1086   /**
1087    * Connection status for this queue.
1088    */
1089   enum GNUNET_TRANSPORT_ConnectionStatus cs;
1090
1091   /**
1092    * How much outbound bandwidth do we have available for this queue?
1093    */
1094   struct GNUNET_BANDWIDTH_Tracker tracker_out;
1095
1096   /**
1097    * How much inbound bandwidth do we have available for this queue?
1098    */
1099   struct GNUNET_BANDWIDTH_Tracker tracker_in;
1100 };
1101
1102
1103 /**
1104  * Information we keep for a message that we are reassembling.
1105  */
1106 struct ReassemblyContext
1107 {
1108
1109   /**
1110    * Original message ID for of the message that all the
1111    * fragments belong to.
1112    */
1113   struct GNUNET_ShortHashCode msg_uuid;
1114
1115   /**
1116    * Which neighbour is this context for?
1117    */
1118   struct Neighbour *neighbour;
1119
1120   /**
1121    * Entry in the reassembly heap (sorted by expiration).
1122    */
1123   struct GNUNET_CONTAINER_HeapNode *hn;
1124
1125   /**
1126    * Bitfield with @e msg_size bits representing the positions
1127    * where we have received fragments.  When we receive a fragment,
1128    * we check the bits in @e bitfield before incrementing @e msg_missing.
1129    *
1130    * Allocated after the reassembled message.
1131    */
1132   uint8_t *bitfield;
1133
1134   /**
1135    * Task for sending ACK. We may send ACKs either because of hitting
1136    * the @e extra_acks limit, or based on time and @e num_acks.  This
1137    * task is for the latter case.
1138    */
1139   struct GNUNET_SCHEDULER_Task *ack_task;
1140
1141   /**
1142    * At what time will we give up reassembly of this message?
1143    */
1144   struct GNUNET_TIME_Absolute reassembly_timeout;
1145
1146   /**
1147    * Average delay of all acks in @e extra_acks and @e frag_uuid.
1148    * Should be reset to zero when @e num_acks is set to 0.
1149    */
1150   struct GNUNET_TIME_Relative avg_ack_delay;
1151
1152   /**
1153    * Time we received the last fragment.  @e avg_ack_delay must be
1154    * incremented by now - @e last_frag multiplied by @e num_acks.
1155    */
1156   struct GNUNET_TIME_Absolute last_frag;
1157
1158   /**
1159    * Bitfield of up to 64 additional fragments following @e frag_uuid
1160    * to be acknowledged in the next cummulative ACK.
1161    */
1162   uint64_t extra_acks;
1163
1164   /**
1165    * Unique ID of the lowest fragment UUID to be acknowledged in the
1166    * next cummulative ACK.  Only valid if @e num_acks > 0.
1167    */
1168   uint32_t frag_uuid;
1169
1170   /**
1171    * Number of ACKs we have accumulated so far.  Reset to 0
1172    * whenever we send a #GNUNET_MESSAGE_TYPE_TRANSPORT_FRAGMENT_ACK.
1173    */
1174   unsigned int num_acks;
1175
1176   /**
1177    * How big is the message we are reassembling in total?
1178    */
1179   uint16_t msg_size;
1180
1181   /**
1182    * How many bytes of the message are still missing?  Defragmentation
1183    * is complete when @e msg_missing == 0.
1184    */
1185   uint16_t msg_missing;
1186
1187   /* Followed by @e msg_size bytes of the (partially) defragmented original message */
1188
1189   /* Followed by @e bitfield data */
1190 };
1191
1192
1193 /**
1194  * A neighbour that at least one communicator is connected to.
1195  */
1196 struct Neighbour
1197 {
1198
1199   /**
1200    * Which peer is this about?
1201    */
1202   struct GNUNET_PeerIdentity pid;
1203
1204   /**
1205    * Map with `struct ReassemblyContext` structs for fragments under
1206    * reassembly. May be NULL if we currently have no fragments from
1207    * this @e pid (lazy initialization).
1208    */
1209   struct GNUNET_CONTAINER_MultiShortmap *reassembly_map;
1210
1211   /**
1212    * Heap with `struct ReassemblyContext` structs for fragments under
1213    * reassembly. May be NULL if we currently have no fragments from
1214    * this @e pid (lazy initialization).
1215    */
1216   struct GNUNET_CONTAINER_Heap *reassembly_heap;
1217
1218   /**
1219    * Task to free old entries from the @e reassembly_heap and @e reassembly_map.
1220    */
1221   struct GNUNET_SCHEDULER_Task *reassembly_timeout_task;
1222
1223   /**
1224    * Head of list of messages pending for this neighbour.
1225    */
1226   struct PendingMessage *pending_msg_head;
1227
1228   /**
1229    * Tail of list of messages pending for this neighbour.
1230    */
1231   struct PendingMessage *pending_msg_tail;
1232
1233   /**
1234    * Head of MDLL of DV hops that have this neighbour as next hop. Must be
1235    * purged if this neighbour goes down.
1236    */
1237   struct DistanceVectorHop *dv_head;
1238
1239   /**
1240    * Tail of MDLL of DV hops that have this neighbour as next hop. Must be
1241    * purged if this neighbour goes down.
1242    */
1243   struct DistanceVectorHop *dv_tail;
1244
1245   /**
1246    * Head of DLL of queues to this peer.
1247    */
1248   struct Queue *queue_head;
1249
1250   /**
1251    * Tail of DLL of queues to this peer.
1252    */
1253   struct Queue *queue_tail;
1254
1255   /**
1256    * Task run to cleanup pending messages that have exceeded their timeout.
1257    */
1258   struct GNUNET_SCHEDULER_Task *timeout_task;
1259
1260   /**
1261    * Quota at which CORE is allowed to transmit to this peer.
1262    *
1263    * FIXME: not yet used, tricky to get right given multiple queues!
1264    *        (=> Idea: measure???)
1265    * FIXME: how do we set this value initially when we tell CORE?
1266    *    Options: start at a minimum value or at literally zero?
1267    *         (=> Current thought: clean would be zero!)
1268    */
1269   struct GNUNET_BANDWIDTH_Value32NBO quota_out;
1270
1271   /**
1272    * What is the earliest timeout of any message in @e pending_msg_tail?
1273    */
1274   struct GNUNET_TIME_Absolute earliest_timeout;
1275
1276 };
1277
1278
1279 /**
1280  * A peer that an application (client) would like us to talk to directly.
1281  */
1282 struct PeerRequest
1283 {
1284
1285   /**
1286    * Which peer is this about?
1287    */
1288   struct GNUNET_PeerIdentity pid;
1289
1290   /**
1291    * Client responsible for the request.
1292    */
1293   struct TransportClient *tc;
1294
1295   /**
1296    * Handle for watching the peerstore for HELLOs for this peer.
1297    */
1298   struct GNUNET_PEERSTORE_WatchContext *wc;
1299
1300   /**
1301    * What kind of performance preference does this @e tc have?
1302    */
1303   enum GNUNET_MQ_PreferenceKind pk;
1304
1305   /**
1306    * How much bandwidth would this @e tc like to see?
1307    */
1308   struct GNUNET_BANDWIDTH_Value32NBO bw;
1309
1310 };
1311
1312
1313 /**
1314  * Types of different pending messages.
1315  */
1316 enum PendingMessageType
1317 {
1318
1319   /**
1320    * Ordinary message received from the CORE service.
1321    */
1322   PMT_CORE = 0,
1323
1324   /**
1325    * Fragment box.
1326    */
1327   PMT_FRAGMENT_BOX = 1,
1328
1329   /**
1330    * Reliability box.
1331    */
1332   PMT_RELIABILITY_BOX = 2,
1333
1334   /**
1335    * Any type of acknowledgement.
1336    */
1337   PMT_ACKNOWLEDGEMENT = 3
1338
1339 };
1340
1341
1342 /**
1343  * Transmission request that is awaiting delivery.  The original
1344  * transmission requests from CORE may be too big for some queues.
1345  * In this case, a *tree* of fragments is created.  At each
1346  * level of the tree, fragments are kept in a DLL ordered by which
1347  * fragment should be sent next (at the head).  The tree is searched
1348  * top-down, with the original message at the root.
1349  *
1350  * To select a node for transmission, first it is checked if the
1351  * current node's message fits with the MTU.  If it does not, we
1352  * either calculate the next fragment (based on @e frag_off) from the
1353  * current node, or, if all fragments have already been created,
1354  * descend to the @e head_frag.  Even though the node was already
1355  * fragmented, the fragment may be too big if the fragment was
1356  * generated for a queue with a larger MTU. In this case, the node
1357  * may be fragmented again, thus creating a tree.
1358  *
1359  * When acknowledgements for fragments are received, the tree
1360  * must be pruned, removing those parts that were already
1361  * acknowledged.  When fragments are sent over a reliable
1362  * channel, they can be immediately removed.
1363  *
1364  * If a message is ever fragmented, then the original "full" message
1365  * is never again transmitted (even if it fits below the MTU), and
1366  * only (remaining) fragments are sent.
1367  */
1368 struct PendingMessage
1369 {
1370   /**
1371    * Kept in a MDLL of messages for this @a target.
1372    */
1373   struct PendingMessage *next_neighbour;
1374
1375   /**
1376    * Kept in a MDLL of messages for this @a target.
1377    */
1378   struct PendingMessage *prev_neighbour;
1379
1380   /**
1381    * Kept in a MDLL of messages from this @a client (if @e pmt is #PMT_CORE)
1382    */
1383   struct PendingMessage *next_client;
1384
1385   /**
1386    * Kept in a MDLL of messages from this @a client  (if @e pmt is #PMT_CORE)
1387    */
1388   struct PendingMessage *prev_client;
1389
1390   /**
1391    * Kept in a MDLL of messages from this @a cpm (if @e pmt is #PMT_FRAGMENT_BOx)
1392    */
1393   struct PendingMessage *next_frag;
1394
1395   /**
1396    * Kept in a MDLL of messages from this @a cpm  (if @e pmt is #PMT_FRAGMENT_BOX)
1397    */
1398   struct PendingMessage *prev_frag;
1399
1400   /**
1401    * This message, reliability boxed. Only possibly available if @e pmt is #PMT_CORE.
1402    */
1403   struct PendingMessage *bpm;
1404
1405   /**
1406    * Target of the request.
1407    */
1408   struct Neighbour *target;
1409
1410   /**
1411    * Client that issued the transmission request, if @e pmt is #PMT_CORE.
1412    */
1413   struct TransportClient *client;
1414
1415   /**
1416    * Head of a MDLL of fragments created for this core message.
1417    */
1418   struct PendingMessage *head_frag;
1419
1420   /**
1421    * Tail of a MDLL of fragments created for this core message.
1422    */
1423   struct PendingMessage *tail_frag;
1424
1425   /**
1426    * Our parent in the fragmentation tree.
1427    */
1428   struct PendingMessage *frag_parent;
1429
1430   /**
1431    * At what time should we give up on the transmission (and no longer retry)?
1432    */
1433   struct GNUNET_TIME_Absolute timeout;
1434
1435   /**
1436    * What is the earliest time for us to retry transmission of this message?
1437    */
1438   struct GNUNET_TIME_Absolute next_attempt;
1439
1440   /**
1441    * UUID to use for this message (used for reassembly of fragments, only
1442    * initialized if @e msg_uuid_set is #GNUNET_YES).
1443    */
1444   struct GNUNET_ShortHashCode msg_uuid;
1445
1446   /**
1447    * Counter incremented per generated fragment.
1448    */
1449   uint32_t frag_uuidgen;
1450
1451   /**
1452    * Type of the pending message.
1453    */
1454   enum PendingMessageType pmt;
1455
1456   /**
1457    * Size of the original message.
1458    */
1459   uint16_t bytes_msg;
1460
1461   /**
1462    * Offset at which we should generate the next fragment.
1463    */
1464   uint16_t frag_off;
1465
1466   /**
1467    * #GNUNET_YES once @e msg_uuid was initialized
1468    */
1469   int16_t msg_uuid_set;
1470
1471   /* Followed by @e bytes_msg to transmit */
1472 };
1473
1474
1475 /**
1476  * One of the addresses of this peer.
1477  */
1478 struct AddressListEntry
1479 {
1480
1481   /**
1482    * Kept in a DLL.
1483    */
1484   struct AddressListEntry *next;
1485
1486   /**
1487    * Kept in a DLL.
1488    */
1489   struct AddressListEntry *prev;
1490
1491   /**
1492    * Which communicator provides this address?
1493    */
1494   struct TransportClient *tc;
1495
1496   /**
1497    * The actual address.
1498    */
1499   const char *address;
1500
1501   /**
1502    * Current context for storing this address in the peerstore.
1503    */
1504   struct GNUNET_PEERSTORE_StoreContext *sc;
1505
1506   /**
1507    * Task to periodically do @e st operation.
1508    */
1509   struct GNUNET_SCHEDULER_Task *st;
1510
1511   /**
1512    * What is a typical lifetime the communicator expects this
1513    * address to have? (Always from now.)
1514    */
1515   struct GNUNET_TIME_Relative expiration;
1516
1517   /**
1518    * Address identifier used by the communicator.
1519    */
1520   uint32_t aid;
1521
1522   /**
1523    * Network type offered by this address.
1524    */
1525   enum GNUNET_NetworkType nt;
1526
1527 };
1528
1529
1530 /**
1531  * Client connected to the transport service.
1532  */
1533 struct TransportClient
1534 {
1535
1536   /**
1537    * Kept in a DLL.
1538    */
1539   struct TransportClient *next;
1540
1541   /**
1542    * Kept in a DLL.
1543    */
1544   struct TransportClient *prev;
1545
1546   /**
1547    * Handle to the client.
1548    */
1549   struct GNUNET_SERVICE_Client *client;
1550
1551   /**
1552    * Message queue to the client.
1553    */
1554   struct GNUNET_MQ_Handle *mq;
1555
1556   /**
1557    * What type of client is this?
1558    */
1559   enum ClientType type;
1560
1561   union
1562   {
1563
1564     /**
1565      * Information for @e type #CT_CORE.
1566      */
1567     struct {
1568
1569       /**
1570        * Head of list of messages pending for this client, sorted by
1571        * transmission time ("next_attempt" + possibly internal prioritization).
1572        */
1573       struct PendingMessage *pending_msg_head;
1574
1575       /**
1576        * Tail of list of messages pending for this client.
1577        */
1578       struct PendingMessage *pending_msg_tail;
1579
1580     } core;
1581
1582     /**
1583      * Information for @e type #CT_MONITOR.
1584      */
1585     struct {
1586
1587       /**
1588        * Peer identity to monitor the addresses of.
1589        * Zero to monitor all neighbours.  Valid if
1590        * @e type is #CT_MONITOR.
1591        */
1592       struct GNUNET_PeerIdentity peer;
1593
1594       /**
1595        * Is this a one-shot monitor?
1596        */
1597       int one_shot;
1598
1599     } monitor;
1600
1601
1602     /**
1603      * Information for @e type #CT_COMMUNICATOR.
1604      */
1605     struct {
1606       /**
1607        * If @e type is #CT_COMMUNICATOR, this communicator
1608        * supports communicating using these addresses.
1609        */
1610       char *address_prefix;
1611
1612       /**
1613        * Head of DLL of queues offered by this communicator.
1614        */
1615       struct Queue *queue_head;
1616
1617       /**
1618        * Tail of DLL of queues offered by this communicator.
1619        */
1620       struct Queue *queue_tail;
1621
1622       /**
1623        * Head of list of the addresses of this peer offered by this communicator.
1624        */
1625       struct AddressListEntry *addr_head;
1626
1627       /**
1628        * Tail of list of the addresses of this peer offered by this communicator.
1629        */
1630       struct AddressListEntry *addr_tail;
1631
1632       /**
1633        * Number of queue entries in all queues to this communicator. Used
1634        * throttle sending to a communicator if we see that the communicator
1635        * is globally unable to keep up.
1636        */
1637       unsigned int total_queue_length;
1638
1639       /**
1640        * Characteristics of this communicator.
1641        */
1642       enum GNUNET_TRANSPORT_CommunicatorCharacteristics cc;
1643
1644     } communicator;
1645
1646     /**
1647      * Information for @e type #CT_APPLICATION
1648      */
1649     struct {
1650
1651       /**
1652        * Map of requests for peers the given client application would like to
1653        * see connections for.  Maps from PIDs to `struct PeerRequest`.
1654        */
1655       struct GNUNET_CONTAINER_MultiPeerMap *requests;
1656
1657     } application;
1658
1659   } details;
1660
1661 };
1662
1663
1664 /**
1665  * State we keep for validation activities.  Each of these
1666  * is both in the #validation_heap and the #validation_map.
1667  */
1668 struct ValidationState
1669 {
1670
1671   /**
1672    * For which peer is @a address to be validated (or possibly valid)?
1673    * Serves as key in the #validation_map.
1674    */
1675   struct GNUNET_PeerIdentity pid;
1676
1677   /**
1678    * How long did the peer claim this @e address to be valid? Capped at
1679    * minimum of #MAX_ADDRESS_VALID_UNTIL relative to the time where we last
1680    * were told about the address and the value claimed by the other peer at
1681    * that time.  May be updated similarly when validation succeeds.
1682    */
1683   struct GNUNET_TIME_Absolute valid_until;
1684
1685   /**
1686    * How long do *we* consider this @e address to be valid?
1687    * In the past or zero if we have not yet validated it.
1688    */
1689   struct GNUNET_TIME_Absolute validated_until;
1690
1691   /**
1692    * When did we FIRST use the current @e challenge in a message?
1693    * Used to sanity-check @code{origin_time} in the response when
1694    * calculating the RTT. If the @code{origin_time} is not in
1695    * the expected range, the response is discarded as malicious.
1696    */
1697   struct GNUNET_TIME_Absolute first_challenge_use;
1698
1699   /**
1700    * When did we LAST use the current @e challenge in a message?
1701    * Used to sanity-check @code{origin_time} in the response when
1702    * calculating the RTT.  If the @code{origin_time} is not in
1703    * the expected range, the response is discarded as malicious.
1704    */
1705   struct GNUNET_TIME_Absolute last_challenge_use;
1706
1707   /**
1708    * Next time we will send the @e challenge to the peer, if this time is past
1709    * @e valid_until, this validation state is released at this time.  If the
1710    * address is valid, @e next_challenge is set to @e validated_until MINUS @e
1711    * validation_delay * #VALIDATION_RTT_BUFFER_FACTOR, such that we will try
1712    * to re-validate before the validity actually expires.
1713    */
1714   struct GNUNET_TIME_Absolute next_challenge;
1715
1716   /**
1717    * Current backoff factor we're applying for sending the @a challenge.
1718    * Reset to 0 if the @a challenge is confirmed upon validation.
1719    * Reduced to minimum of #FAST_VALIDATION_CHALLENGE_FREQ and half of the
1720    * existing value if we receive an unvalidated address again over
1721    * another channel (and thus should consider the information "fresh").
1722    * Maximum is #MAX_VALIDATION_CHALLENGE_FREQ.
1723    */
1724   struct GNUNET_TIME_Relative challenge_backoff;
1725
1726   /**
1727    * Initially set to "forever". Once @e validated_until is set, this value is
1728    * set to the RTT that tells us how long it took to receive the validation.
1729    */
1730   struct GNUNET_TIME_Relative validation_rtt;
1731
1732   /**
1733    * The challenge we sent to the peer to get it to validate the address. Note
1734    * that we rotate the challenge whenever we update @e validated_until to
1735    * avoid attacks where a peer simply replays an old challenge in the future.
1736    * (We must not rotate more often as otherwise we may discard valid answers
1737    * due to packet losses, latency and reorderings on the network).
1738    */
1739   struct GNUNET_ShortHashCode challenge;
1740
1741   /**
1742    * Claimed address of the peer.
1743    */
1744   char *address;
1745
1746   /**
1747    * Entry in the #validation_heap, which is sorted by @e next_challenge. The
1748    * heap is used to figure out when the next validation activity should be
1749    * run.
1750    */
1751   struct GNUNET_CONTAINER_HeapNode *hn;
1752
1753   /**
1754    * Handle to a PEERSTORE store operation for this @e address.  NULL if
1755    * no PEERSTORE operation is pending.
1756    */
1757   struct GNUNET_PEERSTORE_StoreContext *sc;
1758
1759   /**
1760    * We are technically ready to send the challenge, but we are waiting for
1761    * the respective queue to become available for transmission.
1762    */
1763   int awaiting_queue;
1764
1765 };
1766
1767
1768 /**
1769  * Head of linked list of all clients to this service.
1770  */
1771 static struct TransportClient *clients_head;
1772
1773 /**
1774  * Tail of linked list of all clients to this service.
1775  */
1776 static struct TransportClient *clients_tail;
1777
1778 /**
1779  * Statistics handle.
1780  */
1781 static struct GNUNET_STATISTICS_Handle *GST_stats;
1782
1783 /**
1784  * Configuration handle.
1785  */
1786 static const struct GNUNET_CONFIGURATION_Handle *GST_cfg;
1787
1788 /**
1789  * Our public key.
1790  */
1791 static struct GNUNET_PeerIdentity GST_my_identity;
1792
1793 /**
1794  * Our private key.
1795  */
1796 static struct GNUNET_CRYPTO_EddsaPrivateKey *GST_my_private_key;
1797
1798 /**
1799  * Map from PIDs to `struct Neighbour` entries.  A peer is
1800  * a neighbour if we have an MQ to it from some communicator.
1801  */
1802 static struct GNUNET_CONTAINER_MultiPeerMap *neighbours;
1803
1804 /**
1805  * Map from PIDs to `struct DistanceVector` entries describing
1806  * known paths to the peer.
1807  */
1808 static struct GNUNET_CONTAINER_MultiPeerMap *dv_routes;
1809
1810 /**
1811  * Map from PIDs to `struct ValidationState` entries describing
1812  * addresses we are aware of and their validity state.
1813  */
1814 static struct GNUNET_CONTAINER_MultiPeerMap *validation_map;
1815
1816 /**
1817  * MIN Heap sorted by "next_challenge" to `struct ValidationState` entries
1818  * sorting addresses we are aware of by when we should next try to (re)validate
1819  * (or expire) them.
1820  */
1821 static struct GNUNET_CONTAINER_Heap *validation_heap;
1822
1823 /**
1824  * Database for peer's HELLOs.
1825  */
1826 static struct GNUNET_PEERSTORE_Handle *peerstore;
1827
1828 /**
1829  * Heap sorting `struct EphemeralCacheEntry` by their
1830  * key/signature validity.
1831  */
1832 static struct GNUNET_CONTAINER_Heap *ephemeral_heap;
1833
1834 /**
1835  * Hash map for looking up `struct EphemeralCacheEntry`s
1836  * by peer identity. (We may have ephemerals in our
1837  * cache for which we do not have a neighbour entry,
1838  * and similar many neighbours may not need ephemerals,
1839  * so we use a second map.)
1840  */
1841 static struct GNUNET_CONTAINER_MultiPeerMap *ephemeral_map;
1842
1843 /**
1844  * Task to free expired ephemerals.
1845  */
1846 static struct GNUNET_SCHEDULER_Task *ephemeral_task;
1847
1848 /**
1849  * Task to run address validation.
1850  */
1851 static struct GNUNET_SCHEDULER_Task *validation_task;
1852
1853
1854 /**
1855  * Free cached ephemeral key.
1856  *
1857  * @param ece cached signature to free
1858  */
1859 static void
1860 free_ephemeral (struct EphemeralCacheEntry *ece)
1861 {
1862   GNUNET_CONTAINER_multipeermap_remove (ephemeral_map,
1863                                         &ece->target,
1864                                         ece);
1865   GNUNET_CONTAINER_heap_remove_node (ece->hn);
1866   GNUNET_free (ece);
1867 }
1868
1869
1870 /**
1871  * Free validation state.
1872  *
1873  * @param vs validation state to free
1874  */
1875 static void
1876 free_validation_state (struct ValidationState *vs)
1877 {
1878   GNUNET_CONTAINER_multipeermap_remove (validation_map,
1879                                         &vs->pid,
1880                                         vs);
1881   GNUNET_CONTAINER_heap_remove_node (vs->hn);
1882   vs->hn = NULL;
1883   if (NULL != vs->sc)
1884   {
1885     GNUNET_PEERSTORE_store_cancel (vs->sc);
1886     vs->sc = NULL;
1887   }
1888   GNUNET_free (vs->address);
1889   GNUNET_free (vs);
1890 }
1891
1892
1893 /**
1894  * Lookup neighbour record for peer @a pid.
1895  *
1896  * @param pid neighbour to look for
1897  * @return NULL if we do not have this peer as a neighbour
1898  */
1899 static struct Neighbour *
1900 lookup_neighbour (const struct GNUNET_PeerIdentity *pid)
1901 {
1902   return GNUNET_CONTAINER_multipeermap_get (neighbours,
1903                                             pid);
1904 }
1905
1906
1907 /**
1908  * Details about what to notify monitors about.
1909  */
1910 struct MonitorEvent
1911 {
1912   /**
1913    * @deprecated To be discussed if we keep these...
1914    */
1915   struct GNUNET_TIME_Absolute last_validation;
1916   struct GNUNET_TIME_Absolute valid_until;
1917   struct GNUNET_TIME_Absolute next_validation;
1918
1919   /**
1920    * Current round-trip time estimate.
1921    */
1922   struct GNUNET_TIME_Relative rtt;
1923
1924   /**
1925    * Connection status.
1926    */
1927   enum GNUNET_TRANSPORT_ConnectionStatus cs;
1928
1929   /**
1930    * Messages pending.
1931    */
1932   uint32_t num_msg_pending;
1933
1934   /**
1935    * Bytes pending.
1936    */
1937   uint32_t num_bytes_pending;
1938
1939
1940 };
1941
1942
1943 /**
1944  * Free a @dvh. Callers MAY want to check if this was the last path to the
1945  * `target`, and if so call #free_dv_route to also free the associated DV
1946  * entry in #dv_routes (if not, the associated scheduler job should eventually
1947  * take care of it).
1948  *
1949  * @param dvh hop to free
1950  */
1951 static void
1952 free_distance_vector_hop (struct DistanceVectorHop *dvh)
1953 {
1954   struct Neighbour *n = dvh->next_hop;
1955   struct DistanceVector *dv = dvh->dv;
1956
1957   GNUNET_CONTAINER_MDLL_remove (neighbour,
1958                                 n->dv_head,
1959                                 n->dv_tail,
1960                                 dvh);
1961   GNUNET_CONTAINER_MDLL_remove (dv,
1962                                 dv->dv_head,
1963                                 dv->dv_tail,
1964                                 dvh);
1965   GNUNET_free (dvh);
1966 }
1967
1968
1969 /**
1970  * Free entry in #dv_routes.  First frees all hops to the target, and
1971  * if there are no entries left, frees @a dv as well.
1972  *
1973  * @param dv route to free
1974  */
1975 static void
1976 free_dv_route (struct DistanceVector *dv)
1977 {
1978   struct DistanceVectorHop *dvh;
1979
1980   while (NULL != (dvh = dv->dv_head))
1981     free_distance_vector_hop (dvh);
1982   if (NULL == dv->dv_head)
1983   {
1984     GNUNET_assert (GNUNET_YES ==
1985                    GNUNET_CONTAINER_multipeermap_remove (dv_routes,
1986                                                          &dv->target,
1987                                                          dv));
1988     if (NULL != dv->timeout_task)
1989       GNUNET_SCHEDULER_cancel (dv->timeout_task);
1990     GNUNET_free (dv);
1991   }
1992 }
1993
1994
1995 /**
1996  * Notify monitor @a tc about an event.  That @a tc
1997  * cares about the event has already been checked.
1998  *
1999  * Send @a tc information in @a me about a @a peer's status with
2000  * respect to some @a address to all monitors that care.
2001  *
2002  * @param tc monitor to inform
2003  * @param peer peer the information is about
2004  * @param address address the information is about
2005  * @param nt network type associated with @a address
2006  * @param me detailed information to transmit
2007  */
2008 static void
2009 notify_monitor (struct TransportClient *tc,
2010                 const struct GNUNET_PeerIdentity *peer,
2011                 const char *address,
2012                 enum GNUNET_NetworkType nt,
2013                 const struct MonitorEvent *me)
2014 {
2015   struct GNUNET_MQ_Envelope *env;
2016   struct GNUNET_TRANSPORT_MonitorData *md;
2017   size_t addr_len = strlen (address) + 1;
2018
2019   env = GNUNET_MQ_msg_extra (md,
2020                              addr_len,
2021                              GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_DATA);
2022   md->nt = htonl ((uint32_t) nt);
2023   md->peer = *peer;
2024   md->last_validation = GNUNET_TIME_absolute_hton (me->last_validation);
2025   md->valid_until = GNUNET_TIME_absolute_hton (me->valid_until);
2026   md->next_validation = GNUNET_TIME_absolute_hton (me->next_validation);
2027   md->rtt = GNUNET_TIME_relative_hton (me->rtt);
2028   md->cs = htonl ((uint32_t) me->cs);
2029   md->num_msg_pending = htonl (me->num_msg_pending);
2030   md->num_bytes_pending = htonl (me->num_bytes_pending);
2031   memcpy (&md[1],
2032           address,
2033           addr_len);
2034   GNUNET_MQ_send (tc->mq,
2035                   env);
2036 }
2037
2038
2039 /**
2040  * Send information in @a me about a @a peer's status with respect
2041  * to some @a address to all monitors that care.
2042  *
2043  * @param peer peer the information is about
2044  * @param address address the information is about
2045  * @param nt network type associated with @a address
2046  * @param me detailed information to transmit
2047  */
2048 static void
2049 notify_monitors (const struct GNUNET_PeerIdentity *peer,
2050                  const char *address,
2051                  enum GNUNET_NetworkType nt,
2052                  const struct MonitorEvent *me)
2053 {
2054   for (struct TransportClient *tc = clients_head;
2055        NULL != tc;
2056        tc = tc->next)
2057   {
2058     if (CT_MONITOR != tc->type)
2059       continue;
2060     if (tc->details.monitor.one_shot)
2061       continue;
2062     if ( (0 != GNUNET_is_zero (&tc->details.monitor.peer)) &&
2063          (0 != GNUNET_memcmp (&tc->details.monitor.peer,
2064                               peer)) )
2065       continue;
2066     notify_monitor (tc,
2067                     peer,
2068                     address,
2069                     nt,
2070                     me);
2071   }
2072 }
2073
2074
2075 /**
2076  * Called whenever a client connects.  Allocates our
2077  * data structures associated with that client.
2078  *
2079  * @param cls closure, NULL
2080  * @param client identification of the client
2081  * @param mq message queue for the client
2082  * @return our `struct TransportClient`
2083  */
2084 static void *
2085 client_connect_cb (void *cls,
2086                    struct GNUNET_SERVICE_Client *client,
2087                    struct GNUNET_MQ_Handle *mq)
2088 {
2089   struct TransportClient *tc;
2090
2091   tc = GNUNET_new (struct TransportClient);
2092   tc->client = client;
2093   tc->mq = mq;
2094   GNUNET_CONTAINER_DLL_insert (clients_head,
2095                                clients_tail,
2096                                tc);
2097   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2098               "Client %p connected\n",
2099               tc);
2100   return tc;
2101 }
2102
2103
2104 /**
2105  * Free @a rc
2106  *
2107  * @param rc data structure to free
2108  */
2109 static void
2110 free_reassembly_context (struct ReassemblyContext *rc)
2111 {
2112   struct Neighbour *n = rc->neighbour;
2113
2114   GNUNET_assert (rc ==
2115                  GNUNET_CONTAINER_heap_remove_node (rc->hn));
2116   GNUNET_assert (GNUNET_OK ==
2117                  GNUNET_CONTAINER_multishortmap_remove (n->reassembly_map,
2118                                                         &rc->msg_uuid,
2119                                                         rc));
2120   GNUNET_free (rc);
2121 }
2122
2123
2124 /**
2125  * Task run to clean up reassembly context of a neighbour that have expired.
2126  *
2127  * @param cls a `struct Neighbour`
2128  */
2129 static void
2130 reassembly_cleanup_task (void *cls)
2131 {
2132   struct Neighbour *n = cls;
2133   struct ReassemblyContext *rc;
2134
2135   n->reassembly_timeout_task = NULL;
2136   while (NULL != (rc = GNUNET_CONTAINER_heap_peek (n->reassembly_heap)))
2137   {
2138     if (0 == GNUNET_TIME_absolute_get_remaining (rc->reassembly_timeout).rel_value_us)
2139     {
2140       free_reassembly_context (rc);
2141       continue;
2142     }
2143     GNUNET_assert (NULL == n->reassembly_timeout_task);
2144     n->reassembly_timeout_task = GNUNET_SCHEDULER_add_at (rc->reassembly_timeout,
2145                                                           &reassembly_cleanup_task,
2146                                                           n);
2147     return;
2148   }
2149 }
2150
2151
2152 /**
2153  * function called to #free_reassembly_context().
2154  *
2155  * @param cls NULL
2156  * @param key unused
2157  * @param value a `struct ReassemblyContext` to free
2158  * @return #GNUNET_OK (continue iteration)
2159  */
2160 static int
2161 free_reassembly_cb (void *cls,
2162                     const struct GNUNET_ShortHashCode *key,
2163                     void *value)
2164 {
2165   struct ReassemblyContext *rc = value;
2166   (void) cls;
2167   (void) key;
2168
2169   free_reassembly_context (rc);
2170   return GNUNET_OK;
2171 }
2172
2173
2174 /**
2175  * Release memory used by @a neighbour.
2176  *
2177  * @param neighbour neighbour entry to free
2178  */
2179 static void
2180 free_neighbour (struct Neighbour *neighbour)
2181 {
2182   struct DistanceVectorHop *dvh;
2183
2184   GNUNET_assert (NULL == neighbour->queue_head);
2185   GNUNET_assert (GNUNET_YES ==
2186                  GNUNET_CONTAINER_multipeermap_remove (neighbours,
2187                                                        &neighbour->pid,
2188                                                        neighbour));
2189   if (NULL != neighbour->timeout_task)
2190     GNUNET_SCHEDULER_cancel (neighbour->timeout_task);
2191   if (NULL != neighbour->reassembly_map)
2192   {
2193     GNUNET_CONTAINER_multishortmap_iterate (neighbour->reassembly_map,
2194                                             &free_reassembly_cb,
2195                                             NULL);
2196     GNUNET_CONTAINER_multishortmap_destroy (neighbour->reassembly_map);
2197     neighbour->reassembly_map = NULL;
2198     GNUNET_CONTAINER_heap_destroy (neighbour->reassembly_heap);
2199     neighbour->reassembly_heap = NULL;
2200   }
2201   while (NULL != (dvh = neighbour->dv_head))
2202   {
2203     struct DistanceVector *dv = dvh->dv;
2204
2205     free_distance_vector_hop (dvh);
2206     if (NULL == dv->dv_head)
2207       free_dv_route (dv);
2208   }
2209   if (NULL != neighbour->reassembly_timeout_task)
2210     GNUNET_SCHEDULER_cancel (neighbour->reassembly_timeout_task);
2211   GNUNET_free (neighbour);
2212 }
2213
2214
2215 /**
2216  * Send message to CORE clients that we lost a connection.
2217  *
2218  * @param tc client to inform (must be CORE client)
2219  * @param pid peer the connection is for
2220  * @param quota_out current quota for the peer
2221  */
2222 static void
2223 core_send_connect_info (struct TransportClient *tc,
2224                         const struct GNUNET_PeerIdentity *pid,
2225                         struct GNUNET_BANDWIDTH_Value32NBO quota_out)
2226 {
2227   struct GNUNET_MQ_Envelope *env;
2228   struct ConnectInfoMessage *cim;
2229
2230   GNUNET_assert (CT_CORE == tc->type);
2231   env = GNUNET_MQ_msg (cim,
2232                        GNUNET_MESSAGE_TYPE_TRANSPORT_CONNECT);
2233   cim->quota_out = quota_out;
2234   cim->id = *pid;
2235   GNUNET_MQ_send (tc->mq,
2236                   env);
2237 }
2238
2239
2240 /**
2241  * Send message to CORE clients that we gained a connection
2242  *
2243  * @param pid peer the queue was for
2244  * @param quota_out current quota for the peer
2245  */
2246 static void
2247 cores_send_connect_info (const struct GNUNET_PeerIdentity *pid,
2248                          struct GNUNET_BANDWIDTH_Value32NBO quota_out)
2249 {
2250   for (struct TransportClient *tc = clients_head;
2251        NULL != tc;
2252        tc = tc->next)
2253   {
2254     if (CT_CORE != tc->type)
2255       continue;
2256     core_send_connect_info (tc,
2257                             pid,
2258                             quota_out);
2259   }
2260 }
2261
2262
2263 /**
2264  * Send message to CORE clients that we lost a connection.
2265  *
2266  * @param pid peer the connection was for
2267  */
2268 static void
2269 cores_send_disconnect_info (const struct GNUNET_PeerIdentity *pid)
2270 {
2271   for (struct TransportClient *tc = clients_head;
2272        NULL != tc;
2273        tc = tc->next)
2274   {
2275     struct GNUNET_MQ_Envelope *env;
2276     struct DisconnectInfoMessage *dim;
2277
2278     if (CT_CORE != tc->type)
2279       continue;
2280     env = GNUNET_MQ_msg (dim,
2281                          GNUNET_MESSAGE_TYPE_TRANSPORT_DISCONNECT);
2282     dim->peer = *pid;
2283     GNUNET_MQ_send (tc->mq,
2284                     env);
2285   }
2286 }
2287
2288
2289 /**
2290  * We believe we are ready to transmit a message on a queue. Double-checks
2291  * with the queue's "tracker_out" and then gives the message to the
2292  * communicator for transmission (updating the tracker, and re-scheduling
2293  * itself if applicable).
2294  *
2295  * @param cls the `struct Queue` to process transmissions for
2296  */
2297 static void
2298 transmit_on_queue (void *cls);
2299
2300
2301 /**
2302  * Schedule next run of #transmit_on_queue().  Does NOTHING if
2303  * we should run immediately or if the message queue is empty.
2304  * Test for no task being added AND queue not being empty to
2305  * transmit immediately afterwards!  This function must only
2306  * be called if the message queue is non-empty!
2307  *
2308  * @param queue the queue to do scheduling for
2309  */
2310 static void
2311 schedule_transmit_on_queue (struct Queue *queue)
2312 {
2313   struct Neighbour *n = queue->neighbour;
2314   struct PendingMessage *pm = n->pending_msg_head;
2315   struct GNUNET_TIME_Relative out_delay;
2316   unsigned int wsize;
2317
2318   GNUNET_assert (NULL != pm);
2319   if (queue->tc->details.communicator.total_queue_length >=
2320       COMMUNICATOR_TOTAL_QUEUE_LIMIT)
2321   {
2322     GNUNET_STATISTICS_update (GST_stats,
2323                               "# Transmission throttled due to communicator queue limit",
2324                               1,
2325                               GNUNET_NO);
2326     return;
2327   }
2328   if (queue->queue_length >= QUEUE_LENGTH_LIMIT)
2329   {
2330     GNUNET_STATISTICS_update (GST_stats,
2331                               "# Transmission throttled due to queue queue limit",
2332                               1,
2333                               GNUNET_NO);
2334     return;
2335   }
2336
2337   wsize = (0 == queue->mtu)
2338     ? pm->bytes_msg /* FIXME: add overheads? */
2339     : queue->mtu;
2340   out_delay = GNUNET_BANDWIDTH_tracker_get_delay (&queue->tracker_out,
2341                                                   wsize);
2342   out_delay = GNUNET_TIME_relative_max (GNUNET_TIME_absolute_get_remaining (pm->next_attempt),
2343                                         out_delay);
2344   if (0 == out_delay.rel_value_us)
2345     return; /* we should run immediately! */
2346   /* queue has changed since we were scheduled, reschedule again */
2347   queue->transmit_task
2348     = GNUNET_SCHEDULER_add_delayed (out_delay,
2349                                     &transmit_on_queue,
2350                                     queue);
2351   if (out_delay.rel_value_us > DELAY_WARN_THRESHOLD.rel_value_us)
2352     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2353                 "Next transmission on queue `%s' in %s (high delay)\n",
2354                 queue->address,
2355                 GNUNET_STRINGS_relative_time_to_string (out_delay,
2356                                                         GNUNET_YES));
2357   else
2358     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2359                 "Next transmission on queue `%s' in %s\n",
2360                 queue->address,
2361                 GNUNET_STRINGS_relative_time_to_string (out_delay,
2362                                                         GNUNET_YES));
2363 }
2364
2365
2366 /**
2367  * Free @a queue.
2368  *
2369  * @param queue the queue to free
2370  */
2371 static void
2372 free_queue (struct Queue *queue)
2373 {
2374   struct Neighbour *neighbour = queue->neighbour;
2375   struct TransportClient *tc = queue->tc;
2376   struct MonitorEvent me = {
2377     .cs = GNUNET_TRANSPORT_CS_DOWN,
2378     .rtt = GNUNET_TIME_UNIT_FOREVER_REL
2379   };
2380   struct QueueEntry *qe;
2381   int maxxed;
2382
2383   if (NULL != queue->transmit_task)
2384   {
2385     GNUNET_SCHEDULER_cancel (queue->transmit_task);
2386     queue->transmit_task = NULL;
2387   }
2388   GNUNET_CONTAINER_MDLL_remove (neighbour,
2389                                 neighbour->queue_head,
2390                                 neighbour->queue_tail,
2391                                 queue);
2392   GNUNET_CONTAINER_MDLL_remove (client,
2393                                 tc->details.communicator.queue_head,
2394                                 tc->details.communicator.queue_tail,
2395                                 queue);
2396   maxxed = (COMMUNICATOR_TOTAL_QUEUE_LIMIT >= tc->details.communicator.total_queue_length);
2397   while (NULL != (qe = queue->queue_head))
2398   {
2399     GNUNET_CONTAINER_DLL_remove (queue->queue_head,
2400                                  queue->queue_tail,
2401                                  qe);
2402     queue->queue_length--;
2403     tc->details.communicator.total_queue_length--;
2404     GNUNET_free (qe);
2405   }
2406   GNUNET_assert (0 == queue->queue_length);
2407   if ( (maxxed) &&
2408        (COMMUNICATOR_TOTAL_QUEUE_LIMIT < tc->details.communicator.total_queue_length) )
2409   {
2410     /* Communicator dropped below threshold, resume all queues */
2411     GNUNET_STATISTICS_update (GST_stats,
2412                               "# Transmission throttled due to communicator queue limit",
2413                               -1,
2414                               GNUNET_NO);
2415     for (struct Queue *s = tc->details.communicator.queue_head;
2416          NULL != s;
2417          s = s->next_client)
2418       schedule_transmit_on_queue (s);
2419   }
2420   notify_monitors (&neighbour->pid,
2421                    queue->address,
2422                    queue->nt,
2423                    &me);
2424   GNUNET_BANDWIDTH_tracker_notification_stop (&queue->tracker_in);
2425   GNUNET_BANDWIDTH_tracker_notification_stop (&queue->tracker_out);
2426   GNUNET_free (queue);
2427   if (NULL == neighbour->queue_head)
2428   {
2429     cores_send_disconnect_info (&neighbour->pid);
2430     free_neighbour (neighbour);
2431   }
2432 }
2433
2434
2435 /**
2436  * Free @a ale
2437  *
2438  * @param ale address list entry to free
2439  */
2440 static void
2441 free_address_list_entry (struct AddressListEntry *ale)
2442 {
2443   struct TransportClient *tc = ale->tc;
2444
2445   GNUNET_CONTAINER_DLL_remove (tc->details.communicator.addr_head,
2446                                tc->details.communicator.addr_tail,
2447                                ale);
2448   if (NULL != ale->sc)
2449   {
2450     GNUNET_PEERSTORE_store_cancel (ale->sc);
2451     ale->sc = NULL;
2452   }
2453   if (NULL != ale->st)
2454   {
2455     GNUNET_SCHEDULER_cancel (ale->st);
2456     ale->st = NULL;
2457   }
2458   GNUNET_free (ale);
2459 }
2460
2461
2462 /**
2463  * Stop the peer request in @a value.
2464  *
2465  * @param cls a `struct TransportClient` that no longer makes the request
2466  * @param pid the peer's identity
2467  * @param value a `struct PeerRequest`
2468  * @return #GNUNET_YES (always)
2469  */
2470 static int
2471 stop_peer_request (void *cls,
2472                    const struct GNUNET_PeerIdentity *pid,
2473                    void *value)
2474 {
2475   struct TransportClient *tc = cls;
2476   struct PeerRequest *pr = value;
2477
2478   GNUNET_PEERSTORE_watch_cancel (pr->wc);
2479   GNUNET_assert (GNUNET_YES ==
2480                  GNUNET_CONTAINER_multipeermap_remove (tc->details.application.requests,
2481                                                        pid,
2482                                                        pr));
2483   GNUNET_free (pr);
2484
2485   return GNUNET_OK;
2486 }
2487
2488
2489 /**
2490  * Called whenever a client is disconnected.  Frees our
2491  * resources associated with that client.
2492  *
2493  * @param cls closure, NULL
2494  * @param client identification of the client
2495  * @param app_ctx our `struct TransportClient`
2496  */
2497 static void
2498 client_disconnect_cb (void *cls,
2499                       struct GNUNET_SERVICE_Client *client,
2500                       void *app_ctx)
2501 {
2502   struct TransportClient *tc = app_ctx;
2503
2504   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2505               "Client %p disconnected, cleaning up.\n",
2506               tc);
2507   GNUNET_CONTAINER_DLL_remove (clients_head,
2508                                clients_tail,
2509                                tc);
2510   switch (tc->type)
2511   {
2512   case CT_NONE:
2513     break;
2514   case CT_CORE:
2515     {
2516       struct PendingMessage *pm;
2517
2518       while (NULL != (pm = tc->details.core.pending_msg_head))
2519       {
2520         GNUNET_CONTAINER_MDLL_remove (client,
2521                                       tc->details.core.pending_msg_head,
2522                                       tc->details.core.pending_msg_tail,
2523                                       pm);
2524         pm->client = NULL;
2525       }
2526     }
2527     break;
2528   case CT_MONITOR:
2529     break;
2530   case CT_COMMUNICATOR:
2531     {
2532       struct Queue *q;
2533       struct AddressListEntry *ale;
2534
2535       while (NULL != (q = tc->details.communicator.queue_head))
2536         free_queue (q);
2537       while (NULL != (ale = tc->details.communicator.addr_head))
2538         free_address_list_entry (ale);
2539       GNUNET_free (tc->details.communicator.address_prefix);
2540     }
2541     break;
2542   case CT_APPLICATION:
2543     GNUNET_CONTAINER_multipeermap_iterate (tc->details.application.requests,
2544                                            &stop_peer_request,
2545                                            tc);
2546     GNUNET_CONTAINER_multipeermap_destroy (tc->details.application.requests);
2547     break;
2548   }
2549   GNUNET_free (tc);
2550 }
2551
2552
2553 /**
2554  * Iterator telling new CORE client about all existing
2555  * connections to peers.
2556  *
2557  * @param cls the new `struct TransportClient`
2558  * @param pid a connected peer
2559  * @param value the `struct Neighbour` with more information
2560  * @return #GNUNET_OK (continue to iterate)
2561  */
2562 static int
2563 notify_client_connect_info (void *cls,
2564                             const struct GNUNET_PeerIdentity *pid,
2565                             void *value)
2566 {
2567   struct TransportClient *tc = cls;
2568   struct Neighbour *neighbour = value;
2569
2570   core_send_connect_info (tc,
2571                           pid,
2572                           neighbour->quota_out);
2573   return GNUNET_OK;
2574 }
2575
2576
2577 /**
2578  * Initialize a "CORE" client.  We got a start message from this
2579  * client, so add it to the list of clients for broadcasting of
2580  * inbound messages.
2581  *
2582  * @param cls the client
2583  * @param start the start message that was sent
2584  */
2585 static void
2586 handle_client_start (void *cls,
2587                      const struct StartMessage *start)
2588 {
2589   struct TransportClient *tc = cls;
2590   uint32_t options;
2591
2592   options = ntohl (start->options);
2593   if ( (0 != (1 & options)) &&
2594        (0 !=
2595         GNUNET_memcmp (&start->self,
2596                        &GST_my_identity)) )
2597   {
2598     /* client thinks this is a different peer, reject */
2599     GNUNET_break (0);
2600     GNUNET_SERVICE_client_drop (tc->client);
2601     return;
2602   }
2603   if (CT_NONE != tc->type)
2604   {
2605     GNUNET_break (0);
2606     GNUNET_SERVICE_client_drop (tc->client);
2607     return;
2608   }
2609   tc->type = CT_CORE;
2610   GNUNET_CONTAINER_multipeermap_iterate (neighbours,
2611                                          &notify_client_connect_info,
2612                                          tc);
2613   GNUNET_SERVICE_client_continue (tc->client);
2614 }
2615
2616
2617 /**
2618  * Client asked for transmission to a peer.  Process the request.
2619  *
2620  * @param cls the client
2621  * @param obm the send message that was sent
2622  */
2623 static int
2624 check_client_send (void *cls,
2625                    const struct OutboundMessage *obm)
2626 {
2627   struct TransportClient *tc = cls;
2628   uint16_t size;
2629   const struct GNUNET_MessageHeader *obmm;
2630
2631   if (CT_CORE != tc->type)
2632   {
2633     GNUNET_break (0);
2634     return GNUNET_SYSERR;
2635   }
2636   size = ntohs (obm->header.size) - sizeof (struct OutboundMessage);
2637   if (size < sizeof (struct GNUNET_MessageHeader))
2638   {
2639     GNUNET_break (0);
2640     return GNUNET_SYSERR;
2641   }
2642   obmm = (const struct GNUNET_MessageHeader *) &obm[1];
2643   if (size != ntohs (obmm->size))
2644   {
2645     GNUNET_break (0);
2646     return GNUNET_SYSERR;
2647   }
2648   return GNUNET_OK;
2649 }
2650
2651
2652 /**
2653  * Free fragment tree below @e root, excluding @e root itself.
2654  *
2655  * @param root root of the tree to free
2656  */
2657 static void
2658 free_fragment_tree (struct PendingMessage *root)
2659 {
2660   struct PendingMessage *frag;
2661
2662   while (NULL != (frag = root->head_frag))
2663   {
2664     free_fragment_tree (frag);
2665     GNUNET_CONTAINER_MDLL_remove (frag,
2666                                   root->head_frag,
2667                                   root->tail_frag,
2668                                   frag);
2669     GNUNET_free (frag);
2670   }
2671 }
2672
2673
2674 /**
2675  * Release memory associated with @a pm and remove @a pm from associated
2676  * data structures.  @a pm must be a top-level pending message and not
2677  * a fragment in the tree.  The entire tree is freed (if applicable).
2678  *
2679  * @param pm the pending message to free
2680  */
2681 static void
2682 free_pending_message (struct PendingMessage *pm)
2683 {
2684   struct TransportClient *tc = pm->client;
2685   struct Neighbour *target = pm->target;
2686
2687   if (NULL != tc)
2688   {
2689     GNUNET_CONTAINER_MDLL_remove (client,
2690                                   tc->details.core.pending_msg_head,
2691                                   tc->details.core.pending_msg_tail,
2692                                   pm);
2693   }
2694   GNUNET_CONTAINER_MDLL_remove (neighbour,
2695                                 target->pending_msg_head,
2696                                 target->pending_msg_tail,
2697                                 pm);
2698   free_fragment_tree (pm);
2699   GNUNET_free_non_null (pm->bpm);
2700   GNUNET_free (pm);
2701 }
2702
2703
2704 /**
2705  * Send a response to the @a pm that we have processed a
2706  * "send" request with status @a success. We
2707  * transmitted @a bytes_physical on the actual wire.
2708  * Sends a confirmation to the "core" client responsible
2709  * for the original request and free's @a pm.
2710  *
2711  * @param pm handle to the original pending message
2712  * @param success status code, #GNUNET_OK on success, #GNUNET_SYSERR
2713  *          for transmission failure
2714  * @param bytes_physical amount of bandwidth consumed
2715  */
2716 static void
2717 client_send_response (struct PendingMessage *pm,
2718                       int success,
2719                       uint32_t bytes_physical)
2720 {
2721   struct TransportClient *tc = pm->client;
2722   struct Neighbour *target = pm->target;
2723   struct GNUNET_MQ_Envelope *env;
2724   struct SendOkMessage *som;
2725
2726   if (NULL != tc)
2727   {
2728     env = GNUNET_MQ_msg (som,
2729                          GNUNET_MESSAGE_TYPE_TRANSPORT_SEND_OK);
2730     som->success = htonl ((uint32_t) success);
2731     som->bytes_msg = htons (pm->bytes_msg);
2732     som->bytes_physical = htonl (bytes_physical);
2733     som->peer = target->pid;
2734     GNUNET_MQ_send (tc->mq,
2735                     env);
2736   }
2737   free_pending_message (pm);
2738 }
2739
2740
2741 /**
2742  * Checks the message queue for a neighbour for messages that have timed
2743  * out and purges them.
2744  *
2745  * @param cls a `struct Neighbour`
2746  */
2747 static void
2748 check_queue_timeouts (void *cls)
2749 {
2750   struct Neighbour *n = cls;
2751   struct PendingMessage *pm;
2752   struct GNUNET_TIME_Absolute now;
2753   struct GNUNET_TIME_Absolute earliest_timeout;
2754
2755   n->timeout_task = NULL;
2756   earliest_timeout = GNUNET_TIME_UNIT_FOREVER_ABS;
2757   now = GNUNET_TIME_absolute_get ();
2758   for (struct PendingMessage *pos = n->pending_msg_head;
2759        NULL != pos;
2760        pos = pm)
2761   {
2762     pm = pos->next_neighbour;
2763     if (pos->timeout.abs_value_us <= now.abs_value_us)
2764     {
2765       GNUNET_STATISTICS_update (GST_stats,
2766                                 "# messages dropped (timeout before confirmation)",
2767                                 1,
2768                                 GNUNET_NO);
2769       client_send_response (pm,
2770                             GNUNET_NO,
2771                             0);
2772       continue;
2773     }
2774     earliest_timeout = GNUNET_TIME_absolute_min (earliest_timeout,
2775                                                  pos->timeout);
2776   }
2777   n->earliest_timeout = earliest_timeout;
2778   if (NULL != n->pending_msg_head)
2779     n->timeout_task = GNUNET_SCHEDULER_add_at (earliest_timeout,
2780                                                &check_queue_timeouts,
2781                                                n);
2782 }
2783
2784
2785 /**
2786  * Client asked for transmission to a peer.  Process the request.
2787  *
2788  * @param cls the client
2789  * @param obm the send message that was sent
2790  */
2791 static void
2792 handle_client_send (void *cls,
2793                     const struct OutboundMessage *obm)
2794 {
2795   struct TransportClient *tc = cls;
2796   struct PendingMessage *pm;
2797   const struct GNUNET_MessageHeader *obmm;
2798   struct Neighbour *target;
2799   uint32_t bytes_msg;
2800   int was_empty;
2801
2802   GNUNET_assert (CT_CORE == tc->type);
2803   obmm = (const struct GNUNET_MessageHeader *) &obm[1];
2804   bytes_msg = ntohs (obmm->size);
2805   target = lookup_neighbour (&obm->peer);
2806   if (NULL == target)
2807   {
2808     /* Failure: don't have this peer as a neighbour (anymore).
2809        Might have gone down asynchronously, so this is NOT
2810        a protocol violation by CORE. Still count the event,
2811        as this should be rare. */
2812     struct GNUNET_MQ_Envelope *env;
2813     struct SendOkMessage *som;
2814
2815     env = GNUNET_MQ_msg (som,
2816                          GNUNET_MESSAGE_TYPE_TRANSPORT_SEND_OK);
2817     som->success = htonl (GNUNET_SYSERR);
2818     som->bytes_msg = htonl (bytes_msg);
2819     som->bytes_physical = htonl (0);
2820     som->peer = obm->peer;
2821     GNUNET_MQ_send (tc->mq,
2822                     env);
2823     GNUNET_SERVICE_client_continue (tc->client);
2824     GNUNET_STATISTICS_update (GST_stats,
2825                               "# messages dropped (neighbour unknown)",
2826                               1,
2827                               GNUNET_NO);
2828     return;
2829   }
2830   was_empty = (NULL == target->pending_msg_head);
2831   pm = GNUNET_malloc (sizeof (struct PendingMessage) + bytes_msg);
2832   pm->client = tc;
2833   pm->target = target;
2834   pm->bytes_msg = bytes_msg;
2835   pm->timeout = GNUNET_TIME_relative_to_absolute (GNUNET_TIME_relative_ntoh (obm->timeout));
2836   memcpy (&pm[1],
2837           &obm[1],
2838           bytes_msg);
2839   GNUNET_CONTAINER_MDLL_insert (neighbour,
2840                                 target->pending_msg_head,
2841                                 target->pending_msg_tail,
2842                                 pm);
2843   GNUNET_CONTAINER_MDLL_insert (client,
2844                                 tc->details.core.pending_msg_head,
2845                                 tc->details.core.pending_msg_tail,
2846                                 pm);
2847   if (target->earliest_timeout.abs_value_us > pm->timeout.abs_value_us)
2848   {
2849     target->earliest_timeout.abs_value_us = pm->timeout.abs_value_us;
2850     if (NULL != target->timeout_task)
2851       GNUNET_SCHEDULER_cancel (target->timeout_task);
2852     target->timeout_task
2853       = GNUNET_SCHEDULER_add_at (target->earliest_timeout,
2854                                  &check_queue_timeouts,
2855                                  target);
2856   }
2857   if (! was_empty)
2858     return; /* all queues must already be busy */
2859   for (struct Queue *queue = target->queue_head;
2860        NULL != queue;
2861        queue = queue->next_neighbour)
2862   {
2863     /* try transmission on any queue that is idle */
2864     if (NULL == queue->transmit_task)
2865       queue->transmit_task = GNUNET_SCHEDULER_add_now (&transmit_on_queue,
2866                                                        queue);
2867   }
2868 }
2869
2870
2871 /**
2872  * Communicator started.  Test message is well-formed.
2873  *
2874  * @param cls the client
2875  * @param cam the send message that was sent
2876  */
2877 static int
2878 check_communicator_available (void *cls,
2879                               const struct GNUNET_TRANSPORT_CommunicatorAvailableMessage *cam)
2880 {
2881   struct TransportClient *tc = cls;
2882   uint16_t size;
2883
2884   if (CT_NONE != tc->type)
2885   {
2886     GNUNET_break (0);
2887     return GNUNET_SYSERR;
2888   }
2889   tc->type = CT_COMMUNICATOR;
2890   size = ntohs (cam->header.size) - sizeof (*cam);
2891   if (0 == size)
2892     return GNUNET_OK; /* receive-only communicator */
2893   GNUNET_MQ_check_zero_termination (cam);
2894   return GNUNET_OK;
2895 }
2896
2897
2898 /**
2899  * Communicator started.  Process the request.
2900  *
2901  * @param cls the client
2902  * @param cam the send message that was sent
2903  */
2904 static void
2905 handle_communicator_available (void *cls,
2906                                const struct GNUNET_TRANSPORT_CommunicatorAvailableMessage *cam)
2907 {
2908   struct TransportClient *tc = cls;
2909   uint16_t size;
2910
2911   size = ntohs (cam->header.size) - sizeof (*cam);
2912   if (0 == size)
2913     return; /* receive-only communicator */
2914   tc->details.communicator.address_prefix
2915     = GNUNET_strdup ((const char *) &cam[1]);
2916   tc->details.communicator.cc
2917     = (enum GNUNET_TRANSPORT_CommunicatorCharacteristics) ntohl (cam->cc);
2918   GNUNET_SERVICE_client_continue (tc->client);
2919 }
2920
2921
2922 /**
2923  * Communicator requests backchannel transmission.  Check the request.
2924  *
2925  * @param cls the client
2926  * @param cb the send message that was sent
2927  * @return #GNUNET_OK if message is well-formed
2928  */
2929 static int
2930 check_communicator_backchannel (void *cls,
2931                                 const struct GNUNET_TRANSPORT_CommunicatorBackchannel *cb)
2932 {
2933   const struct GNUNET_MessageHeader *inbox;
2934   const char *is;
2935   uint16_t msize;
2936   uint16_t isize;
2937
2938   msize = ntohs (cb->header.size) - sizeof (*cb);
2939   if (UINT16_MAX - msize >
2940       sizeof (struct TransportBackchannelEncapsulationMessage) +
2941       sizeof (struct TransportBackchannelRequestPayload) )
2942   {
2943     GNUNET_break (0);
2944     return GNUNET_SYSERR;
2945   }
2946   inbox = (const struct GNUNET_MessageHeader *) &cb[1];
2947   isize = ntohs (inbox->size);
2948   if (isize >= msize)
2949   {
2950     GNUNET_break (0);
2951     return GNUNET_SYSERR;
2952   }
2953   is = (const char *) inbox;
2954   is += isize;
2955   msize -= isize;
2956   GNUNET_assert (msize > 0);
2957   if ('\0' != is[msize-1])
2958   {
2959     GNUNET_break (0);
2960     return GNUNET_SYSERR;
2961   }
2962   return GNUNET_OK;
2963 }
2964
2965
2966 /**
2967  * Remove memory used by expired ephemeral keys.
2968  *
2969  * @param cls NULL
2970  */
2971 static void
2972 expire_ephemerals (void *cls)
2973 {
2974   struct EphemeralCacheEntry *ece;
2975
2976   (void) cls;
2977   ephemeral_task = NULL;
2978   while (NULL != (ece = GNUNET_CONTAINER_heap_peek (ephemeral_heap)))
2979   {
2980     if (0 == GNUNET_TIME_absolute_get_remaining (ece->ephemeral_validity).rel_value_us)
2981     {
2982       free_ephemeral (ece);
2983       continue;
2984     }
2985     ephemeral_task = GNUNET_SCHEDULER_add_at (ece->ephemeral_validity,
2986                                               &expire_ephemerals,
2987                                               NULL);
2988     return;
2989   }
2990 }
2991
2992
2993 /**
2994  * Lookup ephemeral key in our #ephemeral_map. If no valid one exists, generate
2995  * one, cache it and return it.
2996  *
2997  * @param pid peer to look up ephemeral for
2998  * @param private_key[out] set to the private key
2999  * @param ephemeral_key[out] set to the key
3000  * @param ephemeral_sender_sig[out] set to the signature
3001  * @param ephemeral_validity[out] set to the validity expiration time
3002  */
3003 static void
3004 lookup_ephemeral (const struct GNUNET_PeerIdentity *pid,
3005                   struct GNUNET_CRYPTO_EcdhePrivateKey *private_key,
3006                   struct GNUNET_CRYPTO_EcdhePublicKey *ephemeral_key,
3007                   struct GNUNET_CRYPTO_EddsaSignature *ephemeral_sender_sig,
3008                   struct GNUNET_TIME_Absolute *ephemeral_validity)
3009 {
3010   struct EphemeralCacheEntry *ece;
3011   struct EphemeralConfirmation ec;
3012
3013   ece = GNUNET_CONTAINER_multipeermap_get (ephemeral_map,
3014                                            pid);
3015   if ( (NULL != ece) &&
3016        (0 == GNUNET_TIME_absolute_get_remaining (ece->ephemeral_validity).rel_value_us) )
3017   {
3018     free_ephemeral (ece);
3019     ece = NULL;
3020   }
3021   if (NULL == ece)
3022   {
3023     ece = GNUNET_new (struct EphemeralCacheEntry);
3024     ece->target = *pid;
3025     ece->ephemeral_validity = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get_monotonic (GST_cfg),
3026                                                         EPHEMERAL_VALIDITY);
3027     GNUNET_assert (GNUNET_OK ==
3028                    GNUNET_CRYPTO_ecdhe_key_create2 (&ece->private_key));
3029     GNUNET_CRYPTO_ecdhe_key_get_public (&ece->private_key,
3030                                         &ece->ephemeral_key);
3031     ec.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_EPHEMERAL);
3032     ec.purpose.size = htonl (sizeof (ec));
3033     ec.target = *pid;
3034     ec.ephemeral_key = ece->ephemeral_key;
3035     GNUNET_assert (GNUNET_OK ==
3036                    GNUNET_CRYPTO_eddsa_sign (GST_my_private_key,
3037                                              &ec.purpose,
3038                                              &ece->sender_sig));
3039     ece->hn = GNUNET_CONTAINER_heap_insert (ephemeral_heap,
3040                                             ece,
3041                                             ece->ephemeral_validity.abs_value_us);
3042     GNUNET_assert (GNUNET_OK ==
3043                    GNUNET_CONTAINER_multipeermap_put (ephemeral_map,
3044                                                       &ece->target,
3045                                                       ece,
3046                                                       GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
3047     if (NULL == ephemeral_task)
3048       ephemeral_task = GNUNET_SCHEDULER_add_at (ece->ephemeral_validity,
3049                                                 &expire_ephemerals,
3050                                                 NULL);
3051   }
3052   *private_key = ece->private_key;
3053   *ephemeral_key = ece->ephemeral_key;
3054   *ephemeral_sender_sig = ece->sender_sig;
3055   *ephemeral_validity = ece->ephemeral_validity;
3056 }
3057
3058
3059 /**
3060  * We need to transmit @a hdr to @a target.  If necessary, this may
3061  * involve DV routing or even broadcasting and fragmentation.
3062  *
3063  * @param target peer to receive @a hdr
3064  * @param hdr header of the message to route
3065  */
3066 static void
3067 route_message (const struct GNUNET_PeerIdentity *target,
3068                struct GNUNET_MessageHeader *hdr)
3069 {
3070   // FIXME: this one is tricky:
3071   // - we could try a direct, reliable channel
3072   // - if that is unavailable / for load balancing, we may try:
3073   //   * multiple (?) direct unreliable channels - depending on loss rate?
3074   //   * some (?) DV channels - if above unavailable / too lossy?
3075   //   * _random_ other peers ("broadcasting") in hope of *discovering*
3076   //      a path back! - if all else fails
3077   // => need more on DV first!
3078
3079   // FIXME: send hdr to target, free hdr (possibly using DV, possibly broadcasting)
3080   GNUNET_free (hdr);
3081 }
3082
3083
3084 /**
3085  * Communicator requests backchannel transmission.  Process the request.
3086  *
3087  * @param cls the client
3088  * @param cb the send message that was sent
3089  */
3090 static void
3091 handle_communicator_backchannel (void *cls,
3092                                  const struct GNUNET_TRANSPORT_CommunicatorBackchannel *cb)
3093 {
3094   struct TransportClient *tc = cls;
3095   struct GNUNET_CRYPTO_EcdhePrivateKey private_key;
3096   struct GNUNET_TIME_Absolute ephemeral_validity;
3097   struct TransportBackchannelEncapsulationMessage *enc;
3098   struct TransportBackchannelRequestPayload ppay;
3099   char *mpos;
3100   uint16_t msize;
3101
3102   /* encapsulate and encrypt message */
3103   msize = ntohs (cb->header.size) - sizeof (*cb) + sizeof (struct TransportBackchannelRequestPayload);
3104   enc = GNUNET_malloc (sizeof (*enc) + msize);
3105   enc->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_BACKCHANNEL_ENCAPSULATION);
3106   enc->header.size = htons (sizeof (*enc) + msize);
3107   enc->target = cb->pid;
3108   lookup_ephemeral (&cb->pid,
3109                     &private_key,
3110                     &enc->ephemeral_key,
3111                     &ppay.sender_sig,
3112                     &ephemeral_validity);
3113   // FIXME: setup 'iv'
3114 #if FIXME
3115   dh_key_derive (&private_key,
3116                  &cb->pid,
3117                  &enc->iv,
3118                  &key);
3119 #endif
3120   ppay.ephemeral_validity = GNUNET_TIME_absolute_hton (ephemeral_validity);
3121   ppay.monotonic_time = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get_monotonic (GST_cfg));
3122   mpos = (char *) &enc[1];
3123 #if FIXME
3124   encrypt (key,
3125            &ppay,
3126            &mpos,
3127            sizeof (ppay));
3128   encrypt (key,
3129            &cb[1],
3130            &mpos,
3131            ntohs (cb->header.size) - sizeof (*cb));
3132   hmac (key,
3133         &enc->hmac);
3134 #endif
3135   route_message (&cb->pid,
3136                  &enc->header);
3137   GNUNET_SERVICE_client_continue (tc->client);
3138 }
3139
3140
3141 /**
3142  * Address of our peer added.  Test message is well-formed.
3143  *
3144  * @param cls the client
3145  * @param aam the send message that was sent
3146  * @return #GNUNET_OK if message is well-formed
3147  */
3148 static int
3149 check_add_address (void *cls,
3150                    const struct GNUNET_TRANSPORT_AddAddressMessage *aam)
3151 {
3152   struct TransportClient *tc = cls;
3153
3154   if (CT_COMMUNICATOR != tc->type)
3155   {
3156     GNUNET_break (0);
3157     return GNUNET_SYSERR;
3158   }
3159   GNUNET_MQ_check_zero_termination (aam);
3160   return GNUNET_OK;
3161 }
3162
3163
3164 /**
3165  * Ask peerstore to store our address.
3166  *
3167  * @param cls an `struct AddressListEntry *`
3168  */
3169 static void
3170 store_pi (void *cls);
3171
3172
3173 /**
3174  * Function called when peerstore is done storing our address.
3175  *
3176  * @param cls a `struct AddressListEntry`
3177  * @param success #GNUNET_YES if peerstore was successful
3178  */
3179 static void
3180 peerstore_store_own_cb (void *cls,
3181                         int success)
3182 {
3183   struct AddressListEntry *ale = cls;
3184
3185   ale->sc = NULL;
3186   if (GNUNET_YES != success)
3187     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3188                 "Failed to store our own address `%s' in peerstore!\n",
3189                 ale->address);
3190   /* refresh period is 1/4 of expiration time, that should be plenty
3191      without being excessive. */
3192   ale->st = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_divide (ale->expiration,
3193                                                                        4ULL),
3194                                           &store_pi,
3195                                           ale);
3196 }
3197
3198
3199 /**
3200  * Ask peerstore to store our address.
3201  *
3202  * @param cls an `struct AddressListEntry *`
3203  */
3204 static void
3205 store_pi (void *cls)
3206 {
3207   struct AddressListEntry *ale = cls;
3208   void *addr;
3209   size_t addr_len;
3210   struct GNUNET_TIME_Absolute expiration;
3211
3212   ale->st = NULL;
3213   expiration = GNUNET_TIME_relative_to_absolute (ale->expiration);
3214   GNUNET_HELLO_sign_address (ale->address,
3215                              ale->nt,
3216                              expiration,
3217                              GST_my_private_key,
3218                              &addr,
3219                              &addr_len);
3220   ale->sc = GNUNET_PEERSTORE_store (peerstore,
3221                                     "transport",
3222                                     &GST_my_identity,
3223                                     GNUNET_PEERSTORE_TRANSPORT_HELLO_KEY,
3224                                     addr,
3225                                     addr_len,
3226                                     expiration,
3227                                     GNUNET_PEERSTORE_STOREOPTION_MULTIPLE,
3228                                     &peerstore_store_own_cb,
3229                                     ale);
3230   GNUNET_free (addr);
3231   if (NULL == ale->sc)
3232   {
3233     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
3234                 "Failed to store our address `%s' with peerstore\n",
3235                 ale->address);
3236     ale->st = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
3237                                             &store_pi,
3238                                             ale);
3239   }
3240 }
3241
3242
3243 /**
3244  * Address of our peer added.  Process the request.
3245  *
3246  * @param cls the client
3247  * @param aam the send message that was sent
3248  */
3249 static void
3250 handle_add_address (void *cls,
3251                     const struct GNUNET_TRANSPORT_AddAddressMessage *aam)
3252 {
3253   struct TransportClient *tc = cls;
3254   struct AddressListEntry *ale;
3255   size_t slen;
3256
3257   slen = ntohs (aam->header.size) - sizeof (*aam);
3258   ale = GNUNET_malloc (sizeof (struct AddressListEntry) + slen);
3259   ale->tc = tc;
3260   ale->address = (const char *) &ale[1];
3261   ale->expiration = GNUNET_TIME_relative_ntoh (aam->expiration);
3262   ale->aid = aam->aid;
3263   ale->nt = (enum GNUNET_NetworkType) ntohl (aam->nt);
3264   memcpy (&ale[1],
3265           &aam[1],
3266           slen);
3267   GNUNET_CONTAINER_DLL_insert (tc->details.communicator.addr_head,
3268                                tc->details.communicator.addr_tail,
3269                                ale);
3270   ale->st = GNUNET_SCHEDULER_add_now (&store_pi,
3271                                       ale);
3272   GNUNET_SERVICE_client_continue (tc->client);
3273 }
3274
3275
3276 /**
3277  * Address of our peer deleted.  Process the request.
3278  *
3279  * @param cls the client
3280  * @param dam the send message that was sent
3281  */
3282 static void
3283 handle_del_address (void *cls,
3284                     const struct GNUNET_TRANSPORT_DelAddressMessage *dam)
3285 {
3286   struct TransportClient *tc = cls;
3287
3288   if (CT_COMMUNICATOR != tc->type)
3289   {
3290     GNUNET_break (0);
3291     GNUNET_SERVICE_client_drop (tc->client);
3292     return;
3293   }
3294   for (struct AddressListEntry *ale = tc->details.communicator.addr_head;
3295        NULL != ale;
3296        ale = ale->next)
3297   {
3298     if (dam->aid != ale->aid)
3299       continue;
3300     GNUNET_assert (ale->tc == tc);
3301     free_address_list_entry (ale);
3302     GNUNET_SERVICE_client_continue (tc->client);
3303   }
3304   GNUNET_break (0);
3305   GNUNET_SERVICE_client_drop (tc->client);
3306 }
3307
3308
3309 /**
3310  * Context from #handle_incoming_msg().  Closure for many
3311  * message handlers below.
3312  */
3313 struct CommunicatorMessageContext
3314 {
3315   /**
3316    * Which communicator provided us with the message.
3317    */
3318   struct TransportClient *tc;
3319
3320   /**
3321    * Additional information for flow control and about the sender.
3322    */
3323   struct GNUNET_TRANSPORT_IncomingMessage im;
3324
3325   /**
3326    * Number of hops the message has travelled (if DV-routed).
3327    * FIXME: make use of this in ACK handling!
3328    */
3329   uint16_t total_hops;
3330 };
3331
3332
3333 /**
3334  * Given an inbound message @a msg from a communicator @a cmc,
3335  * demultiplex it based on the type calling the right handler.
3336  *
3337  * @param cmc context for demultiplexing
3338  * @param msg message to demultiplex
3339  */
3340 static void
3341 demultiplex_with_cmc (struct CommunicatorMessageContext *cmc,
3342                       const struct GNUNET_MessageHeader *msg);
3343
3344
3345 /**
3346  * Send ACK to communicator (if requested) and free @a cmc.
3347  *
3348  * @param cmc context for which we are done handling the message
3349  */
3350 static void
3351 finish_cmc_handling (struct CommunicatorMessageContext *cmc)
3352 {
3353   if (0 != ntohl (cmc->im.fc_on))
3354   {
3355     /* send ACK when done to communicator for flow control! */
3356     struct GNUNET_MQ_Envelope *env;
3357     struct GNUNET_TRANSPORT_IncomingMessageAck *ack;
3358
3359     env = GNUNET_MQ_msg (ack,
3360                          GNUNET_MESSAGE_TYPE_TRANSPORT_INCOMING_MSG_ACK);
3361     ack->reserved = htonl (0);
3362     ack->fc_id = cmc->im.fc_id;
3363     ack->sender = cmc->im.sender;
3364     GNUNET_MQ_send (cmc->tc->mq,
3365                     env);
3366   }
3367   GNUNET_SERVICE_client_continue (cmc->tc->client);
3368   GNUNET_free (cmc);
3369 }
3370
3371
3372 /**
3373  * Communicator gave us an unencapsulated message to pass as-is to
3374  * CORE.  Process the request.
3375  *
3376  * @param cls a `struct CommunicatorMessageContext` (must call #finish_cmc_handling() when done)
3377  * @param mh the message that was received
3378  */
3379 static void
3380 handle_raw_message (void *cls,
3381                     const struct GNUNET_MessageHeader *mh)
3382 {
3383   struct CommunicatorMessageContext *cmc = cls;
3384   uint16_t size = ntohs (mh->size);
3385
3386   if ( (size > UINT16_MAX - sizeof (struct InboundMessage)) ||
3387        (size < sizeof (struct GNUNET_MessageHeader)) )
3388   {
3389     struct GNUNET_SERVICE_Client *client = cmc->tc->client;
3390
3391     GNUNET_break (0);
3392     finish_cmc_handling (cmc);
3393     GNUNET_SERVICE_client_drop (client);
3394     return;
3395   }
3396   /* Forward to all CORE clients */
3397   for (struct TransportClient *tc = clients_head;
3398        NULL != tc;
3399        tc = tc->next)
3400   {
3401     struct GNUNET_MQ_Envelope *env;
3402     struct InboundMessage *im;
3403
3404     if (CT_CORE != tc->type)
3405       continue;
3406     env = GNUNET_MQ_msg_extra (im,
3407                                size,
3408                                GNUNET_MESSAGE_TYPE_TRANSPORT_RECV);
3409     im->peer = cmc->im.sender;
3410     memcpy (&im[1],
3411             mh,
3412             size);
3413     GNUNET_MQ_send (tc->mq,
3414                     env);
3415   }
3416   /* FIXME: consider doing this _only_ once the message
3417      was drained from the CORE MQs to extend flow control to CORE!
3418      (basically, increment counter in cmc, decrement on MQ send continuation! */
3419   finish_cmc_handling (cmc);
3420 }
3421
3422
3423 /**
3424  * Communicator gave us a fragment box.  Check the message.
3425  *
3426  * @param cls a `struct CommunicatorMessageContext`
3427  * @param fb the send message that was sent
3428  * @return #GNUNET_YES if message is well-formed
3429  */
3430 static int
3431 check_fragment_box (void *cls,
3432                     const struct TransportFragmentBox *fb)
3433 {
3434   uint16_t size = ntohs (fb->header.size);
3435   uint16_t bsize = size - sizeof (*fb);
3436
3437   if (0 == bsize)
3438   {
3439     GNUNET_break_op (0);
3440     return GNUNET_SYSERR;
3441   }
3442   if (bsize + ntohs (fb->frag_off) > ntohs (fb->msg_size))
3443   {
3444     GNUNET_break_op (0);
3445     return GNUNET_SYSERR;
3446   }
3447   if (ntohs (fb->frag_off) >= ntohs (fb->msg_size))
3448   {
3449     GNUNET_break_op (0);
3450     return GNUNET_SYSERR;
3451   }
3452   return GNUNET_YES;
3453 }
3454
3455
3456 /**
3457  * Generate a fragment acknowledgement for an @a rc.
3458  *
3459  * @param rc context to generate ACK for, @a rc ACK state is reset
3460  */
3461 static void
3462 send_fragment_ack (struct ReassemblyContext *rc)
3463 {
3464   struct TransportFragmentAckMessage *ack;
3465
3466   ack = GNUNET_new (struct TransportFragmentAckMessage);
3467   ack->header.size = htons (sizeof (struct TransportFragmentAckMessage));
3468   ack->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_FRAGMENT_ACK);
3469   ack->frag_uuid = htonl (rc->frag_uuid);
3470   ack->extra_acks = GNUNET_htonll (rc->extra_acks);
3471   ack->msg_uuid = rc->msg_uuid;
3472   ack->avg_ack_delay = GNUNET_TIME_relative_hton (rc->avg_ack_delay);
3473   if (0 == rc->msg_missing)
3474     ack->reassembly_timeout
3475       = GNUNET_TIME_relative_hton (GNUNET_TIME_UNIT_FOREVER_REL); /* signal completion */
3476   else
3477     ack->reassembly_timeout
3478       = GNUNET_TIME_relative_hton (GNUNET_TIME_absolute_get_remaining (rc->reassembly_timeout));
3479   route_message (&rc->neighbour->pid,
3480                  &ack->header);
3481   rc->avg_ack_delay = GNUNET_TIME_UNIT_ZERO;
3482   rc->num_acks = 0;
3483   rc->extra_acks = 0LLU;
3484 }
3485
3486
3487 /**
3488  * Communicator gave us a fragment.  Process the request.
3489  *
3490  * @param cls a `struct CommunicatorMessageContext` (must call #finish_cmc_handling() when done)
3491  * @param fb the message that was received
3492  */
3493 static void
3494 handle_fragment_box (void *cls,
3495                      const struct TransportFragmentBox *fb)
3496 {
3497   struct CommunicatorMessageContext *cmc = cls;
3498   struct Neighbour *n;
3499   struct ReassemblyContext *rc;
3500   const struct GNUNET_MessageHeader *msg;
3501   uint16_t msize;
3502   uint16_t fsize;
3503   uint16_t frag_off;
3504   uint32_t frag_uuid;
3505   char *target;
3506   struct GNUNET_TIME_Relative cdelay;
3507   int ack_now;
3508
3509   n = GNUNET_CONTAINER_multipeermap_get (neighbours,
3510                                          &cmc->im.sender);
3511   if (NULL == n)
3512   {
3513     struct GNUNET_SERVICE_Client *client = cmc->tc->client;
3514
3515     GNUNET_break (0);
3516     finish_cmc_handling (cmc);
3517     GNUNET_SERVICE_client_drop (client);
3518     return;
3519   }
3520   if (NULL == n->reassembly_map)
3521   {
3522     n->reassembly_map = GNUNET_CONTAINER_multishortmap_create (8,
3523                                                                GNUNET_YES);
3524     n->reassembly_heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
3525     n->reassembly_timeout_task = GNUNET_SCHEDULER_add_delayed (REASSEMBLY_EXPIRATION,
3526                                                                &reassembly_cleanup_task,
3527                                                                n);
3528   }
3529   msize = ntohs (fb->msg_size);
3530   rc = GNUNET_CONTAINER_multishortmap_get (n->reassembly_map,
3531                                            &fb->msg_uuid);
3532   if (NULL == rc)
3533   {
3534     rc = GNUNET_malloc (sizeof (*rc) +
3535                         msize + /* reassembly payload buffer */
3536                         (msize + 7) / 8 * sizeof (uint8_t) /* bitfield */);
3537     rc->msg_uuid = fb->msg_uuid;
3538     rc->neighbour = n;
3539     rc->msg_size = msize;
3540     rc->reassembly_timeout = GNUNET_TIME_relative_to_absolute (REASSEMBLY_EXPIRATION);
3541     rc->last_frag = GNUNET_TIME_absolute_get ();
3542     rc->hn = GNUNET_CONTAINER_heap_insert (n->reassembly_heap,
3543                                            rc,
3544                                            rc->reassembly_timeout.abs_value_us);
3545     GNUNET_assert (GNUNET_OK ==
3546                    GNUNET_CONTAINER_multishortmap_put (n->reassembly_map,
3547                                                        &rc->msg_uuid,
3548                                                        rc,
3549                                                        GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
3550     target = (char *) &rc[1];
3551     rc->bitfield = (uint8_t *) (target + rc->msg_size);
3552     rc->msg_missing = rc->msg_size;
3553   }
3554   else
3555   {
3556     target = (char *) &rc[1];
3557   }
3558   if (msize != rc->msg_size)
3559   {
3560     GNUNET_break (0);
3561     finish_cmc_handling (cmc);
3562     return;
3563   }
3564
3565   /* reassemble */
3566   fsize = ntohs (fb->header.size) - sizeof (*fb);
3567   frag_off = ntohs (fb->frag_off);
3568   memcpy (&target[frag_off],
3569           &fb[1],
3570           fsize);
3571   /* update bitfield and msg_missing */
3572   for (unsigned int i=frag_off;i<frag_off+fsize;i++)
3573   {
3574     if (0 == (rc->bitfield[i / 8] & (1 << (i % 8))))
3575     {
3576       rc->bitfield[i / 8] |= (1 << (i % 8));
3577       rc->msg_missing--;
3578     }
3579   }
3580
3581   /* Compute cummulative ACK */
3582   frag_uuid = ntohl (fb->frag_uuid);
3583   cdelay = GNUNET_TIME_absolute_get_duration (rc->last_frag);
3584   cdelay = GNUNET_TIME_relative_multiply (cdelay,
3585                                           rc->num_acks);
3586   rc->last_frag = GNUNET_TIME_absolute_get ();
3587   rc->avg_ack_delay = GNUNET_TIME_relative_add (rc->avg_ack_delay,
3588                                                 cdelay);
3589   ack_now = GNUNET_NO;
3590   if (0 == rc->num_acks)
3591   {
3592     /* case one: first ack */
3593     rc->frag_uuid = frag_uuid;
3594     rc->extra_acks = 0LLU;
3595     rc->num_acks = 1;
3596   }
3597   else if ( (frag_uuid >= rc->frag_uuid) &&
3598             (frag_uuid <= rc->frag_uuid + 64) )
3599   {
3600     /* case two: ack fits after existing min UUID */
3601     if ( (frag_uuid == rc->frag_uuid) ||
3602          (0 != (rc->extra_acks & (1LLU << (frag_uuid - rc->frag_uuid - 1)))) )
3603     {
3604       /* duplicate fragment, ack now! */
3605       ack_now = GNUNET_YES;
3606     }
3607     else
3608     {
3609       rc->extra_acks |= (1LLU << (frag_uuid - rc->frag_uuid - 1));
3610       rc->num_acks++;
3611     }
3612   }
3613   else if ( (rc->frag_uuid > frag_uuid) &&
3614             ( ( (rc->frag_uuid == frag_uuid + 64) &&
3615                 (0 == rc->extra_acks) ) ||
3616               ( (rc->frag_uuid < frag_uuid + 64) &&
3617                 (rc->extra_acks == (rc->extra_acks & ~ ((1LLU << (64 - (rc->frag_uuid - frag_uuid))) - 1LLU))) ) ) )
3618   {
3619     /* can fit ack by shifting extra acks and starting at
3620        frag_uid, test above esured that the bits we will
3621        shift 'extra_acks' by are all zero. */
3622     rc->extra_acks <<= (rc->frag_uuid - frag_uuid);
3623     rc->extra_acks |= (1LLU << (rc->frag_uuid - frag_uuid - 1));
3624     rc->frag_uuid = frag_uuid;
3625     rc->num_acks++;
3626   }
3627   if (65 == rc->num_acks) /* FIXME: maybe use smaller threshold? This is very aggressive. */
3628     ack_now = GNUNET_YES; /* maximum acks received */
3629   // FIXME: possibly also ACK based on RTT (but for that we'd need to
3630   // determine the queue used for the ACK first!)
3631
3632   /* is reassembly complete? */
3633   if (0 != rc->msg_missing)
3634   {
3635     if (ack_now)
3636       send_fragment_ack (rc);
3637     finish_cmc_handling (cmc);
3638     return;
3639   }
3640   /* reassembly is complete, verify result */
3641   msg = (const struct GNUNET_MessageHeader *) &rc[1];
3642   if (ntohs (msg->size) != rc->msg_size)
3643   {
3644     GNUNET_break (0);
3645     free_reassembly_context (rc);
3646     finish_cmc_handling (cmc);
3647     return;
3648   }
3649   /* successful reassembly */
3650   send_fragment_ack (rc);
3651   demultiplex_with_cmc (cmc,
3652                         msg);
3653   /* FIXME: really free here? Might be bad if fragments are still
3654      en-route and we forget that we finished this reassembly immediately!
3655      -> keep around until timeout?
3656      -> shorten timeout based on ACK? */
3657   free_reassembly_context (rc);
3658 }
3659
3660
3661 /**
3662  * Communicator gave us a fragment acknowledgement.  Process the request.
3663  *
3664  * @param cls a `struct CommunicatorMessageContext` (must call #finish_cmc_handling() when done)
3665  * @param fa the message that was received
3666  */
3667 static void
3668 handle_fragment_ack (void *cls,
3669                      const struct TransportFragmentAckMessage *fa)
3670 {
3671   struct CommunicatorMessageContext *cmc = cls;
3672
3673   // FIXME: do work: identify original message; then identify fragments being acked;
3674   // remove those from the tree to prevent retransmission;
3675   // compute RTT
3676   // if entire message is ACKed, handle that as well.
3677   finish_cmc_handling (cmc);
3678 }
3679
3680
3681 /**
3682  * Communicator gave us a reliability box.  Check the message.
3683  *
3684  * @param cls a `struct CommunicatorMessageContext`
3685  * @param rb the send message that was sent
3686  * @return #GNUNET_YES if message is well-formed
3687  */
3688 static int
3689 check_reliability_box (void *cls,
3690                        const struct TransportReliabilityBox *rb)
3691 {
3692   GNUNET_MQ_check_boxed_message (rb);
3693   return GNUNET_YES;
3694 }
3695
3696
3697 /**
3698  * Communicator gave us a reliability box.  Process the request.
3699  *
3700  * @param cls a `struct CommunicatorMessageContext` (must call #finish_cmc_handling() when done)
3701  * @param rb the message that was received
3702  */
3703 static void
3704 handle_reliability_box (void *cls,
3705                         const struct TransportReliabilityBox *rb)
3706 {
3707   struct CommunicatorMessageContext *cmc = cls;
3708   const struct GNUNET_MessageHeader *inbox = (const struct GNUNET_MessageHeader *) &rb[1];
3709
3710   if (0 == ntohl (rb->ack_countdown))
3711   {
3712     struct TransportReliabilityAckMessage *ack;
3713
3714     /* FIXME: implement cummulative ACKs and ack_countdown,
3715        then setting the avg_ack_delay field below: */
3716     ack = GNUNET_malloc (sizeof (*ack) +
3717                          sizeof (struct GNUNET_ShortHashCode));
3718     ack->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_RELIABILITY_ACK);
3719     ack->header.size = htons (sizeof (*ack) +
3720                               sizeof (struct GNUNET_ShortHashCode));
3721     memcpy (&ack[1],
3722             &rb->msg_uuid,
3723             sizeof (struct GNUNET_ShortHashCode));
3724     route_message (&cmc->im.sender,
3725                    &ack->header);
3726   }
3727   /* continue with inner message */
3728   demultiplex_with_cmc (cmc,
3729                         inbox);
3730 }
3731
3732
3733 /**
3734  * Communicator gave us a reliability ack.  Process the request.
3735  *
3736  * @param cls a `struct CommunicatorMessageContext` (must call #finish_cmc_handling() when done)
3737  * @param ra the message that was received
3738  */
3739 static void
3740 handle_reliability_ack (void *cls,
3741                         const struct TransportReliabilityAckMessage *ra)
3742 {
3743   struct CommunicatorMessageContext *cmc = cls;
3744
3745   // FIXME: do work: find message that was acknowledged, and
3746   // remove from transmission queue; update RTT.
3747   finish_cmc_handling (cmc);
3748 }
3749
3750
3751 /**
3752  * Communicator gave us a backchannel encapsulation.  Check the message.
3753  *
3754  * @param cls a `struct CommunicatorMessageContext`
3755  * @param be the send message that was sent
3756  * @return #GNUNET_YES if message is well-formed
3757  */
3758 static int
3759 check_backchannel_encapsulation (void *cls,
3760                                  const struct TransportBackchannelEncapsulationMessage *be)
3761 {
3762   uint16_t size = ntohs (be->header.size);
3763
3764   if (size - sizeof (*be) < sizeof (struct GNUNET_MessageHeader))
3765   {
3766     GNUNET_break_op (0);
3767     return GNUNET_SYSERR;
3768   }
3769   return GNUNET_YES;
3770 }
3771
3772
3773 /**
3774  * Communicator gave us a backchannel encapsulation.  Process the request.
3775  *
3776  * @param cls a `struct CommunicatorMessageContext` (must call #finish_cmc_handling() when done)
3777  * @param be the message that was received
3778  */
3779 static void
3780 handle_backchannel_encapsulation (void *cls,
3781                                   const struct TransportBackchannelEncapsulationMessage *be)
3782 {
3783   struct CommunicatorMessageContext *cmc = cls;
3784
3785   if (0 != GNUNET_memcmp (&be->target,
3786                           &GST_my_identity))
3787   {
3788     /* not for me, try to route to target */
3789     route_message (&be->target,
3790                    GNUNET_copy_message (&be->header));
3791     finish_cmc_handling (cmc);
3792     return;
3793   }
3794   // FIXME: compute shared secret
3795   // FIXME: check HMAC
3796   // FIXME: decrypt payload
3797   // FIXME: forward to specified communicator!
3798   // (using GNUNET_MESSAGE_TYPE_TRANSPORT_COMMUNICATOR_BACKCHANNEL_INCOMING)
3799   finish_cmc_handling (cmc);
3800 }
3801
3802
3803 /**
3804  * Task called when we should check if any of the DV paths
3805  * we have learned to a target are due for garbage collection.
3806  *
3807  * Collects stale paths, and possibly frees the entire DV
3808  * entry if no paths are left. Otherwise re-schedules itself.
3809  *
3810  * @param cls a `struct DistanceVector`
3811  */
3812 static void
3813 path_cleanup_cb (void *cls)
3814 {
3815   struct DistanceVector *dv = cls;
3816   struct DistanceVectorHop *pos;
3817
3818   dv->timeout_task = NULL;
3819   while (NULL != (pos = dv->dv_head))
3820   {
3821     GNUNET_assert (dv == pos->dv);
3822     if (GNUNET_TIME_absolute_get_remaining (pos->timeout).rel_value_us > 0)
3823       break;
3824     free_distance_vector_hop (pos);
3825   }
3826   if (NULL == pos)
3827   {
3828     free_dv_route (dv);
3829     return;
3830   }
3831   dv->timeout_task = GNUNET_SCHEDULER_add_at (pos->timeout,
3832                                               &path_cleanup_cb,
3833                                               dv);
3834 }
3835
3836
3837 /**
3838  * We have learned a @a path through the network to some other peer, add it to
3839  * our DV data structure (returning #GNUNET_YES on success).
3840  *
3841  * We do not add paths if we have a sufficient number of shorter
3842  * paths to this target already (returning #GNUNET_NO).
3843  *
3844  * We also do not add problematic paths, like those where we lack the first
3845  * hop in our neighbour list (i.e. due to a topology change) or where some
3846  * non-first hop is in our neighbour list (returning #GNUNET_SYSERR).
3847  *
3848  * @param path the path we learned, path[0] should be us,
3849  *             and then path contains a valid path from us to `path[path_len-1]`
3850  *             path[1] should be a direct neighbour (we should check!)
3851  * @param path_len number of entries on the @a path, at least three!
3852  * @param network_latency how long does the message take from us to `path[path_len-1]`?
3853  *          set to "forever" if unknown
3854  * @return #GNUNET_YES on success,
3855  *         #GNUNET_NO if we have better path(s) to the target
3856  *         #GNUNET_SYSERR if the path is useless and/or invalid
3857  *                         (i.e. path[1] not a direct neighbour
3858  *                        or path[i+1] is a direct neighbour for i>0)
3859  */
3860 static int
3861 learn_dv_path (const struct GNUNET_PeerIdentity *path,
3862                unsigned int path_len,
3863                struct GNUNET_TIME_Relative network_latency)
3864 {
3865   struct DistanceVectorHop *hop;
3866   struct DistanceVector *dv;
3867   struct Neighbour *next_hop;
3868   unsigned int shorter_distance;
3869
3870   if (path_len < 3)
3871   {
3872     /* what a boring path! not allowed! */
3873     GNUNET_break (0);
3874     return GNUNET_SYSERR;
3875   }
3876   GNUNET_assert (0 ==
3877                  GNUNET_memcmp (&GST_my_identity,
3878                                 &path[0]));
3879   next_hop = GNUNET_CONTAINER_multipeermap_get (neighbours,
3880                                                 &path[1]);
3881   if (NULL == next_hop)
3882   {
3883     /* next hop must be a neighbour, otherwise this whole thing is useless! */
3884     GNUNET_break (0);
3885     return GNUNET_SYSERR;
3886   }
3887   for (unsigned int i=2;i<path_len;i++)
3888     if (NULL !=
3889         GNUNET_CONTAINER_multipeermap_get (neighbours,
3890                                            &path[i]))
3891     {
3892       /* Useless path, we have a direct connection to some hop
3893          in the middle of the path, so this one doesn't even
3894          seem terribly useful for redundancy */
3895       return GNUNET_SYSERR;
3896     }
3897   dv = GNUNET_CONTAINER_multipeermap_get (dv_routes,
3898                                           &path[path_len - 1]);
3899   if (NULL == dv)
3900   {
3901     dv = GNUNET_new (struct DistanceVector);
3902     dv->target = path[path_len - 1];
3903     dv->timeout_task = GNUNET_SCHEDULER_add_delayed (DV_PATH_VALIDITY_TIMEOUT,
3904                                                      &path_cleanup_cb,
3905                                                      dv);
3906     GNUNET_assert (GNUNET_OK ==
3907                    GNUNET_CONTAINER_multipeermap_put (dv_routes,
3908                                                       &dv->target,
3909                                                       dv,
3910                                                       GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
3911   }
3912   /* Check if we have this path already! */
3913   shorter_distance = 0;
3914   for (struct DistanceVectorHop *pos = dv->dv_head;
3915        NULL != pos;
3916        pos = pos->next_dv)
3917   {
3918     if (pos->distance < path_len - 2)
3919       shorter_distance++;
3920     /* Note that the distances in 'pos' excludes us (path[0]) and
3921        the next_hop (path[1]), so we need to subtract two
3922        and check next_hop explicitly */
3923     if ( (pos->distance == path_len - 2) &&
3924          (pos->next_hop == next_hop) )
3925     {
3926       int match = GNUNET_YES;
3927
3928       for (unsigned int i=0;i<pos->distance;i++)
3929       {
3930         if (0 !=
3931             GNUNET_memcmp (&pos->path[i],
3932                            &path[i+2]))
3933         {
3934           match = GNUNET_NO;
3935           break;
3936         }
3937       }
3938       if (GNUNET_YES == match)
3939       {
3940         struct GNUNET_TIME_Relative last_timeout;
3941
3942         /* Re-discovered known path, update timeout */
3943         GNUNET_STATISTICS_update (GST_stats,
3944                                   "# Known DV path refreshed",
3945                                   1,
3946                                   GNUNET_NO);
3947         last_timeout = GNUNET_TIME_absolute_get_remaining (pos->timeout);
3948         pos->timeout
3949           = GNUNET_TIME_relative_to_absolute (DV_PATH_VALIDITY_TIMEOUT);
3950         GNUNET_CONTAINER_MDLL_remove (dv,
3951                                       dv->dv_head,
3952                                       dv->dv_tail,
3953                                       pos);
3954         GNUNET_CONTAINER_MDLL_insert (dv,
3955                                       dv->dv_head,
3956                                       dv->dv_tail,
3957                                       pos);
3958         if (last_timeout.rel_value_us <
3959             GNUNET_TIME_relative_subtract (DV_PATH_VALIDITY_TIMEOUT,
3960                                            DV_PATH_DISCOVERY_FREQUENCY).rel_value_us)
3961         {
3962           /* Some peer send DV learn messages too often, we are learning
3963              the same path faster than it would be useful; do not forward! */
3964           return GNUNET_NO;
3965         }
3966         return GNUNET_YES;
3967       }
3968     }
3969   }
3970   /* Count how many shorter paths we have (incl. direct
3971      neighbours) before simply giving up on this one! */
3972   if (shorter_distance >= MAX_DV_PATHS_TO_TARGET)
3973   {
3974     /* We have a shorter path already! */
3975     return GNUNET_NO;
3976   }
3977   /* create new DV path entry */
3978   hop = GNUNET_malloc (sizeof (struct DistanceVectorHop) +
3979                        sizeof (struct GNUNET_PeerIdentity) * (path_len - 2));
3980   hop->next_hop = next_hop;
3981   hop->dv = dv;
3982   hop->path = (const struct GNUNET_PeerIdentity *) &hop[1];
3983   memcpy (&hop[1],
3984           &path[2],
3985           sizeof (struct GNUNET_PeerIdentity) * (path_len - 2));
3986   hop->timeout = GNUNET_TIME_relative_to_absolute (DV_PATH_VALIDITY_TIMEOUT);
3987   hop->distance = path_len - 2;
3988   GNUNET_CONTAINER_MDLL_insert (dv,
3989                                 dv->dv_head,
3990                                 dv->dv_tail,
3991                                 hop);
3992   GNUNET_CONTAINER_MDLL_insert (neighbour,
3993                                 next_hop->dv_head,
3994                                 next_hop->dv_tail,
3995                                 hop);
3996   return GNUNET_YES;
3997 }
3998
3999
4000 /**
4001  * Communicator gave us a DV learn message.  Check the message.
4002  *
4003  * @param cls a `struct CommunicatorMessageContext`
4004  * @param dvl the send message that was sent
4005  * @return #GNUNET_YES if message is well-formed
4006  */
4007 static int
4008 check_dv_learn (void *cls,
4009                 const struct TransportDVLearn *dvl)
4010 {
4011   uint16_t size = ntohs (dvl->header.size);
4012   uint16_t num_hops = ntohs (dvl->num_hops);
4013   const struct DVPathEntryP *hops = (const struct DVPathEntryP *) &dvl[1];
4014
4015   if (size != sizeof (*dvl) + num_hops * sizeof (struct DVPathEntryP))
4016   {
4017     GNUNET_break_op (0);
4018     return GNUNET_SYSERR;
4019   }
4020   if (num_hops > MAX_DV_HOPS_ALLOWED)
4021   {
4022     GNUNET_break_op (0);
4023     return GNUNET_SYSERR;
4024   }
4025   for (unsigned int i=0;i<num_hops;i++)
4026   {
4027     if (0 == GNUNET_memcmp (&dvl->initiator,
4028                             &hops[i].hop))
4029     {
4030       GNUNET_break_op (0);
4031       return GNUNET_SYSERR;
4032     }
4033     if (0 == GNUNET_memcmp (&GST_my_identity,
4034                             &hops[i].hop))
4035     {
4036       GNUNET_break_op (0);
4037       return GNUNET_SYSERR;
4038     }
4039   }
4040   return GNUNET_YES;
4041 }
4042
4043
4044 /**
4045  * Build and forward a DV learn message to @a next_hop.
4046  *
4047  * @param next_hop peer to send the message to
4048  * @param msg message received
4049  * @param bi_history bitmask specifying hops on path that were bidirectional
4050  * @param nhops length of the @a hops array
4051  * @param hops path the message traversed so far
4052  * @param in_time when did we receive the message, used to calculate network delay
4053  */
4054 static void
4055 forward_dv_learn (const struct GNUNET_PeerIdentity *next_hop,
4056                   const struct TransportDVLearn *msg,
4057                   uint16_t bi_history,
4058                   uint16_t nhops,
4059                   const struct DVPathEntryP *hops,
4060                   struct GNUNET_TIME_Absolute in_time)
4061 {
4062   struct DVPathEntryP *dhops;
4063   struct TransportDVLearn *fwd;
4064   struct GNUNET_TIME_Relative nnd;
4065
4066   /* compute message for forwarding */
4067   GNUNET_assert (nhops < MAX_DV_HOPS_ALLOWED);
4068   fwd = GNUNET_malloc (sizeof (struct TransportDVLearn) +
4069                        (nhops + 1) * sizeof (struct DVPathEntryP));
4070   fwd->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_DV_LEARN);
4071   fwd->header.size = htons (sizeof (struct TransportDVLearn) +
4072                             (nhops + 1) * sizeof (struct DVPathEntryP));
4073   fwd->num_hops = htons (nhops + 1);
4074   fwd->bidirectional = htons (bi_history);
4075   nnd = GNUNET_TIME_relative_add (GNUNET_TIME_absolute_get_duration (in_time),
4076                                   GNUNET_TIME_relative_ntoh (msg->non_network_delay));
4077   fwd->non_network_delay = GNUNET_TIME_relative_hton (nnd);
4078   fwd->init_sig = msg->init_sig;
4079   fwd->initiator = msg->initiator;
4080   fwd->challenge = msg->challenge;
4081   dhops = (struct DVPathEntryP *) &fwd[1];
4082   GNUNET_memcpy (dhops,
4083                  hops,
4084                  sizeof (struct DVPathEntryP) * nhops);
4085   dhops[nhops].hop = GST_my_identity;
4086   {
4087     struct DvHopPS dhp = {
4088       .purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_DV_HOP),
4089       .purpose.size = htonl (sizeof (dhp)),
4090       .pred = dhops[nhops-1].hop,
4091       .succ = *next_hop,
4092       .challenge = msg->challenge
4093     };
4094
4095     GNUNET_assert (GNUNET_OK ==
4096                    GNUNET_CRYPTO_eddsa_sign (GST_my_private_key,
4097                                              &dhp.purpose,
4098                                              &dhops[nhops].hop_sig));
4099   }
4100   route_message (next_hop,
4101                  &fwd->header);
4102 }
4103
4104
4105 /**
4106  * Check signature of type #GNUNET_SIGNATURE_PURPOSE_TRANSPORT_DV_INITIATOR
4107  *
4108  * @param init the signer
4109  * @param challenge the challenge that was signed
4110  * @param init_sig signature presumably by @a init
4111  * @return #GNUNET_OK if the signature is valid
4112  */
4113 static int
4114 validate_dv_initiator_signature (const struct GNUNET_PeerIdentity *init,
4115                                  const struct GNUNET_ShortHashCode *challenge,
4116                                  const struct GNUNET_CRYPTO_EddsaSignature *init_sig)
4117 {
4118   struct DvInitPS ip = {
4119     .purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_DV_INITIATOR),
4120     .purpose.size = htonl (sizeof (ip)),
4121     .challenge = *challenge
4122   };
4123
4124   if (GNUNET_OK !=
4125       GNUNET_CRYPTO_eddsa_verify (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_DV_INITIATOR,
4126                                   &ip.purpose,
4127                                   init_sig,
4128                                   &init->public_key))
4129   {
4130     GNUNET_break_op (0);
4131     return GNUNET_SYSERR;
4132   }
4133   return GNUNET_OK;
4134 }
4135
4136
4137 /**
4138  * Communicator gave us a DV learn message.  Process the request.
4139  *
4140  * @param cls a `struct CommunicatorMessageContext` (must call #finish_cmc_handling() when done)
4141  * @param dvl the message that was received
4142  */
4143 static void
4144 handle_dv_learn (void *cls,
4145                  const struct TransportDVLearn *dvl)
4146 {
4147   struct CommunicatorMessageContext *cmc = cls;
4148   enum GNUNET_TRANSPORT_CommunicatorCharacteristics cc;
4149   int bi_hop;
4150   uint16_t nhops;
4151   uint16_t bi_history;
4152   const struct DVPathEntryP *hops;
4153   int do_fwd;
4154   int did_initiator;
4155   struct GNUNET_TIME_Absolute in_time;
4156
4157   nhops = ntohs (dvl->bidirectional); /* 0 = sender is initiator */
4158   bi_history = ntohs (dvl->bidirectional);
4159   hops = (const struct DVPathEntryP *) &dvl[1];
4160   if (0 == nhops)
4161   {
4162     /* sanity check */
4163     if (0 != GNUNET_memcmp (&dvl->initiator,
4164                             &cmc->im.sender))
4165     {
4166       GNUNET_break (0);
4167       finish_cmc_handling (cmc);
4168       return;
4169     }
4170   }
4171   else
4172   {
4173     /* sanity check */
4174     if (0 != GNUNET_memcmp (&hops[nhops - 1].hop,
4175                             &cmc->im.sender))
4176     {
4177       GNUNET_break (0);
4178       finish_cmc_handling (cmc);
4179       return;
4180     }
4181   }
4182
4183   GNUNET_assert (CT_COMMUNICATOR == cmc->tc->type);
4184   cc = cmc->tc->details.communicator.cc;
4185   bi_hop = (GNUNET_TRANSPORT_CC_RELIABLE == cc); // FIXME: add bi-directional flag to cc?
4186   in_time = GNUNET_TIME_absolute_get ();
4187
4188   /* continue communicator here, everything else can happen asynchronous! */
4189   finish_cmc_handling (cmc);
4190
4191   // FIXME: should we bother to verify _every_ DV initiator signature?
4192   if (GNUNET_OK !=
4193       validate_dv_initiator_signature (&dvl->initiator,
4194                                        &dvl->challenge,
4195                                        &dvl->init_sig))
4196   {
4197     GNUNET_break_op (0);
4198     return;
4199   }
4200   // FIXME: asynchronously (!) verify hop-by-hop signatures!
4201   // => if signature verification load too high, implement random drop strategy!
4202
4203   do_fwd = GNUNET_YES;
4204   if (0 == GNUNET_memcmp (&GST_my_identity,
4205                           &dvl->initiator))
4206   {
4207     struct GNUNET_PeerIdentity path[nhops + 1];
4208     struct GNUNET_TIME_Relative host_latency_sum;
4209     struct GNUNET_TIME_Relative latency;
4210     struct GNUNET_TIME_Relative network_latency;
4211
4212     /* We initiated this, learn the forward path! */
4213     path[0] = GST_my_identity;
4214     path[1] = hops[0].hop;
4215     host_latency_sum = GNUNET_TIME_relative_ntoh (dvl->non_network_delay);
4216
4217     // Need also something to lookup initiation time
4218     // to compute RTT! -> add RTT argument here?
4219     latency = GNUNET_TIME_UNIT_FOREVER_REL; // FIXME: initialize properly
4220     // (based on dvl->challenge, we can identify time of origin!)
4221
4222     network_latency = GNUNET_TIME_relative_subtract (latency,
4223                                                      host_latency_sum);
4224     /* assumption: latency on all links is the same */
4225     network_latency = GNUNET_TIME_relative_divide (network_latency,
4226                                                    nhops);
4227
4228     for (unsigned int i=2;i<=nhops;i++)
4229     {
4230       struct GNUNET_TIME_Relative ilat;
4231
4232       /* assumption: linear latency increase per hop */
4233       ilat = GNUNET_TIME_relative_multiply (network_latency,
4234                                             i);
4235       path[i] = hops[i-1].hop;
4236       learn_dv_path (path,
4237                      i,
4238                      ilat);
4239     }
4240     /* as we initiated, do not forward again (would be circular!) */
4241     do_fwd = GNUNET_NO;
4242     return;
4243   }
4244   else if (bi_hop)
4245   {
4246     /* last hop was bi-directional, we could learn something here! */
4247     struct GNUNET_PeerIdentity path[nhops + 2];
4248
4249     path[0] = GST_my_identity;
4250     path[1] = hops[nhops - 1].hop; /* direct neighbour == predecessor! */
4251     for (unsigned int i=0;i<nhops;i++)
4252     {
4253       int iret;
4254
4255       if (0 == (bi_history & (1 << i)))
4256         break; /* i-th hop not bi-directional, stop learning! */
4257       if (i == nhops)
4258       {
4259         path[i + 2] = dvl->initiator;
4260       }
4261       else
4262       {
4263         path[i + 2] = hops[nhops - i - 2].hop;
4264       }
4265
4266       iret = learn_dv_path (path,
4267                             i + 2,
4268                             GNUNET_TIME_UNIT_FOREVER_REL);
4269       if (GNUNET_SYSERR == iret)
4270       {
4271         /* path invalid or too long to be interesting for US, thus should also
4272            not be interesting to our neighbours, cut path when forwarding to
4273            'i' hops, except of course for the one that goes back to the
4274            initiator */
4275         GNUNET_STATISTICS_update (GST_stats,
4276                                   "# DV learn not forwarded due invalidity of path",
4277                                   1,
4278                                   GNUNET_NO);
4279         do_fwd = GNUNET_NO;
4280         break;
4281       }
4282       if ( (GNUNET_NO == iret) &&
4283            (nhops - 1 == i) )
4284       {
4285         /* we have better paths, and this is the longest target,
4286            so there cannot be anything interesting later */
4287         GNUNET_STATISTICS_update (GST_stats,
4288                                   "# DV learn not forwarded, got better paths",
4289                                   1,
4290                                   GNUNET_NO);
4291         do_fwd = GNUNET_NO;
4292         break;
4293       }
4294     }
4295   }
4296
4297   if (MAX_DV_HOPS_ALLOWED == nhops)
4298   {
4299     /* At limit, we're out of here! */
4300     finish_cmc_handling (cmc);
4301     return;
4302   }
4303
4304   /* Forward to initiator, if path non-trivial and possible */
4305   bi_history = (bi_history << 1) | (bi_hop ? 1 : 0);
4306   did_initiator = GNUNET_NO;
4307   if ( (1 < nhops) &&
4308        (GNUNET_YES ==
4309         GNUNET_CONTAINER_multipeermap_contains (neighbours,
4310                                                 &dvl->initiator)) )
4311   {
4312     /* send back to origin! */
4313     forward_dv_learn (&dvl->initiator,
4314                       dvl,
4315                       bi_history,
4316                       nhops,
4317                       hops,
4318                       in_time);
4319     did_initiator = GNUNET_YES;
4320   }
4321   /* We forward under two conditions: either we still learned something
4322      ourselves (do_fwd), or the path was darn short and thus the initiator is
4323      likely to still be very interested in this (and we did NOT already
4324      send it back to the initiator) */
4325   if ( (do_fwd) ||
4326        ( (nhops < MIN_DV_PATH_LENGTH_FOR_INITIATOR) &&
4327          (GNUNET_NO == did_initiator) ) )
4328   {
4329     /* FIXME: loop over all neighbours, pick those with low
4330        queues AND that are not yet on the path; possibly
4331        adapt threshold to nhops! */
4332 #if FIXME
4333     forward_dv_learn (NULL, // fill in peer from iterator here!
4334                       dvl,
4335                       bi_history,
4336                       nhops,
4337                       hops,
4338                       in_time);
4339 #endif
4340   }
4341 }
4342
4343
4344 /**
4345  * Communicator gave us a DV box.  Check the message.
4346  *
4347  * @param cls a `struct CommunicatorMessageContext`
4348  * @param dvb the send message that was sent
4349  * @return #GNUNET_YES if message is well-formed
4350  */
4351 static int
4352 check_dv_box (void *cls,
4353               const struct TransportDVBox *dvb)
4354 {
4355   uint16_t size = ntohs (dvb->header.size);
4356   uint16_t num_hops = ntohs (dvb->num_hops);
4357   const struct GNUNET_PeerIdentity *hops = (const struct GNUNET_PeerIdentity *) &dvb[1];
4358   const struct GNUNET_MessageHeader *inbox = (const struct GNUNET_MessageHeader *) &hops[num_hops];
4359   uint16_t isize;
4360   uint16_t itype;
4361
4362   if (size < sizeof (*dvb) + num_hops * sizeof (struct GNUNET_PeerIdentity) + sizeof (struct GNUNET_MessageHeader))
4363   {
4364     GNUNET_break_op (0);
4365     return GNUNET_SYSERR;
4366   }
4367   isize = ntohs (inbox->size);
4368   if (size != sizeof (*dvb) + num_hops * sizeof (struct GNUNET_PeerIdentity) + isize)
4369   {
4370     GNUNET_break_op (0);
4371     return GNUNET_SYSERR;
4372   }
4373   itype = ntohs (inbox->type);
4374   if ( (GNUNET_MESSAGE_TYPE_TRANSPORT_DV_BOX == itype) ||
4375        (GNUNET_MESSAGE_TYPE_TRANSPORT_DV_LEARN == itype) )
4376   {
4377     GNUNET_break_op (0);
4378     return GNUNET_SYSERR;
4379   }
4380   return GNUNET_YES;
4381 }
4382
4383
4384 /**
4385  * Communicator gave us a DV box.  Process the request.
4386  *
4387  * @param cls a `struct CommunicatorMessageContext` (must call #finish_cmc_handling() when done)
4388  * @param dvb the message that was received
4389  */
4390 static void
4391 handle_dv_box (void *cls,
4392                const struct TransportDVBox *dvb)
4393 {
4394   struct CommunicatorMessageContext *cmc = cls;
4395   uint16_t size = ntohs (dvb->header.size) - sizeof (*dvb);
4396   uint16_t num_hops = ntohs (dvb->num_hops);
4397   const struct GNUNET_PeerIdentity *hops = (const struct GNUNET_PeerIdentity *) &dvb[1];
4398   const struct GNUNET_MessageHeader *inbox = (const struct GNUNET_MessageHeader *) &hops[num_hops];
4399
4400   if (num_hops > 0)
4401   {
4402     // FIXME: if we are not the target, shorten path and forward along.
4403     // Try from the _end_ of hops array if we know the given
4404     // neighbour (shortening the path!).
4405     // NOTE: increment total_hops!
4406     finish_cmc_handling (cmc);
4407     return;
4408   }
4409   /* We are the target. Unbox and handle message. */
4410   cmc->im.sender = dvb->origin;
4411   cmc->total_hops = ntohs (dvb->total_hops);
4412   demultiplex_with_cmc (cmc,
4413                         inbox);
4414 }
4415
4416
4417 /**
4418  * Client notified us about transmission from a peer.  Process the request.
4419  *
4420  * @param cls a `struct TransportClient` which sent us the message
4421  * @param obm the send message that was sent
4422  * @return #GNUNET_YES if message is well-formed
4423  */
4424 static int
4425 check_incoming_msg (void *cls,
4426                     const struct GNUNET_TRANSPORT_IncomingMessage *im)
4427 {
4428   struct TransportClient *tc = cls;
4429
4430   if (CT_COMMUNICATOR != tc->type)
4431   {
4432     GNUNET_break (0);
4433     return GNUNET_SYSERR;
4434   }
4435   GNUNET_MQ_check_boxed_message (im);
4436   return GNUNET_OK;
4437 }
4438
4439
4440 /**
4441  * Communicator gave us a transport address validation challenge.  Process the request.
4442  *
4443  * @param cls a `struct CommunicatorMessageContext` (must call #finish_cmc_handling() when done)
4444  * @param tvc the message that was received
4445  */
4446 static void
4447 handle_validation_challenge (void *cls,
4448                              const struct TransportValidationChallenge *tvc)
4449 {
4450   struct CommunicatorMessageContext *cmc = cls;
4451   struct TransportValidationResponse *tvr;
4452
4453   if (cmc->total_hops > 0)
4454   {
4455     /* DV routing is not allowed for validation challenges! */
4456     GNUNET_break_op (0);
4457     finish_cmc_handling (cmc);
4458     return;
4459   }
4460   tvr = GNUNET_new (struct TransportValidationResponse);
4461   tvr->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_VALIDATION_RESPONSE);
4462   tvr->header.size = htons (sizeof (*tvr));
4463   tvr->challenge = tvc->challenge;
4464   tvr->origin_time = tvc->sender_time;
4465   tvr->validity_duration = cmc->im.expected_address_validity;
4466   {
4467     /* create signature */
4468     struct TransportValidationPS tvp = {
4469       .purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_CHALLENGE),
4470       .purpose.size = htonl (sizeof (tvp)),
4471       .validity_duration = tvr->validity_duration,
4472       .challenge = tvc->challenge
4473     };
4474
4475     GNUNET_assert (GNUNET_OK ==
4476                    GNUNET_CRYPTO_eddsa_sign (GST_my_private_key,
4477                                              &tvp.purpose,
4478                                              &tvr->signature));
4479   }
4480   route_message (&cmc->im.sender,
4481                  &tvr->header);
4482   finish_cmc_handling (cmc);
4483 }
4484
4485
4486 /**
4487  * Closure for #check_known_challenge.
4488  */
4489 struct CheckKnownChallengeContext
4490 {
4491   /**
4492    * Set to the challenge we are looking for.
4493    */
4494   const struct GNUNET_ShortHashCode *challenge;
4495
4496   /**
4497    * Set to a matching validation state, if one was found.
4498    */
4499   struct ValidationState *vs;
4500 };
4501
4502
4503 /**
4504  * Test if the validation state in @a value matches the
4505  * challenge from @a cls.
4506  *
4507  * @param cls a `struct CheckKnownChallengeContext`
4508  * @param pid unused (must match though)
4509  * @param value a `struct ValidationState`
4510  * @return #GNUNET_OK if not matching, #GNUNET_NO if match found
4511  */
4512 static int
4513 check_known_challenge (void *cls,
4514                        const struct GNUNET_PeerIdentity *pid,
4515                        void *value)
4516 {
4517   struct CheckKnownChallengeContext *ckac = cls;
4518   struct ValidationState *vs = value;
4519
4520   (void) pid;
4521   if (0 != GNUNET_memcmp (&vs->challenge,
4522                           ckac->challenge))
4523     return GNUNET_OK;
4524   ckac->vs = vs;
4525   return GNUNET_NO;
4526 }
4527
4528
4529 /**
4530  * Function called when peerstore is done storing a
4531  * validated address.
4532  *
4533  * @param cls a `struct ValidationState`
4534  * @param success #GNUNET_YES on success
4535  */
4536 static void
4537 peerstore_store_validation_cb (void *cls,
4538                                int success)
4539 {
4540   struct ValidationState *vs = cls;
4541
4542   vs->sc = NULL;
4543   if (GNUNET_YES == success)
4544     return;
4545   GNUNET_STATISTICS_update (GST_stats,
4546                             "# Peerstore failed to store foreign address",
4547                             1,
4548                             GNUNET_NO);
4549 }
4550
4551
4552 /**
4553  * Task run periodically to validate some address based on #validation_heap.
4554  *
4555  * @param cls NULL
4556  */
4557 static void
4558 validation_start_cb (void *cls);
4559
4560
4561 /**
4562  * Set the time for next_challenge of @a vs to @a new_time.
4563  * Updates the heap and if necessary reschedules the job.
4564  *
4565  * @param vs validation state to update
4566  * @param new_time new time for revalidation
4567  */
4568 static void
4569 update_next_challenge_time (struct ValidationState *vs,
4570                             struct GNUNET_TIME_Absolute new_time)
4571 {
4572   struct GNUNET_TIME_Relative delta;
4573
4574   if (new_time.abs_value_us == vs->next_challenge.abs_value_us)
4575     return; /* be lazy */
4576   vs->next_challenge = new_time;
4577   if (NULL == vs->hn)
4578     vs->hn = GNUNET_CONTAINER_heap_insert (validation_heap,
4579                                            vs,
4580                                            new_time.abs_value_us);
4581   else
4582     GNUNET_CONTAINER_heap_update_cost (vs->hn,
4583                                        new_time.abs_value_us);
4584   if ( (vs != GNUNET_CONTAINER_heap_peek (validation_heap)) &&
4585        (NULL != validation_task) )
4586     return;
4587   if (NULL != validation_task)
4588     GNUNET_SCHEDULER_cancel (validation_task);
4589   /* randomize a bit */
4590   delta.rel_value_us = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK,
4591                                                  MIN_DELAY_ADDRESS_VALIDATION.rel_value_us);
4592   new_time = GNUNET_TIME_absolute_add (new_time,
4593                                        delta);
4594   validation_task = GNUNET_SCHEDULER_add_at (new_time,
4595                                              &validation_start_cb,
4596                                              NULL);
4597 }
4598
4599
4600 /**
4601  * Communicator gave us a transport address validation response.  Process the request.
4602  *
4603  * @param cls a `struct CommunicatorMessageContext` (must call #finish_cmc_handling() when done)
4604  * @param tvr the message that was received
4605  */
4606 static void
4607 handle_validation_response (void *cls,
4608                             const struct TransportValidationResponse *tvr)
4609 {
4610   struct CommunicatorMessageContext *cmc = cls;
4611   struct ValidationState *vs;
4612   struct CheckKnownChallengeContext ckac = {
4613     .challenge = &tvr->challenge,
4614     .vs = NULL
4615   };
4616   struct GNUNET_TIME_Absolute origin_time;
4617
4618   /* check this is one of our challenges */
4619   (void) GNUNET_CONTAINER_multipeermap_get_multiple (validation_map,
4620                                                      &cmc->im.sender,
4621                                                      &check_known_challenge,
4622                                                      &ckac);
4623   if (NULL == (vs = ckac.vs))
4624   {
4625     /* This can happen simply if we 'forgot' the challenge by now,
4626        i.e. because we received the validation response twice */
4627     GNUNET_STATISTICS_update (GST_stats,
4628                               "# Validations dropped, challenge unknown",
4629                               1,
4630                               GNUNET_NO);
4631     finish_cmc_handling (cmc);
4632     return;
4633   }
4634
4635   /* sanity check on origin time */
4636   origin_time = GNUNET_TIME_absolute_ntoh (tvr->origin_time);
4637   if ( (origin_time.abs_value_us < vs->first_challenge_use.abs_value_us) ||
4638        (origin_time.abs_value_us > vs->last_challenge_use.abs_value_us) )
4639   {
4640     GNUNET_break_op (0);
4641     finish_cmc_handling (cmc);
4642     return;
4643   }
4644
4645   {
4646     /* check signature */
4647     struct TransportValidationPS tvp = {
4648       .purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_CHALLENGE),
4649       .purpose.size = htonl (sizeof (tvp)),
4650       .validity_duration = tvr->validity_duration,
4651       .challenge = tvr->challenge
4652     };
4653
4654     if (GNUNET_OK !=
4655         GNUNET_CRYPTO_eddsa_verify (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_CHALLENGE,
4656                                     &tvp.purpose,
4657                                     &tvr->signature,
4658                                     &cmc->im.sender.public_key))
4659     {
4660       GNUNET_break_op (0);
4661       finish_cmc_handling (cmc);
4662       return;
4663     }
4664   }
4665
4666   /* validity is capped by our willingness to keep track of the
4667      validation entry and the maximum the other peer allows */
4668   vs->valid_until
4669     = GNUNET_TIME_relative_to_absolute (GNUNET_TIME_relative_min (GNUNET_TIME_relative_ntoh (tvr->validity_duration),
4670                                                                   MAX_ADDRESS_VALID_UNTIL));
4671   vs->validated_until
4672     = GNUNET_TIME_absolute_min (vs->valid_until,
4673                                 GNUNET_TIME_relative_to_absolute (ADDRESS_VALIDATION_LIFETIME));
4674   vs->validation_rtt = GNUNET_TIME_absolute_get_duration (origin_time);
4675   vs->challenge_backoff = GNUNET_TIME_UNIT_ZERO;
4676   GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE,
4677                               &vs->challenge,
4678                               sizeof (vs->challenge));
4679   vs->first_challenge_use = GNUNET_TIME_absolute_subtract (vs->validated_until,
4680                                                            GNUNET_TIME_relative_multiply (vs->validation_rtt,
4681                                                                                           VALIDATION_RTT_BUFFER_FACTOR));
4682   vs->last_challenge_use = GNUNET_TIME_UNIT_ZERO_ABS; /* challenge was not yet used */
4683   update_next_challenge_time (vs,
4684                               vs->first_challenge_use);
4685   vs->sc = GNUNET_PEERSTORE_store (peerstore,
4686                                    "transport",
4687                                    &cmc->im.sender,
4688                                    GNUNET_PEERSTORE_TRANSPORT_URLADDRESS_KEY,
4689                                    vs->address,
4690                                    strlen (vs->address) + 1,
4691                                    vs->valid_until,
4692                                    GNUNET_PEERSTORE_STOREOPTION_MULTIPLE,
4693                                    &peerstore_store_validation_cb,
4694                                    vs);
4695   // FIXME: should we find the matching queue and update the RTT?
4696   finish_cmc_handling (cmc);
4697 }
4698
4699
4700 /**
4701  * Incoming meessage.  Process the request.
4702  *
4703  * @param im the send message that was received
4704  */
4705 static void
4706 handle_incoming_msg (void *cls,
4707                      const struct GNUNET_TRANSPORT_IncomingMessage *im)
4708 {
4709   struct TransportClient *tc = cls;
4710   struct CommunicatorMessageContext *cmc = GNUNET_new (struct CommunicatorMessageContext);
4711
4712   cmc->tc = tc;
4713   cmc->im = *im;
4714   demultiplex_with_cmc (cmc,
4715                         (const struct GNUNET_MessageHeader *) &im[1]);
4716 }
4717
4718
4719 /**
4720  * Given an inbound message @a msg from a communicator @a cmc,
4721  * demultiplex it based on the type calling the right handler.
4722  *
4723  * @param cmc context for demultiplexing
4724  * @param msg message to demultiplex
4725  */
4726 static void
4727 demultiplex_with_cmc (struct CommunicatorMessageContext *cmc,
4728                       const struct GNUNET_MessageHeader *msg)
4729 {
4730   struct GNUNET_MQ_MessageHandler handlers[] = {
4731     GNUNET_MQ_hd_var_size (fragment_box,
4732                            GNUNET_MESSAGE_TYPE_TRANSPORT_FRAGMENT,
4733                            struct TransportFragmentBox,
4734                            &cmc),
4735     GNUNET_MQ_hd_fixed_size (fragment_ack,
4736                              GNUNET_MESSAGE_TYPE_TRANSPORT_FRAGMENT_ACK,
4737                              struct TransportFragmentAckMessage,
4738                              &cmc),
4739     GNUNET_MQ_hd_var_size (reliability_box,
4740                            GNUNET_MESSAGE_TYPE_TRANSPORT_RELIABILITY_BOX,
4741                            struct TransportReliabilityBox,
4742                            &cmc),
4743     GNUNET_MQ_hd_fixed_size (reliability_ack,
4744                              GNUNET_MESSAGE_TYPE_TRANSPORT_RELIABILITY_ACK,
4745                              struct TransportReliabilityAckMessage,
4746                              &cmc),
4747     GNUNET_MQ_hd_var_size (backchannel_encapsulation,
4748                            GNUNET_MESSAGE_TYPE_TRANSPORT_BACKCHANNEL_ENCAPSULATION,
4749                            struct TransportBackchannelEncapsulationMessage,
4750                            &cmc),
4751     GNUNET_MQ_hd_var_size (dv_learn,
4752                            GNUNET_MESSAGE_TYPE_TRANSPORT_DV_LEARN,
4753                            struct TransportDVLearn,
4754                            &cmc),
4755     GNUNET_MQ_hd_var_size (dv_box,
4756                            GNUNET_MESSAGE_TYPE_TRANSPORT_DV_BOX,
4757                            struct TransportDVBox,
4758                            &cmc),
4759     GNUNET_MQ_hd_fixed_size (validation_challenge,
4760                              GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_VALIDATION_CHALLENGE,
4761                              struct TransportValidationChallenge,
4762                              &cmc),
4763     GNUNET_MQ_hd_fixed_size (validation_response,
4764                              GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_VALIDATION_RESPONSE,
4765                              struct TransportValidationResponse,
4766                              &cmc),
4767     GNUNET_MQ_handler_end()
4768   };
4769   int ret;
4770
4771   ret = GNUNET_MQ_handle_message (handlers,
4772                                   msg);
4773   if (GNUNET_SYSERR == ret)
4774   {
4775     GNUNET_break (0);
4776     GNUNET_SERVICE_client_drop (cmc->tc->client);
4777     GNUNET_free (cmc);
4778     return;
4779   }
4780   if (GNUNET_NO == ret)
4781   {
4782     /* unencapsulated 'raw' message */
4783     handle_raw_message (&cmc,
4784                         msg);
4785   }
4786 }
4787
4788
4789 /**
4790  * New queue became available.  Check message.
4791  *
4792  * @param cls the client
4793  * @param aqm the send message that was sent
4794  */
4795 static int
4796 check_add_queue_message (void *cls,
4797                          const struct GNUNET_TRANSPORT_AddQueueMessage *aqm)
4798 {
4799   struct TransportClient *tc = cls;
4800
4801   if (CT_COMMUNICATOR != tc->type)
4802   {
4803     GNUNET_break (0);
4804     return GNUNET_SYSERR;
4805   }
4806   GNUNET_MQ_check_zero_termination (aqm);
4807   return GNUNET_OK;
4808 }
4809
4810
4811 /**
4812  * Bandwidth tracker informs us that the delay until we should receive
4813  * more has changed.
4814  *
4815  * @param cls a `struct Queue` for which the delay changed
4816  */
4817 static void
4818 tracker_update_in_cb (void *cls)
4819 {
4820   struct Queue *queue = cls;
4821   struct GNUNET_TIME_Relative in_delay;
4822   unsigned int rsize;
4823
4824   rsize = (0 == queue->mtu) ? IN_PACKET_SIZE_WITHOUT_MTU : queue->mtu;
4825   in_delay = GNUNET_BANDWIDTH_tracker_get_delay (&queue->tracker_in,
4826                                                  rsize);
4827   // FIXME: how exactly do we do inbound flow control?
4828 }
4829
4830
4831 /**
4832  * If necessary, generates the UUID for a @a pm
4833  *
4834  * @param pm pending message to generate UUID for.
4835  */
4836 static void
4837 set_pending_message_uuid (struct PendingMessage *pm)
4838 {
4839   if (pm->msg_uuid_set)
4840     return;
4841   GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE,
4842                               &pm->msg_uuid,
4843                               sizeof (pm->msg_uuid));
4844   pm->msg_uuid_set = GNUNET_YES;
4845 }
4846
4847
4848 /**
4849  * Fragment the given @a pm to the given @a mtu.  Adds
4850  * additional fragments to the neighbour as well. If the
4851  * @a mtu is too small, generates and error for the @a pm
4852  * and returns NULL.
4853  *
4854  * @param pm pending message to fragment for transmission
4855  * @param mtu MTU to apply
4856  * @return new message to transmit
4857  */
4858 static struct PendingMessage *
4859 fragment_message (struct PendingMessage *pm,
4860                   uint16_t mtu)
4861 {
4862   struct PendingMessage *ff;
4863
4864   set_pending_message_uuid (pm);
4865
4866   /* This invariant is established in #handle_add_queue_message() */
4867   GNUNET_assert (mtu > sizeof (struct TransportFragmentBox));
4868
4869   /* select fragment for transmission, descending the tree if it has
4870      been expanded until we are at a leaf or at a fragment that is small enough */
4871   ff = pm;
4872   while ( ( (ff->bytes_msg > mtu) ||
4873             (pm == ff) ) &&
4874           (ff->frag_off == ff->bytes_msg) &&
4875           (NULL != ff->head_frag) )
4876   {
4877     ff = ff->head_frag; /* descent into fragmented fragments */
4878   }
4879
4880   if ( ( (ff->bytes_msg > mtu) ||
4881          (pm == ff) ) &&
4882        (pm->frag_off < pm->bytes_msg) )
4883   {
4884     /* Did not yet calculate all fragments, calculate next fragment */
4885     struct PendingMessage *frag;
4886     struct TransportFragmentBox tfb;
4887     const char *orig;
4888     char *msg;
4889     uint16_t fragmax;
4890     uint16_t fragsize;
4891     uint16_t msize;
4892     uint16_t xoff = 0;
4893
4894     orig = (const char *) &ff[1];
4895     msize = ff->bytes_msg;
4896     if (pm != ff)
4897     {
4898       const struct TransportFragmentBox *tfbo;
4899
4900       tfbo = (const struct TransportFragmentBox *) orig;
4901       orig += sizeof (struct TransportFragmentBox);
4902       msize -= sizeof (struct TransportFragmentBox);
4903       xoff = ntohs (tfbo->frag_off);
4904     }
4905     fragmax = mtu - sizeof (struct TransportFragmentBox);
4906     fragsize = GNUNET_MIN (msize - ff->frag_off,
4907                            fragmax);
4908     frag = GNUNET_malloc (sizeof (struct PendingMessage) +
4909                           sizeof (struct TransportFragmentBox) +
4910                           fragsize);
4911     frag->target = pm->target;
4912     frag->frag_parent = ff;
4913     frag->timeout = pm->timeout;
4914     frag->bytes_msg = sizeof (struct TransportFragmentBox) + fragsize;
4915     frag->pmt = PMT_FRAGMENT_BOX;
4916     msg = (char *) &frag[1];
4917     tfb.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_FRAGMENT);
4918     tfb.header.size = htons (sizeof (struct TransportFragmentBox) +
4919                              fragsize);
4920     tfb.frag_uuid = htonl (pm->frag_uuidgen++);
4921     tfb.msg_uuid = pm->msg_uuid;
4922     tfb.frag_off = htons (ff->frag_off + xoff);
4923     tfb.msg_size = htons (pm->bytes_msg);
4924     memcpy (msg,
4925             &tfb,
4926             sizeof (tfb));
4927     memcpy (&msg[sizeof (tfb)],
4928             &orig[ff->frag_off],
4929             fragsize);
4930     GNUNET_CONTAINER_MDLL_insert (frag,
4931                                   ff->head_frag,
4932                                   ff->tail_frag,
4933                                   frag);
4934     ff->frag_off += fragsize;
4935     ff = frag;
4936   }
4937
4938   /* Move head to the tail and return it */
4939   GNUNET_CONTAINER_MDLL_remove (frag,
4940                                 ff->frag_parent->head_frag,
4941                                 ff->frag_parent->tail_frag,
4942                                 ff);
4943   GNUNET_CONTAINER_MDLL_insert_tail (frag,
4944                                      ff->frag_parent->head_frag,
4945                                      ff->frag_parent->tail_frag,
4946                                      ff);
4947   return ff;
4948 }
4949
4950
4951 /**
4952  * Reliability-box the given @a pm. On error (can there be any), NULL
4953  * may be returned, otherwise the "replacement" for @a pm (which
4954  * should then be added to the respective neighbour's queue instead of
4955  * @a pm).  If the @a pm is already fragmented or reliability boxed,
4956  * or itself an ACK, this function simply returns @a pm.
4957  *
4958  * @param pm pending message to box for transmission over unreliabile queue
4959  * @return new message to transmit
4960  */
4961 static struct PendingMessage *
4962 reliability_box_message (struct PendingMessage *pm)
4963 {
4964   struct TransportReliabilityBox rbox;
4965   struct PendingMessage *bpm;
4966   char *msg;
4967
4968   if (PMT_CORE != pm->pmt)
4969     return pm;  /* already fragmented or reliability boxed, or control message: do nothing */
4970   if (NULL != pm->bpm)
4971     return pm->bpm; /* already computed earlier: do nothing */
4972   GNUNET_assert (NULL == pm->head_frag);
4973   if (pm->bytes_msg + sizeof (rbox) > UINT16_MAX)
4974   {
4975     /* failed hard */
4976     GNUNET_break (0);
4977     client_send_response (pm,
4978                           GNUNET_NO,
4979                           0);
4980     return NULL;
4981   }
4982   bpm = GNUNET_malloc (sizeof (struct PendingMessage) +
4983                        sizeof (rbox) +
4984                        pm->bytes_msg);
4985   bpm->target = pm->target;
4986   bpm->frag_parent = pm;
4987   GNUNET_CONTAINER_MDLL_insert (frag,
4988                                 pm->head_frag,
4989                                 pm->tail_frag,
4990                                 bpm);
4991   bpm->timeout = pm->timeout;
4992   bpm->pmt = PMT_RELIABILITY_BOX;
4993   bpm->bytes_msg = pm->bytes_msg + sizeof (rbox);
4994   set_pending_message_uuid (bpm);
4995   rbox.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_RELIABILITY_BOX);
4996   rbox.header.size = htons (sizeof (rbox) + pm->bytes_msg);
4997   rbox.ack_countdown = htonl (0); // FIXME: implement ACK countdown support
4998   rbox.msg_uuid = pm->msg_uuid;
4999   msg = (char *) &bpm[1];
5000   memcpy (msg,
5001           &rbox,
5002           sizeof (rbox));
5003   memcpy (&msg[sizeof (rbox)],
5004           &pm[1],
5005           pm->bytes_msg);
5006   pm->bpm = bpm;
5007   return bpm;
5008 }
5009
5010
5011 /**
5012  * We believe we are ready to transmit a message on a queue. Double-checks
5013  * with the queue's "tracker_out" and then gives the message to the
5014  * communicator for transmission (updating the tracker, and re-scheduling
5015  * itself if applicable).
5016  *
5017  * @param cls the `struct Queue` to process transmissions for
5018  */
5019 static void
5020 transmit_on_queue (void *cls)
5021 {
5022   struct Queue *queue = cls;
5023   struct Neighbour *n = queue->neighbour;
5024   struct PendingMessage *pm;
5025   struct PendingMessage *s;
5026   uint32_t overhead;
5027   struct GNUNET_TRANSPORT_SendMessageTo *smt;
5028   struct GNUNET_MQ_Envelope *env;
5029
5030   queue->transmit_task = NULL;
5031   if (NULL == (pm = n->pending_msg_head))
5032   {
5033     /* no message pending, nothing to do here! */
5034     return;
5035   }
5036   schedule_transmit_on_queue (queue);
5037   if (NULL != queue->transmit_task)
5038     return; /* do it later */
5039   overhead = 0;
5040   if (GNUNET_TRANSPORT_CC_RELIABLE != queue->tc->details.communicator.cc)
5041     overhead += sizeof (struct TransportReliabilityBox);
5042   s = pm;
5043   if ( ( (0 != queue->mtu) &&
5044          (pm->bytes_msg + overhead > queue->mtu) ) ||
5045        (pm->bytes_msg > UINT16_MAX - sizeof (struct GNUNET_TRANSPORT_SendMessageTo)) ||
5046        (NULL != pm->head_frag /* fragments already exist, should
5047                                  respect that even if MTU is 0 for
5048                                  this queue */) )
5049     s = fragment_message (s,
5050                           (0 == queue->mtu)
5051                           ? UINT16_MAX - sizeof (struct GNUNET_TRANSPORT_SendMessageTo)
5052                           : queue->mtu);
5053   if (NULL == s)
5054   {
5055     /* Fragmentation failed, try next message... */
5056     schedule_transmit_on_queue (queue);
5057     return;
5058   }
5059   if (GNUNET_TRANSPORT_CC_RELIABLE != queue->tc->details.communicator.cc)
5060     s = reliability_box_message (s);
5061   if (NULL == s)
5062   {
5063     /* Reliability boxing failed, try next message... */
5064     schedule_transmit_on_queue (queue);
5065     return;
5066   }
5067
5068   /* Pass 's' for transission to the communicator */
5069   env = GNUNET_MQ_msg_extra (smt,
5070                              s->bytes_msg,
5071                              GNUNET_MESSAGE_TYPE_TRANSPORT_SEND_MSG);
5072   smt->qid = queue->qid;
5073   smt->mid = queue->mid_gen;
5074   smt->receiver = n->pid;
5075   memcpy (&smt[1],
5076           &s[1],
5077           s->bytes_msg);
5078   {
5079     /* Pass the env to the communicator of queue for transmission. */
5080     struct QueueEntry *qe;
5081
5082     qe = GNUNET_new (struct QueueEntry);
5083     qe->mid = queue->mid_gen++;
5084     qe->queue = queue;
5085     // qe->pm = s; // FIXME: not so easy, reference management on 'free(s)'!
5086     GNUNET_CONTAINER_DLL_insert (queue->queue_head,
5087                                  queue->queue_tail,
5088                                  qe);
5089     GNUNET_assert (CT_COMMUNICATOR == queue->tc->type);
5090     queue->queue_length++;
5091     queue->tc->details.communicator.total_queue_length++;
5092     GNUNET_MQ_send (queue->tc->mq,
5093                     env);
5094   }
5095
5096   // FIXME: do something similar to the logic below
5097   // in defragmentation / reliability ACK handling!
5098
5099   /* Check if this transmission somehow conclusively finished handing 'pm'
5100      even without any explicit ACKs */
5101   if ( (PMT_CORE == s->pmt) &&
5102        (GNUNET_TRANSPORT_CC_RELIABLE == queue->tc->details.communicator.cc) )
5103   {
5104     /* Full message sent, and over reliabile channel */
5105     client_send_response (pm,
5106                           GNUNET_YES,
5107                           pm->bytes_msg);
5108   }
5109   else if ( (GNUNET_TRANSPORT_CC_RELIABLE == queue->tc->details.communicator.cc) &&
5110             (PMT_FRAGMENT_BOX == s->pmt) )
5111   {
5112     struct PendingMessage *pos;
5113
5114     /* Fragment sent over reliabile channel */
5115     free_fragment_tree (s);
5116     pos = s->frag_parent;
5117     GNUNET_CONTAINER_MDLL_remove (frag,
5118                                   pos->head_frag,
5119                                   pos->tail_frag,
5120                                   s);
5121     GNUNET_free (s);
5122     /* check if subtree is done */
5123     while ( (NULL == pos->head_frag) &&
5124             (pos->frag_off == pos->bytes_msg) &&
5125             (pos != pm) )
5126     {
5127       s = pos;
5128       pos = s->frag_parent;
5129       GNUNET_CONTAINER_MDLL_remove (frag,
5130                                     pos->head_frag,
5131                                     pos->tail_frag,
5132                                     s);
5133       GNUNET_free (s);
5134     }
5135
5136     /* Was this the last applicable fragmment? */
5137     if ( (NULL == pm->head_frag) &&
5138          (pm->frag_off == pm->bytes_msg) )
5139       client_send_response (pm,
5140                             GNUNET_YES,
5141                             pm->bytes_msg /* FIXME: calculate and add overheads! */);
5142   }
5143   else if (PMT_CORE != pm->pmt)
5144   {
5145     /* This was an acknowledgement of some type, always free */
5146     free_pending_message (pm);
5147   }
5148   else
5149   {
5150     /* message not finished, waiting for acknowledgement */
5151     struct Neighbour *neighbour = pm->target;
5152     /* Update time by which we might retransmit 's' based on queue
5153        characteristics (i.e. RTT); it takes one RTT for the message to
5154        arrive and the ACK to come back in the best case; but the other
5155        side is allowed to delay ACKs by 2 RTTs, so we use 4 RTT before
5156        retransmitting.  Note that in the future this heuristic should
5157        likely be improved further (measure RTT stability, consider
5158        message urgency and size when delaying ACKs, etc.) */
5159     s->next_attempt = GNUNET_TIME_relative_to_absolute
5160       (GNUNET_TIME_relative_multiply (queue->rtt,
5161                                       4));
5162     if (s == pm)
5163     {
5164       struct PendingMessage *pos;
5165
5166       /* re-insert sort in neighbour list */
5167       GNUNET_CONTAINER_MDLL_remove (neighbour,
5168                                     neighbour->pending_msg_head,
5169                                     neighbour->pending_msg_tail,
5170                                     pm);
5171       pos = neighbour->pending_msg_tail;
5172       while ( (NULL != pos) &&
5173               (pm->next_attempt.abs_value_us > pos->next_attempt.abs_value_us) )
5174         pos = pos->prev_neighbour;
5175       GNUNET_CONTAINER_MDLL_insert_after (neighbour,
5176                                           neighbour->pending_msg_head,
5177                                           neighbour->pending_msg_tail,
5178                                           pos,
5179                                           pm);
5180     }
5181     else
5182     {
5183       /* re-insert sort in fragment list */
5184       struct PendingMessage *fp = s->frag_parent;
5185       struct PendingMessage *pos;
5186
5187       GNUNET_CONTAINER_MDLL_remove (frag,
5188                                     fp->head_frag,
5189                                     fp->tail_frag,
5190                                     s);
5191       pos = fp->tail_frag;
5192       while ( (NULL != pos) &&
5193               (s->next_attempt.abs_value_us > pos->next_attempt.abs_value_us) )
5194         pos = pos->prev_frag;
5195       GNUNET_CONTAINER_MDLL_insert_after (frag,
5196                                           fp->head_frag,
5197                                           fp->tail_frag,
5198                                           pos,
5199                                           s);
5200     }
5201   }
5202
5203   /* finally, re-schedule queue transmission task itself */
5204   schedule_transmit_on_queue (queue);
5205 }
5206
5207
5208 /**
5209  * Bandwidth tracker informs us that the delay until we
5210  * can transmit again changed.
5211  *
5212  * @param cls a `struct Queue` for which the delay changed
5213  */
5214 static void
5215 tracker_update_out_cb (void *cls)
5216 {
5217   struct Queue *queue = cls;
5218   struct Neighbour *n = queue->neighbour;
5219
5220   if (NULL == n->pending_msg_head)
5221   {
5222     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5223                 "Bandwidth allocation updated for empty transmission queue `%s'\n",
5224                 queue->address);
5225     return; /* no message pending, nothing to do here! */
5226   }
5227   GNUNET_SCHEDULER_cancel (queue->transmit_task);
5228   queue->transmit_task = NULL;
5229   schedule_transmit_on_queue (queue);
5230 }
5231
5232
5233 /**
5234  * Bandwidth tracker informs us that excessive outbound bandwidth was
5235  * allocated which is not being used.
5236  *
5237  * @param cls a `struct Queue` for which the excess was noted
5238  */
5239 static void
5240 tracker_excess_out_cb (void *cls)
5241 {
5242   /* FIXME: trigger excess bandwidth report to core? Right now,
5243      this is done internally within transport_api2_core already,
5244      but we probably want to change the logic and trigger it
5245      from here via a message instead! */
5246   /* TODO: maybe inform someone at this point? */
5247   GNUNET_STATISTICS_update (GST_stats,
5248                             "# Excess outbound bandwidth reported",
5249                             1,
5250                             GNUNET_NO);
5251 }
5252
5253
5254
5255 /**
5256  * Bandwidth tracker informs us that excessive inbound bandwidth was allocated
5257  * which is not being used.
5258  *
5259  * @param cls a `struct Queue` for which the excess was noted
5260  */
5261 static void
5262 tracker_excess_in_cb (void *cls)
5263 {
5264   /* TODO: maybe inform somone at this point? */
5265   GNUNET_STATISTICS_update (GST_stats,
5266                             "# Excess inbound bandwidth reported",
5267                             1,
5268                             GNUNET_NO);
5269 }
5270
5271
5272 /**
5273  * Queue to a peer went down.  Process the request.
5274  *
5275  * @param cls the client
5276  * @param dqm the send message that was sent
5277  */
5278 static void
5279 handle_del_queue_message (void *cls,
5280                           const struct GNUNET_TRANSPORT_DelQueueMessage *dqm)
5281 {
5282   struct TransportClient *tc = cls;
5283
5284   if (CT_COMMUNICATOR != tc->type)
5285   {
5286     GNUNET_break (0);
5287     GNUNET_SERVICE_client_drop (tc->client);
5288     return;
5289   }
5290   for (struct Queue *queue = tc->details.communicator.queue_head;
5291        NULL != queue;
5292        queue = queue->next_client)
5293   {
5294     struct Neighbour *neighbour = queue->neighbour;
5295
5296     if ( (dqm->qid != queue->qid) ||
5297          (0 != GNUNET_memcmp (&dqm->receiver,
5298                               &neighbour->pid)) )
5299       continue;
5300     free_queue (queue);
5301     GNUNET_SERVICE_client_continue (tc->client);
5302     return;
5303   }
5304   GNUNET_break (0);
5305   GNUNET_SERVICE_client_drop (tc->client);
5306 }
5307
5308
5309 /**
5310  * Message was transmitted.  Process the request.
5311  *
5312  * @param cls the client
5313  * @param sma the send message that was sent
5314  */
5315 static void
5316 handle_send_message_ack (void *cls,
5317                          const struct GNUNET_TRANSPORT_SendMessageToAck *sma)
5318 {
5319   struct TransportClient *tc = cls;
5320   struct QueueEntry *qe;
5321
5322   if (CT_COMMUNICATOR != tc->type)
5323   {
5324     GNUNET_break (0);
5325     GNUNET_SERVICE_client_drop (tc->client);
5326     return;
5327   }
5328
5329   /* find our queue entry matching the ACK */
5330   qe = NULL;
5331   for (struct Queue *queue = tc->details.communicator.queue_head;
5332        NULL != queue;
5333        queue = queue->next_client)
5334   {
5335     if (0 != GNUNET_memcmp (&queue->neighbour->pid,
5336                             &sma->receiver))
5337       continue;
5338     for (struct QueueEntry *qep = queue->queue_head;
5339          NULL != qep;
5340          qep = qep->next)
5341     {
5342       if (qep->mid != sma->mid)
5343         continue;
5344       qe = qep;
5345       break;
5346     }
5347     break;
5348   }
5349   if (NULL == qe)
5350   {
5351     /* this should never happen */
5352     GNUNET_break (0);
5353     GNUNET_SERVICE_client_drop (tc->client);
5354     return;
5355   }
5356   GNUNET_CONTAINER_DLL_remove (qe->queue->queue_head,
5357                                qe->queue->queue_tail,
5358                                qe);
5359   qe->queue->queue_length--;
5360   tc->details.communicator.total_queue_length--;
5361   GNUNET_SERVICE_client_continue (tc->client);
5362
5363   /* if applicable, resume transmissions that waited on ACK */
5364   if (COMMUNICATOR_TOTAL_QUEUE_LIMIT - 1 == tc->details.communicator.total_queue_length)
5365   {
5366     /* Communicator dropped below threshold, resume all queues */
5367     GNUNET_STATISTICS_update (GST_stats,
5368                               "# Transmission throttled due to communicator queue limit",
5369                               -1,
5370                               GNUNET_NO);
5371     for (struct Queue *queue = tc->details.communicator.queue_head;
5372          NULL != queue;
5373          queue = queue->next_client)
5374       schedule_transmit_on_queue (queue);
5375   }
5376   else if (QUEUE_LENGTH_LIMIT - 1 == qe->queue->queue_length)
5377   {
5378     /* queue dropped below threshold; only resume this one queue */
5379     GNUNET_STATISTICS_update (GST_stats,
5380                               "# Transmission throttled due to queue queue limit",
5381                               -1,
5382                               GNUNET_NO);
5383     schedule_transmit_on_queue (qe->queue);
5384   }
5385
5386   /* TODO: we also should react on the status! */
5387   // FIXME: this probably requires queue->pm = s assignment!
5388   // FIXME: react to communicator status about transmission request. We got:
5389   sma->status; // OK success, SYSERR failure
5390
5391   GNUNET_free (qe);
5392 }
5393
5394
5395 /**
5396  * Iterator telling new MONITOR client about all existing
5397  * queues to peers.
5398  *
5399  * @param cls the new `struct TransportClient`
5400  * @param pid a connected peer
5401  * @param value the `struct Neighbour` with more information
5402  * @return #GNUNET_OK (continue to iterate)
5403  */
5404 static int
5405 notify_client_queues (void *cls,
5406                       const struct GNUNET_PeerIdentity *pid,
5407                       void *value)
5408 {
5409   struct TransportClient *tc = cls;
5410   struct Neighbour *neighbour = value;
5411
5412   GNUNET_assert (CT_MONITOR == tc->type);
5413   for (struct Queue *q = neighbour->queue_head;
5414        NULL != q;
5415        q = q->next_neighbour)
5416   {
5417     struct MonitorEvent me = {
5418       .rtt = q->rtt,
5419       .cs = q->cs,
5420       .num_msg_pending = q->num_msg_pending,
5421       .num_bytes_pending = q->num_bytes_pending
5422     };
5423
5424     notify_monitor (tc,
5425                     pid,
5426                     q->address,
5427                     q->nt,
5428                     &me);
5429   }
5430   return GNUNET_OK;
5431 }
5432
5433
5434 /**
5435  * Initialize a monitor client.
5436  *
5437  * @param cls the client
5438  * @param start the start message that was sent
5439  */
5440 static void
5441 handle_monitor_start (void *cls,
5442                       const struct GNUNET_TRANSPORT_MonitorStart *start)
5443 {
5444   struct TransportClient *tc = cls;
5445
5446   if (CT_NONE != tc->type)
5447   {
5448     GNUNET_break (0);
5449     GNUNET_SERVICE_client_drop (tc->client);
5450     return;
5451   }
5452   tc->type = CT_MONITOR;
5453   tc->details.monitor.peer = start->peer;
5454   tc->details.monitor.one_shot = ntohl (start->one_shot);
5455   GNUNET_CONTAINER_multipeermap_iterate (neighbours,
5456                                          &notify_client_queues,
5457                                          tc);
5458   GNUNET_SERVICE_client_mark_monitor (tc->client);
5459   GNUNET_SERVICE_client_continue (tc->client);
5460 }
5461
5462
5463 /**
5464  * Find transport client providing communication service
5465  * for the protocol @a prefix.
5466  *
5467  * @param prefix communicator name
5468  * @return NULL if no such transport client is available
5469  */
5470 static struct TransportClient *
5471 lookup_communicator (const char *prefix)
5472 {
5473   for (struct TransportClient *tc = clients_head;
5474        NULL != tc;
5475        tc = tc->next)
5476   {
5477     if (CT_COMMUNICATOR != tc->type)
5478       continue;
5479     if (0 == strcmp (prefix,
5480                      tc->details.communicator.address_prefix))
5481       return tc;
5482   }
5483   GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
5484               "Somone suggested use of communicator for `%s', but we do not have such a communicator!\n",
5485               prefix);
5486   return NULL;
5487 }
5488
5489
5490 /**
5491  * Signature of a function called with a communicator @a address of a peer
5492  * @a pid that an application wants us to connect to.
5493  *
5494  * @param pid target peer
5495  * @param address the address to try
5496  */
5497 static void
5498 suggest_to_connect (const struct GNUNET_PeerIdentity *pid,
5499                     const char *address)
5500 {
5501   static uint32_t idgen;
5502   struct TransportClient *tc;
5503   char *prefix;
5504   struct GNUNET_TRANSPORT_CreateQueue *cqm;
5505   struct GNUNET_MQ_Envelope *env;
5506   size_t alen;
5507
5508   prefix = GNUNET_HELLO_address_to_prefix (address);
5509   if (NULL == prefix)
5510   {
5511     GNUNET_break (0); /* We got an invalid address!? */
5512     return;
5513   }
5514   tc = lookup_communicator (prefix);
5515   if (NULL == tc)
5516   {
5517     GNUNET_STATISTICS_update (GST_stats,
5518                               "# Suggestions ignored due to missing communicator",
5519                               1,
5520                               GNUNET_NO);
5521     return;
5522   }
5523   /* forward suggestion for queue creation to communicator */
5524   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5525               "Request #%u for `%s' communicator to create queue to `%s'\n",
5526               (unsigned int) idgen,
5527               prefix,
5528               address);
5529   alen = strlen (address) + 1;
5530   env = GNUNET_MQ_msg_extra (cqm,
5531                              alen,
5532                              GNUNET_MESSAGE_TYPE_TRANSPORT_QUEUE_CREATE);
5533   cqm->request_id = htonl (idgen++);
5534   cqm->receiver = *pid;
5535   memcpy (&cqm[1],
5536           address,
5537           alen);
5538   GNUNET_MQ_send (tc->mq,
5539                   env);
5540 }
5541
5542
5543 /**
5544  * The queue @a q (which matches the peer and address in @a vs) is
5545  * ready for queueing. We should now queue the validation request.
5546  *
5547  * @param q queue to send on
5548  * @param vs state to derive validation challenge from
5549  */
5550 static void
5551 validation_transmit_on_queue (struct Queue *q,
5552                               struct ValidationState *vs)
5553 {
5554   struct GNUNET_MQ_Envelope *env;
5555   struct TransportValidationChallenge *tvc;
5556
5557   vs->last_challenge_use = GNUNET_TIME_absolute_get ();
5558   env = GNUNET_MQ_msg (tvc,
5559                        GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_VALIDATION_CHALLENGE);
5560   tvc->reserved = htonl (0);
5561   tvc->challenge = vs->challenge;
5562   tvc->sender_time = GNUNET_TIME_absolute_hton (vs->last_challenge_use);
5563   GNUNET_MQ_send (q->tc->mq,
5564                   env);
5565 }
5566
5567
5568 /**
5569  * Task run periodically to validate some address based on #validation_heap.
5570  *
5571  * @param cls NULL
5572  */
5573 static void
5574 validation_start_cb (void *cls)
5575 {
5576   struct ValidationState *vs;
5577   struct Neighbour *n;
5578   struct Queue *q;
5579
5580   (void) cls;
5581   validation_task = NULL;
5582   vs = GNUNET_CONTAINER_heap_peek (validation_heap);
5583   /* drop validations past their expiration */
5584   while ( (NULL != vs) &&
5585           (0 == GNUNET_TIME_absolute_get_remaining (vs->valid_until).rel_value_us) )
5586   {
5587     free_validation_state (vs);
5588     vs = GNUNET_CONTAINER_heap_peek (validation_heap);
5589   }
5590   if (NULL == vs)
5591     return; /* woopsie, no more addresses known, should only
5592                happen if we're really a lonely peer */
5593   n = GNUNET_CONTAINER_multipeermap_get (neighbours,
5594                                          &vs->pid);
5595   q = NULL;
5596   if (NULL != n)
5597   {
5598     for (struct Queue *pos = n->queue_head;
5599          NULL != pos;
5600          pos = pos->next_neighbour)
5601     {
5602       if (0 == strcmp (pos->address,
5603                        vs->address))
5604       {
5605         q = pos;
5606         break;
5607       }
5608     }
5609   }
5610   if (NULL == q)
5611   {
5612     vs->awaiting_queue = GNUNET_YES;
5613     suggest_to_connect (&vs->pid,
5614                         vs->address);
5615   }
5616   else
5617     validation_transmit_on_queue (q,
5618                                   vs);
5619   /* Finally, reschedule next attempt */
5620   vs->challenge_backoff = GNUNET_TIME_randomized_backoff (vs->challenge_backoff,
5621                                                           MAX_VALIDATION_CHALLENGE_FREQ);
5622   update_next_challenge_time (vs,
5623                               GNUNET_TIME_relative_to_absolute (vs->challenge_backoff));
5624 }
5625
5626
5627 /**
5628  * A new queue has been created, check if any address validation
5629  * requests have been waiting for it.
5630  *
5631  * @param cls a `struct Queue`
5632  * @param pid peer concerned (unused)
5633  * @param value a `struct ValidationState`
5634  * @return #GNUNET_NO if a match was found and we can stop looking
5635  */
5636 static int
5637 check_validation_request_pending (void *cls,
5638                                   const struct GNUNET_PeerIdentity *pid,
5639                                   void *value)
5640 {
5641   struct Queue *q = cls;
5642   struct ValidationState *vs = value;
5643
5644   (void) pid;
5645   if ( (GNUNET_YES == vs->awaiting_queue) &&
5646        (0 == strcmp (vs->address,
5647                      q->address)) )
5648   {
5649     vs->awaiting_queue = GNUNET_NO;
5650     validation_transmit_on_queue (q,
5651                                   vs);
5652     return GNUNET_NO;
5653   }
5654   return GNUNET_OK;
5655 }
5656
5657
5658 /**
5659  * New queue became available.  Process the request.
5660  *
5661  * @param cls the client
5662  * @param aqm the send message that was sent
5663  */
5664 static void
5665 handle_add_queue_message (void *cls,
5666                           const struct GNUNET_TRANSPORT_AddQueueMessage *aqm)
5667 {
5668   struct TransportClient *tc = cls;
5669   struct Queue *queue;
5670   struct Neighbour *neighbour;
5671   const char *addr;
5672   uint16_t addr_len;
5673
5674   if (ntohl (aqm->mtu) <= sizeof (struct TransportFragmentBox))
5675   {
5676     /* MTU so small as to be useless for transmissions,
5677        required for #fragment_message()! */
5678     GNUNET_break_op (0);
5679     GNUNET_SERVICE_client_drop (tc->client);
5680     return;
5681   }
5682   neighbour = lookup_neighbour (&aqm->receiver);
5683   if (NULL == neighbour)
5684   {
5685     neighbour = GNUNET_new (struct Neighbour);
5686     neighbour->earliest_timeout = GNUNET_TIME_UNIT_FOREVER_ABS;
5687     neighbour->pid = aqm->receiver;
5688     GNUNET_assert (GNUNET_OK ==
5689                    GNUNET_CONTAINER_multipeermap_put (neighbours,
5690                                                       &neighbour->pid,
5691                                                       neighbour,
5692                                                       GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
5693     cores_send_connect_info (&neighbour->pid,
5694                              GNUNET_BANDWIDTH_ZERO);
5695   }
5696   addr_len = ntohs (aqm->header.size) - sizeof (*aqm);
5697   addr = (const char *) &aqm[1];
5698
5699   queue = GNUNET_malloc (sizeof (struct Queue) + addr_len);
5700   queue->tc = tc;
5701   queue->address = (const char *) &queue[1];
5702   queue->rtt = GNUNET_TIME_UNIT_FOREVER_REL;
5703   queue->qid = aqm->qid;
5704   queue->mtu = ntohl (aqm->mtu);
5705   queue->nt = (enum GNUNET_NetworkType) ntohl (aqm->nt);
5706   queue->cs = (enum GNUNET_TRANSPORT_ConnectionStatus) ntohl (aqm->cs);
5707   queue->neighbour = neighbour;
5708   GNUNET_BANDWIDTH_tracker_init2 (&queue->tracker_in,
5709                                   &tracker_update_in_cb,
5710                                   queue,
5711                                   GNUNET_BANDWIDTH_ZERO,
5712                                   GNUNET_CONSTANTS_MAX_BANDWIDTH_CARRY_S,
5713                                   &tracker_excess_in_cb,
5714                                   queue);
5715   GNUNET_BANDWIDTH_tracker_init2 (&queue->tracker_out,
5716                                   &tracker_update_out_cb,
5717                                   queue,
5718                                   GNUNET_BANDWIDTH_ZERO,
5719                                   GNUNET_CONSTANTS_MAX_BANDWIDTH_CARRY_S,
5720                                   &tracker_excess_out_cb,
5721                                   queue);
5722   memcpy (&queue[1],
5723           addr,
5724           addr_len);
5725   /* notify monitors about new queue */
5726   {
5727     struct MonitorEvent me = {
5728       .rtt = queue->rtt,
5729       .cs = queue->cs
5730     };
5731
5732     notify_monitors (&neighbour->pid,
5733                      queue->address,
5734                      queue->nt,
5735                      &me);
5736   }
5737   GNUNET_CONTAINER_MDLL_insert (neighbour,
5738                                 neighbour->queue_head,
5739                                 neighbour->queue_tail,
5740                                 queue);
5741   GNUNET_CONTAINER_MDLL_insert (client,
5742                                 tc->details.communicator.queue_head,
5743                                 tc->details.communicator.queue_tail,
5744                                 queue);
5745   /* check if valdiations are waiting for the queue */
5746   (void) GNUNET_CONTAINER_multipeermap_get_multiple (validation_map,
5747                                                      &aqm->receiver,
5748                                                      &check_validation_request_pending,
5749                                                      queue);
5750   GNUNET_SERVICE_client_continue (tc->client);
5751 }
5752
5753
5754 /**
5755  * Communicator tells us that our request to create a queue "worked", that
5756  * is setting up the queue is now in process.
5757  *
5758  * @param cls the `struct TransportClient`
5759  * @param cqr confirmation message
5760  */
5761 static void
5762 handle_queue_create_ok (void *cls,
5763                         const struct GNUNET_TRANSPORT_CreateQueueResponse *cqr)
5764 {
5765   struct TransportClient *tc = cls;
5766
5767   if (CT_COMMUNICATOR != tc->type)
5768   {
5769     GNUNET_break (0);
5770     GNUNET_SERVICE_client_drop (tc->client);
5771     return;
5772   }
5773   GNUNET_STATISTICS_update (GST_stats,
5774                             "# Suggestions succeeded at communicator",
5775                             1,
5776                             GNUNET_NO);
5777   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5778               "Request #%u for communicator to create queue succeeded\n",
5779               (unsigned int) ntohs (cqr->request_id));
5780   GNUNET_SERVICE_client_continue (tc->client);
5781 }
5782
5783
5784 /**
5785  * Communicator tells us that our request to create a queue failed. This usually
5786  * indicates that the provided address is simply invalid or that the communicator's
5787  * resources are exhausted.
5788  *
5789  * @param cls the `struct TransportClient`
5790  * @param cqr failure message
5791  */
5792 static void
5793 handle_queue_create_fail (void *cls,
5794                           const struct GNUNET_TRANSPORT_CreateQueueResponse *cqr)
5795 {
5796   struct TransportClient *tc = cls;
5797
5798   if (CT_COMMUNICATOR != tc->type)
5799   {
5800     GNUNET_break (0);
5801     GNUNET_SERVICE_client_drop (tc->client);
5802     return;
5803   }
5804   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5805               "Request #%u for communicator to create queue failed\n",
5806               (unsigned int) ntohs (cqr->request_id));
5807   GNUNET_STATISTICS_update (GST_stats,
5808                             "# Suggestions failed in queue creation at communicator",
5809                             1,
5810                             GNUNET_NO);
5811   GNUNET_SERVICE_client_continue (tc->client);
5812 }
5813
5814
5815 /**
5816  * We have received a `struct ExpressPreferenceMessage` from an application client.
5817  *
5818  * @param cls handle to the client
5819  * @param msg the start message
5820  */
5821 static void
5822 handle_suggest_cancel (void *cls,
5823                        const struct ExpressPreferenceMessage *msg)
5824 {
5825   struct TransportClient *tc = cls;
5826   struct PeerRequest *pr;
5827
5828   if (CT_APPLICATION != tc->type)
5829   {
5830     GNUNET_break (0);
5831     GNUNET_SERVICE_client_drop (tc->client);
5832     return;
5833   }
5834   pr = GNUNET_CONTAINER_multipeermap_get (tc->details.application.requests,
5835                                           &msg->peer);
5836   if (NULL == pr)
5837   {
5838     GNUNET_break (0);
5839     GNUNET_SERVICE_client_drop (tc->client);
5840     return;
5841   }
5842   (void) stop_peer_request (tc,
5843                             &pr->pid,
5844                             pr);
5845   GNUNET_SERVICE_client_continue (tc->client);
5846 }
5847
5848
5849 /**
5850  * Check #GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_CONSIDER_VERIFY
5851  * messages. We do nothing here, real verification is done later.
5852  *
5853  * @param cls a `struct TransportClient *`
5854  * @param msg message to verify
5855  * @return #GNUNET_OK
5856  */
5857 static int
5858 check_address_consider_verify (void *cls,
5859                                const struct GNUNET_TRANSPORT_AddressToVerify *hdr)
5860 {
5861   (void) cls;
5862   (void) hdr;
5863   return GNUNET_OK;
5864 }
5865
5866
5867 /**
5868  * Closure for #check_known_address.
5869  */
5870 struct CheckKnownAddressContext
5871 {
5872   /**
5873    * Set to the address we are looking for.
5874    */
5875   const char *address;
5876
5877   /**
5878    * Set to a matching validation state, if one was found.
5879    */
5880   struct ValidationState *vs;
5881 };
5882
5883
5884 /**
5885  * Test if the validation state in @a value matches the
5886  * address from @a cls.
5887  *
5888  * @param cls a `struct CheckKnownAddressContext`
5889  * @param pid unused (must match though)
5890  * @param value a `struct ValidationState`
5891  * @return #GNUNET_OK if not matching, #GNUNET_NO if match found
5892  */
5893 static int
5894 check_known_address (void *cls,
5895                      const struct GNUNET_PeerIdentity *pid,
5896                      void *value)
5897 {
5898   struct CheckKnownAddressContext *ckac = cls;
5899   struct ValidationState *vs = value;
5900
5901   (void) pid;
5902   if (0 != strcmp (vs->address,
5903                    ckac->address))
5904     return GNUNET_OK;
5905   ckac->vs = vs;
5906   return GNUNET_NO;
5907 }
5908
5909
5910 /**
5911  * Start address validation.
5912  *
5913  * @param pid peer the @a address is for
5914  * @param address an address to reach @a pid (presumably)
5915  * @param expiration when did @a pid claim @a address will become invalid
5916  */
5917 static void
5918 start_address_validation (const struct GNUNET_PeerIdentity *pid,
5919                           const char *address,
5920                           struct GNUNET_TIME_Absolute expiration)
5921 {
5922   struct GNUNET_TIME_Absolute now;
5923   struct ValidationState *vs;
5924   struct CheckKnownAddressContext ckac = {
5925     .address = address,
5926     .vs = NULL
5927   };
5928
5929   if (0 == GNUNET_TIME_absolute_get_remaining (expiration).rel_value_us)
5930     return; /* expired */
5931   (void) GNUNET_CONTAINER_multipeermap_get_multiple (validation_map,
5932                                                      pid,
5933                                                      &check_known_address,
5934                                                      &ckac);
5935   if (NULL != (vs = ckac.vs))
5936   {
5937     /* if 'vs' is not currently valid, we need to speed up retrying the validation */
5938     if (vs->validated_until.abs_value_us < vs->next_challenge.abs_value_us)
5939     {
5940       /* reduce backoff as we got a fresh advertisement */
5941       vs->challenge_backoff = GNUNET_TIME_relative_min (FAST_VALIDATION_CHALLENGE_FREQ,
5942                                                         GNUNET_TIME_relative_divide (vs->challenge_backoff,
5943                                                                                      2));
5944       update_next_challenge_time (vs,
5945                                   GNUNET_TIME_relative_to_absolute (vs->challenge_backoff));
5946     }
5947     return;
5948   }
5949   now = GNUNET_TIME_absolute_get();
5950   vs = GNUNET_new (struct ValidationState);
5951   vs->pid = *pid;
5952   vs->valid_until = expiration;
5953   vs->first_challenge_use = now;
5954   vs->validation_rtt = GNUNET_TIME_UNIT_FOREVER_REL;
5955   GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE,
5956                               &vs->challenge,
5957                               sizeof (vs->challenge));
5958   vs->address = GNUNET_strdup (address);
5959   GNUNET_assert (GNUNET_YES ==
5960                  GNUNET_CONTAINER_multipeermap_put (validation_map,
5961                                                     &vs->pid,
5962                                                     vs,
5963                                                     GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
5964   update_next_challenge_time (vs,
5965                               now);
5966 }
5967
5968
5969 /**
5970  * Function called by PEERSTORE for each matching record.
5971  *
5972  * @param cls closure
5973  * @param record peerstore record information
5974  * @param emsg error message, or NULL if no errors
5975  */
5976 static void
5977 handle_hello (void *cls,
5978               const struct GNUNET_PEERSTORE_Record *record,
5979               const char *emsg)
5980 {
5981   struct PeerRequest *pr = cls;
5982   const char *val;
5983
5984   if (NULL != emsg)
5985   {
5986     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
5987                 "Got failure from PEERSTORE: %s\n",
5988                 emsg);
5989     return;
5990   }
5991   val = record->value;
5992   if ( (0 == record->value_size) ||
5993        ('\0' != val[record->value_size - 1]) )
5994   {
5995     GNUNET_break (0);
5996     return;
5997   }
5998   start_address_validation (&pr->pid,
5999                             (const char *) record->value,
6000                             record->expiry);
6001 }
6002
6003
6004 /**
6005  * We have received a `struct ExpressPreferenceMessage` from an application client.
6006  *
6007  * @param cls handle to the client
6008  * @param msg the start message
6009  */
6010 static void
6011 handle_suggest (void *cls,
6012                 const struct ExpressPreferenceMessage *msg)
6013 {
6014   struct TransportClient *tc = cls;
6015   struct PeerRequest *pr;
6016
6017   if (CT_NONE == tc->type)
6018   {
6019     tc->type = CT_APPLICATION;
6020     tc->details.application.requests
6021       = GNUNET_CONTAINER_multipeermap_create (16,
6022                                               GNUNET_YES);
6023   }
6024   if (CT_APPLICATION != tc->type)
6025   {
6026     GNUNET_break (0);
6027     GNUNET_SERVICE_client_drop (tc->client);
6028     return;
6029   }
6030   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
6031               "Client suggested we talk to %s with preference %d at rate %u\n",
6032               GNUNET_i2s (&msg->peer),
6033               (int) ntohl (msg->pk),
6034               (int) ntohl (msg->bw.value__));
6035   pr = GNUNET_new (struct PeerRequest);
6036   pr->tc = tc;
6037   pr->pid = msg->peer;
6038   pr->bw = msg->bw;
6039   pr->pk = (enum GNUNET_MQ_PreferenceKind) ntohl (msg->pk);
6040   if (GNUNET_YES !=
6041       GNUNET_CONTAINER_multipeermap_put (tc->details.application.requests,
6042                                          &pr->pid,
6043                                          pr,
6044                                          GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
6045   {
6046     GNUNET_break (0);
6047     GNUNET_free (pr);
6048     GNUNET_SERVICE_client_drop (tc->client);
6049     return;
6050   }
6051   pr->wc = GNUNET_PEERSTORE_watch (peerstore,
6052                                    "transport",
6053                                    &pr->pid,
6054                                    GNUNET_PEERSTORE_TRANSPORT_URLADDRESS_KEY,
6055                                    &handle_hello,
6056                                    pr);
6057   GNUNET_SERVICE_client_continue (tc->client);
6058 }
6059
6060
6061 /**
6062  * Given another peers address, consider checking it for validity
6063  * and then adding it to the Peerstore.
6064  *
6065  * @param cls a `struct TransportClient`
6066  * @param hdr message containing the raw address data and
6067  *        signature in the body, see #GNUNET_HELLO_extract_address()
6068  */
6069 static void
6070 handle_address_consider_verify (void *cls,
6071                                 const struct GNUNET_TRANSPORT_AddressToVerify *hdr)
6072 {
6073   struct TransportClient *tc = cls;
6074   char *address;
6075   enum GNUNET_NetworkType nt;
6076   struct GNUNET_TIME_Absolute expiration;
6077
6078   (void) cls;
6079   // FIXME: checking that we know this address already should
6080   //        be done BEFORE checking the signature => HELLO API change!
6081   // FIXME: pre-check: rate-limit signature verification / validation?!
6082   address = GNUNET_HELLO_extract_address (&hdr[1],
6083                                           ntohs (hdr->header.size) - sizeof (*hdr),
6084                                           &hdr->peer,
6085                                           &nt,
6086                                           &expiration);
6087   if (NULL == address)
6088   {
6089     GNUNET_break_op (0);
6090     return;
6091   }
6092   start_address_validation (&hdr->peer,
6093                             address,
6094                             expiration);
6095   GNUNET_free (address);
6096   GNUNET_SERVICE_client_continue (tc->client);
6097 }
6098
6099
6100 /**
6101  * Check #GNUNET_MESSAGE_TYPE_TRANSPORT_REQUEST_HELLO_VALIDATION
6102  * messages.
6103  *
6104  * @param cls a `struct TransportClient *`
6105  * @param m message to verify
6106  * @return #GNUNET_OK on success
6107  */
6108 static int
6109 check_request_hello_validation (void *cls,
6110                                 const struct RequestHelloValidationMessage *m)
6111 {
6112   GNUNET_MQ_check_zero_termination (m);
6113   return GNUNET_OK;
6114 }
6115
6116
6117 /**
6118  * A client encountered an address of another peer. Consider validating it,
6119  * and if validation succeeds, persist it to PEERSTORE.
6120  *
6121  * @param cls a `struct TransportClient *`
6122  * @param m message to verify
6123  */
6124 static void
6125 handle_request_hello_validation (void *cls,
6126                                  const struct RequestHelloValidationMessage *m)
6127 {
6128   struct TransportClient *tc = cls;
6129
6130   start_address_validation (&m->peer,
6131                             (const char *) &m[1],
6132                             GNUNET_TIME_absolute_ntoh (m->expiration));
6133   GNUNET_SERVICE_client_continue (tc->client);
6134 }
6135
6136
6137 /**
6138  * Free neighbour entry.
6139  *
6140  * @param cls NULL
6141  * @param pid unused
6142  * @param value a `struct Neighbour`
6143  * @return #GNUNET_OK (always)
6144  */
6145 static int
6146 free_neighbour_cb (void *cls,
6147                    const struct GNUNET_PeerIdentity *pid,
6148                    void *value)
6149 {
6150   struct Neighbour *neighbour = value;
6151
6152   (void) cls;
6153   (void) pid;
6154   GNUNET_break (0); // should this ever happen?
6155   free_neighbour (neighbour);
6156
6157   return GNUNET_OK;
6158 }
6159
6160
6161 /**
6162  * Free DV route entry.
6163  *
6164  * @param cls NULL
6165  * @param pid unused
6166  * @param value a `struct DistanceVector`
6167  * @return #GNUNET_OK (always)
6168  */
6169 static int
6170 free_dv_routes_cb (void *cls,
6171                    const struct GNUNET_PeerIdentity *pid,
6172                    void *value)
6173 {
6174   struct DistanceVector *dv = value;
6175
6176   (void) cls;
6177   (void) pid;
6178   free_dv_route (dv);
6179
6180   return GNUNET_OK;
6181 }
6182
6183
6184 /**
6185  * Free ephemeral entry.
6186  *
6187  * @param cls NULL
6188  * @param pid unused
6189  * @param value a `struct EphemeralCacheEntry`
6190  * @return #GNUNET_OK (always)
6191  */
6192 static int
6193 free_ephemeral_cb (void *cls,
6194                    const struct GNUNET_PeerIdentity *pid,
6195                    void *value)
6196 {
6197   struct EphemeralCacheEntry *ece = value;
6198
6199   (void) cls;
6200   (void) pid;
6201   free_ephemeral (ece);
6202   return GNUNET_OK;
6203 }
6204
6205
6206 /**
6207  * Free validation state.
6208  *
6209  * @param cls NULL
6210  * @param pid unused
6211  * @param value a `struct ValidationState`
6212  * @return #GNUNET_OK (always)
6213  */
6214 static int
6215 free_validation_state_cb (void *cls,
6216                           const struct GNUNET_PeerIdentity *pid,
6217                           void *value)
6218 {
6219   struct ValidationState *vs = value;
6220
6221   (void) cls;
6222   (void) pid;
6223   free_validation_state (vs);
6224   return GNUNET_OK;
6225 }
6226
6227
6228 /**
6229  * Function called when the service shuts down.  Unloads our plugins
6230  * and cancels pending validations.
6231  *
6232  * @param cls closure, unused
6233  */
6234 static void
6235 do_shutdown (void *cls)
6236 {
6237   (void) cls;
6238
6239   if (NULL != ephemeral_task)
6240   {
6241     GNUNET_SCHEDULER_cancel (ephemeral_task);
6242     ephemeral_task = NULL;
6243   }
6244   GNUNET_CONTAINER_multipeermap_iterate (neighbours,
6245                                          &free_neighbour_cb,
6246                                          NULL);
6247   if (NULL != peerstore)
6248   {
6249     GNUNET_PEERSTORE_disconnect (peerstore,
6250                                  GNUNET_NO);
6251     peerstore = NULL;
6252   }
6253   if (NULL != GST_stats)
6254   {
6255     GNUNET_STATISTICS_destroy (GST_stats,
6256                                GNUNET_NO);
6257     GST_stats = NULL;
6258   }
6259   if (NULL != GST_my_private_key)
6260   {
6261     GNUNET_free (GST_my_private_key);
6262     GST_my_private_key = NULL;
6263   }
6264   GNUNET_CONTAINER_multipeermap_destroy (neighbours);
6265   neighbours = NULL;
6266   GNUNET_CONTAINER_multipeermap_iterate (validation_map,
6267                                          &free_validation_state_cb,
6268                                          NULL);
6269   GNUNET_CONTAINER_multipeermap_destroy (validation_map);
6270   validation_map = NULL;
6271   GNUNET_CONTAINER_heap_destroy (validation_heap);
6272   validation_heap = NULL;
6273   GNUNET_CONTAINER_multipeermap_iterate (dv_routes,
6274                                          &free_dv_routes_cb,
6275                                          NULL);
6276   GNUNET_CONTAINER_multipeermap_destroy (dv_routes);
6277   dv_routes = NULL;
6278   GNUNET_CONTAINER_multipeermap_iterate (ephemeral_map,
6279                                          &free_ephemeral_cb,
6280                                          NULL);
6281   GNUNET_CONTAINER_multipeermap_destroy (ephemeral_map);
6282   ephemeral_map = NULL;
6283   GNUNET_CONTAINER_heap_destroy (ephemeral_heap);
6284   ephemeral_heap = NULL;
6285 }
6286
6287
6288 /**
6289  * Initiate transport service.
6290  *
6291  * @param cls closure
6292  * @param c configuration to use
6293  * @param service the initialized service
6294  */
6295 static void
6296 run (void *cls,
6297      const struct GNUNET_CONFIGURATION_Handle *c,
6298      struct GNUNET_SERVICE_Handle *service)
6299 {
6300   (void) cls;
6301   /* setup globals */
6302   GST_cfg = c;
6303   neighbours = GNUNET_CONTAINER_multipeermap_create (1024,
6304                                                      GNUNET_YES);
6305   dv_routes = GNUNET_CONTAINER_multipeermap_create (1024,
6306                                                     GNUNET_YES);
6307   ephemeral_map = GNUNET_CONTAINER_multipeermap_create (32,
6308                                                         GNUNET_YES);
6309   ephemeral_heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
6310   validation_map = GNUNET_CONTAINER_multipeermap_create (1024,
6311                                                          GNUNET_YES);
6312   validation_heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
6313   GST_my_private_key = GNUNET_CRYPTO_eddsa_key_create_from_configuration (GST_cfg);
6314   if (NULL == GST_my_private_key)
6315   {
6316     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
6317                 _("Transport service is lacking key configuration settings. Exiting.\n"));
6318     GNUNET_SCHEDULER_shutdown ();
6319     return;
6320   }
6321   GNUNET_CRYPTO_eddsa_key_get_public (GST_my_private_key,
6322                                       &GST_my_identity.public_key);
6323   GNUNET_log(GNUNET_ERROR_TYPE_INFO,
6324              "My identity is `%s'\n",
6325              GNUNET_i2s_full (&GST_my_identity));
6326   GST_stats = GNUNET_STATISTICS_create ("transport",
6327                                         GST_cfg);
6328   GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
6329                                  NULL);
6330   peerstore = GNUNET_PEERSTORE_connect (GST_cfg);
6331   if (NULL == peerstore)
6332   {
6333     GNUNET_break (0);
6334     GNUNET_SCHEDULER_shutdown ();
6335     return;
6336   }
6337 }
6338
6339
6340 /**
6341  * Define "main" method using service macro.
6342  */
6343 GNUNET_SERVICE_MAIN
6344 ("transport",
6345  GNUNET_SERVICE_OPTION_SOFT_SHUTDOWN,
6346  &run,
6347  &client_connect_cb,
6348  &client_disconnect_cb,
6349  NULL,
6350  /* communication with applications */
6351  GNUNET_MQ_hd_fixed_size (suggest,
6352                           GNUNET_MESSAGE_TYPE_TRANSPORT_SUGGEST,
6353                           struct ExpressPreferenceMessage,
6354                           NULL),
6355  GNUNET_MQ_hd_fixed_size (suggest_cancel,
6356                           GNUNET_MESSAGE_TYPE_TRANSPORT_SUGGEST_CANCEL,
6357                           struct ExpressPreferenceMessage,
6358                           NULL),
6359  GNUNET_MQ_hd_var_size (request_hello_validation,
6360                         GNUNET_MESSAGE_TYPE_TRANSPORT_REQUEST_HELLO_VALIDATION,
6361                         struct RequestHelloValidationMessage,
6362                         NULL),
6363  /* communication with core */
6364  GNUNET_MQ_hd_fixed_size (client_start,
6365                           GNUNET_MESSAGE_TYPE_TRANSPORT_START,
6366                           struct StartMessage,
6367                           NULL),
6368  GNUNET_MQ_hd_var_size (client_send,
6369                         GNUNET_MESSAGE_TYPE_TRANSPORT_SEND,
6370                         struct OutboundMessage,
6371                         NULL),
6372  /* communication with communicators */
6373  GNUNET_MQ_hd_var_size (communicator_available,
6374                         GNUNET_MESSAGE_TYPE_TRANSPORT_NEW_COMMUNICATOR,
6375                         struct GNUNET_TRANSPORT_CommunicatorAvailableMessage,
6376                         NULL),
6377  GNUNET_MQ_hd_var_size (communicator_backchannel,
6378                         GNUNET_MESSAGE_TYPE_TRANSPORT_COMMUNICATOR_BACKCHANNEL,
6379                         struct GNUNET_TRANSPORT_CommunicatorBackchannel,
6380                         NULL),
6381  GNUNET_MQ_hd_var_size (add_address,
6382                         GNUNET_MESSAGE_TYPE_TRANSPORT_ADD_ADDRESS,
6383                         struct GNUNET_TRANSPORT_AddAddressMessage,
6384                         NULL),
6385  GNUNET_MQ_hd_fixed_size (del_address,
6386                           GNUNET_MESSAGE_TYPE_TRANSPORT_DEL_ADDRESS,
6387                           struct GNUNET_TRANSPORT_DelAddressMessage,
6388                           NULL),
6389  GNUNET_MQ_hd_var_size (incoming_msg,
6390                         GNUNET_MESSAGE_TYPE_TRANSPORT_INCOMING_MSG,
6391                         struct GNUNET_TRANSPORT_IncomingMessage,
6392                         NULL),
6393  GNUNET_MQ_hd_fixed_size (queue_create_ok,
6394                           GNUNET_MESSAGE_TYPE_TRANSPORT_QUEUE_CREATE_OK,
6395                           struct GNUNET_TRANSPORT_CreateQueueResponse,
6396                           NULL),
6397  GNUNET_MQ_hd_fixed_size (queue_create_fail,
6398                           GNUNET_MESSAGE_TYPE_TRANSPORT_QUEUE_CREATE_FAIL,
6399                           struct GNUNET_TRANSPORT_CreateQueueResponse,
6400                           NULL),
6401  GNUNET_MQ_hd_var_size (add_queue_message,
6402                         GNUNET_MESSAGE_TYPE_TRANSPORT_QUEUE_SETUP,
6403                         struct GNUNET_TRANSPORT_AddQueueMessage,
6404                         NULL),
6405  GNUNET_MQ_hd_var_size (address_consider_verify,
6406                         GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_CONSIDER_VERIFY,
6407                         struct GNUNET_TRANSPORT_AddressToVerify,
6408                         NULL),
6409  GNUNET_MQ_hd_fixed_size (del_queue_message,
6410                           GNUNET_MESSAGE_TYPE_TRANSPORT_QUEUE_TEARDOWN,
6411                           struct GNUNET_TRANSPORT_DelQueueMessage,
6412                           NULL),
6413  GNUNET_MQ_hd_fixed_size (send_message_ack,
6414                           GNUNET_MESSAGE_TYPE_TRANSPORT_SEND_MSG_ACK,
6415                           struct GNUNET_TRANSPORT_SendMessageToAck,
6416                           NULL),
6417  /* communication with monitors */
6418  GNUNET_MQ_hd_fixed_size (monitor_start,
6419                           GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_START,
6420                           struct GNUNET_TRANSPORT_MonitorStart,
6421                           NULL),
6422  GNUNET_MQ_handler_end ());
6423
6424
6425 /* end of file gnunet-service-transport.c */