hxing typemap
[oweals/gnunet.git] / src / core / gnunet-service-core.c
1 /*
2      This file is part of GNUnet.
3      (C) 2009, 2010 Christian Grothoff (and other contributing authors)
4
5      GNUnet is free software; you can redistribute it and/or modify
6      it under the terms of the GNU General Public License as published
7      by the Free Software Foundation; either version 3, or (at your
8      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      General Public License for more details.
14
15      You should have received a copy of the GNU General Public License
16      along with GNUnet; see the file COPYING.  If not, write to the
17      Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18      Boston, MA 02111-1307, USA.
19 */
20
21 /**
22  * @file core/gnunet-service-core.c
23  * @brief high-level P2P messaging
24  * @author Christian Grothoff
25  *
26  * Type map implementation:
27  * - track type maps for neighbours (can wait)
28  * - only notify clients about peers with matching type maps (can wait)
29  *
30  * Considerations for later:
31  * - check that hostkey used by transport (for HELLOs) is the
32  *   same as the hostkey that we are using!
33  */
34 #include "platform.h"
35 #include <zlib.h>
36 #include "gnunet_constants.h"
37 #include "gnunet_util_lib.h"
38 #include "gnunet_hello_lib.h"
39 #include "gnunet_peerinfo_service.h"
40 #include "gnunet_protocols.h"
41 #include "gnunet_signatures.h"
42 #include "gnunet_statistics_service.h"
43 #include "gnunet_transport_service.h"
44 #include "core.h"
45
46
47 #define DEBUG_HANDSHAKE GNUNET_EXTRA_LOGGING
48
49 #define DEBUG_CORE_QUOTA GNUNET_EXTRA_LOGGING
50
51 /**
52  * Receive and send buffer windows grow over time.  For
53  * how long can 'unused' bandwidth accumulate before we
54  * need to cap it?  (specified in seconds).
55  */
56 #define MAX_WINDOW_TIME_S (5 * 60)
57
58 /**
59  * How many messages do we queue up at most for optional
60  * notifications to a client?  (this can cause notifications
61  * about outgoing messages to be dropped).
62  */
63 #define MAX_NOTIFY_QUEUE 1024
64
65 /**
66  * Minimum bandwidth (out) to assign to any connected peer.
67  * Should be rather low; values larger than DEFAULT_BW_IN_OUT make no
68  * sense.
69  */
70 #define MIN_BANDWIDTH_PER_PEER GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT
71
72 /**
73  * After how much time past the "official" expiration time do
74  * we discard messages?  Should not be zero since we may
75  * intentionally defer transmission until close to the deadline
76  * and then may be slightly past the deadline due to inaccuracy
77  * in sleep and our own CPU consumption.
78  */
79 #define PAST_EXPIRATION_DISCARD_TIME GNUNET_TIME_UNIT_SECONDS
80
81 /**
82  * What is the maximum delay for a SET_KEY message?
83  */
84 #define MAX_SET_KEY_DELAY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10)
85
86 /**
87  * How long do we wait for SET_KEY confirmation initially?
88  */
89 #define INITIAL_SET_KEY_RETRY_FREQUENCY GNUNET_TIME_relative_multiply (MAX_SET_KEY_DELAY, 1)
90
91 /**
92  * What is the maximum delay for a PING message?
93  */
94 #define MAX_PING_DELAY GNUNET_TIME_relative_multiply (MAX_SET_KEY_DELAY, 2)
95
96 /**
97  * What is the maximum delay for a PONG message?
98  */
99 #define MAX_PONG_DELAY GNUNET_TIME_relative_multiply (MAX_PING_DELAY, 2)
100
101 /**
102  * What is the minimum frequency for a PING message?
103  */
104 #define MIN_PING_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5)
105
106 /**
107  * How often do we recalculate bandwidth quotas?
108  */
109 #define QUOTA_UPDATE_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5)
110
111 /**
112  * What is the priority for a SET_KEY message?
113  */
114 #define SET_KEY_PRIORITY 0xFFFFFF
115
116 /**
117  * What is the priority for a PING message?
118  */
119 #define PING_PRIORITY 0xFFFFFF
120
121 /**
122  * What is the priority for a PONG message?
123  */
124 #define PONG_PRIORITY 0xFFFFFF
125
126 /**
127  * How many messages do we queue per peer at most?  Must be at
128  * least two.
129  */
130 #define MAX_PEER_QUEUE_SIZE 16
131
132 /**
133  * How many non-mandatory messages do we queue per client at most?
134  */
135 #define MAX_CLIENT_QUEUE_SIZE 32
136
137 /**
138  * What is the maximum age of a message for us to consider
139  * processing it?  Note that this looks at the timestamp used
140  * by the other peer, so clock skew between machines does
141  * come into play here.  So this should be picked high enough
142  * so that a little bit of clock skew does not prevent peers
143  * from connecting to us.
144  */
145 #define MAX_MESSAGE_AGE GNUNET_TIME_UNIT_DAYS
146
147
148 /**
149  * State machine for our P2P encryption handshake.  Everyone starts in
150  * "DOWN", if we receive the other peer's key (other peer initiated)
151  * we start in state RECEIVED (since we will immediately send our
152  * own); otherwise we start in SENT.  If we get back a PONG from
153  * within either state, we move up to CONFIRMED (the PONG will always
154  * be sent back encrypted with the key we sent to the other peer).
155  */
156 enum PeerStateMachine
157 {
158   /**
159    * No handshake yet.
160    */
161   PEER_STATE_DOWN,
162
163   /**
164    * We've sent our session key.
165    */
166   PEER_STATE_KEY_SENT,
167
168   /**
169    * We've received the other peers session key.
170    */
171   PEER_STATE_KEY_RECEIVED,
172
173   /**
174    * The other peer has confirmed our session key with a message
175    * encrypted with his session key (which we got).  Session is now fully up.
176    */
177   PEER_STATE_KEY_CONFIRMED
178 };
179
180
181 /**
182  * Encapsulation for encrypted messages exchanged between
183  * peers.  Followed by the actual encrypted data.
184  */
185 struct EncryptedMessage
186 {
187   /**
188    * Message type is either CORE_ENCRYPTED_MESSAGE.
189    */
190   struct GNUNET_MessageHeader header;
191
192   /**
193    * Random value used for IV generation.
194    */
195   uint32_t iv_seed GNUNET_PACKED;
196
197   /**
198    * MAC of the encrypted message (starting at 'sequence_number'),
199    * used to verify message integrity. Everything after this value
200    * (excluding this value itself) will be encrypted and authenticated.
201    * ENCRYPTED_HEADER_SIZE must be set to the offset of the *next* field.
202    */
203   GNUNET_HashCode hmac;
204
205   /**
206    * Sequence number, in network byte order.  This field
207    * must be the first encrypted/decrypted field
208    */
209   uint32_t sequence_number GNUNET_PACKED;
210
211   /**
212    * Desired bandwidth (how much we should send to this peer / how
213    * much is the sender willing to receive)?
214    */
215   struct GNUNET_BANDWIDTH_Value32NBO inbound_bw_limit;
216
217   /**
218    * Timestamp.  Used to prevent reply of ancient messages
219    * (recent messages are caught with the sequence number).
220    */
221   struct GNUNET_TIME_AbsoluteNBO timestamp;
222
223 };
224
225
226 /**
227  * Number of bytes (at the beginning) of "struct EncryptedMessage"
228  * that are NOT encrypted.
229  */
230 #define ENCRYPTED_HEADER_SIZE (offsetof(struct EncryptedMessage, sequence_number))
231
232
233 /**
234  * We're sending an (encrypted) PING to the other peer to check if he
235  * can decrypt.  The other peer should respond with a PONG with the
236  * same content, except this time encrypted with the receiver's key.
237  */
238 struct PingMessage
239 {
240   /**
241    * Message type is CORE_PING.
242    */
243   struct GNUNET_MessageHeader header;
244
245   /**
246    * Seed for the IV
247    */
248   uint32_t iv_seed GNUNET_PACKED;
249
250   /**
251    * Intended target of the PING, used primarily to check
252    * that decryption actually worked.
253    */
254   struct GNUNET_PeerIdentity target;
255
256   /**
257    * Random number chosen to make reply harder.
258    */
259   uint32_t challenge GNUNET_PACKED;
260 };
261
262
263
264 /**
265  * Response to a PING.  Includes data from the original PING
266  * plus initial bandwidth quota information.
267  */
268 struct PongMessage
269 {
270   /**
271    * Message type is CORE_PONG.
272    */
273   struct GNUNET_MessageHeader header;
274
275   /**
276    * Seed for the IV
277    */
278   uint32_t iv_seed GNUNET_PACKED;
279
280   /**
281    * Random number to make faking the reply harder.  Must be
282    * first field after header (this is where we start to encrypt!).
283    */
284   uint32_t challenge GNUNET_PACKED;
285
286   /**
287    * Desired bandwidth (how much we should send to this
288    * peer / how much is the sender willing to receive).
289    */
290   struct GNUNET_BANDWIDTH_Value32NBO inbound_bw_limit;
291
292   /**
293    * Intended target of the PING, used primarily to check
294    * that decryption actually worked.
295    */
296   struct GNUNET_PeerIdentity target;
297 };
298
299
300 /**
301  * Message transmitted to set (or update) a session key.
302  */
303 struct SetKeyMessage
304 {
305
306   /**
307    * Message type is either CORE_SET_KEY.
308    */
309   struct GNUNET_MessageHeader header;
310
311   /**
312    * Status of the sender (should be in "enum PeerStateMachine"), nbo.
313    */
314   int32_t sender_status GNUNET_PACKED;
315
316   /**
317    * Purpose of the signature, will be
318    * GNUNET_SIGNATURE_PURPOSE_SET_KEY.
319    */
320   struct GNUNET_CRYPTO_RsaSignaturePurpose purpose;
321
322   /**
323    * At what time was this key created?
324    */
325   struct GNUNET_TIME_AbsoluteNBO creation_time;
326
327   /**
328    * The encrypted session key.
329    */
330   struct GNUNET_CRYPTO_RsaEncryptedData encrypted_key;
331
332   /**
333    * Who is the intended recipient?
334    */
335   struct GNUNET_PeerIdentity target;
336
337   /**
338    * Signature of the stuff above (starting at purpose).
339    */
340   struct GNUNET_CRYPTO_RsaSignature signature;
341
342 };
343
344
345 /**
346  * Message waiting for transmission. This struct
347  * is followed by the actual content of the message.
348  */
349 struct MessageEntry
350 {
351
352   /**
353    * We keep messages in a doubly linked list.
354    */
355   struct MessageEntry *next;
356
357   /**
358    * We keep messages in a doubly linked list.
359    */
360   struct MessageEntry *prev;
361
362   /**
363    * By when are we supposed to transmit this message?
364    */
365   struct GNUNET_TIME_Absolute deadline;
366
367   /**
368    * By when are we supposed to transmit this message (after
369    * giving slack)?
370    */
371   struct GNUNET_TIME_Absolute slack_deadline;
372
373   /**
374    * How important is this message to us?
375    */
376   unsigned int priority;
377
378   /**
379    * If this is a SET_KEY message, what was our connection status when this
380    * message was queued?
381    */
382   enum PeerStateMachine sender_status;
383
384   /**
385    * Is this a SET_KEY message?
386    */
387   int is_setkey;
388
389   /**
390    * How long is the message? (number of bytes following
391    * the "struct MessageEntry", but not including the
392    * size of "struct MessageEntry" itself!)
393    */
394   uint16_t size;
395
396   /**
397    * Was this message selected for transmission in the
398    * current round? GNUNET_YES or GNUNET_NO.
399    */
400   int8_t do_transmit;
401
402   /**
403    * Did we give this message some slack (delayed sending) previously
404    * (and hence should not give it any more slack)? GNUNET_YES or
405    * GNUNET_NO.
406    */
407   int8_t got_slack;
408
409 };
410
411
412 /**
413  * Record kept for each request for transmission issued by a
414  * client that is still pending.
415  */
416 struct ClientActiveRequest;
417
418 /**
419  * Data kept per neighbouring peer.
420  */
421 struct Neighbour
422 {
423
424   /**
425    * Unencrypted messages destined for this peer.
426    */
427   struct MessageEntry *messages;
428
429   /**
430    * Head of the batched, encrypted message queue (already ordered,
431    * transmit starting with the head).
432    */
433   struct MessageEntry *encrypted_head;
434
435   /**
436    * Tail of the batched, encrypted message queue (already ordered,
437    * append new messages to tail)
438    */
439   struct MessageEntry *encrypted_tail;
440
441   /**
442    * Head of list of requests from clients for transmission to
443    * this peer.
444    */
445   struct ClientActiveRequest *active_client_request_head;
446
447   /**
448    * Tail of list of requests from clients for transmission to
449    * this peer.
450    */
451   struct ClientActiveRequest *active_client_request_tail;
452
453   /**
454    * Handle for pending requests for transmission to this peer
455    * with the transport service.  NULL if no request is pending.
456    */
457   struct GNUNET_TRANSPORT_TransmitHandle *th;
458
459   /**
460    * Public key of the neighbour, NULL if we don't have it yet.
461    */
462   struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *public_key;
463
464   /**
465    * We received a PING message before we got the "public_key"
466    * (or the SET_KEY).  We keep it here until we have a key
467    * to decrypt it.  NULL if no PING is pending.
468    */
469   struct PingMessage *pending_ping;
470
471   /**
472    * We received a PONG message before we got the "public_key"
473    * (or the SET_KEY).  We keep it here until we have a key
474    * to decrypt it.  NULL if no PONG is pending.
475    */
476   struct PongMessage *pending_pong;
477
478   /**
479    * Non-NULL if we are currently looking up HELLOs for this peer.
480    * for this peer.
481    */
482   struct GNUNET_PEERINFO_IteratorContext *pitr;
483
484   /**
485    * SetKeyMessage to transmit, NULL if we are not currently trying
486    * to send one.
487    */
488   struct SetKeyMessage *skm;
489
490   /**
491    * Performance data for the peer.
492    */
493   struct GNUNET_TRANSPORT_ATS_Information *ats;
494
495   /**
496    * Identity of the neighbour.
497    */
498   struct GNUNET_PeerIdentity peer;
499
500   /**
501    * Key we use to encrypt our messages for the other peer
502    * (initialized by us when we do the handshake).
503    */
504   struct GNUNET_CRYPTO_AesSessionKey encrypt_key;
505
506   /**
507    * Key we use to decrypt messages from the other peer
508    * (given to us by the other peer during the handshake).
509    */
510   struct GNUNET_CRYPTO_AesSessionKey decrypt_key;
511
512   /**
513    * ID of task used for re-trying plaintext scheduling.
514    */
515   GNUNET_SCHEDULER_TaskIdentifier retry_plaintext_task;
516
517   /**
518    * ID of task used for re-trying SET_KEY and PING message.
519    */
520   GNUNET_SCHEDULER_TaskIdentifier retry_set_key_task;
521
522   /**
523    * ID of task used for updating bandwidth quota for this neighbour.
524    */
525   GNUNET_SCHEDULER_TaskIdentifier quota_update_task;
526
527   /**
528    * ID of task used for sending keep-alive pings.
529    */
530   GNUNET_SCHEDULER_TaskIdentifier keep_alive_task;
531
532   /**
533    * ID of task used for cleaning up dead neighbour entries.
534    */
535   GNUNET_SCHEDULER_TaskIdentifier dead_clean_task;
536
537   /**
538    * At what time did we generate our encryption key?
539    */
540   struct GNUNET_TIME_Absolute encrypt_key_created;
541
542   /**
543    * At what time did the other peer generate the decryption key?
544    */
545   struct GNUNET_TIME_Absolute decrypt_key_created;
546
547   /**
548    * At what time did we initially establish (as in, complete session
549    * key handshake) this connection?  Should be zero if status != KEY_CONFIRMED.
550    */
551   struct GNUNET_TIME_Absolute time_established;
552
553   /**
554    * At what time did we last receive an encrypted message from the
555    * other peer?  Should be zero if status != KEY_CONFIRMED.
556    */
557   struct GNUNET_TIME_Absolute last_activity;
558
559   /**
560    * At what frequency are we currently re-trying SET_KEY messages?
561    */
562   struct GNUNET_TIME_Relative set_key_retry_frequency;
563
564   /**
565    * Tracking bandwidth for sending to this peer.
566    */
567   struct GNUNET_BANDWIDTH_Tracker available_send_window;
568
569   /**
570    * Tracking bandwidth for receiving from this peer.
571    */
572   struct GNUNET_BANDWIDTH_Tracker available_recv_window;
573
574   /**
575    * How valueable were the messages of this peer recently?
576    */
577   unsigned long long current_preference;
578
579   /**
580    * Number of entries in 'ats'.
581    */
582   unsigned int ats_count;
583
584   /**
585    * Bit map indicating which of the 32 sequence numbers before the last
586    * were received (good for accepting out-of-order packets and
587    * estimating reliability of the connection)
588    */
589   unsigned int last_packets_bitmap;
590
591   /**
592    * last sequence number received on this connection (highest)
593    */
594   uint32_t last_sequence_number_received;
595
596   /**
597    * last sequence number transmitted
598    */
599   uint32_t last_sequence_number_sent;
600
601   /**
602    * Available bandwidth in for this peer (current target).
603    */
604   struct GNUNET_BANDWIDTH_Value32NBO bw_in;
605
606   /**
607    * Available bandwidth out for this peer (current target).
608    */
609   struct GNUNET_BANDWIDTH_Value32NBO bw_out;
610
611   /**
612    * Internal bandwidth limit set for this peer (initially typically
613    * set to "-1").  Actual "bw_out" is MIN of
614    * "bpm_out_internal_limit" and "bw_out_external_limit".
615    */
616   struct GNUNET_BANDWIDTH_Value32NBO bw_out_internal_limit;
617
618   /**
619    * External bandwidth limit set for this peer by the
620    * peer that we are communicating with.  "bw_out" is MIN of
621    * "bw_out_internal_limit" and "bw_out_external_limit".
622    */
623   struct GNUNET_BANDWIDTH_Value32NBO bw_out_external_limit;
624
625   /**
626    * What was our PING challenge number (for this peer)?
627    */
628   uint32_t ping_challenge;
629
630   /**
631    * What is our connection status?
632    */
633   enum PeerStateMachine status;
634
635   /**
636    * Are we currently connected to this neighbour?
637    */
638   int is_connected;
639
640 };
641
642
643 /**
644  * Data structure for each client connected to the core service.
645  */
646 struct Client
647 {
648   /**
649    * Clients are kept in a linked list.
650    */
651   struct Client *next;
652
653   /**
654    * Handle for the client with the server API.
655    */
656   struct GNUNET_SERVER_Client *client_handle;
657
658   /**
659    * Array of the types of messages this peer cares
660    * about (with "tcnt" entries).  Allocated as part
661    * of this client struct, do not free!
662    */
663   const uint16_t *types;
664
665   /**
666    * Map of peer identities to active transmission requests of this
667    * client to the peer (of type 'struct ClientActiveRequest').
668    */
669   struct GNUNET_CONTAINER_MultiHashMap *requests;
670
671   /**
672    * Options for messages this client cares about,
673    * see GNUNET_CORE_OPTION_ values.
674    */
675   uint32_t options;
676
677   /**
678    * Number of types of incoming messages this client
679    * specifically cares about.  Size of the "types" array.
680    */
681   unsigned int tcnt;
682
683 };
684
685
686 /**
687  * Record kept for each request for transmission issued by a
688  * client that is still pending.
689  */
690 struct ClientActiveRequest
691 {
692
693   /**
694    * Active requests are kept in a doubly-linked list of
695    * the respective target peer.
696    */
697   struct ClientActiveRequest *next;
698
699   /**
700    * Active requests are kept in a doubly-linked list of
701    * the respective target peer.
702    */
703   struct ClientActiveRequest *prev;
704
705   /**
706    * Handle to the client.
707    */
708   struct Client *client;
709
710   /**
711    * By what time would the client want to see this message out?
712    */
713   struct GNUNET_TIME_Absolute deadline;
714
715   /**
716    * How important is this request.
717    */
718   uint32_t priority;
719
720   /**
721    * How many more requests does this client have?
722    */
723   uint32_t queue_size;
724
725   /**
726    * How many bytes does the client intend to send?
727    */
728   uint16_t msize;
729
730   /**
731    * Unique request ID (in big endian).
732    */
733   uint16_t smr_id;
734
735 };
736
737
738
739 /**
740  * Our public key.
741  */
742 static struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded my_public_key;
743
744 /**
745  * Our identity.
746  */
747 static struct GNUNET_PeerIdentity my_identity;
748
749 /**
750  * Our private key.
751  */
752 static struct GNUNET_CRYPTO_RsaPrivateKey *my_private_key;
753
754 /**
755  * Bitmap of message types this peer is able to handle.
756  */
757 static uint32_t my_type_map[(UINT16_MAX + 1) / 32];
758
759 /**
760  * Handle to peerinfo service.
761  */
762 static struct GNUNET_PEERINFO_Handle *peerinfo;
763
764 /**
765  * Our message stream tokenizer (for encrypted payload).
766  */
767 static struct GNUNET_SERVER_MessageStreamTokenizer *mst;
768
769 /**
770  * Our configuration.
771  */
772 const struct GNUNET_CONFIGURATION_Handle *cfg;
773
774 /**
775  * Transport service.
776  */
777 static struct GNUNET_TRANSPORT_Handle *transport;
778
779 /**
780  * Linked list of our clients.
781  */
782 static struct Client *clients;
783
784 /**
785  * Context for notifications we need to send to our clients.
786  */
787 static struct GNUNET_SERVER_NotificationContext *notifier;
788
789 /**
790  * Map of peer identities to 'struct Neighbour'.
791  */
792 static struct GNUNET_CONTAINER_MultiHashMap *neighbours;
793
794 /**
795  * Neighbour entry for "this" peer.
796  */
797 static struct Neighbour self;
798
799 /**
800  * For creating statistics.
801  */
802 static struct GNUNET_STATISTICS_Handle *stats;
803
804 /**
805  * Sum of all preferences among all neighbours.
806  */
807 static unsigned long long preference_sum;
808
809 /**
810  * How much inbound bandwidth are we supposed to be using per second?
811  */
812 static unsigned long long bandwidth_target_in_bps;
813
814 /**
815  * How much outbound bandwidth are we supposed to be using per second?
816  */
817 static unsigned long long bandwidth_target_out_bps;
818
819 /**
820  * Derive an authentication key from "set key" information
821  */
822 static void
823 derive_auth_key (struct GNUNET_CRYPTO_AuthKey *akey,
824                  const struct GNUNET_CRYPTO_AesSessionKey *skey, uint32_t seed,
825                  struct GNUNET_TIME_Absolute creation_time)
826 {
827   static const char ctx[] = "authentication key";
828   struct GNUNET_TIME_AbsoluteNBO ctbe;
829
830
831   ctbe = GNUNET_TIME_absolute_hton (creation_time);
832   GNUNET_CRYPTO_hmac_derive_key (akey, skey, &seed, sizeof (seed), &skey->key,
833                                  sizeof (skey->key), &ctbe, sizeof (ctbe), ctx,
834                                  sizeof (ctx), NULL);
835 }
836
837
838 /**
839  * Derive an IV from packet information
840  */
841 static void
842 derive_iv (struct GNUNET_CRYPTO_AesInitializationVector *iv,
843            const struct GNUNET_CRYPTO_AesSessionKey *skey, uint32_t seed,
844            const struct GNUNET_PeerIdentity *identity)
845 {
846   static const char ctx[] = "initialization vector";
847
848   GNUNET_CRYPTO_aes_derive_iv (iv, skey, &seed, sizeof (seed),
849                                &identity->hashPubKey.bits,
850                                sizeof (identity->hashPubKey.bits), ctx,
851                                sizeof (ctx), NULL);
852 }
853
854 /**
855  * Derive an IV from pong packet information
856  */
857 static void
858 derive_pong_iv (struct GNUNET_CRYPTO_AesInitializationVector *iv,
859                 const struct GNUNET_CRYPTO_AesSessionKey *skey, uint32_t seed,
860                 uint32_t challenge, const struct GNUNET_PeerIdentity *identity)
861 {
862   static const char ctx[] = "pong initialization vector";
863
864   GNUNET_CRYPTO_aes_derive_iv (iv, skey, &seed, sizeof (seed),
865                                &identity->hashPubKey.bits,
866                                sizeof (identity->hashPubKey.bits), &challenge,
867                                sizeof (challenge), ctx, sizeof (ctx), NULL);
868 }
869
870
871 /**
872  * At what time should the connection to the given neighbour
873  * time out (given no further activity?)
874  *
875  * @param n neighbour in question
876  * @return absolute timeout
877  */
878 static struct GNUNET_TIME_Absolute
879 get_neighbour_timeout (struct Neighbour *n)
880 {
881   return GNUNET_TIME_absolute_add (n->last_activity,
882                                    GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT);
883 }
884
885
886 /**
887  * Helper function for update_preference_sum.
888  */
889 static int
890 update_preference (void *cls, const GNUNET_HashCode * key, void *value)
891 {
892   unsigned long long *ps = cls;
893   struct Neighbour *n = value;
894
895   n->current_preference /= 2;
896   *ps += n->current_preference;
897   return GNUNET_OK;
898 }
899
900
901 /**
902  * A preference value for a neighbour was update.  Update
903  * the preference sum accordingly.
904  *
905  * @param inc how much was a preference value increased?
906  */
907 static void
908 update_preference_sum (unsigned long long inc)
909 {
910   unsigned long long os;
911
912   os = preference_sum;
913   preference_sum += inc;
914   if (preference_sum >= os)
915     return;                     /* done! */
916   /* overflow! compensate by cutting all values in half! */
917   preference_sum = 0;
918   GNUNET_CONTAINER_multihashmap_iterate (neighbours, &update_preference,
919                                          &preference_sum);
920   GNUNET_STATISTICS_set (stats, gettext_noop ("# total peer preference"),
921                          preference_sum, GNUNET_NO);
922 }
923
924
925 /**
926  * Find the entry for the given neighbour.
927  *
928  * @param peer identity of the neighbour
929  * @return NULL if we are not connected, otherwise the
930  *         neighbour's entry.
931  */
932 static struct Neighbour *
933 find_neighbour (const struct GNUNET_PeerIdentity *peer)
934 {
935   return GNUNET_CONTAINER_multihashmap_get (neighbours, &peer->hashPubKey);
936 }
937
938
939 /**
940  * Send a message to one of our clients.
941  *
942  * @param client target for the message
943  * @param msg message to transmit
944  * @param can_drop could this message be dropped if the
945  *        client's queue is getting too large?
946  */
947 static void
948 send_to_client (struct Client *client, const struct GNUNET_MessageHeader *msg,
949                 int can_drop)
950 {
951 #if DEBUG_CORE_CLIENT
952   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
953               "Preparing to send %u bytes of message of type %u to client.\n",
954               (unsigned int) ntohs (msg->size),
955               (unsigned int) ntohs (msg->type));
956 #endif
957   GNUNET_SERVER_notification_context_unicast (notifier, client->client_handle,
958                                               msg, can_drop);
959 }
960
961
962 /**
963  * Send a message to all of our current clients that have
964  * the right options set.
965  *
966  * @param msg message to multicast
967  * @param can_drop can this message be discarded if the queue is too long
968  * @param options mask to use
969  */
970 static void
971 send_to_all_clients (const struct GNUNET_MessageHeader *msg, int can_drop,
972                      int options)
973 {
974   struct Client *c;
975
976   c = clients;
977   while (c != NULL)
978   {
979     if (0 != (c->options & options))
980     {
981 #if DEBUG_CORE_CLIENT > 1
982       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
983                   "Sending message of type %u to client.\n",
984                   (unsigned int) ntohs (msg->type));
985 #endif
986       send_to_client (c, msg, can_drop);
987     }
988     c = c->next;
989   }
990 }
991
992
993 /**
994  * Function called by transport telling us that a peer
995  * changed status.
996  *
997  * @param n the peer that changed status
998  */
999 static void
1000 handle_peer_status_change (struct Neighbour *n)
1001 {
1002   struct PeerStatusNotifyMessage *psnm;
1003   char buf[GNUNET_SERVER_MAX_MESSAGE_SIZE - 1];
1004   struct GNUNET_TRANSPORT_ATS_Information *ats;
1005   size_t size;
1006
1007   if ((!n->is_connected) || (n->status != PEER_STATE_KEY_CONFIRMED))
1008     return;
1009 #if DEBUG_CORE > 1
1010   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer `%4s' changed status\n",
1011               GNUNET_i2s (&n->peer));
1012 #endif
1013   size =
1014       sizeof (struct PeerStatusNotifyMessage) +
1015       n->ats_count * sizeof (struct GNUNET_TRANSPORT_ATS_Information);
1016   if (size >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
1017   {
1018     GNUNET_break (0);
1019     /* recovery strategy: throw away performance data */
1020     GNUNET_array_grow (n->ats, n->ats_count, 0);
1021     size =
1022         sizeof (struct PeerStatusNotifyMessage) +
1023         n->ats_count * sizeof (struct GNUNET_TRANSPORT_ATS_Information);
1024   }
1025   psnm = (struct PeerStatusNotifyMessage *) buf;
1026   psnm->header.size = htons (size);
1027   psnm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_STATUS_CHANGE);
1028   psnm->timeout = GNUNET_TIME_absolute_hton (get_neighbour_timeout (n));
1029   psnm->bandwidth_in = n->bw_in;
1030   psnm->bandwidth_out = n->bw_out;
1031   psnm->peer = n->peer;
1032   psnm->ats_count = htonl (n->ats_count);
1033   ats = &psnm->ats;
1034   memcpy (ats, n->ats,
1035           n->ats_count * sizeof (struct GNUNET_TRANSPORT_ATS_Information));
1036   ats[n->ats_count].type = htonl (0);
1037   ats[n->ats_count].value = htonl (0);
1038   send_to_all_clients (&psnm->header, GNUNET_YES,
1039                        GNUNET_CORE_OPTION_SEND_STATUS_CHANGE);
1040   GNUNET_STATISTICS_update (stats, gettext_noop ("# peer status changes"), 1,
1041                             GNUNET_NO);
1042 }
1043
1044
1045 /**
1046  * Go over our message queue and if it is not too long, go
1047  * over the pending requests from clients for this
1048  * neighbour and send some clients a 'READY' notification.
1049  *
1050  * @param n which peer to process
1051  */
1052 static void
1053 schedule_peer_messages (struct Neighbour *n)
1054 {
1055   struct SendMessageReady smr;
1056   struct ClientActiveRequest *car;
1057   struct ClientActiveRequest *pos;
1058   struct Client *c;
1059   struct MessageEntry *mqe;
1060   unsigned int queue_size;
1061
1062   /* check if neighbour queue is empty enough! */
1063   if (n != &self)
1064   {
1065     queue_size = 0;
1066     mqe = n->messages;
1067     while (mqe != NULL)
1068     {
1069       queue_size++;
1070       mqe = mqe->next;
1071     }
1072     if (queue_size >= MAX_PEER_QUEUE_SIZE)
1073     {
1074 #if DEBUG_CORE_CLIENT
1075       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1076                   "Not considering client transmission requests: queue full\n");
1077 #endif
1078       return;                   /* queue still full */
1079     }
1080     /* find highest priority request */
1081     pos = n->active_client_request_head;
1082     car = NULL;
1083     while (pos != NULL)
1084     {
1085       if ((car == NULL) || (pos->priority > car->priority))
1086         car = pos;
1087       pos = pos->next;
1088     }
1089   }
1090   else
1091   {
1092     car = n->active_client_request_head;
1093   }
1094   if (car == NULL)
1095     return;                     /* no pending requests */
1096 #if DEBUG_CORE_CLIENT
1097   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1098               "Permitting client transmission request to `%s'\n",
1099               GNUNET_i2s (&n->peer));
1100 #endif
1101   c = car->client;
1102   GNUNET_CONTAINER_DLL_remove (n->active_client_request_head,
1103                                n->active_client_request_tail, car);
1104   GNUNET_assert (GNUNET_YES ==
1105                  GNUNET_CONTAINER_multihashmap_remove (c->requests,
1106                                                        &n->peer.hashPubKey,
1107                                                        car));
1108   smr.header.size = htons (sizeof (struct SendMessageReady));
1109   smr.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_SEND_READY);
1110   smr.size = htons (car->msize);
1111   smr.smr_id = car->smr_id;
1112   smr.peer = n->peer;
1113   send_to_client (c, &smr.header, GNUNET_NO);
1114   GNUNET_free (car);
1115 }
1116
1117
1118 /**
1119  * Compute a type map message for this peer.
1120  *
1121  * @return this peers current type map message.
1122  */
1123 static struct GNUNET_MessageHeader *
1124 compute_type_map_message ()
1125 {
1126   char *tmp;
1127   uLongf dlen;
1128   struct GNUNET_MessageHeader *hdr;
1129
1130 #ifdef compressBound
1131   dlen = compressBound (sizeof (my_type_map));
1132 #else
1133   dlen = sizeof (my_type_map) + (sizeof (my_type_map) / 100) + 20;
1134   /* documentation says 100.1% oldSize + 12 bytes, but we
1135    * should be able to overshoot by more to be safe */
1136 #endif
1137   hdr = GNUNET_malloc (dlen + sizeof (struct GNUNET_MessageHeader));
1138   hdr->size = htons ((uint16_t) dlen + sizeof (struct GNUNET_MessageHeader));
1139   tmp = (char *) &hdr[1];
1140   if ((Z_OK !=
1141        compress2 ((Bytef *) tmp, &dlen, (const Bytef *) my_type_map,
1142                   sizeof (my_type_map), 9)) || (dlen >= sizeof (my_type_map)))
1143   {
1144     dlen = sizeof (my_type_map);
1145     memcpy (tmp, my_type_map, sizeof (my_type_map));
1146     hdr->type = htons (GNUNET_MESSAGE_TYPE_CORE_BINARY_TYPE_MAP);
1147   }
1148   else
1149   {
1150     hdr->type = htons (GNUNET_MESSAGE_TYPE_CORE_COMPRESSED_TYPE_MAP);
1151   }
1152   return hdr;
1153 }
1154
1155
1156 /**
1157  * Send a type map message to the neighbour.
1158  *
1159  * @param cls the type map message
1160  * @param key neighbour's identity
1161  * @param value 'struct Neighbour' of the target
1162  * @return always GNUNET_OK
1163  */
1164 static int
1165 send_type_map_to_neighbour (void *cls, const GNUNET_HashCode * key, void *value)
1166 {
1167   struct GNUNET_MessageHeader *hdr = cls;
1168   struct Neighbour *n = value;
1169   struct MessageEntry *m;
1170   uint16_t size;
1171
1172   if (n == &self)
1173     return GNUNET_OK;
1174   size = ntohs (hdr->size);
1175   m = GNUNET_malloc (sizeof (struct MessageEntry) + size);
1176   memcpy (&m[1], hdr, size);
1177   m->deadline = GNUNET_TIME_UNIT_FOREVER_ABS;
1178   m->slack_deadline = GNUNET_TIME_UNIT_FOREVER_ABS;
1179   m->priority = UINT_MAX;
1180   m->sender_status = n->status;
1181   m->size = size;
1182   m->next = n->messages;
1183   n->messages = m;
1184   return GNUNET_OK;
1185 }
1186
1187
1188
1189 /**
1190  * Send my type map to all connected peers (it got changed).
1191  */
1192 static void
1193 broadcast_my_type_map ()
1194 {
1195   struct GNUNET_MessageHeader *hdr;
1196
1197   if (NULL == neighbours)
1198     return;
1199   hdr = compute_type_map_message ();
1200   GNUNET_CONTAINER_multihashmap_iterate (neighbours,
1201                                          &send_type_map_to_neighbour, hdr);
1202   GNUNET_free (hdr);
1203 }
1204
1205
1206 /**
1207  * Handle CORE_SEND_REQUEST message.
1208  */
1209 static void
1210 handle_client_send_request (void *cls, struct GNUNET_SERVER_Client *client,
1211                             const struct GNUNET_MessageHeader *message)
1212 {
1213   const struct SendMessageRequest *req;
1214   struct Neighbour *n;
1215   struct Client *c;
1216   struct ClientActiveRequest *car;
1217
1218   req = (const struct SendMessageRequest *) message;
1219   if (0 ==
1220       memcmp (&req->peer, &my_identity, sizeof (struct GNUNET_PeerIdentity)))
1221     n = &self;
1222   else
1223     n = find_neighbour (&req->peer);
1224   if ((n == NULL) || (GNUNET_YES != n->is_connected) ||
1225       (n->status != PEER_STATE_KEY_CONFIRMED))
1226   {
1227     /* neighbour must have disconnected since request was issued,
1228      * ignore (client will realize it once it processes the
1229      * disconnect notification) */
1230 #if DEBUG_CORE_CLIENT
1231     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1232                 "Dropped client request for transmission (am disconnected)\n");
1233 #endif
1234     GNUNET_STATISTICS_update (stats,
1235                               gettext_noop
1236                               ("# send requests dropped (disconnected)"), 1,
1237                               GNUNET_NO);
1238     GNUNET_SERVER_receive_done (client, GNUNET_OK);
1239     return;
1240   }
1241   c = clients;
1242   while ((c != NULL) && (c->client_handle != client))
1243     c = c->next;
1244   if (c == NULL)
1245   {
1246     /* client did not send INIT first! */
1247     GNUNET_break (0);
1248     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1249     return;
1250   }
1251   if (c->requests == NULL)
1252     c->requests = GNUNET_CONTAINER_multihashmap_create (16);
1253 #if DEBUG_CORE_CLIENT
1254   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1255               "Received client transmission request. queueing\n");
1256 #endif
1257   car = GNUNET_CONTAINER_multihashmap_get (c->requests, &req->peer.hashPubKey);
1258   if (car == NULL)
1259   {
1260     /* create new entry */
1261     car = GNUNET_malloc (sizeof (struct ClientActiveRequest));
1262     GNUNET_assert (GNUNET_OK ==
1263                    GNUNET_CONTAINER_multihashmap_put (c->requests,
1264                                                       &req->peer.hashPubKey,
1265                                                       car,
1266                                                       GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST));
1267     GNUNET_CONTAINER_DLL_insert (n->active_client_request_head,
1268                                  n->active_client_request_tail, car);
1269     car->client = c;
1270   }
1271   car->deadline = GNUNET_TIME_absolute_ntoh (req->deadline);
1272   car->priority = ntohl (req->priority);
1273   car->queue_size = ntohl (req->queue_size);
1274   car->msize = ntohs (req->size);
1275   car->smr_id = req->smr_id;
1276   schedule_peer_messages (n);
1277   GNUNET_SERVER_receive_done (client, GNUNET_OK);
1278 }
1279
1280
1281 /**
1282  * Notify client about an existing connection to one of our neighbours.
1283  */
1284 static int
1285 notify_client_about_neighbour (void *cls, const GNUNET_HashCode * key,
1286                                void *value)
1287 {
1288   struct Client *c = cls;
1289   struct Neighbour *n = value;
1290   size_t size;
1291   char buf[GNUNET_SERVER_MAX_MESSAGE_SIZE - 1];
1292   struct GNUNET_TRANSPORT_ATS_Information *ats;
1293   struct ConnectNotifyMessage *cnm;
1294
1295   size =
1296       sizeof (struct ConnectNotifyMessage) +
1297       (n->ats_count) * sizeof (struct GNUNET_TRANSPORT_ATS_Information);
1298   if (size >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
1299   {
1300     GNUNET_break (0);
1301     /* recovery strategy: throw away performance data */
1302     GNUNET_array_grow (n->ats, n->ats_count, 0);
1303     size =
1304         sizeof (struct ConnectNotifyMessage) +
1305         (n->ats_count) * sizeof (struct GNUNET_TRANSPORT_ATS_Information);
1306   }
1307   cnm = (struct ConnectNotifyMessage *) buf;
1308   cnm->header.size = htons (size);
1309   cnm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT);
1310   cnm->ats_count = htonl (n->ats_count);
1311   ats = &cnm->ats;
1312   memcpy (ats, n->ats,
1313           sizeof (struct GNUNET_TRANSPORT_ATS_Information) * n->ats_count);
1314   ats[n->ats_count].type = htonl (GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR);
1315   ats[n->ats_count].value = htonl (0);
1316   if (n->status == PEER_STATE_KEY_CONFIRMED)
1317   {
1318 #if DEBUG_CORE_CLIENT
1319     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message to client.\n",
1320                 "NOTIFY_CONNECT");
1321 #endif
1322     cnm->peer = n->peer;
1323     send_to_client (c, &cnm->header, GNUNET_NO);
1324   }
1325   return GNUNET_OK;
1326 }
1327
1328
1329
1330 /**
1331  * Handle CORE_INIT request.
1332  */
1333 static void
1334 handle_client_init (void *cls, struct GNUNET_SERVER_Client *client,
1335                     const struct GNUNET_MessageHeader *message)
1336 {
1337   const struct InitMessage *im;
1338   struct InitReplyMessage irm;
1339   struct Client *c;
1340   uint16_t msize;
1341   const uint16_t *types;
1342   uint16_t *wtypes;
1343   unsigned int i;
1344
1345 #if DEBUG_CORE_CLIENT
1346   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1347               "Client connecting to core service with `%s' message\n", "INIT");
1348 #endif
1349   /* check that we don't have an entry already */
1350   c = clients;
1351   while (c != NULL)
1352   {
1353     if (client == c->client_handle)
1354     {
1355       GNUNET_break (0);
1356       GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1357       return;
1358     }
1359     c = c->next;
1360   }
1361   msize = ntohs (message->size);
1362   if (msize < sizeof (struct InitMessage))
1363   {
1364     GNUNET_break (0);
1365     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1366     return;
1367   }
1368   GNUNET_SERVER_notification_context_add (notifier, client);
1369   im = (const struct InitMessage *) message;
1370   types = (const uint16_t *) &im[1];
1371   msize -= sizeof (struct InitMessage);
1372   c = GNUNET_malloc (sizeof (struct Client) + msize);
1373   c->client_handle = client;
1374   c->next = clients;
1375   clients = c;
1376   c->tcnt = msize / sizeof (uint16_t);
1377   c->types = (const uint16_t *) &c[1];
1378   wtypes = (uint16_t *) & c[1];
1379   for (i = 0; i < c->tcnt; i++)
1380   {
1381     wtypes[i] = ntohs (types[i]);
1382     my_type_map[wtypes[i] / 32] |= (1 << (wtypes[i] % 32));
1383   }
1384   if (c->tcnt > 0)
1385     broadcast_my_type_map ();
1386   c->options = ntohl (im->options);
1387 #if DEBUG_CORE_CLIENT
1388   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1389               "Client %p is interested in %u message types\n", c,
1390               (unsigned int) c->tcnt);
1391 #endif
1392   /* send init reply message */
1393   irm.header.size = htons (sizeof (struct InitReplyMessage));
1394   irm.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_INIT_REPLY);
1395   irm.reserved = htonl (0);
1396   irm.my_identity = my_identity;
1397 #if DEBUG_CORE_CLIENT
1398   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message to client.\n",
1399               "INIT_REPLY");
1400 #endif
1401   send_to_client (c, &irm.header, GNUNET_NO);
1402   if (0 != (c->options & GNUNET_CORE_OPTION_SEND_CONNECT))
1403   {
1404     /* notify new client about existing neighbours */
1405     GNUNET_CONTAINER_multihashmap_iterate (neighbours,
1406                                            &notify_client_about_neighbour, c);
1407   }
1408   GNUNET_SERVER_receive_done (client, GNUNET_OK);
1409 }
1410
1411
1412 /**
1413  * Free client request records.
1414  *
1415  * @param cls NULL
1416  * @param key identity of peer for which this is an active request
1417  * @param value the 'struct ClientActiveRequest' to free
1418  * @return GNUNET_YES (continue iteration)
1419  */
1420 static int
1421 destroy_active_client_request (void *cls, const GNUNET_HashCode * key,
1422                                void *value)
1423 {
1424   struct ClientActiveRequest *car = value;
1425   struct Neighbour *n;
1426   struct GNUNET_PeerIdentity peer;
1427
1428   peer.hashPubKey = *key;
1429   n = find_neighbour (&peer);
1430   GNUNET_assert (NULL != n);
1431   GNUNET_CONTAINER_DLL_remove (n->active_client_request_head,
1432                                n->active_client_request_tail, car);
1433   GNUNET_free (car);
1434   return GNUNET_YES;
1435 }
1436
1437
1438 /**
1439  * A client disconnected, clean up.
1440  *
1441  * @param cls closure
1442  * @param client identification of the client
1443  */
1444 static void
1445 handle_client_disconnect (void *cls, struct GNUNET_SERVER_Client *client)
1446 {
1447   struct Client *pos;
1448   struct Client *prev;
1449   unsigned int i;
1450   const uint16_t *wtypes;
1451
1452   if (client == NULL)
1453     return;
1454 #if DEBUG_CORE_CLIENT
1455   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1456               "Client %p has disconnected from core service.\n", client);
1457 #endif
1458   prev = NULL;
1459   pos = clients;
1460   while (pos != NULL)
1461   {
1462     if (client == pos->client_handle)
1463       break;
1464     prev = pos;
1465     pos = pos->next;
1466   }
1467   if (pos == NULL)
1468   {
1469     /* client never sent INIT */
1470     return;
1471   }
1472   if (prev == NULL)
1473     clients = pos->next;
1474   else
1475     prev->next = pos->next;
1476   if (pos->requests != NULL)
1477   {
1478     GNUNET_CONTAINER_multihashmap_iterate (pos->requests,
1479                                            &destroy_active_client_request,
1480                                            NULL);
1481     GNUNET_CONTAINER_multihashmap_destroy (pos->requests);
1482   }
1483   GNUNET_free (pos);
1484
1485   /* rebuild my_type_map */
1486   memset (my_type_map, 0, sizeof (my_type_map));
1487   for (pos = clients; NULL != pos; pos = pos->next)
1488   {
1489     wtypes = (const uint16_t *) &pos[1];
1490     for (i = 0; i < pos->tcnt; i++)
1491       my_type_map[wtypes[i] / 32] |= (1 << (wtypes[i] % 32));
1492   }
1493   broadcast_my_type_map ();
1494 }
1495
1496
1497 /**
1498  * Helper function for handle_client_iterate_peers.
1499  *
1500  * @param cls the 'struct GNUNET_SERVER_TransmitContext' to queue replies
1501  * @param key identity of the connected peer
1502  * @param value the 'struct Neighbour' for the peer
1503  * @return GNUNET_OK (continue to iterate)
1504  */
1505 static int
1506 queue_connect_message (void *cls, const GNUNET_HashCode * key, void *value)
1507 {
1508   struct GNUNET_SERVER_TransmitContext *tc = cls;
1509   struct Neighbour *n = value;
1510   char buf[GNUNET_SERVER_MAX_MESSAGE_SIZE - 1];
1511   struct GNUNET_TRANSPORT_ATS_Information *ats;
1512   size_t size;
1513   struct ConnectNotifyMessage *cnm;
1514
1515   cnm = (struct ConnectNotifyMessage *) buf;
1516   if (n->status != PEER_STATE_KEY_CONFIRMED)
1517     return GNUNET_OK;
1518   size =
1519       sizeof (struct ConnectNotifyMessage) +
1520       (n->ats_count) * sizeof (struct GNUNET_TRANSPORT_ATS_Information);
1521   if (size >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
1522   {
1523     GNUNET_break (0);
1524     /* recovery strategy: throw away performance data */
1525     GNUNET_array_grow (n->ats, n->ats_count, 0);
1526     size =
1527         sizeof (struct PeerStatusNotifyMessage) +
1528         n->ats_count * sizeof (struct GNUNET_TRANSPORT_ATS_Information);
1529   }
1530   cnm = (struct ConnectNotifyMessage *) buf;
1531   cnm->header.size = htons (size);
1532   cnm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT);
1533   cnm->ats_count = htonl (n->ats_count);
1534   ats = &cnm->ats;
1535   memcpy (ats, n->ats,
1536           n->ats_count * sizeof (struct GNUNET_TRANSPORT_ATS_Information));
1537   ats[n->ats_count].type = htonl (GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR);
1538   ats[n->ats_count].value = htonl (0);
1539 #if DEBUG_CORE_CLIENT
1540   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message to client.\n",
1541               "NOTIFY_CONNECT");
1542 #endif
1543   cnm->peer = n->peer;
1544   GNUNET_SERVER_transmit_context_append_message (tc, &cnm->header);
1545   return GNUNET_OK;
1546 }
1547
1548
1549 /**
1550  * Handle CORE_ITERATE_PEERS request.
1551  *
1552  * @param cls unused
1553  * @param client client sending the iteration request
1554  * @param message iteration request message
1555  */
1556 static void
1557 handle_client_iterate_peers (void *cls, struct GNUNET_SERVER_Client *client,
1558                              const struct GNUNET_MessageHeader *message)
1559 {
1560   struct GNUNET_MessageHeader done_msg;
1561   struct GNUNET_SERVER_TransmitContext *tc;
1562   int msize;
1563
1564   /* notify new client about existing neighbours */
1565
1566   msize = ntohs (message->size);
1567   tc = GNUNET_SERVER_transmit_context_create (client);
1568   if (msize == sizeof (struct GNUNET_MessageHeader))
1569     GNUNET_CONTAINER_multihashmap_iterate (neighbours, &queue_connect_message,
1570                                            tc);
1571   else
1572     GNUNET_break (0);
1573
1574   done_msg.size = htons (sizeof (struct GNUNET_MessageHeader));
1575   done_msg.type = htons (GNUNET_MESSAGE_TYPE_CORE_ITERATE_PEERS_END);
1576   GNUNET_SERVER_transmit_context_append_message (tc, &done_msg);
1577   GNUNET_SERVER_transmit_context_run (tc, GNUNET_TIME_UNIT_FOREVER_REL);
1578 }
1579
1580
1581 /**
1582  * Handle CORE_PEER_CONNECTED request.  Notify client about existing neighbours.
1583  *
1584  * @param cls unused
1585  * @param client client sending the iteration request
1586  * @param message iteration request message
1587  */
1588 static void
1589 handle_client_have_peer (void *cls, struct GNUNET_SERVER_Client *client,
1590                          const struct GNUNET_MessageHeader *message)
1591 {
1592   struct GNUNET_MessageHeader done_msg;
1593   struct GNUNET_SERVER_TransmitContext *tc;
1594   struct GNUNET_PeerIdentity *peer;
1595
1596   tc = GNUNET_SERVER_transmit_context_create (client);
1597   peer = (struct GNUNET_PeerIdentity *) &message[1];
1598   GNUNET_CONTAINER_multihashmap_get_multiple (neighbours, &peer->hashPubKey,
1599                                               &queue_connect_message, tc);
1600   done_msg.size = htons (sizeof (struct GNUNET_MessageHeader));
1601   done_msg.type = htons (GNUNET_MESSAGE_TYPE_CORE_ITERATE_PEERS_END);
1602   GNUNET_SERVER_transmit_context_append_message (tc, &done_msg);
1603   GNUNET_SERVER_transmit_context_run (tc, GNUNET_TIME_UNIT_FOREVER_REL);
1604 }
1605
1606
1607 /**
1608  * Handle REQUEST_INFO request.
1609  *
1610  * @param cls unused
1611  * @param client client sending the request
1612  * @param message iteration request message
1613  */
1614 static void
1615 handle_client_request_info (void *cls, struct GNUNET_SERVER_Client *client,
1616                             const struct GNUNET_MessageHeader *message)
1617 {
1618   const struct RequestInfoMessage *rcm;
1619   struct Client *pos;
1620   struct Neighbour *n;
1621   struct ConfigurationInfoMessage cim;
1622   int32_t want_reserv;
1623   int32_t got_reserv;
1624   unsigned long long old_preference;
1625   struct GNUNET_TIME_Relative rdelay;
1626
1627   rdelay = GNUNET_TIME_relative_get_zero ();
1628 #if DEBUG_CORE_CLIENT
1629   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Core service receives `%s' request.\n",
1630               "REQUEST_INFO");
1631 #endif
1632   pos = clients;
1633   while (pos != NULL)
1634   {
1635     if (client == pos->client_handle)
1636       break;
1637     pos = pos->next;
1638   }
1639   if (pos == NULL)
1640   {
1641     GNUNET_break (0);
1642     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1643     return;
1644   }
1645
1646   rcm = (const struct RequestInfoMessage *) message;
1647   n = find_neighbour (&rcm->peer);
1648   memset (&cim, 0, sizeof (cim));
1649   if ((n != NULL) && (GNUNET_YES == n->is_connected))
1650   {
1651     want_reserv = ntohl (rcm->reserve_inbound);
1652     if (n->bw_out_internal_limit.value__ != rcm->limit_outbound.value__)
1653     {
1654       n->bw_out_internal_limit = rcm->limit_outbound;
1655       if (n->bw_out.value__ !=
1656           GNUNET_BANDWIDTH_value_min (n->bw_out_internal_limit,
1657                                       n->bw_out_external_limit).value__)
1658       {
1659         n->bw_out =
1660             GNUNET_BANDWIDTH_value_min (n->bw_out_internal_limit,
1661                                         n->bw_out_external_limit);
1662         GNUNET_BANDWIDTH_tracker_update_quota (&n->available_recv_window,
1663                                                n->bw_out);
1664         GNUNET_TRANSPORT_set_quota (transport, &n->peer, n->bw_in, n->bw_out);
1665         handle_peer_status_change (n);
1666       }
1667     }
1668     if (want_reserv < 0)
1669     {
1670       got_reserv = want_reserv;
1671     }
1672     else if (want_reserv > 0)
1673     {
1674       rdelay =
1675           GNUNET_BANDWIDTH_tracker_get_delay (&n->available_recv_window,
1676                                               want_reserv);
1677       if (rdelay.rel_value == 0)
1678         got_reserv = want_reserv;
1679       else
1680         got_reserv = 0;         /* all or nothing */
1681     }
1682     else
1683       got_reserv = 0;
1684     GNUNET_BANDWIDTH_tracker_consume (&n->available_recv_window, got_reserv);
1685     old_preference = n->current_preference;
1686     n->current_preference += GNUNET_ntohll (rcm->preference_change);
1687     if (old_preference > n->current_preference)
1688     {
1689       /* overflow; cap at maximum value */
1690       n->current_preference = ULLONG_MAX;
1691     }
1692     update_preference_sum (n->current_preference - old_preference);
1693 #if DEBUG_CORE_QUOTA
1694     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1695                 "Received reservation request for %d bytes for peer `%4s', reserved %d bytes, suggesting delay of %llu ms\n",
1696                 (int) want_reserv, GNUNET_i2s (&rcm->peer), (int) got_reserv,
1697                 (unsigned long long) rdelay.rel_value);
1698 #endif
1699     cim.reserved_amount = htonl (got_reserv);
1700     cim.reserve_delay = GNUNET_TIME_relative_hton (rdelay);
1701     cim.bw_out = n->bw_out;
1702     cim.preference = n->current_preference;
1703   }
1704   else
1705   {
1706     /* Technically, this COULD happen (due to asynchronous behavior),
1707      * but it should be rare, so we should generate an info event
1708      * to help diagnosis of serious errors that might be masked by this */
1709     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1710                 _
1711                 ("Client asked for preference change with peer `%s', which is not connected!\n"),
1712                 GNUNET_i2s (&rcm->peer));
1713     GNUNET_SERVER_receive_done (client, GNUNET_OK);
1714     return;
1715   }
1716   cim.header.size = htons (sizeof (struct ConfigurationInfoMessage));
1717   cim.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_CONFIGURATION_INFO);
1718   cim.peer = rcm->peer;
1719   cim.rim_id = rcm->rim_id;
1720 #if DEBUG_CORE_CLIENT
1721   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message to client.\n",
1722               "CONFIGURATION_INFO");
1723 #endif
1724   send_to_client (pos, &cim.header, GNUNET_NO);
1725   GNUNET_SERVER_receive_done (client, GNUNET_OK);
1726 }
1727
1728
1729 /**
1730  * Free the given entry for the neighbour (it has
1731  * already been removed from the list at this point).
1732  *
1733  * @param n neighbour to free
1734  */
1735 static void
1736 free_neighbour (struct Neighbour *n)
1737 {
1738   struct MessageEntry *m;
1739   struct ClientActiveRequest *car;
1740
1741 #if DEBUG_CORE
1742   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1743               "Destroying neighbour entry for peer `%4s'\n",
1744               GNUNET_i2s (&n->peer));
1745 #endif
1746   if (n->pitr != NULL)
1747   {
1748     GNUNET_PEERINFO_iterate_cancel (n->pitr);
1749     n->pitr = NULL;
1750   }
1751   if (n->skm != NULL)
1752   {
1753     GNUNET_free (n->skm);
1754     n->skm = NULL;
1755   }
1756   while (NULL != (m = n->messages))
1757   {
1758     n->messages = m->next;
1759     GNUNET_free (m);
1760   }
1761   while (NULL != (m = n->encrypted_head))
1762   {
1763     GNUNET_CONTAINER_DLL_remove (n->encrypted_head, n->encrypted_tail, m);
1764     GNUNET_free (m);
1765   }
1766   while (NULL != (car = n->active_client_request_head))
1767   {
1768     GNUNET_CONTAINER_DLL_remove (n->active_client_request_head,
1769                                  n->active_client_request_tail, car);
1770     GNUNET_assert (GNUNET_YES ==
1771                    GNUNET_CONTAINER_multihashmap_remove (car->client->requests,
1772                                                          &n->peer.hashPubKey,
1773                                                          car));
1774     GNUNET_free (car);
1775   }
1776   if (NULL != n->th)
1777   {
1778     GNUNET_TRANSPORT_notify_transmit_ready_cancel (n->th);
1779     n->th = NULL;
1780   }
1781   if (n->retry_plaintext_task != GNUNET_SCHEDULER_NO_TASK)
1782     GNUNET_SCHEDULER_cancel (n->retry_plaintext_task);
1783   if (n->retry_set_key_task != GNUNET_SCHEDULER_NO_TASK)
1784     GNUNET_SCHEDULER_cancel (n->retry_set_key_task);
1785   if (n->quota_update_task != GNUNET_SCHEDULER_NO_TASK)
1786     GNUNET_SCHEDULER_cancel (n->quota_update_task);
1787   if (n->dead_clean_task != GNUNET_SCHEDULER_NO_TASK)
1788     GNUNET_SCHEDULER_cancel (n->dead_clean_task);
1789   if (n->keep_alive_task != GNUNET_SCHEDULER_NO_TASK)
1790     GNUNET_SCHEDULER_cancel (n->keep_alive_task);
1791   if (n->status == PEER_STATE_KEY_CONFIRMED)
1792     GNUNET_STATISTICS_update (stats, gettext_noop ("# established sessions"),
1793                               -1, GNUNET_NO);
1794   GNUNET_array_grow (n->ats, n->ats_count, 0);
1795   GNUNET_free_non_null (n->public_key);
1796   GNUNET_free_non_null (n->pending_ping);
1797   GNUNET_free_non_null (n->pending_pong);
1798   GNUNET_free (n);
1799 }
1800
1801
1802 /**
1803  * Check if we have encrypted messages for the specified neighbour
1804  * pending, and if so, check with the transport about sending them
1805  * out.
1806  *
1807  * @param n neighbour to check.
1808  */
1809 static void
1810 process_encrypted_neighbour_queue (struct Neighbour *n);
1811
1812
1813 /**
1814  * Encrypt size bytes from in and write the result to out.  Use the
1815  * key for outbound traffic of the given neighbour.
1816  *
1817  * @param n neighbour we are sending to
1818  * @param iv initialization vector to use
1819  * @param in ciphertext
1820  * @param out plaintext
1821  * @param size size of in/out
1822  * @return GNUNET_OK on success
1823  */
1824 static int
1825 do_encrypt (struct Neighbour *n,
1826             const struct GNUNET_CRYPTO_AesInitializationVector *iv,
1827             const void *in, void *out, size_t size)
1828 {
1829   if (size != (uint16_t) size)
1830   {
1831     GNUNET_break (0);
1832     return GNUNET_NO;
1833   }
1834   GNUNET_assert (size ==
1835                  GNUNET_CRYPTO_aes_encrypt (in, (uint16_t) size,
1836                                             &n->encrypt_key, iv, out));
1837   GNUNET_STATISTICS_update (stats, gettext_noop ("# bytes encrypted"), size,
1838                             GNUNET_NO);
1839 #if DEBUG_CORE > 2
1840   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1841               "Encrypted %u bytes for `%4s' using key %u, IV %u\n",
1842               (unsigned int) size, GNUNET_i2s (&n->peer),
1843               (unsigned int) n->encrypt_key.crc32, GNUNET_CRYPTO_crc32_n (iv,
1844                                                                           sizeof
1845                                                                           (iv)));
1846 #endif
1847   return GNUNET_OK;
1848 }
1849
1850
1851 /**
1852  * Consider freeing the given neighbour since we may not need
1853  * to keep it around anymore.
1854  *
1855  * @param n neighbour to consider discarding
1856  */
1857 static void
1858 consider_free_neighbour (struct Neighbour *n);
1859
1860
1861 /**
1862  * Task triggered when a neighbour entry is about to time out
1863  * (and we should prevent this by sending a PING).
1864  *
1865  * @param cls the 'struct Neighbour'
1866  * @param tc scheduler context (not used)
1867  */
1868 static void
1869 send_keep_alive (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1870 {
1871   struct Neighbour *n = cls;
1872   struct GNUNET_TIME_Relative retry;
1873   struct GNUNET_TIME_Relative left;
1874   struct MessageEntry *me;
1875   struct PingMessage pp;
1876   struct PingMessage *pm;
1877   struct GNUNET_CRYPTO_AesInitializationVector iv;
1878
1879   n->keep_alive_task = GNUNET_SCHEDULER_NO_TASK;
1880   /* send PING */
1881   me = GNUNET_malloc (sizeof (struct MessageEntry) +
1882                       sizeof (struct PingMessage));
1883   me->deadline = GNUNET_TIME_relative_to_absolute (MAX_PING_DELAY);
1884   me->priority = PING_PRIORITY;
1885   me->size = sizeof (struct PingMessage);
1886   GNUNET_CONTAINER_DLL_insert_after (n->encrypted_head, n->encrypted_tail,
1887                                      n->encrypted_tail, me);
1888   pm = (struct PingMessage *) &me[1];
1889   pm->header.size = htons (sizeof (struct PingMessage));
1890   pm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_PING);
1891   pm->iv_seed =
1892       GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, UINT32_MAX);
1893   derive_iv (&iv, &n->encrypt_key, pm->iv_seed, &n->peer);
1894   pp.challenge = n->ping_challenge;
1895   pp.target = n->peer;
1896 #if DEBUG_HANDSHAKE
1897   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1898               "Encrypting `%s' message with challenge %u for `%4s' using key %u, IV %u (salt %u).\n",
1899               "PING", (unsigned int) n->ping_challenge, GNUNET_i2s (&n->peer),
1900               (unsigned int) n->encrypt_key.crc32, GNUNET_CRYPTO_crc32_n (&iv,
1901                                                                           sizeof
1902                                                                           (iv)),
1903               pm->iv_seed);
1904 #endif
1905   do_encrypt (n, &iv, &pp.target, &pm->target,
1906               sizeof (struct PingMessage) - ((void *) &pm->target -
1907                                              (void *) pm));
1908   process_encrypted_neighbour_queue (n);
1909   /* reschedule PING job */
1910   left = GNUNET_TIME_absolute_get_remaining (get_neighbour_timeout (n));
1911   retry =
1912       GNUNET_TIME_relative_max (GNUNET_TIME_relative_divide (left, 2),
1913                                 MIN_PING_FREQUENCY);
1914   n->keep_alive_task =
1915       GNUNET_SCHEDULER_add_delayed (retry, &send_keep_alive, n);
1916
1917 }
1918
1919
1920 /**
1921  * Task triggered when a neighbour entry might have gotten stale.
1922  *
1923  * @param cls the 'struct Neighbour'
1924  * @param tc scheduler context (not used)
1925  */
1926 static void
1927 consider_free_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1928 {
1929   struct Neighbour *n = cls;
1930
1931   n->dead_clean_task = GNUNET_SCHEDULER_NO_TASK;
1932   consider_free_neighbour (n);
1933 }
1934
1935
1936 /**
1937  * Consider freeing the given neighbour since we may not need
1938  * to keep it around anymore.
1939  *
1940  * @param n neighbour to consider discarding
1941  */
1942 static void
1943 consider_free_neighbour (struct Neighbour *n)
1944 {
1945   struct GNUNET_TIME_Relative left;
1946
1947   if ((n->th != NULL) || (n->pitr != NULL) || (GNUNET_YES == n->is_connected))
1948     return;                     /* no chance */
1949
1950   left = GNUNET_TIME_absolute_get_remaining (get_neighbour_timeout (n));
1951   if (left.rel_value > 0)
1952   {
1953     if (n->dead_clean_task != GNUNET_SCHEDULER_NO_TASK)
1954       GNUNET_SCHEDULER_cancel (n->dead_clean_task);
1955     n->dead_clean_task =
1956         GNUNET_SCHEDULER_add_delayed (left, &consider_free_task, n);
1957     return;
1958   }
1959   /* actually free the neighbour... */
1960   GNUNET_assert (GNUNET_YES ==
1961                  GNUNET_CONTAINER_multihashmap_remove (neighbours,
1962                                                        &n->peer.hashPubKey, n));
1963   GNUNET_STATISTICS_set (stats, gettext_noop ("# neighbour entries allocated"),
1964                          GNUNET_CONTAINER_multihashmap_size (neighbours),
1965                          GNUNET_NO);
1966   free_neighbour (n);
1967 }
1968
1969
1970 /**
1971  * Function called when the transport service is ready to
1972  * receive an encrypted message for the respective peer
1973  *
1974  * @param cls neighbour to use message from
1975  * @param size number of bytes we can transmit
1976  * @param buf where to copy the message
1977  * @return number of bytes transmitted
1978  */
1979 static size_t
1980 notify_encrypted_transmit_ready (void *cls, size_t size, void *buf)
1981 {
1982   struct Neighbour *n = cls;
1983   struct MessageEntry *m;
1984   size_t ret;
1985   char *cbuf;
1986
1987   n->th = NULL;
1988   m = n->encrypted_head;
1989   if (m == NULL)
1990   {
1991 #if DEBUG_CORE
1992     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1993                 "Encrypted message queue empty, no messages added to buffer for `%4s'\n",
1994                 GNUNET_i2s (&n->peer));
1995 #endif
1996     return 0;
1997   }
1998   GNUNET_CONTAINER_DLL_remove (n->encrypted_head, n->encrypted_tail, m);
1999   ret = 0;
2000   cbuf = buf;
2001   if (buf != NULL)
2002   {
2003     GNUNET_assert (size >= m->size);
2004     memcpy (cbuf, &m[1], m->size);
2005     ret = m->size;
2006     GNUNET_BANDWIDTH_tracker_consume (&n->available_send_window, m->size);
2007 #if DEBUG_CORE
2008     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2009                 "Copied message of type %u and size %u into transport buffer for `%4s'\n",
2010                 (unsigned int)
2011                 ntohs (((struct GNUNET_MessageHeader *) &m[1])->type),
2012                 (unsigned int) ret, GNUNET_i2s (&n->peer));
2013 #endif
2014     process_encrypted_neighbour_queue (n);
2015   }
2016   else
2017   {
2018 #if DEBUG_CORE
2019     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2020                 "Transmission of message of type %u and size %u failed\n",
2021                 (unsigned int)
2022                 ntohs (((struct GNUNET_MessageHeader *) &m[1])->type),
2023                 (unsigned int) m->size);
2024 #endif
2025   }
2026   GNUNET_free (m);
2027   consider_free_neighbour (n);
2028   GNUNET_STATISTICS_update (stats,
2029                             gettext_noop
2030                             ("# encrypted bytes given to transport"), ret,
2031                             GNUNET_NO);
2032   return ret;
2033 }
2034
2035
2036 /**
2037  * Check if we have plaintext messages for the specified neighbour
2038  * pending, and if so, consider batching and encrypting them (and
2039  * then trigger processing of the encrypted queue if needed).
2040  *
2041  * @param n neighbour to check.
2042  */
2043 static void
2044 process_plaintext_neighbour_queue (struct Neighbour *n);
2045
2046
2047 /**
2048  * Check if we have encrypted messages for the specified neighbour
2049  * pending, and if so, check with the transport about sending them
2050  * out.
2051  *
2052  * @param n neighbour to check.
2053  */
2054 static void
2055 process_encrypted_neighbour_queue (struct Neighbour *n)
2056 {
2057   struct MessageEntry *m;
2058
2059   if (n->th != NULL)
2060     return;                     /* request already pending */
2061   if (GNUNET_YES != n->is_connected)
2062   {
2063     GNUNET_break (0);
2064     return;
2065   }
2066   m = n->encrypted_head;
2067   if (m == NULL)
2068   {
2069     /* encrypted queue empty, try plaintext instead */
2070     process_plaintext_neighbour_queue (n);
2071     return;
2072   }
2073 #if DEBUG_CORE > 1
2074   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2075               "Asking transport for transmission of %u bytes to `%4s' in next %llu ms\n",
2076               (unsigned int) m->size, GNUNET_i2s (&n->peer),
2077               (unsigned long long)
2078               GNUNET_TIME_absolute_get_remaining (m->deadline).rel_value);
2079 #endif
2080   n->th =
2081        GNUNET_TRANSPORT_notify_transmit_ready (transport, &n->peer, m->size,
2082                                               m->priority,
2083                                               GNUNET_TIME_absolute_get_remaining
2084                                               (m->deadline),
2085                                               &notify_encrypted_transmit_ready,
2086                                               n);
2087   if (n->th == NULL)
2088   {
2089     /* message request too large or duplicate request */
2090     GNUNET_break (0);
2091     /* discard encrypted message */
2092     GNUNET_CONTAINER_DLL_remove (n->encrypted_head, n->encrypted_tail, m);
2093     GNUNET_free (m);
2094     process_encrypted_neighbour_queue (n);
2095   }
2096 }
2097
2098
2099 /**
2100  * Decrypt size bytes from in and write the result to out.  Use the
2101  * key for inbound traffic of the given neighbour.  This function does
2102  * NOT do any integrity-checks on the result.
2103  *
2104  * @param n neighbour we are receiving from
2105  * @param iv initialization vector to use
2106  * @param in ciphertext
2107  * @param out plaintext
2108  * @param size size of in/out
2109  * @return GNUNET_OK on success
2110  */
2111 static int
2112 do_decrypt (struct Neighbour *n,
2113             const struct GNUNET_CRYPTO_AesInitializationVector *iv,
2114             const void *in, void *out, size_t size)
2115 {
2116   if (size != (uint16_t) size)
2117   {
2118     GNUNET_break (0);
2119     return GNUNET_NO;
2120   }
2121   if ((n->status != PEER_STATE_KEY_RECEIVED) &&
2122       (n->status != PEER_STATE_KEY_CONFIRMED))
2123   {
2124     GNUNET_break_op (0);
2125     return GNUNET_SYSERR;
2126   }
2127   if (size !=
2128       GNUNET_CRYPTO_aes_decrypt (in, (uint16_t) size, &n->decrypt_key, iv, out))
2129   {
2130     GNUNET_break (0);
2131     return GNUNET_SYSERR;
2132   }
2133   GNUNET_STATISTICS_update (stats, gettext_noop ("# bytes decrypted"), size,
2134                             GNUNET_NO);
2135 #if DEBUG_CORE > 1
2136   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2137               "Decrypted %u bytes from `%4s' using key %u, IV %u\n",
2138               (unsigned int) size, GNUNET_i2s (&n->peer),
2139               (unsigned int) n->decrypt_key.crc32, GNUNET_CRYPTO_crc32_n (iv,
2140                                                                           sizeof
2141                                                                           (*iv)));
2142 #endif
2143   return GNUNET_OK;
2144 }
2145
2146
2147 /**
2148  * Select messages for transmission.  This heuristic uses a combination
2149  * of earliest deadline first (EDF) scheduling (with bounded horizon)
2150  * and priority-based discard (in case no feasible schedule exist) and
2151  * speculative optimization (defer any kind of transmission until
2152  * we either create a batch of significant size, 25% of max, or until
2153  * we are close to a deadline).  Furthermore, when scheduling the
2154  * heuristic also packs as many messages into the batch as possible,
2155  * starting with those with the earliest deadline.  Yes, this is fun.
2156  *
2157  * @param n neighbour to select messages from
2158  * @param size number of bytes to select for transmission
2159  * @param retry_time set to the time when we should try again
2160  *        (only valid if this function returns zero)
2161  * @return number of bytes selected, or 0 if we decided to
2162  *         defer scheduling overall; in that case, retry_time is set.
2163  */
2164 static size_t
2165 select_messages (struct Neighbour *n, size_t size,
2166                  struct GNUNET_TIME_Relative *retry_time)
2167 {
2168   struct MessageEntry *pos;
2169   struct MessageEntry *min;
2170   struct MessageEntry *last;
2171   unsigned int min_prio;
2172   struct GNUNET_TIME_Absolute t;
2173   struct GNUNET_TIME_Absolute now;
2174   struct GNUNET_TIME_Relative delta;
2175   uint64_t avail;
2176   struct GNUNET_TIME_Relative slack;    /* how long could we wait before missing deadlines? */
2177   size_t off;
2178   uint64_t tsize;
2179   unsigned int queue_size;
2180   int discard_low_prio;
2181
2182   GNUNET_assert (NULL != n->messages);
2183   now = GNUNET_TIME_absolute_get ();
2184   /* last entry in linked list of messages processed */
2185   last = NULL;
2186   /* should we remove the entry with the lowest
2187    * priority from consideration for scheduling at the
2188    * end of the loop? */
2189   queue_size = 0;
2190   tsize = 0;
2191   pos = n->messages;
2192   while (pos != NULL)
2193   {
2194     queue_size++;
2195     tsize += pos->size;
2196     pos = pos->next;
2197   }
2198   discard_low_prio = GNUNET_YES;
2199   while (GNUNET_YES == discard_low_prio)
2200   {
2201     min = NULL;
2202     min_prio = UINT_MAX;
2203     discard_low_prio = GNUNET_NO;
2204     /* calculate number of bytes available for transmission at time "t" */
2205     avail = GNUNET_BANDWIDTH_tracker_get_available (&n->available_send_window);
2206     t = now;
2207     /* how many bytes have we (hypothetically) scheduled so far */
2208     off = 0;
2209     /* maximum time we can wait before transmitting anything
2210      * and still make all of our deadlines */
2211     slack = GNUNET_TIME_UNIT_FOREVER_REL;
2212     pos = n->messages;
2213     /* note that we use "*2" here because we want to look
2214      * a bit further into the future; much more makes no
2215      * sense since new message might be scheduled in the
2216      * meantime... */
2217     while ((pos != NULL) && (off < size * 2))
2218     {
2219       if (pos->do_transmit == GNUNET_YES)
2220       {
2221         /* already removed from consideration */
2222         pos = pos->next;
2223         continue;
2224       }
2225       if (discard_low_prio == GNUNET_NO)
2226       {
2227         delta = GNUNET_TIME_absolute_get_difference (t, pos->deadline);
2228         if (delta.rel_value > 0)
2229         {
2230           // FIXME: HUH? Check!
2231           t = pos->deadline;
2232           avail +=
2233               GNUNET_BANDWIDTH_value_get_available_until (n->bw_out, delta);
2234         }
2235         if (avail < pos->size)
2236         {
2237           // FIXME: HUH? Check!
2238           discard_low_prio = GNUNET_YES;        /* we could not schedule this one! */
2239         }
2240         else
2241         {
2242           avail -= pos->size;
2243           /* update slack, considering both its absolute deadline
2244            * and relative deadlines caused by other messages
2245            * with their respective load */
2246           slack =
2247               GNUNET_TIME_relative_min (slack,
2248                                         GNUNET_BANDWIDTH_value_get_delay_for
2249                                         (n->bw_out, avail));
2250           if (pos->deadline.abs_value <= now.abs_value)
2251           {
2252             /* now or never */
2253             slack = GNUNET_TIME_UNIT_ZERO;
2254           }
2255           else if (GNUNET_YES == pos->got_slack)
2256           {
2257             /* should be soon now! */
2258             slack =
2259                 GNUNET_TIME_relative_min (slack,
2260                                           GNUNET_TIME_absolute_get_remaining
2261                                           (pos->slack_deadline));
2262           }
2263           else
2264           {
2265             slack =
2266                 GNUNET_TIME_relative_min (slack,
2267                                           GNUNET_TIME_absolute_get_difference
2268                                           (now, pos->deadline));
2269             pos->got_slack = GNUNET_YES;
2270             pos->slack_deadline =
2271                 GNUNET_TIME_absolute_min (pos->deadline,
2272                                           GNUNET_TIME_relative_to_absolute
2273                                           (GNUNET_CONSTANTS_MAX_CORK_DELAY));
2274           }
2275         }
2276       }
2277       off += pos->size;
2278       t = GNUNET_TIME_absolute_max (pos->deadline, t);  // HUH? Check!
2279       if (pos->priority <= min_prio)
2280       {
2281         /* update min for discard */
2282         min_prio = pos->priority;
2283         min = pos;
2284       }
2285       pos = pos->next;
2286     }
2287     if (discard_low_prio)
2288     {
2289       GNUNET_assert (min != NULL);
2290       /* remove lowest-priority entry from consideration */
2291       min->do_transmit = GNUNET_YES;    /* means: discard (for now) */
2292     }
2293     last = pos;
2294   }
2295   /* guard against sending "tiny" messages with large headers without
2296    * urgent deadlines */
2297   if ((slack.rel_value > GNUNET_CONSTANTS_MAX_CORK_DELAY.rel_value) &&
2298       (size > 4 * off) && (queue_size <= MAX_PEER_QUEUE_SIZE - 2))
2299   {
2300     /* less than 25% of message would be filled with deadlines still
2301      * being met if we delay by one second or more; so just wait for
2302      * more data; but do not wait longer than 1s (since we don't want
2303      * to delay messages for a really long time either). */
2304     *retry_time = GNUNET_CONSTANTS_MAX_CORK_DELAY;
2305     /* reset do_transmit values for next time */
2306     while (pos != last)
2307     {
2308       pos->do_transmit = GNUNET_NO;
2309       pos = pos->next;
2310     }
2311     GNUNET_STATISTICS_update (stats,
2312                               gettext_noop
2313                               ("# transmissions delayed due to corking"), 1,
2314                               GNUNET_NO);
2315 #if DEBUG_CORE
2316     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2317                 "Deferring transmission for %llums due to underfull message buffer size (%u/%u)\n",
2318                 (unsigned long long) retry_time->rel_value, (unsigned int) off,
2319                 (unsigned int) size);
2320 #endif
2321     return 0;
2322   }
2323   /* select marked messages (up to size) for transmission */
2324   off = 0;
2325   pos = n->messages;
2326   while (pos != last)
2327   {
2328     if ((pos->size <= size) && (pos->do_transmit == GNUNET_NO))
2329     {
2330       pos->do_transmit = GNUNET_YES;    /* mark for transmission */
2331       off += pos->size;
2332       size -= pos->size;
2333 #if DEBUG_CORE > 1
2334       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2335                   "Selecting message of size %u for transmission\n",
2336                   (unsigned int) pos->size);
2337 #endif
2338     }
2339     else
2340     {
2341 #if DEBUG_CORE > 1
2342       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2343                   "Not selecting message of size %u for transmission at this time (maximum is %u)\n",
2344                   (unsigned int) pos->size, size);
2345 #endif
2346       pos->do_transmit = GNUNET_NO;     /* mark for not transmitting! */
2347     }
2348     pos = pos->next;
2349   }
2350 #if DEBUG_CORE
2351   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2352               "Selected %llu/%llu bytes of %u/%u plaintext messages for transmission to `%4s'.\n",
2353               (unsigned long long) off, (unsigned long long) tsize, queue_size,
2354               (unsigned int) MAX_PEER_QUEUE_SIZE, GNUNET_i2s (&n->peer));
2355 #endif
2356   return off;
2357 }
2358
2359
2360 /**
2361  * Batch multiple messages into a larger buffer.
2362  *
2363  * @param n neighbour to take messages from
2364  * @param buf target buffer
2365  * @param size size of buf
2366  * @param deadline set to transmission deadline for the result
2367  * @param retry_time set to the time when we should try again
2368  *        (only valid if this function returns zero)
2369  * @param priority set to the priority of the batch
2370  * @return number of bytes written to buf (can be zero)
2371  */
2372 static size_t
2373 batch_message (struct Neighbour *n, char *buf, size_t size,
2374                struct GNUNET_TIME_Absolute *deadline,
2375                struct GNUNET_TIME_Relative *retry_time, unsigned int *priority)
2376 {
2377   char ntmb[GNUNET_SERVER_MAX_MESSAGE_SIZE - 1];
2378   struct NotifyTrafficMessage *ntm = (struct NotifyTrafficMessage *) ntmb;
2379   struct MessageEntry *pos;
2380   struct MessageEntry *prev;
2381   struct MessageEntry *next;
2382   size_t ret;
2383
2384   ret = 0;
2385   *priority = 0;
2386   *deadline = GNUNET_TIME_UNIT_FOREVER_ABS;
2387   *retry_time = GNUNET_TIME_UNIT_FOREVER_REL;
2388   if (0 == select_messages (n, size, retry_time))
2389   {
2390 #if DEBUG_CORE
2391     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2392                 "No messages selected, will try again in %llu ms\n",
2393                 retry_time->rel_value);
2394 #endif
2395     return 0;
2396   }
2397   ntm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_OUTBOUND);
2398   ntm->ats_count = htonl (0);
2399   ntm->ats.type = htonl (0);
2400   ntm->ats.value = htonl (0);
2401   ntm->peer = n->peer;
2402   pos = n->messages;
2403   prev = NULL;
2404   while ((pos != NULL) && (size >= sizeof (struct GNUNET_MessageHeader)))
2405   {
2406     next = pos->next;
2407     if (GNUNET_YES == pos->do_transmit)
2408     {
2409       GNUNET_assert (pos->size <= size);
2410       /* do notifications */
2411       /* FIXME: track if we have *any* client that wants
2412        * full notifications and only do this if that is
2413        * actually true */
2414       if (pos->size <
2415           GNUNET_SERVER_MAX_MESSAGE_SIZE - sizeof (struct NotifyTrafficMessage))
2416       {
2417         memcpy (&ntm[1], &pos[1], pos->size);
2418         ntm->header.size =
2419             htons (sizeof (struct NotifyTrafficMessage) +
2420                    sizeof (struct GNUNET_MessageHeader));
2421         send_to_all_clients (&ntm->header, GNUNET_YES,
2422                              GNUNET_CORE_OPTION_SEND_HDR_OUTBOUND);
2423       }
2424       else
2425       {
2426         /* message too large for 'full' notifications, we do at
2427          * least the 'hdr' type */
2428         memcpy (&ntm[1], &pos[1], sizeof (struct GNUNET_MessageHeader));
2429       }
2430       ntm->header.size =
2431           htons (sizeof (struct NotifyTrafficMessage) + pos->size);
2432       send_to_all_clients (&ntm->header, GNUNET_YES,
2433                            GNUNET_CORE_OPTION_SEND_FULL_OUTBOUND);
2434 #if DEBUG_HANDSHAKE
2435       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2436                   "Encrypting %u bytes with message of type %u and size %u\n",
2437                   pos->size,
2438                   (unsigned int)
2439                   ntohs (((const struct GNUNET_MessageHeader *) &pos[1])->type),
2440                   (unsigned int)
2441                   ntohs (((const struct GNUNET_MessageHeader *)
2442                           &pos[1])->size));
2443 #endif
2444       /* copy for encrypted transmission */
2445       memcpy (&buf[ret], &pos[1], pos->size);
2446       ret += pos->size;
2447       size -= pos->size;
2448       *priority += pos->priority;
2449 #if DEBUG_CORE > 1
2450       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2451                   "Adding plaintext message of size %u with deadline %llu ms to batch\n",
2452                   (unsigned int) pos->size,
2453                   (unsigned long long)
2454                   GNUNET_TIME_absolute_get_remaining (pos->deadline).rel_value);
2455 #endif
2456       deadline->abs_value =
2457           GNUNET_MIN (deadline->abs_value, pos->deadline.abs_value);
2458       GNUNET_free (pos);
2459       if (prev == NULL)
2460         n->messages = next;
2461       else
2462         prev->next = next;
2463     }
2464     else
2465     {
2466       prev = pos;
2467     }
2468     pos = next;
2469   }
2470 #if DEBUG_CORE > 1
2471   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2472               "Deadline for message batch is %llu ms\n",
2473               GNUNET_TIME_absolute_get_remaining (*deadline).rel_value);
2474 #endif
2475   return ret;
2476 }
2477
2478
2479 /**
2480  * Remove messages with deadlines that have long expired from
2481  * the queue.
2482  *
2483  * @param n neighbour to inspect
2484  */
2485 static void
2486 discard_expired_messages (struct Neighbour *n)
2487 {
2488   struct MessageEntry *prev;
2489   struct MessageEntry *next;
2490   struct MessageEntry *pos;
2491   struct GNUNET_TIME_Absolute now;
2492   struct GNUNET_TIME_Relative delta;
2493   int disc;
2494   unsigned int queue_length;
2495
2496   disc = GNUNET_NO;
2497   now = GNUNET_TIME_absolute_get ();
2498   prev = NULL;
2499   queue_length = 0;
2500   pos = n->messages;
2501   while (pos != NULL)
2502   {
2503     queue_length++;
2504     next = pos->next;
2505     delta = GNUNET_TIME_absolute_get_difference (pos->deadline, now);
2506     if (delta.rel_value > PAST_EXPIRATION_DISCARD_TIME.rel_value)
2507     {
2508 #if DEBUG_CORE
2509       GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2510                   "Message is %llu ms past due, discarding.\n",
2511                   delta.rel_value);
2512 #endif
2513       if (prev == NULL)
2514         n->messages = next;
2515       else
2516         prev->next = next;
2517       GNUNET_STATISTICS_update (stats,
2518                                 gettext_noop
2519                                 ("# messages discarded (expired prior to transmission)"),
2520                                 1, GNUNET_NO);
2521       disc = GNUNET_YES;
2522       GNUNET_free (pos);
2523     }
2524     else
2525       prev = pos;
2526     pos = next;
2527   }
2528   if ( (GNUNET_YES == disc) &&
2529        (queue_length == MAX_PEER_QUEUE_SIZE) )
2530     schedule_peer_messages (n);
2531 }
2532
2533
2534 /**
2535  * Signature of the main function of a task.
2536  *
2537  * @param cls closure
2538  * @param tc context information (why was this task triggered now)
2539  */
2540 static void
2541 retry_plaintext_processing (void *cls,
2542                             const struct GNUNET_SCHEDULER_TaskContext *tc)
2543 {
2544   struct Neighbour *n = cls;
2545
2546   n->retry_plaintext_task = GNUNET_SCHEDULER_NO_TASK;
2547   process_plaintext_neighbour_queue (n);
2548 }
2549
2550
2551 /**
2552  * Send our key (and encrypted PING) to the other peer.
2553  *
2554  * @param n the other peer
2555  */
2556 static void
2557 send_key (struct Neighbour *n);
2558
2559 /**
2560  * Task that will retry "send_key" if our previous attempt failed
2561  * to yield a PONG.
2562  */
2563 static void
2564 set_key_retry_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
2565 {
2566   struct Neighbour *n = cls;
2567
2568 #if DEBUG_CORE
2569   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Retrying key transmission to `%4s'\n",
2570               GNUNET_i2s (&n->peer));
2571 #endif
2572   n->retry_set_key_task = GNUNET_SCHEDULER_NO_TASK;
2573   n->set_key_retry_frequency =
2574       GNUNET_TIME_relative_multiply (n->set_key_retry_frequency, 2);
2575   send_key (n);
2576 }
2577
2578
2579 /**
2580  * Check if we have plaintext messages for the specified neighbour
2581  * pending, and if so, consider batching and encrypting them (and
2582  * then trigger processing of the encrypted queue if needed).
2583  *
2584  * @param n neighbour to check.
2585  */
2586 static void
2587 process_plaintext_neighbour_queue (struct Neighbour *n)
2588 {
2589   char pbuf[GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE + sizeof (struct EncryptedMessage)];    /* plaintext */
2590   size_t used;
2591   struct EncryptedMessage *em;  /* encrypted message */
2592   struct EncryptedMessage *ph;  /* plaintext header */
2593   struct MessageEntry *me;
2594   unsigned int priority;
2595   struct GNUNET_TIME_Absolute deadline;
2596   struct GNUNET_TIME_Relative retry_time;
2597   struct GNUNET_CRYPTO_AesInitializationVector iv;
2598   struct GNUNET_CRYPTO_AuthKey auth_key;
2599
2600   if (n->retry_plaintext_task != GNUNET_SCHEDULER_NO_TASK)
2601   {
2602     GNUNET_SCHEDULER_cancel (n->retry_plaintext_task);
2603     n->retry_plaintext_task = GNUNET_SCHEDULER_NO_TASK;
2604   }
2605   switch (n->status)
2606   {
2607   case PEER_STATE_DOWN:
2608     send_key (n);
2609 #if DEBUG_CORE
2610     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2611                 "Not yet connected to `%4s', deferring processing of plaintext messages.\n",
2612                 GNUNET_i2s (&n->peer));
2613 #endif
2614     return;
2615   case PEER_STATE_KEY_SENT:
2616     if (n->retry_set_key_task == GNUNET_SCHEDULER_NO_TASK)
2617       n->retry_set_key_task =
2618           GNUNET_SCHEDULER_add_delayed (n->set_key_retry_frequency,
2619                                         &set_key_retry_task, n);
2620 #if DEBUG_CORE
2621     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2622                 "Not yet connected to `%4s', deferring processing of plaintext messages.\n",
2623                 GNUNET_i2s (&n->peer));
2624 #endif
2625     return;
2626   case PEER_STATE_KEY_RECEIVED:
2627     if (n->retry_set_key_task == GNUNET_SCHEDULER_NO_TASK)
2628       n->retry_set_key_task =
2629           GNUNET_SCHEDULER_add_delayed (n->set_key_retry_frequency,
2630                                         &set_key_retry_task, n);
2631 #if DEBUG_CORE
2632     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2633                 "Not yet connected to `%4s', deferring processing of plaintext messages.\n",
2634                 GNUNET_i2s (&n->peer));
2635 #endif
2636     return;
2637   case PEER_STATE_KEY_CONFIRMED:
2638     /* ready to continue */
2639     break;
2640   }
2641   discard_expired_messages (n);
2642   if (n->messages == NULL)
2643   {
2644 #if DEBUG_CORE
2645     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2646                 "Plaintext message queue for `%4s' is empty.\n",
2647                 GNUNET_i2s (&n->peer));
2648 #endif
2649     return;                     /* no pending messages */
2650   }
2651   if (n->encrypted_head != NULL)
2652   {
2653 #if DEBUG_CORE > 2
2654     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2655                 "Encrypted message queue for `%4s' is still full, delaying plaintext processing.\n",
2656                 GNUNET_i2s (&n->peer));
2657 #endif
2658     return;                     /* wait for messages already encrypted to be
2659                                  * processed first! */
2660   }
2661   ph = (struct EncryptedMessage *) pbuf;
2662   deadline = GNUNET_TIME_UNIT_FOREVER_ABS;
2663   priority = 0;
2664   used = sizeof (struct EncryptedMessage);
2665   used +=
2666       batch_message (n, &pbuf[used],
2667                      GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE, &deadline,
2668                      &retry_time, &priority);
2669   if (used == sizeof (struct EncryptedMessage))
2670   {
2671 #if DEBUG_CORE > 1
2672     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2673                 "No messages selected for transmission to `%4s' at this time, will try again later.\n",
2674                 GNUNET_i2s (&n->peer));
2675 #endif
2676     /* no messages selected for sending, try again later... */
2677     n->retry_plaintext_task =
2678         GNUNET_SCHEDULER_add_delayed (retry_time, &retry_plaintext_processing,
2679                                       n);
2680     return;
2681   }
2682 #if DEBUG_CORE_QUOTA
2683   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2684               "Sending %u b/s as new limit to peer `%4s'\n",
2685               (unsigned int) ntohl (n->bw_in.value__), GNUNET_i2s (&n->peer));
2686 #endif
2687   ph->iv_seed =
2688       htonl (GNUNET_CRYPTO_random_u32
2689              (GNUNET_CRYPTO_QUALITY_NONCE, UINT32_MAX));
2690   ph->sequence_number = htonl (++n->last_sequence_number_sent);
2691   ph->inbound_bw_limit = n->bw_in;
2692   ph->timestamp = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get ());
2693
2694   /* setup encryption message header */
2695   me = GNUNET_malloc (sizeof (struct MessageEntry) + used);
2696   me->deadline = deadline;
2697   me->priority = priority;
2698   me->size = used;
2699   em = (struct EncryptedMessage *) &me[1];
2700   em->header.size = htons (used);
2701   em->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_ENCRYPTED_MESSAGE);
2702   em->iv_seed = ph->iv_seed;
2703   derive_iv (&iv, &n->encrypt_key, ph->iv_seed, &n->peer);
2704   /* encrypt */
2705 #if DEBUG_HANDSHAKE
2706   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2707               "Encrypting %u bytes of plaintext messages for `%4s' for transmission in %llums.\n",
2708               (unsigned int) used - ENCRYPTED_HEADER_SIZE,
2709               GNUNET_i2s (&n->peer),
2710               (unsigned long long)
2711               GNUNET_TIME_absolute_get_remaining (deadline).rel_value);
2712 #endif
2713   GNUNET_assert (GNUNET_OK ==
2714                  do_encrypt (n, &iv, &ph->sequence_number, &em->sequence_number,
2715                              used - ENCRYPTED_HEADER_SIZE));
2716   derive_auth_key (&auth_key, &n->encrypt_key, ph->iv_seed,
2717                    n->encrypt_key_created);
2718   GNUNET_CRYPTO_hmac (&auth_key, &em->sequence_number,
2719                       used - ENCRYPTED_HEADER_SIZE, &em->hmac);
2720 #if DEBUG_HANDSHAKE
2721   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2722               "Authenticated %u bytes of ciphertext %u: `%s'\n",
2723               used - ENCRYPTED_HEADER_SIZE,
2724               GNUNET_CRYPTO_crc32_n (&em->sequence_number,
2725                                      used - ENCRYPTED_HEADER_SIZE),
2726               GNUNET_h2s (&em->hmac));
2727 #endif
2728   /* append to transmission list */
2729   GNUNET_CONTAINER_DLL_insert_after (n->encrypted_head, n->encrypted_tail,
2730                                      n->encrypted_tail, me);
2731   process_encrypted_neighbour_queue (n);
2732   schedule_peer_messages (n);
2733 }
2734
2735
2736 /**
2737  * Function that recalculates the bandwidth quota for the
2738  * given neighbour and transmits it to the transport service.
2739  *
2740  * @param cls neighbour for the quota update
2741  * @param tc context
2742  */
2743 static void
2744 neighbour_quota_update (void *cls,
2745                         const struct GNUNET_SCHEDULER_TaskContext *tc);
2746
2747
2748 /**
2749  * Schedule the task that will recalculate the bandwidth
2750  * quota for this peer (and possibly force a disconnect of
2751  * idle peers by calculating a bandwidth of zero).
2752  */
2753 static void
2754 schedule_quota_update (struct Neighbour *n)
2755 {
2756   GNUNET_assert (n->quota_update_task == GNUNET_SCHEDULER_NO_TASK);
2757   n->quota_update_task =
2758       GNUNET_SCHEDULER_add_delayed (QUOTA_UPDATE_FREQUENCY,
2759                                     &neighbour_quota_update, n);
2760 }
2761
2762
2763 /**
2764  * Initialize a new 'struct Neighbour'.
2765  *
2766  * @param pid ID of the new neighbour
2767  * @return handle for the new neighbour
2768  */
2769 static struct Neighbour *
2770 create_neighbour (const struct GNUNET_PeerIdentity *pid)
2771 {
2772   struct Neighbour *n;
2773   struct GNUNET_TIME_Absolute now;
2774
2775 #if DEBUG_CORE
2776   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2777               "Creating neighbour entry for peer `%4s'\n", GNUNET_i2s (pid));
2778 #endif
2779   n = GNUNET_malloc (sizeof (struct Neighbour));
2780   n->peer = *pid;
2781   GNUNET_CRYPTO_aes_create_session_key (&n->encrypt_key);
2782   now = GNUNET_TIME_absolute_get ();
2783   n->encrypt_key_created = now;
2784   n->last_activity = now;
2785   n->set_key_retry_frequency = INITIAL_SET_KEY_RETRY_FREQUENCY;
2786   n->bw_in = GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT;
2787   n->bw_out = GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT;
2788   n->bw_out_internal_limit = GNUNET_BANDWIDTH_value_init (UINT32_MAX);
2789   n->bw_out_external_limit = GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT;
2790   n->ping_challenge =
2791       GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, UINT32_MAX);
2792   GNUNET_assert (GNUNET_OK ==
2793                  GNUNET_CONTAINER_multihashmap_put (neighbours,
2794                                                     &n->peer.hashPubKey, n,
2795                                                     GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
2796   GNUNET_STATISTICS_set (stats, gettext_noop ("# neighbour entries allocated"),
2797                          GNUNET_CONTAINER_multihashmap_size (neighbours),
2798                          GNUNET_NO);
2799   neighbour_quota_update (n, NULL);
2800   consider_free_neighbour (n);
2801   return n;
2802 }
2803
2804
2805 /**
2806  * Handle CORE_SEND request.
2807  *
2808  * @param cls unused
2809  * @param client the client issuing the request
2810  * @param message the "struct SendMessage"
2811  */
2812 static void
2813 handle_client_send (void *cls, struct GNUNET_SERVER_Client *client,
2814                     const struct GNUNET_MessageHeader *message)
2815 {
2816   const struct SendMessage *sm;
2817   struct Neighbour *n;
2818   struct MessageEntry *prev;
2819   struct MessageEntry *pos;
2820   struct MessageEntry *e;
2821   struct MessageEntry *min_prio_entry;
2822   struct MessageEntry *min_prio_prev;
2823   unsigned int min_prio;
2824   unsigned int queue_size;
2825   uint16_t msize;
2826
2827   msize = ntohs (message->size);
2828   if (msize <
2829       sizeof (struct SendMessage) + sizeof (struct GNUNET_MessageHeader))
2830   {
2831     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2832                 "msize is %u, should be at least %u (in %s:%d)\n", msize,
2833                 sizeof (struct SendMessage) +
2834                 sizeof (struct GNUNET_MessageHeader), __FILE__, __LINE__);
2835     GNUNET_break (0);
2836     if (client != NULL)
2837       GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
2838     return;
2839   }
2840   sm = (const struct SendMessage *) message;
2841   msize -= sizeof (struct SendMessage);
2842   if (0 ==
2843       memcmp (&sm->peer, &my_identity, sizeof (struct GNUNET_PeerIdentity)))
2844   {
2845     /* loopback */
2846     GNUNET_SERVER_mst_receive (mst, &self, (const char *) &sm[1], msize,
2847                                GNUNET_YES, GNUNET_NO);
2848     if (client != NULL)
2849       GNUNET_SERVER_receive_done (client, GNUNET_OK);
2850     return;
2851   }
2852   n = find_neighbour (&sm->peer);
2853   if ((n == NULL) || (GNUNET_YES != n->is_connected) ||
2854       (n->status != PEER_STATE_KEY_CONFIRMED))
2855   {
2856     /* attempt to send message to peer that is not connected anymore
2857      * (can happen due to asynchrony) */
2858     GNUNET_STATISTICS_update (stats,
2859                               gettext_noop
2860                               ("# messages discarded (disconnected)"), 1,
2861                               GNUNET_NO);
2862     if (client != NULL)
2863       GNUNET_SERVER_receive_done (client, GNUNET_OK);
2864     return;
2865   }
2866 #if DEBUG_CORE
2867   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2868               "Core received `%s' request, queueing %u bytes of plaintext data for transmission to `%4s'.\n",
2869               "SEND", (unsigned int) msize, GNUNET_i2s (&sm->peer));
2870 #endif
2871   discard_expired_messages (n);
2872   /* bound queue size */
2873   /* NOTE: this entire block to bound the queue size should be
2874    * obsolete with the new client-request code and the
2875    * 'schedule_peer_messages' mechanism; we still have this code in
2876    * here for now as a sanity check for the new mechanmism;
2877    * ultimately, we should probably simply reject SEND messages that
2878    * are not 'approved' (or provide a new core API for very unreliable
2879    * delivery that always sends with priority 0).  Food for thought. */
2880   min_prio = UINT32_MAX;
2881   min_prio_entry = NULL;
2882   min_prio_prev = NULL;
2883   queue_size = 0;
2884   prev = NULL;
2885   pos = n->messages;
2886   while (pos != NULL)
2887   {
2888     if (pos->priority <= min_prio)
2889     {
2890       min_prio_entry = pos;
2891       min_prio_prev = prev;
2892       min_prio = pos->priority;
2893     }
2894     queue_size++;
2895     prev = pos;
2896     pos = pos->next;
2897   }
2898   if (queue_size >= MAX_PEER_QUEUE_SIZE)
2899   {
2900     /* queue full */
2901     if (ntohl (sm->priority) <= min_prio)
2902     {
2903       /* discard new entry; this should no longer happen! */
2904       GNUNET_break (0);
2905 #if DEBUG_CORE
2906       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2907                   "Queue full (%u/%u), discarding new request (%u bytes of type %u)\n",
2908                   queue_size, (unsigned int) MAX_PEER_QUEUE_SIZE,
2909                   (unsigned int) msize, (unsigned int) ntohs (message->type));
2910 #endif
2911       GNUNET_STATISTICS_update (stats,
2912                                 gettext_noop ("# discarded CORE_SEND requests"),
2913                                 1, GNUNET_NO);
2914
2915       if (client != NULL)
2916         GNUNET_SERVER_receive_done (client, GNUNET_OK);
2917       return;
2918     }
2919     GNUNET_assert (min_prio_entry != NULL);
2920     /* discard "min_prio_entry" */
2921 #if DEBUG_CORE
2922     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2923                 "Queue full, discarding existing older request\n");
2924 #endif
2925     GNUNET_STATISTICS_update (stats,
2926                               gettext_noop
2927                               ("# discarded lower priority CORE_SEND requests"),
2928                               1, GNUNET_NO);
2929     if (min_prio_prev == NULL)
2930       n->messages = min_prio_entry->next;
2931     else
2932       min_prio_prev->next = min_prio_entry->next;
2933     GNUNET_free (min_prio_entry);
2934   }
2935
2936 #if DEBUG_CORE
2937   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2938               "Adding transmission request for `%4s' of size %u to queue\n",
2939               GNUNET_i2s (&sm->peer), (unsigned int) msize);
2940 #endif
2941   GNUNET_break (0 == ntohl (sm->reserved));
2942   e = GNUNET_malloc (sizeof (struct MessageEntry) + msize);
2943   e->deadline = GNUNET_TIME_absolute_ntoh (sm->deadline);
2944   e->priority = ntohl (sm->priority);
2945   e->size = msize;
2946   if (GNUNET_YES != (int) ntohl (sm->cork))
2947     e->got_slack = GNUNET_YES;
2948   memcpy (&e[1], &sm[1], msize);
2949
2950   /* insert, keep list sorted by deadline */
2951   prev = NULL;
2952   pos = n->messages;
2953   while ((pos != NULL) && (pos->deadline.abs_value < e->deadline.abs_value))
2954   {
2955     prev = pos;
2956     pos = pos->next;
2957   }
2958   if (prev == NULL)
2959     n->messages = e;
2960   else
2961     prev->next = e;
2962   e->next = pos;
2963
2964   /* consider scheduling now */
2965   process_plaintext_neighbour_queue (n);
2966   if (client != NULL)
2967     GNUNET_SERVER_receive_done (client, GNUNET_OK);
2968 }
2969
2970
2971 /**
2972  * PEERINFO is giving us a HELLO for a peer.  Add the public key to
2973  * the neighbour's struct and retry send_key.  Or, if we did not get a
2974  * HELLO, just do nothing.
2975  *
2976  * @param cls the 'struct Neighbour' to retry sending the key for
2977  * @param peer the peer for which this is the HELLO
2978  * @param hello HELLO message of that peer
2979  * @param err_msg NULL if successful, otherwise contains error message
2980  */
2981 static void
2982 process_hello_retry_send_key (void *cls, const struct GNUNET_PeerIdentity *peer,
2983                               const struct GNUNET_HELLO_Message *hello,
2984                               const char *err_msg)
2985 {
2986   struct Neighbour *n = cls;
2987
2988   if (err_msg != NULL)
2989   {
2990     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2991                 _("Error in communication with PEERINFO service\n"));
2992     /* return; */
2993   }
2994
2995   if (peer == NULL)
2996   {
2997 #if DEBUG_CORE
2998     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Entered `%s' and `%s' is NULL!\n",
2999                 "process_hello_retry_send_key", "peer");
3000 #endif
3001     n->pitr = NULL;
3002     if (n->public_key != NULL)
3003     {
3004       if (n->retry_set_key_task != GNUNET_SCHEDULER_NO_TASK)
3005       {
3006         GNUNET_SCHEDULER_cancel (n->retry_set_key_task);
3007         n->retry_set_key_task = GNUNET_SCHEDULER_NO_TASK;
3008       }
3009       GNUNET_STATISTICS_update (stats,
3010                                 gettext_noop
3011                                 ("# SET_KEY messages deferred (need public key)"),
3012                                 -1, GNUNET_NO);
3013       send_key (n);
3014     }
3015     else
3016     {
3017 #if DEBUG_CORE
3018       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3019                   "Failed to obtain public key for peer `%4s', delaying processing of SET_KEY\n",
3020                   GNUNET_i2s (&n->peer));
3021 #endif
3022       GNUNET_STATISTICS_update (stats,
3023                                 gettext_noop
3024                                 ("# Delayed connecting due to lack of public key"),
3025                                 1, GNUNET_NO);
3026       if (GNUNET_SCHEDULER_NO_TASK == n->retry_set_key_task)
3027         n->retry_set_key_task =
3028             GNUNET_SCHEDULER_add_delayed (n->set_key_retry_frequency,
3029                                           &set_key_retry_task, n);
3030     }
3031     return;
3032   }
3033
3034 #if DEBUG_CORE
3035   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Entered `%s' for peer `%4s'\n",
3036               "process_hello_retry_send_key", GNUNET_i2s (peer));
3037 #endif
3038   if (n->public_key != NULL)
3039   {
3040     /* already have public key, why are we here? */
3041     GNUNET_break (0);
3042     return;
3043   }
3044
3045 #if DEBUG_CORE
3046   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3047               "Received new `%s' message for `%4s', initiating key exchange.\n",
3048               "HELLO", GNUNET_i2s (peer));
3049 #endif
3050   n->public_key =
3051       GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded));
3052   if (GNUNET_OK != GNUNET_HELLO_get_key (hello, n->public_key))
3053   {
3054     GNUNET_STATISTICS_update (stats,
3055                               gettext_noop
3056                               ("# Error extracting public key from HELLO"), 1,
3057                               GNUNET_NO);
3058     GNUNET_free (n->public_key);
3059     n->public_key = NULL;
3060 #if DEBUG_CORE
3061     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3062                 "GNUNET_HELLO_get_key returned awfully\n");
3063 #endif
3064     return;
3065   }
3066 }
3067
3068
3069 /**
3070  * Send our key (and encrypted PING) to the other peer.
3071  *
3072  * @param n the other peer
3073  */
3074 static void
3075 send_key (struct Neighbour *n)
3076 {
3077   struct MessageEntry *pos;
3078   struct SetKeyMessage *sm;
3079   struct MessageEntry *me;
3080   struct PingMessage pp;
3081   struct PingMessage *pm;
3082   struct GNUNET_CRYPTO_AesInitializationVector iv;
3083
3084   if (n->retry_set_key_task != GNUNET_SCHEDULER_NO_TASK)
3085   {
3086     GNUNET_SCHEDULER_cancel (n->retry_set_key_task);
3087     n->retry_set_key_task = GNUNET_SCHEDULER_NO_TASK;
3088   }
3089   if (n->pitr != NULL)
3090   {
3091 #if DEBUG_CORE
3092     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3093                 "Key exchange in progress with `%4s'.\n",
3094                 GNUNET_i2s (&n->peer));
3095 #endif
3096     return;                     /* already in progress */
3097   }
3098   if (GNUNET_YES != n->is_connected)
3099   {
3100     GNUNET_STATISTICS_update (stats,
3101                               gettext_noop
3102                               ("# Asking transport to connect (for SET_KEY)"),
3103                               1, GNUNET_NO);
3104     GNUNET_TRANSPORT_try_connect (transport, &n->peer);
3105     return;
3106   }
3107 #if DEBUG_CORE
3108   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3109               "Asked to perform key exchange with `%4s'.\n",
3110               GNUNET_i2s (&n->peer));
3111 #endif
3112   if (n->public_key == NULL)
3113   {
3114     /* lookup n's public key, then try again */
3115 #if DEBUG_CORE
3116     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3117                 "Lacking public key for `%4s', trying to obtain one (send_key).\n",
3118                 GNUNET_i2s (&n->peer));
3119 #endif
3120     GNUNET_assert (n->pitr == NULL);
3121     n->pitr =
3122         GNUNET_PEERINFO_iterate (peerinfo, &n->peer,
3123                                  GNUNET_TIME_relative_multiply
3124                                  (GNUNET_TIME_UNIT_SECONDS, 20),
3125                                  &process_hello_retry_send_key, n);
3126     return;
3127   }
3128   pos = n->encrypted_head;
3129   while (pos != NULL)
3130   {
3131     if (GNUNET_YES == pos->is_setkey)
3132     {
3133       if (pos->sender_status == n->status)
3134       {
3135 #if DEBUG_CORE
3136         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3137                     "`%s' message for `%4s' queued already\n", "SET_KEY",
3138                     GNUNET_i2s (&n->peer));
3139 #endif
3140         goto trigger_processing;
3141       }
3142       GNUNET_CONTAINER_DLL_remove (n->encrypted_head, n->encrypted_tail, pos);
3143       GNUNET_free (pos);
3144 #if DEBUG_CORE
3145       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3146                   "Removing queued `%s' message for `%4s', will create a new one\n",
3147                   "SET_KEY", GNUNET_i2s (&n->peer));
3148 #endif
3149       break;
3150     }
3151     pos = pos->next;
3152   }
3153
3154   /* update status */
3155   switch (n->status)
3156   {
3157   case PEER_STATE_DOWN:
3158     n->status = PEER_STATE_KEY_SENT;
3159     break;
3160   case PEER_STATE_KEY_SENT:
3161     break;
3162   case PEER_STATE_KEY_RECEIVED:
3163     break;
3164   case PEER_STATE_KEY_CONFIRMED:
3165     break;
3166   default:
3167     GNUNET_break (0);
3168     break;
3169   }
3170
3171
3172   /* first, set key message */
3173   me = GNUNET_malloc (sizeof (struct MessageEntry) +
3174                       sizeof (struct SetKeyMessage) +
3175                       sizeof (struct PingMessage));
3176   me->deadline = GNUNET_TIME_relative_to_absolute (MAX_SET_KEY_DELAY);
3177   me->priority = SET_KEY_PRIORITY;
3178   me->size = sizeof (struct SetKeyMessage) + sizeof (struct PingMessage);
3179   me->is_setkey = GNUNET_YES;
3180   me->got_slack = GNUNET_YES;   /* do not defer this one! */
3181   me->sender_status = n->status;
3182   GNUNET_CONTAINER_DLL_insert_after (n->encrypted_head, n->encrypted_tail,
3183                                      n->encrypted_tail, me);
3184   sm = (struct SetKeyMessage *) &me[1];
3185   sm->header.size = htons (sizeof (struct SetKeyMessage));
3186   sm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_SET_KEY);
3187   sm->sender_status =
3188       htonl ((int32_t)
3189              ((n->status ==
3190                PEER_STATE_DOWN) ? PEER_STATE_KEY_SENT : n->status));
3191   sm->purpose.size =
3192       htonl (sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) +
3193              sizeof (struct GNUNET_TIME_AbsoluteNBO) +
3194              sizeof (struct GNUNET_CRYPTO_RsaEncryptedData) +
3195              sizeof (struct GNUNET_PeerIdentity));
3196   sm->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_SET_KEY);
3197   sm->creation_time = GNUNET_TIME_absolute_hton (n->encrypt_key_created);
3198   sm->target = n->peer;
3199   GNUNET_assert (GNUNET_OK ==
3200                  GNUNET_CRYPTO_rsa_encrypt (&n->encrypt_key,
3201                                             sizeof (struct
3202                                                     GNUNET_CRYPTO_AesSessionKey),
3203                                             n->public_key, &sm->encrypted_key));
3204   GNUNET_assert (GNUNET_OK ==
3205                  GNUNET_CRYPTO_rsa_sign (my_private_key, &sm->purpose,
3206                                          &sm->signature));
3207   pm = (struct PingMessage *) &sm[1];
3208   pm->header.size = htons (sizeof (struct PingMessage));
3209   pm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_PING);
3210   pm->iv_seed =
3211       GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, UINT32_MAX);
3212   derive_iv (&iv, &n->encrypt_key, pm->iv_seed, &n->peer);
3213   pp.challenge = n->ping_challenge;
3214   pp.target = n->peer;
3215 #if DEBUG_HANDSHAKE
3216   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3217               "Encrypting `%s' and `%s' messages with challenge %u for `%4s' using key %u, IV %u (salt %u).\n",
3218               "SET_KEY", "PING", (unsigned int) n->ping_challenge,
3219               GNUNET_i2s (&n->peer), (unsigned int) n->encrypt_key.crc32,
3220               GNUNET_CRYPTO_crc32_n (&iv, sizeof (iv)), pm->iv_seed);
3221 #endif
3222   do_encrypt (n, &iv, &pp.target, &pm->target,
3223               sizeof (struct PingMessage) - ((void *) &pm->target -
3224                                              (void *) pm));
3225   GNUNET_STATISTICS_update (stats,
3226                             gettext_noop
3227                             ("# SET_KEY and PING messages created"), 1,
3228                             GNUNET_NO);
3229 #if DEBUG_CORE
3230   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3231               "Have %llu ms left for `%s' transmission.\n",
3232               (unsigned long long)
3233               GNUNET_TIME_absolute_get_remaining (me->deadline).rel_value,
3234               "SET_KEY");
3235 #endif
3236 trigger_processing:
3237   /* trigger queue processing */
3238   process_encrypted_neighbour_queue (n);
3239   if ((n->status != PEER_STATE_KEY_CONFIRMED) &&
3240       (GNUNET_SCHEDULER_NO_TASK == n->retry_set_key_task))
3241     n->retry_set_key_task =
3242         GNUNET_SCHEDULER_add_delayed (n->set_key_retry_frequency,
3243                                       &set_key_retry_task, n);
3244 }
3245
3246
3247 /**
3248  * We received a SET_KEY message.  Validate and update
3249  * our key material and status.
3250  *
3251  * @param n the neighbour from which we received message m
3252  * @param m the set key message we received
3253  * @param ats performance data
3254  * @param ats_count number of entries in ats (excluding 0-termination)
3255  */
3256 static void
3257 handle_set_key (struct Neighbour *n, const struct SetKeyMessage *m,
3258                 const struct GNUNET_TRANSPORT_ATS_Information *ats,
3259                 uint32_t ats_count);
3260
3261
3262
3263 /**
3264  * PEERINFO is giving us a HELLO for a peer.  Add the public key to
3265  * the neighbour's struct and retry handling the set_key message.  Or,
3266  * if we did not get a HELLO, just free the set key message.
3267  *
3268  * @param cls pointer to the set key message
3269  * @param peer the peer for which this is the HELLO
3270  * @param hello HELLO message of that peer
3271  * @param err_msg NULL if successful, otherwise contains error message
3272  */
3273 static void
3274 process_hello_retry_handle_set_key (void *cls,
3275                                     const struct GNUNET_PeerIdentity *peer,
3276                                     const struct GNUNET_HELLO_Message *hello,
3277                                     const char *err_msg)
3278 {
3279   struct Neighbour *n = cls;
3280   struct SetKeyMessage *sm = n->skm;
3281
3282   if (err_msg != NULL)
3283   {
3284     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3285                 _("Error in communication with PEERINFO service\n"));
3286     /* return; */
3287   }
3288
3289   if (peer == NULL)
3290   {
3291     n->skm = NULL;
3292     n->pitr = NULL;
3293     if (n->public_key != NULL)
3294     {
3295 #if DEBUG_CORE
3296       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3297                   "Received `%s' for `%4s', continuing processing of `%s' message.\n",
3298                   "HELLO", GNUNET_i2s (&n->peer), "SET_KEY");
3299 #endif
3300       handle_set_key (n, sm, NULL, 0);
3301     }
3302     else
3303     {
3304       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3305                   _
3306                   ("Ignoring `%s' message due to lack of public key for peer `%4s' (failed to obtain one).\n"),
3307                   "SET_KEY", GNUNET_i2s (&n->peer));
3308     }
3309     GNUNET_free (sm);
3310     return;
3311   }
3312   if (n->public_key != NULL)
3313     return;                     /* multiple HELLOs match!? */
3314   n->public_key =
3315       GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded));
3316   if (GNUNET_OK != GNUNET_HELLO_get_key (hello, n->public_key))
3317   {
3318     GNUNET_break_op (0);
3319     GNUNET_free (n->public_key);
3320     n->public_key = NULL;
3321   }
3322 }
3323
3324
3325 /**
3326  * Merge the given performance data with the data we currently
3327  * track for the given neighbour.
3328  *
3329  * @param n neighbour
3330  * @param ats new performance data
3331  * @param ats_count number of records in ats
3332  */
3333 static void
3334 update_neighbour_performance (struct Neighbour *n,
3335                               const struct GNUNET_TRANSPORT_ATS_Information
3336                               *ats, uint32_t ats_count)
3337 {
3338   uint32_t i;
3339   unsigned int j;
3340
3341   if (ats_count == 0)
3342     return;
3343   for (i = 0; i < ats_count; i++)
3344   {
3345     for (j = 0; j < n->ats_count; j++)
3346     {
3347       if (n->ats[j].type == ats[i].type)
3348       {
3349         n->ats[j].value = ats[i].value;
3350         break;
3351       }
3352     }
3353     if (j == n->ats_count)
3354     {
3355       GNUNET_array_append (n->ats, n->ats_count, ats[i]);
3356     }
3357   }
3358 }
3359
3360
3361 /**
3362  * We received a PING message.  Validate and transmit
3363  * PONG.
3364  *
3365  * @param n sender of the PING
3366  * @param m the encrypted PING message itself
3367  * @param ats performance data
3368  * @param ats_count number of entries in ats (excluding 0-termination)
3369  */
3370 static void
3371 handle_ping (struct Neighbour *n, const struct PingMessage *m,
3372              const struct GNUNET_TRANSPORT_ATS_Information *ats,
3373              uint32_t ats_count)
3374 {
3375   struct PingMessage t;
3376   struct PongMessage tx;
3377   struct PongMessage *tp;
3378   struct MessageEntry *me;
3379   struct GNUNET_CRYPTO_AesInitializationVector iv;
3380
3381 #if DEBUG_CORE
3382   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3383               "Core service receives `%s' request from `%4s'.\n", "PING",
3384               GNUNET_i2s (&n->peer));
3385 #endif
3386   derive_iv (&iv, &n->decrypt_key, m->iv_seed, &my_identity);
3387   if (GNUNET_OK !=
3388       do_decrypt (n, &iv, &m->target, &t.target,
3389                   sizeof (struct PingMessage) - ((void *) &m->target -
3390                                                  (void *) m)))
3391     return;
3392 #if DEBUG_HANDSHAKE
3393   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3394               "Decrypted `%s' to `%4s' with challenge %u decrypted using key %u, IV %u (salt %u)\n",
3395               "PING", GNUNET_i2s (&t.target), (unsigned int) t.challenge,
3396               (unsigned int) n->decrypt_key.crc32, GNUNET_CRYPTO_crc32_n (&iv,
3397                                                                           sizeof
3398                                                                           (iv)),
3399               m->iv_seed);
3400 #endif
3401   GNUNET_STATISTICS_update (stats, gettext_noop ("# PING messages decrypted"),
3402                             1, GNUNET_NO);
3403   if (0 !=
3404       memcmp (&t.target, &my_identity, sizeof (struct GNUNET_PeerIdentity)))
3405   {
3406     char sender[9];
3407     char peer[9];
3408
3409     GNUNET_snprintf (sender, sizeof (sender), "%8s", GNUNET_i2s (&n->peer));
3410     GNUNET_snprintf (peer, sizeof (peer), "%8s", GNUNET_i2s (&t.target));
3411     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3412                 _
3413                 ("Received PING from `%s' for different identity: I am `%s', PONG identity: `%s'\n"),
3414                 sender, GNUNET_i2s (&my_identity), peer);
3415     GNUNET_break_op (0);
3416     return;
3417   }
3418   update_neighbour_performance (n, ats, ats_count);
3419   me = GNUNET_malloc (sizeof (struct MessageEntry) +
3420                       sizeof (struct PongMessage));
3421   GNUNET_CONTAINER_DLL_insert_after (n->encrypted_head, n->encrypted_tail,
3422                                      n->encrypted_tail, me);
3423   me->deadline = GNUNET_TIME_relative_to_absolute (MAX_PONG_DELAY);
3424   me->priority = PONG_PRIORITY;
3425   me->size = sizeof (struct PongMessage);
3426   tx.inbound_bw_limit = n->bw_in;
3427   tx.challenge = t.challenge;
3428   tx.target = t.target;
3429   tp = (struct PongMessage *) &me[1];
3430   tp->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_PONG);
3431   tp->header.size = htons (sizeof (struct PongMessage));
3432   tp->iv_seed =
3433       GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, UINT32_MAX);
3434   derive_pong_iv (&iv, &n->encrypt_key, tp->iv_seed, t.challenge, &n->peer);
3435   do_encrypt (n, &iv, &tx.challenge, &tp->challenge,
3436               sizeof (struct PongMessage) - ((void *) &tp->challenge -
3437                                              (void *) tp));
3438   GNUNET_STATISTICS_update (stats, gettext_noop ("# PONG messages created"), 1,
3439                             GNUNET_NO);
3440 #if DEBUG_HANDSHAKE
3441   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3442               "Encrypting `%s' with challenge %u using key %u, IV %u (salt %u)\n",
3443               "PONG", (unsigned int) t.challenge,
3444               (unsigned int) n->encrypt_key.crc32, GNUNET_CRYPTO_crc32_n (&iv,
3445                                                                           sizeof
3446                                                                           (iv)),
3447               tp->iv_seed);
3448 #endif
3449   /* trigger queue processing */
3450   process_encrypted_neighbour_queue (n);
3451 }
3452
3453
3454 /**
3455  * We received a PONG message.  Validate and update our status.
3456  *
3457  * @param n sender of the PONG
3458  * @param m the encrypted PONG message itself
3459  * @param ats performance data
3460  * @param ats_count number of entries in ats (excluding 0-termination)
3461  */
3462 static void
3463 handle_pong (struct Neighbour *n, const struct PongMessage *m,
3464              const struct GNUNET_TRANSPORT_ATS_Information *ats,
3465              uint32_t ats_count)
3466 {
3467   struct PongMessage t;
3468   struct ConnectNotifyMessage *cnm;
3469   struct GNUNET_CRYPTO_AesInitializationVector iv;
3470   char buf[GNUNET_SERVER_MAX_MESSAGE_SIZE - 1];
3471   struct GNUNET_TRANSPORT_ATS_Information *mats;
3472   size_t size;
3473
3474 #if DEBUG_HANDSHAKE
3475   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3476               "Core service receives `%s' response from `%4s'.\n", "PONG",
3477               GNUNET_i2s (&n->peer));
3478 #endif
3479   /* mark as garbage, just to be sure */
3480   memset (&t, 255, sizeof (t));
3481   derive_pong_iv (&iv, &n->decrypt_key, m->iv_seed, n->ping_challenge,
3482                   &my_identity);
3483   if (GNUNET_OK !=
3484       do_decrypt (n, &iv, &m->challenge, &t.challenge,
3485                   sizeof (struct PongMessage) - ((void *) &m->challenge -
3486                                                  (void *) m)))
3487   {
3488     GNUNET_break_op (0);
3489     return;
3490   }
3491   GNUNET_STATISTICS_update (stats, gettext_noop ("# PONG messages decrypted"),
3492                             1, GNUNET_NO);
3493 #if DEBUG_HANDSHAKE
3494   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3495               "Decrypted `%s' from `%4s' with challenge %u using key %u, IV %u (salt %u)\n",
3496               "PONG", GNUNET_i2s (&t.target), (unsigned int) t.challenge,
3497               (unsigned int) n->decrypt_key.crc32, GNUNET_CRYPTO_crc32_n (&iv,
3498                                                                           sizeof
3499                                                                           (iv)),
3500               m->iv_seed);
3501 #endif
3502   if ((0 != memcmp (&t.target, &n->peer, sizeof (struct GNUNET_PeerIdentity)))
3503       || (n->ping_challenge != t.challenge))
3504   {
3505     /* PONG malformed */
3506 #if DEBUG_CORE
3507     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3508                 "Received malformed `%s' wanted sender `%4s' with challenge %u\n",
3509                 "PONG", GNUNET_i2s (&n->peer),
3510                 (unsigned int) n->ping_challenge);
3511     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3512                 "Received malformed `%s' received from `%4s' with challenge %u\n",
3513                 "PONG", GNUNET_i2s (&t.target), (unsigned int) t.challenge);
3514 #endif
3515     GNUNET_break_op (n->ping_challenge != t.challenge);
3516     return;
3517   }
3518   switch (n->status)
3519   {
3520   case PEER_STATE_DOWN:
3521     GNUNET_break (0);           /* should be impossible */
3522     return;
3523   case PEER_STATE_KEY_SENT:
3524     GNUNET_break (0);           /* should be impossible, how did we decrypt? */
3525     return;
3526   case PEER_STATE_KEY_RECEIVED:
3527     GNUNET_STATISTICS_update (stats,
3528                               gettext_noop
3529                               ("# Session keys confirmed via PONG"), 1,
3530                               GNUNET_NO);
3531     n->status = PEER_STATE_KEY_CONFIRMED;
3532     {
3533       struct GNUNET_MessageHeader *hdr;
3534
3535       hdr = compute_type_map_message ();
3536       send_type_map_to_neighbour (hdr, &n->peer.hashPubKey, n);
3537       GNUNET_free (hdr);
3538     }
3539     if (n->bw_out_external_limit.value__ != t.inbound_bw_limit.value__)
3540     {
3541       n->bw_out_external_limit = t.inbound_bw_limit;
3542       n->bw_out =
3543           GNUNET_BANDWIDTH_value_min (n->bw_out_external_limit,
3544                                       n->bw_out_internal_limit);
3545       GNUNET_BANDWIDTH_tracker_update_quota (&n->available_send_window,
3546                                              n->bw_out);
3547       GNUNET_TRANSPORT_set_quota (transport, &n->peer, n->bw_in, n->bw_out);
3548     }
3549 #if DEBUG_CORE
3550     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3551                 "Confirmed key via `%s' message for peer `%4s'\n", "PONG",
3552                 GNUNET_i2s (&n->peer));
3553 #endif
3554     if (n->retry_set_key_task != GNUNET_SCHEDULER_NO_TASK)
3555     {
3556       GNUNET_SCHEDULER_cancel (n->retry_set_key_task);
3557       n->retry_set_key_task = GNUNET_SCHEDULER_NO_TASK;
3558     }
3559     update_neighbour_performance (n, ats, ats_count);
3560     size =
3561         sizeof (struct ConnectNotifyMessage) +
3562         (n->ats_count) * sizeof (struct GNUNET_TRANSPORT_ATS_Information);
3563     if (size >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
3564     {
3565       GNUNET_break (0);
3566       /* recovery strategy: throw away performance data */
3567       GNUNET_array_grow (n->ats, n->ats_count, 0);
3568       size =
3569           sizeof (struct PeerStatusNotifyMessage) +
3570           n->ats_count * sizeof (struct GNUNET_TRANSPORT_ATS_Information);
3571     }
3572     cnm = (struct ConnectNotifyMessage *) buf;
3573     cnm->header.size = htons (size);
3574     cnm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT);
3575     cnm->ats_count = htonl (n->ats_count);
3576     cnm->peer = n->peer;
3577     mats = &cnm->ats;
3578     memcpy (mats, n->ats,
3579             n->ats_count * sizeof (struct GNUNET_TRANSPORT_ATS_Information));
3580     mats[n->ats_count].type = htonl (GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR);
3581     mats[n->ats_count].value = htonl (0);
3582     send_to_all_clients (&cnm->header, GNUNET_NO,
3583                          GNUNET_CORE_OPTION_SEND_CONNECT);
3584     process_encrypted_neighbour_queue (n);
3585     /* fall-through! */
3586   case PEER_STATE_KEY_CONFIRMED:
3587     n->last_activity = GNUNET_TIME_absolute_get ();
3588     if (n->keep_alive_task != GNUNET_SCHEDULER_NO_TASK)
3589       GNUNET_SCHEDULER_cancel (n->keep_alive_task);
3590     n->keep_alive_task =
3591         GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_divide
3592                                       (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
3593                                        2), &send_keep_alive, n);
3594     handle_peer_status_change (n);
3595     break;
3596   default:
3597     GNUNET_break (0);
3598     break;
3599   }
3600 }
3601
3602
3603 /**
3604  * We received a SET_KEY message.  Validate and update
3605  * our key material and status.
3606  *
3607  * @param n the neighbour from which we received message m
3608  * @param m the set key message we received
3609  * @param ats performance data
3610  * @param ats_count number of entries in ats (excluding 0-termination)
3611  */
3612 static void
3613 handle_set_key (struct Neighbour *n, const struct SetKeyMessage *m,
3614                 const struct GNUNET_TRANSPORT_ATS_Information *ats,
3615                 uint32_t ats_count)
3616 {
3617   struct SetKeyMessage *m_cpy;
3618   struct GNUNET_TIME_Absolute t;
3619   struct GNUNET_CRYPTO_AesSessionKey k;
3620   struct PingMessage *ping;
3621   struct PongMessage *pong;
3622   enum PeerStateMachine sender_status;
3623
3624 #if DEBUG_CORE
3625   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3626               "Core service receives `%s' request from `%4s'.\n", "SET_KEY",
3627               GNUNET_i2s (&n->peer));
3628 #endif
3629   if (n->public_key == NULL)
3630   {
3631     if (n->pitr != NULL)
3632     {
3633 #if DEBUG_CORE
3634       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3635                   "Ignoring `%s' message due to lack of public key for peer (still trying to obtain one).\n",
3636                   "SET_KEY");
3637 #endif
3638       return;
3639     }
3640 #if DEBUG_CORE
3641     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3642                 "Lacking public key for peer, trying to obtain one (handle_set_key).\n");
3643 #endif
3644     m_cpy = GNUNET_malloc (sizeof (struct SetKeyMessage));
3645     memcpy (m_cpy, m, sizeof (struct SetKeyMessage));
3646     /* lookup n's public key, then try again */
3647     GNUNET_assert (n->skm == NULL);
3648     n->skm = m_cpy;
3649     n->pitr =
3650         GNUNET_PEERINFO_iterate (peerinfo, &n->peer, GNUNET_TIME_UNIT_MINUTES,
3651                                  &process_hello_retry_handle_set_key, n);
3652     GNUNET_STATISTICS_update (stats,
3653                               gettext_noop
3654                               ("# SET_KEY messages deferred (need public key)"),
3655                               1, GNUNET_NO);
3656     return;
3657   }
3658   if (0 !=
3659       memcmp (&m->target, &my_identity, sizeof (struct GNUNET_PeerIdentity)))
3660   {
3661     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3662                 _
3663                 ("Received `%s' message that was for `%s', not for me.  Ignoring.\n"),
3664                 "SET_KEY", GNUNET_i2s (&m->target));
3665     return;
3666   }
3667   if ((ntohl (m->purpose.size) !=
3668        sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) +
3669        sizeof (struct GNUNET_TIME_AbsoluteNBO) +
3670        sizeof (struct GNUNET_CRYPTO_RsaEncryptedData) +
3671        sizeof (struct GNUNET_PeerIdentity)) ||
3672       (GNUNET_OK !=
3673        GNUNET_CRYPTO_rsa_verify (GNUNET_SIGNATURE_PURPOSE_SET_KEY, &m->purpose,
3674                                  &m->signature, n->public_key)))
3675   {
3676     /* invalid signature */
3677     GNUNET_break_op (0);
3678     return;
3679   }
3680   t = GNUNET_TIME_absolute_ntoh (m->creation_time);
3681   if (((n->status == PEER_STATE_KEY_RECEIVED) ||
3682        (n->status == PEER_STATE_KEY_CONFIRMED)) &&
3683       (t.abs_value < n->decrypt_key_created.abs_value))
3684   {
3685     /* this could rarely happen due to massive re-ordering of
3686      * messages on the network level, but is most likely either
3687      * a bug or some adversary messing with us.  Report. */
3688     GNUNET_break_op (0);
3689     return;
3690   }
3691 #if DEBUG_CORE
3692   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Decrypting key material.\n");
3693 #endif
3694   if ((GNUNET_CRYPTO_rsa_decrypt
3695        (my_private_key, &m->encrypted_key, &k,
3696         sizeof (struct GNUNET_CRYPTO_AesSessionKey)) !=
3697        sizeof (struct GNUNET_CRYPTO_AesSessionKey)) ||
3698       (GNUNET_OK != GNUNET_CRYPTO_aes_check_session_key (&k)))
3699   {
3700     /* failed to decrypt !? */
3701     GNUNET_break_op (0);
3702     return;
3703   }
3704   GNUNET_STATISTICS_update (stats,
3705                             gettext_noop ("# SET_KEY messages decrypted"), 1,
3706                             GNUNET_NO);
3707   n->decrypt_key = k;
3708   if (n->decrypt_key_created.abs_value != t.abs_value)
3709   {
3710     /* fresh key, reset sequence numbers */
3711     n->last_sequence_number_received = 0;
3712     n->last_packets_bitmap = 0;
3713     n->decrypt_key_created = t;
3714   }
3715   update_neighbour_performance (n, ats, ats_count);
3716   sender_status = (enum PeerStateMachine) ntohl (m->sender_status);
3717   switch (n->status)
3718   {
3719   case PEER_STATE_DOWN:
3720     n->status = PEER_STATE_KEY_RECEIVED;
3721 #if DEBUG_CORE
3722     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3723                 "Responding to `%s' with my own key.\n", "SET_KEY");
3724 #endif
3725     send_key (n);
3726     break;
3727   case PEER_STATE_KEY_SENT:
3728   case PEER_STATE_KEY_RECEIVED:
3729     n->status = PEER_STATE_KEY_RECEIVED;
3730     if ((sender_status != PEER_STATE_KEY_RECEIVED) &&
3731         (sender_status != PEER_STATE_KEY_CONFIRMED))
3732     {
3733 #if DEBUG_CORE
3734       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3735                   "Responding to `%s' with my own key (other peer has status %u).\n",
3736                   "SET_KEY", (unsigned int) sender_status);
3737 #endif
3738       send_key (n);
3739     }
3740     break;
3741   case PEER_STATE_KEY_CONFIRMED:
3742     if ((sender_status != PEER_STATE_KEY_RECEIVED) &&
3743         (sender_status != PEER_STATE_KEY_CONFIRMED))
3744     {
3745 #if DEBUG_CORE
3746       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3747                   "Responding to `%s' with my own key (other peer has status %u), I was already fully up.\n",
3748                   "SET_KEY", (unsigned int) sender_status);
3749 #endif
3750       send_key (n);
3751     }
3752     break;
3753   default:
3754     GNUNET_break (0);
3755     break;
3756   }
3757   if (n->pending_ping != NULL)
3758   {
3759     ping = n->pending_ping;
3760     n->pending_ping = NULL;
3761     handle_ping (n, ping, NULL, 0);
3762     GNUNET_free (ping);
3763   }
3764   if (n->pending_pong != NULL)
3765   {
3766     pong = n->pending_pong;
3767     n->pending_pong = NULL;
3768     handle_pong (n, pong, NULL, 0);
3769     GNUNET_free (pong);
3770   }
3771 }
3772
3773
3774 /**
3775  * Send a P2P message to a client.
3776  *
3777  * @param sender who sent us the message?
3778  * @param client who should we give the message to?
3779  * @param m contains the message to transmit
3780  * @param msize number of bytes in buf to transmit
3781  */
3782 static void
3783 send_p2p_message_to_client (struct Neighbour *sender, struct Client *client,
3784                             const void *m, size_t msize)
3785 {
3786   size_t size =
3787       msize + sizeof (struct NotifyTrafficMessage) +
3788       (sender->ats_count) * sizeof (struct GNUNET_TRANSPORT_ATS_Information);
3789   char buf[size];
3790   struct NotifyTrafficMessage *ntm;
3791   struct GNUNET_TRANSPORT_ATS_Information *ats;
3792
3793   GNUNET_assert (GNUNET_YES == sender->is_connected);
3794   GNUNET_break (sender->status == PEER_STATE_KEY_CONFIRMED);
3795   if (size >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
3796   {
3797     GNUNET_break (0);
3798     /* recovery strategy: throw performance data away... */
3799     GNUNET_array_grow (sender->ats, sender->ats_count, 0);
3800     size =
3801         msize + sizeof (struct NotifyTrafficMessage) +
3802         (sender->ats_count) * sizeof (struct GNUNET_TRANSPORT_ATS_Information);
3803   }
3804 #if DEBUG_CORE
3805   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3806               "Core service passes message from `%4s' of type %u to client.\n",
3807               GNUNET_i2s (&sender->peer),
3808               (unsigned int)
3809               ntohs (((const struct GNUNET_MessageHeader *) m)->type));
3810 #endif
3811   ntm = (struct NotifyTrafficMessage *) buf;
3812   ntm->header.size = htons (size);
3813   ntm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_INBOUND);
3814   ntm->ats_count = htonl (sender->ats_count);
3815   ntm->peer = sender->peer;
3816   ats = &ntm->ats;
3817   memcpy (ats, sender->ats,
3818           sizeof (struct GNUNET_TRANSPORT_ATS_Information) * sender->ats_count);
3819   ats[sender->ats_count].type = htonl (GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR);
3820   ats[sender->ats_count].value = htonl (0);
3821   memcpy (&ats[sender->ats_count + 1], m, msize);
3822   send_to_client (client, &ntm->header, GNUNET_YES);
3823 }
3824
3825
3826 /**
3827  * Deliver P2P message to interested clients.
3828  *
3829  * @param cls always NULL
3830  * @param client who sent us the message (struct Neighbour)
3831  * @param m the message
3832  */
3833 static void
3834 deliver_message (void *cls, void *client, const struct GNUNET_MessageHeader *m)
3835 {
3836   struct Neighbour *sender = client;
3837   size_t msize = ntohs (m->size);
3838   char buf[256];
3839   struct Client *cpos;
3840   uint16_t type;
3841   unsigned int tpos;
3842   int deliver_full;
3843   int dropped;
3844
3845   GNUNET_break (sender->status == PEER_STATE_KEY_CONFIRMED);
3846   type = ntohs (m->type);
3847 #if DEBUG_CORE > 1
3848   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3849               "Received encapsulated message of type %u and size %u from `%4s'\n",
3850               (unsigned int) type, ntohs (m->size), GNUNET_i2s (&sender->peer));
3851 #endif
3852   GNUNET_snprintf (buf, sizeof (buf),
3853                    gettext_noop ("# bytes of messages of type %u received"),
3854                    (unsigned int) type);
3855   GNUNET_STATISTICS_update (stats, buf, msize, GNUNET_NO);
3856   if ((GNUNET_MESSAGE_TYPE_CORE_BINARY_TYPE_MAP == type) ||
3857       (GNUNET_MESSAGE_TYPE_CORE_COMPRESSED_TYPE_MAP == type))
3858   {
3859     /* FIXME: update message type map for 'Neighbour' */
3860     return;
3861   }
3862   dropped = GNUNET_YES;
3863   cpos = clients;
3864   while (cpos != NULL)
3865   {
3866     deliver_full = GNUNET_NO;
3867     if (0 != (cpos->options & GNUNET_CORE_OPTION_SEND_FULL_INBOUND))
3868       deliver_full = GNUNET_YES;
3869     else
3870     {
3871       for (tpos = 0; tpos < cpos->tcnt; tpos++)
3872       {
3873         if (type != cpos->types[tpos])
3874           continue;
3875         deliver_full = GNUNET_YES;
3876         break;
3877       }
3878     }
3879     if (GNUNET_YES == deliver_full)
3880     {
3881       send_p2p_message_to_client (sender, cpos, m, msize);
3882       dropped = GNUNET_NO;
3883     }
3884     else if (cpos->options & GNUNET_CORE_OPTION_SEND_HDR_INBOUND)
3885     {
3886       send_p2p_message_to_client (sender, cpos, m,
3887                                   sizeof (struct GNUNET_MessageHeader));
3888     }
3889     cpos = cpos->next;
3890   }
3891   if (dropped == GNUNET_YES)
3892   {
3893 #if DEBUG_CORE
3894     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3895                 "Message of type %u from `%4s' not delivered to any client.\n",
3896                 (unsigned int) type, GNUNET_i2s (&sender->peer));
3897 #endif
3898     GNUNET_STATISTICS_update (stats,
3899                               gettext_noop
3900                               ("# messages not delivered to any client"), 1,
3901                               GNUNET_NO);
3902   }
3903 }
3904
3905
3906 /**
3907  * We received an encrypted message.  Decrypt, validate and
3908  * pass on to the appropriate clients.
3909  *
3910  * @param n target of the message
3911  * @param m encrypted message
3912  * @param ats performance data
3913  * @param ats_count number of entries in ats (excluding 0-termination)
3914  */
3915 static void
3916 handle_encrypted_message (struct Neighbour *n, const struct EncryptedMessage *m,
3917                           const struct GNUNET_TRANSPORT_ATS_Information *ats,
3918                           uint32_t ats_count)
3919 {
3920   size_t size = ntohs (m->header.size);
3921   char buf[size];
3922   struct EncryptedMessage *pt;  /* plaintext */
3923   GNUNET_HashCode ph;
3924   uint32_t snum;
3925   struct GNUNET_TIME_Absolute t;
3926   struct GNUNET_CRYPTO_AesInitializationVector iv;
3927   struct GNUNET_CRYPTO_AuthKey auth_key;
3928
3929 #if DEBUG_CORE
3930   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3931               "Core service receives `%s' request from `%4s'.\n",
3932               "ENCRYPTED_MESSAGE", GNUNET_i2s (&n->peer));
3933 #endif
3934   /* validate hash */
3935   derive_auth_key (&auth_key, &n->decrypt_key, m->iv_seed,
3936                    n->decrypt_key_created);
3937   GNUNET_CRYPTO_hmac (&auth_key, &m->sequence_number,
3938                       size - ENCRYPTED_HEADER_SIZE, &ph);
3939 #if DEBUG_HANDSHAKE
3940   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3941               "Re-Authenticated %u bytes of ciphertext (`%u'): `%s'\n",
3942               (unsigned int) size - ENCRYPTED_HEADER_SIZE,
3943               GNUNET_CRYPTO_crc32_n (&m->sequence_number,
3944                                      size - ENCRYPTED_HEADER_SIZE),
3945               GNUNET_h2s (&ph));
3946 #endif
3947
3948   if (0 != memcmp (&ph, &m->hmac, sizeof (GNUNET_HashCode)))
3949   {
3950     /* checksum failed */
3951     GNUNET_break_op (0);
3952     return;
3953   }
3954   derive_iv (&iv, &n->decrypt_key, m->iv_seed, &my_identity);
3955   /* decrypt */
3956   if (GNUNET_OK !=
3957       do_decrypt (n, &iv, &m->sequence_number, &buf[ENCRYPTED_HEADER_SIZE],
3958                   size - ENCRYPTED_HEADER_SIZE))
3959     return;
3960   pt = (struct EncryptedMessage *) buf;
3961
3962   /* validate sequence number */
3963   snum = ntohl (pt->sequence_number);
3964   if (n->last_sequence_number_received == snum)
3965   {
3966     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
3967                 "Received duplicate message, ignoring.\n");
3968     /* duplicate, ignore */
3969     GNUNET_STATISTICS_update (stats,
3970                               gettext_noop ("# bytes dropped (duplicates)"),
3971                               size, GNUNET_NO);
3972     return;
3973   }
3974   if ((n->last_sequence_number_received > snum) &&
3975       (n->last_sequence_number_received - snum > 32))
3976   {
3977     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
3978                 "Received ancient out of sequence message, ignoring.\n");
3979     /* ancient out of sequence, ignore */
3980     GNUNET_STATISTICS_update (stats,
3981                               gettext_noop
3982                               ("# bytes dropped (out of sequence)"), size,
3983                               GNUNET_NO);
3984     return;
3985   }
3986   if (n->last_sequence_number_received > snum)
3987   {
3988     unsigned int rotbit = 1 << (n->last_sequence_number_received - snum - 1);
3989
3990     if ((n->last_packets_bitmap & rotbit) != 0)
3991     {
3992       GNUNET_log (GNUNET_ERROR_TYPE_INFO,
3993                   "Received duplicate message, ignoring.\n");
3994       GNUNET_STATISTICS_update (stats,
3995                                 gettext_noop ("# bytes dropped (duplicates)"),
3996                                 size, GNUNET_NO);
3997       /* duplicate, ignore */
3998       return;
3999     }
4000     n->last_packets_bitmap |= rotbit;
4001   }
4002   if (n->last_sequence_number_received < snum)
4003   {
4004     int shift = (snum - n->last_sequence_number_received);
4005
4006     if (shift >= 8 * sizeof (n->last_packets_bitmap))
4007       n->last_packets_bitmap = 0;
4008     else
4009       n->last_packets_bitmap <<= shift;
4010     n->last_sequence_number_received = snum;
4011   }
4012
4013   /* check timestamp */
4014   t = GNUNET_TIME_absolute_ntoh (pt->timestamp);
4015   if (GNUNET_TIME_absolute_get_duration (t).rel_value >
4016       MAX_MESSAGE_AGE.rel_value)
4017   {
4018     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
4019                 _("Message received far too old (%llu ms). Content ignored.\n"),
4020                 GNUNET_TIME_absolute_get_duration (t).rel_value);
4021     GNUNET_STATISTICS_update (stats,
4022                               gettext_noop
4023                               ("# bytes dropped (ancient message)"), size,
4024                               GNUNET_NO);
4025     return;
4026   }
4027
4028   /* process decrypted message(s) */
4029   if (n->bw_out_external_limit.value__ != pt->inbound_bw_limit.value__)
4030   {
4031 #if DEBUG_CORE_SET_QUOTA
4032     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4033                 "Received %u b/s as new inbound limit for peer `%4s'\n",
4034                 (unsigned int) ntohl (pt->inbound_bw_limit.value__),
4035                 GNUNET_i2s (&n->peer));
4036 #endif
4037     n->bw_out_external_limit = pt->inbound_bw_limit;
4038     n->bw_out =
4039         GNUNET_BANDWIDTH_value_min (n->bw_out_external_limit,
4040                                     n->bw_out_internal_limit);
4041     GNUNET_BANDWIDTH_tracker_update_quota (&n->available_send_window,
4042                                            n->bw_out);
4043     GNUNET_TRANSPORT_set_quota (transport, &n->peer, n->bw_in, n->bw_out);
4044   }
4045   n->last_activity = GNUNET_TIME_absolute_get ();
4046   if (n->keep_alive_task != GNUNET_SCHEDULER_NO_TASK)
4047     GNUNET_SCHEDULER_cancel (n->keep_alive_task);
4048   n->keep_alive_task =
4049       GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_divide
4050                                     (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
4051                                      2), &send_keep_alive, n);
4052   GNUNET_STATISTICS_update (stats,
4053                             gettext_noop ("# bytes of payload decrypted"),
4054                             size - sizeof (struct EncryptedMessage), GNUNET_NO);
4055   handle_peer_status_change (n);
4056   update_neighbour_performance (n, ats, ats_count);
4057   if (GNUNET_OK !=
4058       GNUNET_SERVER_mst_receive (mst, n, &buf[sizeof (struct EncryptedMessage)],
4059                                  size - sizeof (struct EncryptedMessage),
4060                                  GNUNET_YES, GNUNET_NO))
4061     GNUNET_break_op (0);
4062 }
4063
4064
4065 /**
4066  * Function called by the transport for each received message.
4067  *
4068  * @param cls closure
4069  * @param peer (claimed) identity of the other peer
4070  * @param message the message
4071  * @param ats performance data
4072  * @param ats_count number of entries in ats (excluding 0-termination)
4073  */
4074 static void
4075 handle_transport_receive (void *cls, const struct GNUNET_PeerIdentity *peer,
4076                           const struct GNUNET_MessageHeader *message,
4077                           const struct GNUNET_TRANSPORT_ATS_Information *ats,
4078                           uint32_t ats_count)
4079 {
4080   struct Neighbour *n;
4081   struct GNUNET_TIME_Absolute now;
4082   int up;
4083   uint16_t type;
4084   uint16_t size;
4085   int changed;
4086
4087 #if DEBUG_CORE > 1
4088   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4089               "Received message of type %u from `%4s', demultiplexing.\n",
4090               (unsigned int) ntohs (message->type), GNUNET_i2s (peer));
4091 #endif
4092   if (0 == memcmp (peer, &my_identity, sizeof (struct GNUNET_PeerIdentity)))
4093   {
4094     GNUNET_break (0);
4095     return;
4096   }
4097   n = find_neighbour (peer);
4098   if ((n == NULL) || (GNUNET_NO == n->is_connected))
4099   {
4100     /* received message from peer that is not connected!? */
4101     GNUNET_break (0);
4102     return;
4103   }
4104   changed = GNUNET_NO;
4105   up = (n->status == PEER_STATE_KEY_CONFIRMED);
4106   type = ntohs (message->type);
4107   size = ntohs (message->size);
4108   switch (type)
4109   {
4110   case GNUNET_MESSAGE_TYPE_CORE_SET_KEY:
4111     if (size != sizeof (struct SetKeyMessage))
4112     {
4113       GNUNET_break_op (0);
4114       return;
4115     }
4116     GNUNET_STATISTICS_update (stats, gettext_noop ("# session keys received"),
4117                               1, GNUNET_NO);
4118     handle_set_key (n, (const struct SetKeyMessage *) message, ats, ats_count);
4119     break;
4120   case GNUNET_MESSAGE_TYPE_CORE_ENCRYPTED_MESSAGE:
4121     if (size <
4122         sizeof (struct EncryptedMessage) + sizeof (struct GNUNET_MessageHeader))
4123     {
4124       GNUNET_break_op (0);
4125       return;
4126     }
4127     if ((n->status != PEER_STATE_KEY_RECEIVED) &&
4128         (n->status != PEER_STATE_KEY_CONFIRMED))
4129     {
4130       GNUNET_STATISTICS_update (stats,
4131                                 gettext_noop
4132                                 ("# failed to decrypt message (no session key)"),
4133                                 1, GNUNET_NO);
4134       send_key (n);
4135       return;
4136     }
4137     handle_encrypted_message (n, (const struct EncryptedMessage *) message, ats,
4138                               ats_count);
4139     break;
4140   case GNUNET_MESSAGE_TYPE_CORE_PING:
4141     if (size != sizeof (struct PingMessage))
4142     {
4143       GNUNET_break_op (0);
4144       return;
4145     }
4146     GNUNET_STATISTICS_update (stats, gettext_noop ("# PING messages received"),
4147                               1, GNUNET_NO);
4148     if ((n->status != PEER_STATE_KEY_RECEIVED) &&
4149         (n->status != PEER_STATE_KEY_CONFIRMED))
4150     {
4151 #if DEBUG_CORE > 1
4152       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4153                   "Core service receives `%s' request from `%4s' but have not processed key; marking as pending.\n",
4154                   "PING", GNUNET_i2s (&n->peer));
4155 #endif
4156       GNUNET_free_non_null (n->pending_ping);
4157       n->pending_ping = GNUNET_malloc (sizeof (struct PingMessage));
4158       memcpy (n->pending_ping, message, sizeof (struct PingMessage));
4159       return;
4160     }
4161     handle_ping (n, (const struct PingMessage *) message, ats, ats_count);
4162     break;
4163   case GNUNET_MESSAGE_TYPE_CORE_PONG:
4164     if (size != sizeof (struct PongMessage))
4165     {
4166       GNUNET_break_op (0);
4167       return;
4168     }
4169     GNUNET_STATISTICS_update (stats, gettext_noop ("# PONG messages received"),
4170                               1, GNUNET_NO);
4171     if ((n->status != PEER_STATE_KEY_RECEIVED) &&
4172         (n->status != PEER_STATE_KEY_CONFIRMED))
4173     {
4174 #if DEBUG_CORE > 1
4175       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4176                   "Core service receives `%s' request from `%4s' but have not processed key; marking as pending.\n",
4177                   "PONG", GNUNET_i2s (&n->peer));
4178 #endif
4179       GNUNET_free_non_null (n->pending_pong);
4180       n->pending_pong = GNUNET_malloc (sizeof (struct PongMessage));
4181       memcpy (n->pending_pong, message, sizeof (struct PongMessage));
4182       return;
4183     }
4184     handle_pong (n, (const struct PongMessage *) message, ats, ats_count);
4185     break;
4186   default:
4187     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
4188                 _("Unsupported message of type %u received.\n"),
4189                 (unsigned int) type);
4190     return;
4191   }
4192   if (n->status == PEER_STATE_KEY_CONFIRMED)
4193   {
4194     now = GNUNET_TIME_absolute_get ();
4195     n->last_activity = now;
4196     changed = GNUNET_YES;
4197     if (!up)
4198     {
4199       GNUNET_STATISTICS_update (stats, gettext_noop ("# established sessions"),
4200                                 1, GNUNET_NO);
4201       n->time_established = now;
4202     }
4203     if (n->keep_alive_task != GNUNET_SCHEDULER_NO_TASK)
4204       GNUNET_SCHEDULER_cancel (n->keep_alive_task);
4205     n->keep_alive_task =
4206         GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_divide
4207                                       (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
4208                                        2), &send_keep_alive, n);
4209   }
4210   if (changed)
4211     handle_peer_status_change (n);
4212 }
4213
4214
4215 /**
4216  * Function that recalculates the bandwidth quota for the
4217  * given neighbour and transmits it to the transport service.
4218  *
4219  * @param cls neighbour for the quota update
4220  * @param tc context
4221  */
4222 static void
4223 neighbour_quota_update (void *cls,
4224                         const struct GNUNET_SCHEDULER_TaskContext *tc)
4225 {
4226   struct Neighbour *n = cls;
4227   struct GNUNET_BANDWIDTH_Value32NBO q_in;
4228   struct GNUNET_BANDWIDTH_Value32NBO q_out;
4229   struct GNUNET_BANDWIDTH_Value32NBO q_out_min;
4230   double pref_rel;
4231   double share;
4232   unsigned long long distributable;
4233   uint64_t need_per_peer;
4234   uint64_t need_per_second;
4235   unsigned int neighbour_count;
4236
4237 #if DEBUG_CORE > 1
4238   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4239               "Neighbour quota update calculation running for peer `%4s'\n",
4240               GNUNET_i2s (&n->peer));
4241 #endif
4242   n->quota_update_task = GNUNET_SCHEDULER_NO_TASK;
4243   /* calculate relative preference among all neighbours;
4244    * divides by a bit more to avoid division by zero AND to
4245    * account for possibility of new neighbours joining any time
4246    * AND to convert to double... */
4247   neighbour_count = GNUNET_CONTAINER_multihashmap_size (neighbours);
4248   if (neighbour_count == 0)
4249     return;
4250   if (preference_sum == 0)
4251   {
4252     pref_rel = 1.0 / (double) neighbour_count;
4253   }
4254   else
4255   {
4256     pref_rel = (double) n->current_preference / preference_sum;
4257   }
4258   need_per_peer =
4259       GNUNET_BANDWIDTH_value_get_available_until (MIN_BANDWIDTH_PER_PEER,
4260                                                   GNUNET_TIME_UNIT_SECONDS);
4261   need_per_second = need_per_peer * neighbour_count;
4262
4263   /* calculate inbound bandwidth per peer */
4264   distributable = 0;
4265   if (bandwidth_target_in_bps > need_per_second)
4266     distributable = bandwidth_target_in_bps - need_per_second;
4267   share = distributable * pref_rel;
4268   if (share + need_per_peer > UINT32_MAX)
4269     q_in = GNUNET_BANDWIDTH_value_init (UINT32_MAX);
4270   else
4271     q_in = GNUNET_BANDWIDTH_value_init (need_per_peer + (uint32_t) share);
4272
4273   /* calculate outbound bandwidth per peer */
4274   distributable = 0;
4275   if (bandwidth_target_out_bps > need_per_second)
4276     distributable = bandwidth_target_out_bps - need_per_second;
4277   share = distributable * pref_rel;
4278   if (share + need_per_peer > UINT32_MAX)
4279     q_out = GNUNET_BANDWIDTH_value_init (UINT32_MAX);
4280   else
4281     q_out = GNUNET_BANDWIDTH_value_init (need_per_peer + (uint32_t) share);
4282   n->bw_out_internal_limit = q_out;
4283
4284   q_out_min =
4285       GNUNET_BANDWIDTH_value_min (n->bw_out_external_limit,
4286                                   n->bw_out_internal_limit);
4287   GNUNET_BANDWIDTH_tracker_update_quota (&n->available_send_window, n->bw_out);
4288
4289   /* check if we want to disconnect for good due to inactivity */
4290   if ((GNUNET_TIME_absolute_get_duration (get_neighbour_timeout (n)).rel_value >
4291        0) &&
4292       (GNUNET_TIME_absolute_get_duration (n->time_established).rel_value >
4293        GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value))
4294   {
4295 #if DEBUG_CORE
4296     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4297                 "Forcing disconnect of `%4s' due to inactivity\n",
4298                 GNUNET_i2s (&n->peer));
4299 #endif
4300     GNUNET_STATISTICS_update (stats,
4301                               gettext_noop ("# peers disconnected due to inactivity"), 1,
4302                               GNUNET_NO);
4303     q_in = GNUNET_BANDWIDTH_value_init (0);     /* force disconnect */
4304   }
4305 #if DEBUG_CORE_QUOTA
4306   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4307               "Current quota for `%4s' is %u/%llu b/s in (old: %u b/s) / %u out (%u internal)\n",
4308               GNUNET_i2s (&n->peer), (unsigned int) ntohl (q_in.value__),
4309               bandwidth_target_out_bps, (unsigned int) ntohl (n->bw_in.value__),
4310               (unsigned int) ntohl (n->bw_out.value__),
4311               (unsigned int) ntohl (n->bw_out_internal_limit.value__));
4312 #endif
4313   if ((n->bw_in.value__ != q_in.value__) ||
4314       (n->bw_out.value__ != q_out_min.value__))
4315   {
4316     if (n->bw_in.value__ != q_in.value__)
4317       n->bw_in = q_in;
4318     if (n->bw_out.value__ != q_out_min.value__)
4319       n->bw_out = q_out_min;
4320     if (GNUNET_YES == n->is_connected)
4321       GNUNET_TRANSPORT_set_quota (transport, &n->peer, n->bw_in, n->bw_out);
4322     handle_peer_status_change (n);
4323   }
4324   schedule_quota_update (n);
4325 }
4326
4327
4328 /**
4329  * Function called by transport to notify us that
4330  * a peer connected to us (on the network level).
4331  *
4332  * @param cls closure
4333  * @param peer the peer that connected
4334  * @param ats performance data
4335  * @param ats_count number of entries in ats (excluding 0-termination)
4336  */
4337 static void
4338 handle_transport_notify_connect (void *cls,
4339                                  const struct GNUNET_PeerIdentity *peer,
4340                                  const struct GNUNET_TRANSPORT_ATS_Information
4341                                  *ats, uint32_t ats_count)
4342 {
4343   struct Neighbour *n;
4344
4345   if (0 == memcmp (peer, &my_identity, sizeof (struct GNUNET_PeerIdentity)))
4346   {
4347     GNUNET_break (0);
4348     return;
4349   }
4350   n = find_neighbour (peer);
4351   if (n != NULL)
4352   {
4353     if (GNUNET_YES == n->is_connected)
4354     {
4355       /* duplicate connect notification!? */
4356       GNUNET_break (0);
4357       return;
4358     }
4359   }
4360   else
4361   {
4362     n = create_neighbour (peer);
4363   }
4364   GNUNET_STATISTICS_update (stats,
4365                             gettext_noop ("# peers connected (transport)"), 1,
4366                             GNUNET_NO);
4367   n->is_connected = GNUNET_YES;
4368   update_neighbour_performance (n, ats, ats_count);
4369   GNUNET_BANDWIDTH_tracker_init (&n->available_send_window, n->bw_out,
4370                                  MAX_WINDOW_TIME_S);
4371   GNUNET_BANDWIDTH_tracker_init (&n->available_recv_window, n->bw_in,
4372                                  MAX_WINDOW_TIME_S);
4373 #if DEBUG_CORE
4374   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received connection from `%4s'.\n",
4375               GNUNET_i2s (&n->peer));
4376 #endif
4377   GNUNET_TRANSPORT_set_quota (transport, &n->peer, n->bw_in, n->bw_out);
4378   send_key (n);
4379 }
4380
4381
4382 /**
4383  * Function called by transport telling us that a peer
4384  * disconnected.
4385  *
4386  * @param cls closure
4387  * @param peer the peer that disconnected
4388  */
4389 static void
4390 handle_transport_notify_disconnect (void *cls,
4391                                     const struct GNUNET_PeerIdentity *peer)
4392 {
4393   struct DisconnectNotifyMessage cnm;
4394   struct Neighbour *n;
4395   struct ClientActiveRequest *car;
4396   struct GNUNET_TIME_Relative left;
4397
4398 #if DEBUG_CORE
4399   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4400               "Peer `%4s' disconnected from us; received notification from transport.\n",
4401               GNUNET_i2s (peer));
4402 #endif
4403   n = find_neighbour (peer);
4404   if (n == NULL)
4405   {
4406     GNUNET_break (0);
4407     return;
4408   }
4409   GNUNET_break (n->is_connected == GNUNET_YES);
4410   if (n->status == PEER_STATE_KEY_CONFIRMED)
4411   {
4412     GNUNET_STATISTICS_update (stats,
4413                               gettext_noop ("# peers disconnected due to transport disconnect"), 1,
4414                               GNUNET_NO);
4415     cnm.header.size = htons (sizeof (struct DisconnectNotifyMessage));
4416     cnm.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_DISCONNECT);
4417     cnm.reserved = htonl (0);
4418     cnm.peer = *peer;
4419     send_to_all_clients (&cnm.header, GNUNET_NO,
4420                          GNUNET_CORE_OPTION_SEND_DISCONNECT);
4421     GNUNET_STATISTICS_update (stats, gettext_noop ("# established sessions"),
4422                               -1, GNUNET_NO);
4423   }
4424
4425   /* On transport disconnect transport doesn't cancel requests, so must do so here. */
4426   if (n->th != NULL)
4427   {
4428     GNUNET_TRANSPORT_notify_transmit_ready_cancel (n->th);
4429     n->th = NULL;
4430   }
4431   if (GNUNET_SCHEDULER_NO_TASK != n->keep_alive_task)
4432   {
4433     GNUNET_SCHEDULER_cancel (n->keep_alive_task);
4434     n->keep_alive_task = GNUNET_SCHEDULER_NO_TASK;
4435   }
4436   n->is_connected = GNUNET_NO;
4437   n->status = PEER_STATE_DOWN;
4438   while (NULL != (car = n->active_client_request_head))
4439   {
4440     GNUNET_CONTAINER_DLL_remove (n->active_client_request_head,
4441                                  n->active_client_request_tail, car);
4442     GNUNET_assert (GNUNET_YES ==
4443                    GNUNET_CONTAINER_multihashmap_remove (car->client->requests,
4444                                                          &n->peer.hashPubKey,
4445                                                          car));
4446     GNUNET_free (car);
4447   }
4448
4449   GNUNET_STATISTICS_update (stats,
4450                             gettext_noop ("# peers connected (transport)"), -1,
4451                             GNUNET_NO);
4452   if (n->dead_clean_task != GNUNET_SCHEDULER_NO_TASK)
4453     GNUNET_SCHEDULER_cancel (n->dead_clean_task);
4454   left =
4455       GNUNET_TIME_relative_subtract (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
4456                                      GNUNET_CONSTANTS_DISCONNECT_SESSION_TIMEOUT);
4457   n->last_activity =
4458       GNUNET_TIME_absolute_subtract (GNUNET_TIME_absolute_get (), left);
4459   n->dead_clean_task =
4460       GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_DISCONNECT_SESSION_TIMEOUT,
4461                                     &consider_free_task, n);
4462 }
4463
4464
4465 /**
4466  * Wrapper around 'free_neighbour'; helper for 'cleaning_task'.
4467  */
4468 static int
4469 free_neighbour_helper (void *cls, const GNUNET_HashCode * key, void *value)
4470 {
4471   struct Neighbour *n = value;
4472
4473   free_neighbour (n);
4474   return GNUNET_OK;
4475 }
4476
4477
4478 /**
4479  * Last task run during shutdown.  Disconnects us from
4480  * the transport.
4481  */
4482 static void
4483 cleaning_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
4484 {
4485   struct Client *c;
4486
4487 #if DEBUG_CORE
4488   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Core service shutting down.\n");
4489 #endif
4490   GNUNET_assert (transport != NULL);
4491   GNUNET_TRANSPORT_disconnect (transport);
4492   transport = NULL;
4493   GNUNET_CONTAINER_multihashmap_iterate (neighbours, &free_neighbour_helper,
4494                                          NULL);
4495   GNUNET_CONTAINER_multihashmap_destroy (neighbours);
4496   neighbours = NULL;
4497   GNUNET_STATISTICS_set (stats, gettext_noop ("# neighbour entries allocated"),
4498                          0, GNUNET_NO);
4499   GNUNET_SERVER_notification_context_destroy (notifier);
4500   notifier = NULL;
4501   while (NULL != (c = clients))
4502     handle_client_disconnect (NULL, c->client_handle);
4503   if (my_private_key != NULL)
4504     GNUNET_CRYPTO_rsa_key_free (my_private_key);
4505   if (stats != NULL)
4506     GNUNET_STATISTICS_destroy (stats, GNUNET_NO);
4507   if (peerinfo != NULL)
4508     GNUNET_PEERINFO_disconnect (peerinfo);
4509   if (mst != NULL)
4510     GNUNET_SERVER_mst_destroy (mst);
4511 }
4512
4513
4514 /**
4515  * Initiate core service.
4516  *
4517  * @param cls closure
4518  * @param server the initialized server
4519  * @param c configuration to use
4520  */
4521 static void
4522 run (void *cls, struct GNUNET_SERVER_Handle *server,
4523      const struct GNUNET_CONFIGURATION_Handle *c)
4524 {
4525   static const struct GNUNET_SERVER_MessageHandler handlers[] = {
4526     {&handle_client_init, NULL,
4527      GNUNET_MESSAGE_TYPE_CORE_INIT, 0},
4528     {&handle_client_iterate_peers, NULL,
4529      GNUNET_MESSAGE_TYPE_CORE_ITERATE_PEERS,
4530      sizeof (struct GNUNET_MessageHeader)},
4531     {&handle_client_have_peer, NULL,
4532      GNUNET_MESSAGE_TYPE_CORE_PEER_CONNECTED,
4533      sizeof (struct GNUNET_MessageHeader) +
4534      sizeof (struct GNUNET_PeerIdentity)},
4535     {&handle_client_request_info, NULL,
4536      GNUNET_MESSAGE_TYPE_CORE_REQUEST_INFO,
4537      sizeof (struct RequestInfoMessage)},
4538     {&handle_client_send_request, NULL,
4539      GNUNET_MESSAGE_TYPE_CORE_SEND_REQUEST,
4540      sizeof (struct SendMessageRequest)},
4541     {&handle_client_send, NULL,
4542      GNUNET_MESSAGE_TYPE_CORE_SEND, 0},
4543     {NULL, NULL, 0, 0}
4544   };
4545   char *keyfile;
4546
4547   cfg = c;
4548   /* parse configuration */
4549   if ((GNUNET_OK !=
4550        GNUNET_CONFIGURATION_get_value_number (c, "CORE", "TOTAL_QUOTA_IN",
4551                                               &bandwidth_target_in_bps)) ||
4552       (GNUNET_OK !=
4553        GNUNET_CONFIGURATION_get_value_number (c, "CORE", "TOTAL_QUOTA_OUT",
4554                                               &bandwidth_target_out_bps)) ||
4555       (GNUNET_OK !=
4556        GNUNET_CONFIGURATION_get_value_filename (c, "GNUNETD", "HOSTKEY",
4557                                                 &keyfile)))
4558   {
4559     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
4560                 _
4561                 ("Core service is lacking key configuration settings.  Exiting.\n"));
4562     GNUNET_SCHEDULER_shutdown ();
4563     return;
4564   }
4565   peerinfo = GNUNET_PEERINFO_connect (cfg);
4566   if (NULL == peerinfo)
4567   {
4568     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
4569                 _("Could not access PEERINFO service.  Exiting.\n"));
4570     GNUNET_SCHEDULER_shutdown ();
4571     GNUNET_free (keyfile);
4572     return;
4573   }
4574   my_private_key = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile);
4575   GNUNET_free (keyfile);
4576   if (my_private_key == NULL)
4577   {
4578     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
4579                 _("Core service could not access hostkey.  Exiting.\n"));
4580     GNUNET_PEERINFO_disconnect (peerinfo);
4581     GNUNET_SCHEDULER_shutdown ();
4582     return;
4583   }
4584   neighbours = GNUNET_CONTAINER_multihashmap_create (128);
4585   GNUNET_CRYPTO_rsa_key_get_public (my_private_key, &my_public_key);
4586   GNUNET_CRYPTO_hash (&my_public_key, sizeof (my_public_key),
4587                       &my_identity.hashPubKey);
4588   self.public_key = &my_public_key;
4589   self.peer = my_identity;
4590   self.last_activity = GNUNET_TIME_UNIT_FOREVER_ABS;
4591   self.status = PEER_STATE_KEY_CONFIRMED;
4592   self.is_connected = GNUNET_YES;
4593   /* setup notification */
4594   notifier =
4595       GNUNET_SERVER_notification_context_create (server, MAX_NOTIFY_QUEUE);
4596   GNUNET_SERVER_disconnect_notify (server, &handle_client_disconnect, NULL);
4597   /* setup transport connection */
4598   transport =
4599       GNUNET_TRANSPORT_connect (cfg, &my_identity, NULL,
4600                                 &handle_transport_receive,
4601                                 &handle_transport_notify_connect,
4602                                 &handle_transport_notify_disconnect);
4603   GNUNET_assert (NULL != transport);
4604   stats = GNUNET_STATISTICS_create ("core", cfg);
4605   mst = GNUNET_SERVER_mst_create (&deliver_message, NULL);
4606   GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &cleaning_task,
4607                                 NULL);
4608   /* process client requests */
4609   GNUNET_SERVER_add_handlers (server, handlers);
4610   GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Core service of `%4s' ready.\n"),
4611               GNUNET_i2s (&my_identity));
4612 }
4613
4614
4615
4616 /**
4617  * The main function for the transport service.
4618  *
4619  * @param argc number of arguments from the command line
4620  * @param argv command line arguments
4621  * @return 0 ok, 1 on error
4622  */
4623 int
4624 main (int argc, char *const *argv)
4625 {
4626   return (GNUNET_OK ==
4627           GNUNET_SERVICE_run (argc, argv, "core", GNUNET_SERVICE_OPTION_NONE,
4628                               &run, NULL)) ? 0 : 1;
4629 }
4630
4631 /* end of gnunet-service-core.c */