e97e9fe46e85767e51827520e07f68f979f3bd3c
[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_NO
48
49 #define DEBUG_CORE_QUOTA GNUNET_NO
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   memcpy (&irm.publicKey, &my_public_key,
1397           sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded));
1398 #if DEBUG_CORE_CLIENT
1399   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message to client.\n",
1400               "INIT_REPLY");
1401 #endif
1402   send_to_client (c, &irm.header, GNUNET_NO);
1403   if (0 != (c->options & GNUNET_CORE_OPTION_SEND_CONNECT))
1404   {
1405     /* notify new client about existing neighbours */
1406     GNUNET_CONTAINER_multihashmap_iterate (neighbours,
1407                                            &notify_client_about_neighbour, c);
1408   }
1409   GNUNET_SERVER_receive_done (client, GNUNET_OK);
1410 }
1411
1412
1413 /**
1414  * Free client request records.
1415  *
1416  * @param cls NULL
1417  * @param key identity of peer for which this is an active request
1418  * @param value the 'struct ClientActiveRequest' to free
1419  * @return GNUNET_YES (continue iteration)
1420  */
1421 static int
1422 destroy_active_client_request (void *cls, const GNUNET_HashCode * key,
1423                                void *value)
1424 {
1425   struct ClientActiveRequest *car = value;
1426   struct Neighbour *n;
1427   struct GNUNET_PeerIdentity peer;
1428
1429   peer.hashPubKey = *key;
1430   n = find_neighbour (&peer);
1431   GNUNET_assert (NULL != n);
1432   GNUNET_CONTAINER_DLL_remove (n->active_client_request_head,
1433                                n->active_client_request_tail, car);
1434   GNUNET_free (car);
1435   return GNUNET_YES;
1436 }
1437
1438
1439 /**
1440  * A client disconnected, clean up.
1441  *
1442  * @param cls closure
1443  * @param client identification of the client
1444  */
1445 static void
1446 handle_client_disconnect (void *cls, struct GNUNET_SERVER_Client *client)
1447 {
1448   struct Client *pos;
1449   struct Client *prev;
1450   unsigned int i;
1451   const uint16_t *wtypes;
1452
1453   if (client == NULL)
1454     return;
1455 #if DEBUG_CORE_CLIENT
1456   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1457               "Client %p has disconnected from core service.\n", client);
1458 #endif
1459   prev = NULL;
1460   pos = clients;
1461   while (pos != NULL)
1462   {
1463     if (client == pos->client_handle)
1464       break;
1465     prev = pos;
1466     pos = pos->next;
1467   }
1468   if (pos == NULL)
1469   {
1470     /* client never sent INIT */
1471     return;
1472   }
1473   if (prev == NULL)
1474     clients = pos->next;
1475   else
1476     prev->next = pos->next;
1477   if (pos->requests != NULL)
1478   {
1479     GNUNET_CONTAINER_multihashmap_iterate (pos->requests,
1480                                            &destroy_active_client_request,
1481                                            NULL);
1482     GNUNET_CONTAINER_multihashmap_destroy (pos->requests);
1483   }
1484   GNUNET_free (pos);
1485
1486   /* rebuild my_type_map */
1487   memset (my_type_map, 0, sizeof (my_type_map));
1488   for (pos = clients; NULL != pos; pos = pos->next)
1489   {
1490     wtypes = (const uint16_t *) &pos[1];
1491     for (i = 0; i < pos->tcnt; i++)
1492       my_type_map[wtypes[i] / 32] |= (1 << (wtypes[i] % 32));
1493   }
1494   broadcast_my_type_map ();
1495 }
1496
1497
1498 /**
1499  * Helper function for handle_client_iterate_peers.
1500  *
1501  * @param cls the 'struct GNUNET_SERVER_TransmitContext' to queue replies
1502  * @param key identity of the connected peer
1503  * @param value the 'struct Neighbour' for the peer
1504  * @return GNUNET_OK (continue to iterate)
1505  */
1506 static int
1507 queue_connect_message (void *cls, const GNUNET_HashCode * key, void *value)
1508 {
1509   struct GNUNET_SERVER_TransmitContext *tc = cls;
1510   struct Neighbour *n = value;
1511   char buf[GNUNET_SERVER_MAX_MESSAGE_SIZE - 1];
1512   struct GNUNET_TRANSPORT_ATS_Information *ats;
1513   size_t size;
1514   struct ConnectNotifyMessage *cnm;
1515
1516   cnm = (struct ConnectNotifyMessage *) buf;
1517   if (n->status != PEER_STATE_KEY_CONFIRMED)
1518     return GNUNET_OK;
1519   size =
1520       sizeof (struct ConnectNotifyMessage) +
1521       (n->ats_count) * sizeof (struct GNUNET_TRANSPORT_ATS_Information);
1522   if (size >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
1523   {
1524     GNUNET_break (0);
1525     /* recovery strategy: throw away performance data */
1526     GNUNET_array_grow (n->ats, n->ats_count, 0);
1527     size =
1528         sizeof (struct PeerStatusNotifyMessage) +
1529         n->ats_count * sizeof (struct GNUNET_TRANSPORT_ATS_Information);
1530   }
1531   cnm = (struct ConnectNotifyMessage *) buf;
1532   cnm->header.size = htons (size);
1533   cnm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT);
1534   cnm->ats_count = htonl (n->ats_count);
1535   ats = &cnm->ats;
1536   memcpy (ats, n->ats,
1537           n->ats_count * sizeof (struct GNUNET_TRANSPORT_ATS_Information));
1538   ats[n->ats_count].type = htonl (GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR);
1539   ats[n->ats_count].value = htonl (0);
1540 #if DEBUG_CORE_CLIENT
1541   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message to client.\n",
1542               "NOTIFY_CONNECT");
1543 #endif
1544   cnm->peer = n->peer;
1545   GNUNET_SERVER_transmit_context_append_message (tc, &cnm->header);
1546   return GNUNET_OK;
1547 }
1548
1549
1550 /**
1551  * Handle CORE_ITERATE_PEERS request.
1552  *
1553  * @param cls unused
1554  * @param client client sending the iteration request
1555  * @param message iteration request message
1556  */
1557 static void
1558 handle_client_iterate_peers (void *cls, struct GNUNET_SERVER_Client *client,
1559                              const struct GNUNET_MessageHeader *message)
1560 {
1561   struct GNUNET_MessageHeader done_msg;
1562   struct GNUNET_SERVER_TransmitContext *tc;
1563   int msize;
1564
1565   /* notify new client about existing neighbours */
1566
1567   msize = ntohs (message->size);
1568   tc = GNUNET_SERVER_transmit_context_create (client);
1569   if (msize == sizeof (struct GNUNET_MessageHeader))
1570     GNUNET_CONTAINER_multihashmap_iterate (neighbours, &queue_connect_message,
1571                                            tc);
1572   else
1573     GNUNET_break (0);
1574
1575   done_msg.size = htons (sizeof (struct GNUNET_MessageHeader));
1576   done_msg.type = htons (GNUNET_MESSAGE_TYPE_CORE_ITERATE_PEERS_END);
1577   GNUNET_SERVER_transmit_context_append_message (tc, &done_msg);
1578   GNUNET_SERVER_transmit_context_run (tc, GNUNET_TIME_UNIT_FOREVER_REL);
1579 }
1580
1581
1582 /**
1583  * Handle CORE_PEER_CONNECTED request.  Notify client about existing neighbours.
1584  *
1585  * @param cls unused
1586  * @param client client sending the iteration request
1587  * @param message iteration request message
1588  */
1589 static void
1590 handle_client_have_peer (void *cls, struct GNUNET_SERVER_Client *client,
1591                          const struct GNUNET_MessageHeader *message)
1592 {
1593   struct GNUNET_MessageHeader done_msg;
1594   struct GNUNET_SERVER_TransmitContext *tc;
1595   struct GNUNET_PeerIdentity *peer;
1596
1597   tc = GNUNET_SERVER_transmit_context_create (client);
1598   peer = (struct GNUNET_PeerIdentity *) &message[1];
1599   GNUNET_CONTAINER_multihashmap_get_multiple (neighbours, &peer->hashPubKey,
1600                                               &queue_connect_message, tc);
1601   done_msg.size = htons (sizeof (struct GNUNET_MessageHeader));
1602   done_msg.type = htons (GNUNET_MESSAGE_TYPE_CORE_ITERATE_PEERS_END);
1603   GNUNET_SERVER_transmit_context_append_message (tc, &done_msg);
1604   GNUNET_SERVER_transmit_context_run (tc, GNUNET_TIME_UNIT_FOREVER_REL);
1605 }
1606
1607
1608 /**
1609  * Handle REQUEST_INFO request.
1610  *
1611  * @param cls unused
1612  * @param client client sending the request
1613  * @param message iteration request message
1614  */
1615 static void
1616 handle_client_request_info (void *cls, struct GNUNET_SERVER_Client *client,
1617                             const struct GNUNET_MessageHeader *message)
1618 {
1619   const struct RequestInfoMessage *rcm;
1620   struct Client *pos;
1621   struct Neighbour *n;
1622   struct ConfigurationInfoMessage cim;
1623   int32_t want_reserv;
1624   int32_t got_reserv;
1625   unsigned long long old_preference;
1626   struct GNUNET_TIME_Relative rdelay;
1627
1628   rdelay = GNUNET_TIME_relative_get_zero ();
1629 #if DEBUG_CORE_CLIENT
1630   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Core service receives `%s' request.\n",
1631               "REQUEST_INFO");
1632 #endif
1633   pos = clients;
1634   while (pos != NULL)
1635   {
1636     if (client == pos->client_handle)
1637       break;
1638     pos = pos->next;
1639   }
1640   if (pos == NULL)
1641   {
1642     GNUNET_break (0);
1643     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1644     return;
1645   }
1646
1647   rcm = (const struct RequestInfoMessage *) message;
1648   n = find_neighbour (&rcm->peer);
1649   memset (&cim, 0, sizeof (cim));
1650   if ((n != NULL) && (GNUNET_YES == n->is_connected))
1651   {
1652     want_reserv = ntohl (rcm->reserve_inbound);
1653     if (n->bw_out_internal_limit.value__ != rcm->limit_outbound.value__)
1654     {
1655       n->bw_out_internal_limit = rcm->limit_outbound;
1656       if (n->bw_out.value__ !=
1657           GNUNET_BANDWIDTH_value_min (n->bw_out_internal_limit,
1658                                       n->bw_out_external_limit).value__)
1659       {
1660         n->bw_out =
1661             GNUNET_BANDWIDTH_value_min (n->bw_out_internal_limit,
1662                                         n->bw_out_external_limit);
1663         GNUNET_BANDWIDTH_tracker_update_quota (&n->available_recv_window,
1664                                                n->bw_out);
1665         GNUNET_TRANSPORT_set_quota (transport, &n->peer, n->bw_in, n->bw_out);
1666         handle_peer_status_change (n);
1667       }
1668     }
1669     if (want_reserv < 0)
1670     {
1671       got_reserv = want_reserv;
1672     }
1673     else if (want_reserv > 0)
1674     {
1675       rdelay =
1676           GNUNET_BANDWIDTH_tracker_get_delay (&n->available_recv_window,
1677                                               want_reserv);
1678       if (rdelay.rel_value == 0)
1679         got_reserv = want_reserv;
1680       else
1681         got_reserv = 0;         /* all or nothing */
1682     }
1683     else
1684       got_reserv = 0;
1685     GNUNET_BANDWIDTH_tracker_consume (&n->available_recv_window, got_reserv);
1686     old_preference = n->current_preference;
1687     n->current_preference += GNUNET_ntohll (rcm->preference_change);
1688     if (old_preference > n->current_preference)
1689     {
1690       /* overflow; cap at maximum value */
1691       n->current_preference = ULLONG_MAX;
1692     }
1693     update_preference_sum (n->current_preference - old_preference);
1694 #if DEBUG_CORE_QUOTA
1695     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1696                 "Received reservation request for %d bytes for peer `%4s', reserved %d bytes, suggesting delay of %llu ms\n",
1697                 (int) want_reserv, GNUNET_i2s (&rcm->peer), (int) got_reserv,
1698                 (unsigned long long) rdelay.rel_value);
1699 #endif
1700     cim.reserved_amount = htonl (got_reserv);
1701     cim.reserve_delay = GNUNET_TIME_relative_hton (rdelay);
1702     cim.bw_out = n->bw_out;
1703     cim.preference = n->current_preference;
1704   }
1705   else
1706   {
1707     /* Technically, this COULD happen (due to asynchronous behavior),
1708      * but it should be rare, so we should generate an info event 
1709      * to help diagnosis of serious errors that might be masked by this */
1710     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1711                 _
1712                 ("Client asked for preference change with peer `%s', which is not connected!\n"),
1713                 GNUNET_i2s (&rcm->peer));
1714     GNUNET_SERVER_receive_done (client, GNUNET_OK);
1715     return;
1716   }
1717   cim.header.size = htons (sizeof (struct ConfigurationInfoMessage));
1718   cim.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_CONFIGURATION_INFO);
1719   cim.peer = rcm->peer;
1720   cim.rim_id = rcm->rim_id;
1721 #if DEBUG_CORE_CLIENT
1722   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message to client.\n",
1723               "CONFIGURATION_INFO");
1724 #endif
1725   send_to_client (pos, &cim.header, GNUNET_NO);
1726   GNUNET_SERVER_receive_done (client, GNUNET_OK);
1727 }
1728
1729
1730 /**
1731  * Free the given entry for the neighbour (it has
1732  * already been removed from the list at this point).
1733  *
1734  * @param n neighbour to free
1735  */
1736 static void
1737 free_neighbour (struct Neighbour *n)
1738 {
1739   struct MessageEntry *m;
1740   struct ClientActiveRequest *car;
1741
1742 #if DEBUG_CORE
1743   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1744               "Destroying neighbour entry for peer `%4s'\n",
1745               GNUNET_i2s (&n->peer));
1746 #endif
1747   if (n->pitr != NULL)
1748   {
1749     GNUNET_PEERINFO_iterate_cancel (n->pitr);
1750     n->pitr = NULL;
1751   }
1752   if (n->skm != NULL)
1753   {
1754     GNUNET_free (n->skm);
1755     n->skm = NULL;
1756   }
1757   while (NULL != (m = n->messages))
1758   {
1759     n->messages = m->next;
1760     GNUNET_free (m);
1761   }
1762   while (NULL != (m = n->encrypted_head))
1763   {
1764     GNUNET_CONTAINER_DLL_remove (n->encrypted_head, n->encrypted_tail, m);
1765     GNUNET_free (m);
1766   }
1767   while (NULL != (car = n->active_client_request_head))
1768   {
1769     GNUNET_CONTAINER_DLL_remove (n->active_client_request_head,
1770                                  n->active_client_request_tail, car);
1771     GNUNET_assert (GNUNET_YES ==
1772                    GNUNET_CONTAINER_multihashmap_remove (car->client->requests,
1773                                                          &n->peer.hashPubKey,
1774                                                          car));
1775     GNUNET_free (car);
1776   }
1777   if (NULL != n->th)
1778   {
1779     GNUNET_TRANSPORT_notify_transmit_ready_cancel (n->th);
1780     n->th = NULL;
1781   }
1782   if (n->retry_plaintext_task != GNUNET_SCHEDULER_NO_TASK)
1783     GNUNET_SCHEDULER_cancel (n->retry_plaintext_task);
1784   if (n->retry_set_key_task != GNUNET_SCHEDULER_NO_TASK)
1785     GNUNET_SCHEDULER_cancel (n->retry_set_key_task);
1786   if (n->quota_update_task != GNUNET_SCHEDULER_NO_TASK)
1787     GNUNET_SCHEDULER_cancel (n->quota_update_task);
1788   if (n->dead_clean_task != GNUNET_SCHEDULER_NO_TASK)
1789     GNUNET_SCHEDULER_cancel (n->dead_clean_task);
1790   if (n->keep_alive_task != GNUNET_SCHEDULER_NO_TASK)
1791     GNUNET_SCHEDULER_cancel (n->keep_alive_task);
1792   if (n->status == PEER_STATE_KEY_CONFIRMED)
1793     GNUNET_STATISTICS_update (stats, gettext_noop ("# established sessions"),
1794                               -1, GNUNET_NO);
1795   GNUNET_array_grow (n->ats, n->ats_count, 0);
1796   GNUNET_free_non_null (n->public_key);
1797   GNUNET_free_non_null (n->pending_ping);
1798   GNUNET_free_non_null (n->pending_pong);
1799   GNUNET_free (n);
1800 }
1801
1802
1803 /**
1804  * Check if we have encrypted messages for the specified neighbour
1805  * pending, and if so, check with the transport about sending them
1806  * out.
1807  *
1808  * @param n neighbour to check.
1809  */
1810 static void 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 consider_free_neighbour (struct Neighbour *n);
1858
1859
1860 /**
1861  * Task triggered when a neighbour entry is about to time out 
1862  * (and we should prevent this by sending a PING).
1863  *
1864  * @param cls the 'struct Neighbour'
1865  * @param tc scheduler context (not used)
1866  */
1867 static void
1868 send_keep_alive (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1869 {
1870   struct Neighbour *n = cls;
1871   struct GNUNET_TIME_Relative retry;
1872   struct GNUNET_TIME_Relative left;
1873   struct MessageEntry *me;
1874   struct PingMessage pp;
1875   struct PingMessage *pm;
1876   struct GNUNET_CRYPTO_AesInitializationVector iv;
1877
1878   n->keep_alive_task = GNUNET_SCHEDULER_NO_TASK;
1879   /* send PING */
1880   me = GNUNET_malloc (sizeof (struct MessageEntry) +
1881                       sizeof (struct PingMessage));
1882   me->deadline = GNUNET_TIME_relative_to_absolute (MAX_PING_DELAY);
1883   me->priority = PING_PRIORITY;
1884   me->size = sizeof (struct PingMessage);
1885   GNUNET_CONTAINER_DLL_insert_after (n->encrypted_head, n->encrypted_tail,
1886                                      n->encrypted_tail, me);
1887   pm = (struct PingMessage *) &me[1];
1888   pm->header.size = htons (sizeof (struct PingMessage));
1889   pm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_PING);
1890   pm->iv_seed =
1891       GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, UINT32_MAX);
1892   derive_iv (&iv, &n->encrypt_key, pm->iv_seed, &n->peer);
1893   pp.challenge = n->ping_challenge;
1894   pp.target = n->peer;
1895 #if DEBUG_HANDSHAKE
1896   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1897               "Encrypting `%s' message with challenge %u for `%4s' using key %u, IV %u (salt %u).\n",
1898               "PING", (unsigned int) n->ping_challenge, GNUNET_i2s (&n->peer),
1899               (unsigned int) n->encrypt_key.crc32, GNUNET_CRYPTO_crc32_n (&iv,
1900                                                                           sizeof
1901                                                                           (iv)),
1902               pm->iv_seed);
1903 #endif
1904   do_encrypt (n, &iv, &pp.target, &pm->target,
1905               sizeof (struct PingMessage) - ((void *) &pm->target -
1906                                              (void *) pm));
1907   process_encrypted_neighbour_queue (n);
1908   /* reschedule PING job */
1909   left = GNUNET_TIME_absolute_get_remaining (get_neighbour_timeout (n));
1910   retry =
1911       GNUNET_TIME_relative_max (GNUNET_TIME_relative_divide (left, 2),
1912                                 MIN_PING_FREQUENCY);
1913   n->keep_alive_task =
1914       GNUNET_SCHEDULER_add_delayed (retry, &send_keep_alive, n);
1915
1916 }
1917
1918
1919 /**
1920  * Task triggered when a neighbour entry might have gotten stale.
1921  *
1922  * @param cls the 'struct Neighbour'
1923  * @param tc scheduler context (not used)
1924  */
1925 static void
1926 consider_free_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1927 {
1928   struct Neighbour *n = cls;
1929
1930   n->dead_clean_task = GNUNET_SCHEDULER_NO_TASK;
1931   consider_free_neighbour (n);
1932 }
1933
1934
1935 /**
1936  * Consider freeing the given neighbour since we may not need
1937  * to keep it around anymore.
1938  *
1939  * @param n neighbour to consider discarding
1940  */
1941 static void
1942 consider_free_neighbour (struct Neighbour *n)
1943 {
1944   struct GNUNET_TIME_Relative left;
1945
1946   if ((n->th != NULL) || (n->pitr != NULL) || (GNUNET_YES == n->is_connected))
1947     return;                     /* no chance */
1948
1949   left = GNUNET_TIME_absolute_get_remaining (get_neighbour_timeout (n));
1950   if (left.rel_value > 0)
1951   {
1952     if (n->dead_clean_task != GNUNET_SCHEDULER_NO_TASK)
1953       GNUNET_SCHEDULER_cancel (n->dead_clean_task);
1954     n->dead_clean_task =
1955         GNUNET_SCHEDULER_add_delayed (left, &consider_free_task, n);
1956     return;
1957   }
1958   /* actually free the neighbour... */
1959   GNUNET_assert (GNUNET_YES ==
1960                  GNUNET_CONTAINER_multihashmap_remove (neighbours,
1961                                                        &n->peer.hashPubKey, n));
1962   GNUNET_STATISTICS_set (stats, gettext_noop ("# neighbour entries allocated"),
1963                          GNUNET_CONTAINER_multihashmap_size (neighbours),
1964                          GNUNET_NO);
1965   free_neighbour (n);
1966 }
1967
1968
1969 /**
1970  * Function called when the transport service is ready to
1971  * receive an encrypted message for the respective peer
1972  *
1973  * @param cls neighbour to use message from
1974  * @param size number of bytes we can transmit
1975  * @param buf where to copy the message
1976  * @return number of bytes transmitted
1977  */
1978 static size_t
1979 notify_encrypted_transmit_ready (void *cls, size_t size, void *buf)
1980 {
1981   struct Neighbour *n = cls;
1982   struct MessageEntry *m;
1983   size_t ret;
1984   char *cbuf;
1985
1986   n->th = NULL;
1987   m = n->encrypted_head;
1988   if (m == NULL)
1989   {
1990 #if DEBUG_CORE
1991     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1992                 "Encrypted message queue empty, no messages added to buffer for `%4s'\n",
1993                 GNUNET_i2s (&n->peer));
1994 #endif
1995     return 0;
1996   }
1997   GNUNET_CONTAINER_DLL_remove (n->encrypted_head, n->encrypted_tail, m);
1998   ret = 0;
1999   cbuf = buf;
2000   if (buf != NULL)
2001   {
2002     GNUNET_assert (size >= m->size);
2003     memcpy (cbuf, &m[1], m->size);
2004     ret = m->size;
2005     GNUNET_BANDWIDTH_tracker_consume (&n->available_send_window, m->size);
2006 #if DEBUG_CORE
2007     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2008                 "Copied message of type %u and size %u into transport buffer for `%4s'\n",
2009                 (unsigned int) ntohs (((struct GNUNET_MessageHeader *) &m[1])->
2010                                       type), (unsigned int) ret,
2011                 GNUNET_i2s (&n->peer));
2012 #endif
2013     process_encrypted_neighbour_queue (n);
2014   }
2015   else
2016   {
2017 #if DEBUG_CORE
2018     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2019                 "Transmission of message of type %u and size %u failed\n",
2020                 (unsigned int) ntohs (((struct GNUNET_MessageHeader *) &m[1])->
2021                                       type), (unsigned int) m->size);
2022 #endif
2023   }
2024   GNUNET_free (m);
2025   consider_free_neighbour (n);
2026   GNUNET_STATISTICS_update (stats,
2027                             gettext_noop
2028                             ("# encrypted bytes given to transport"), ret,
2029                             GNUNET_NO);
2030   return ret;
2031 }
2032
2033
2034 /**
2035  * Check if we have plaintext messages for the specified neighbour
2036  * pending, and if so, consider batching and encrypting them (and
2037  * then trigger processing of the encrypted queue if needed).
2038  *
2039  * @param n neighbour to check.
2040  */
2041 static void process_plaintext_neighbour_queue (struct Neighbour *n);
2042
2043
2044 /**
2045  * Check if we have encrypted messages for the specified neighbour
2046  * pending, and if so, check with the transport about sending them
2047  * out.
2048  *
2049  * @param n neighbour to check.
2050  */
2051 static void
2052 process_encrypted_neighbour_queue (struct Neighbour *n)
2053 {
2054   struct MessageEntry *m;
2055
2056   if (n->th != NULL)
2057     return;                     /* request already pending */
2058   if (GNUNET_YES != n->is_connected)
2059   {
2060     GNUNET_break (0);
2061     return;
2062   }
2063   m = n->encrypted_head;
2064   if (m == NULL)
2065   {
2066     /* encrypted queue empty, try plaintext instead */
2067     process_plaintext_neighbour_queue (n);
2068     return;
2069   }
2070 #if DEBUG_CORE > 1
2071   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2072               "Asking transport for transmission of %u bytes to `%4s' in next %llu ms\n",
2073               (unsigned int) m->size, GNUNET_i2s (&n->peer),
2074               (unsigned long long) GNUNET_TIME_absolute_get_remaining (m->
2075                                                                        deadline).
2076               rel_value);
2077 #endif
2078   n->th =
2079       GNUNET_TRANSPORT_notify_transmit_ready (transport, &n->peer, m->size,
2080                                               m->priority,
2081                                               GNUNET_TIME_absolute_get_remaining
2082                                               (m->deadline),
2083                                               &notify_encrypted_transmit_ready,
2084                                               n);
2085   if (n->th == NULL)
2086   {
2087     /* message request too large or duplicate request */
2088     GNUNET_break (0);
2089     /* discard encrypted message */
2090     GNUNET_CONTAINER_DLL_remove (n->encrypted_head, n->encrypted_tail, m);
2091     GNUNET_free (m);
2092     process_encrypted_neighbour_queue (n);
2093   }
2094 }
2095
2096
2097 /**
2098  * Decrypt size bytes from in and write the result to out.  Use the
2099  * key for inbound traffic of the given neighbour.  This function does
2100  * NOT do any integrity-checks on the result.
2101  *
2102  * @param n neighbour we are receiving from
2103  * @param iv initialization vector to use
2104  * @param in ciphertext
2105  * @param out plaintext
2106  * @param size size of in/out
2107  * @return GNUNET_OK on success
2108  */
2109 static int
2110 do_decrypt (struct Neighbour *n,
2111             const struct GNUNET_CRYPTO_AesInitializationVector *iv,
2112             const void *in, void *out, size_t size)
2113 {
2114   if (size != (uint16_t) size)
2115   {
2116     GNUNET_break (0);
2117     return GNUNET_NO;
2118   }
2119   if ((n->status != PEER_STATE_KEY_RECEIVED) &&
2120       (n->status != PEER_STATE_KEY_CONFIRMED))
2121   {
2122     GNUNET_break_op (0);
2123     return GNUNET_SYSERR;
2124   }
2125   if (size !=
2126       GNUNET_CRYPTO_aes_decrypt (in, (uint16_t) size, &n->decrypt_key, iv, out))
2127   {
2128     GNUNET_break (0);
2129     return GNUNET_SYSERR;
2130   }
2131   GNUNET_STATISTICS_update (stats, gettext_noop ("# bytes decrypted"), size,
2132                             GNUNET_NO);
2133 #if DEBUG_CORE > 1
2134   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2135               "Decrypted %u bytes from `%4s' using key %u, IV %u\n",
2136               (unsigned int) size, GNUNET_i2s (&n->peer),
2137               (unsigned int) n->decrypt_key.crc32, GNUNET_CRYPTO_crc32_n (iv,
2138                                                                           sizeof
2139                                                                           (*iv)));
2140 #endif
2141   return GNUNET_OK;
2142 }
2143
2144
2145 /**
2146  * Select messages for transmission.  This heuristic uses a combination
2147  * of earliest deadline first (EDF) scheduling (with bounded horizon)
2148  * and priority-based discard (in case no feasible schedule exist) and
2149  * speculative optimization (defer any kind of transmission until
2150  * we either create a batch of significant size, 25% of max, or until
2151  * we are close to a deadline).  Furthermore, when scheduling the
2152  * heuristic also packs as many messages into the batch as possible,
2153  * starting with those with the earliest deadline.  Yes, this is fun.
2154  *
2155  * @param n neighbour to select messages from
2156  * @param size number of bytes to select for transmission
2157  * @param retry_time set to the time when we should try again
2158  *        (only valid if this function returns zero)
2159  * @return number of bytes selected, or 0 if we decided to
2160  *         defer scheduling overall; in that case, retry_time is set.
2161  */
2162 static size_t
2163 select_messages (struct Neighbour *n, size_t size,
2164                  struct GNUNET_TIME_Relative *retry_time)
2165 {
2166   struct MessageEntry *pos;
2167   struct MessageEntry *min;
2168   struct MessageEntry *last;
2169   unsigned int min_prio;
2170   struct GNUNET_TIME_Absolute t;
2171   struct GNUNET_TIME_Absolute now;
2172   struct GNUNET_TIME_Relative delta;
2173   uint64_t avail;
2174   struct GNUNET_TIME_Relative slack;    /* how long could we wait before missing deadlines? */
2175   size_t off;
2176   uint64_t tsize;
2177   unsigned int queue_size;
2178   int discard_low_prio;
2179
2180   GNUNET_assert (NULL != n->messages);
2181   now = GNUNET_TIME_absolute_get ();
2182   /* last entry in linked list of messages processed */
2183   last = NULL;
2184   /* should we remove the entry with the lowest
2185    * priority from consideration for scheduling at the
2186    * end of the loop? */
2187   queue_size = 0;
2188   tsize = 0;
2189   pos = n->messages;
2190   while (pos != NULL)
2191   {
2192     queue_size++;
2193     tsize += pos->size;
2194     pos = pos->next;
2195   }
2196   discard_low_prio = GNUNET_YES;
2197   while (GNUNET_YES == discard_low_prio)
2198   {
2199     min = NULL;
2200     min_prio = UINT_MAX;
2201     discard_low_prio = GNUNET_NO;
2202     /* calculate number of bytes available for transmission at time "t" */
2203     avail = GNUNET_BANDWIDTH_tracker_get_available (&n->available_send_window);
2204     t = now;
2205     /* how many bytes have we (hypothetically) scheduled so far */
2206     off = 0;
2207     /* maximum time we can wait before transmitting anything
2208      * and still make all of our deadlines */
2209     slack = GNUNET_TIME_UNIT_FOREVER_REL;
2210     pos = n->messages;
2211     /* note that we use "*2" here because we want to look
2212      * a bit further into the future; much more makes no
2213      * sense since new message might be scheduled in the
2214      * meantime... */
2215     while ((pos != NULL) && (off < size * 2))
2216     {
2217       if (pos->do_transmit == GNUNET_YES)
2218       {
2219         /* already removed from consideration */
2220         pos = pos->next;
2221         continue;
2222       }
2223       if (discard_low_prio == GNUNET_NO)
2224       {
2225         delta = GNUNET_TIME_absolute_get_difference (t, pos->deadline);
2226         if (delta.rel_value > 0)
2227         {
2228           // FIXME: HUH? Check!
2229           t = pos->deadline;
2230           avail +=
2231               GNUNET_BANDWIDTH_value_get_available_until (n->bw_out, delta);
2232         }
2233         if (avail < pos->size)
2234         {
2235           // FIXME: HUH? Check!
2236           discard_low_prio = GNUNET_YES;        /* we could not schedule this one! */
2237         }
2238         else
2239         {
2240           avail -= pos->size;
2241           /* update slack, considering both its absolute deadline
2242            * and relative deadlines caused by other messages
2243            * with their respective load */
2244           slack =
2245               GNUNET_TIME_relative_min (slack,
2246                                         GNUNET_BANDWIDTH_value_get_delay_for
2247                                         (n->bw_out, avail));
2248           if (pos->deadline.abs_value <= now.abs_value)
2249           {
2250             /* now or never */
2251             slack = GNUNET_TIME_UNIT_ZERO;
2252           }
2253           else if (GNUNET_YES == pos->got_slack)
2254           {
2255             /* should be soon now! */
2256             slack =
2257                 GNUNET_TIME_relative_min (slack,
2258                                           GNUNET_TIME_absolute_get_remaining
2259                                           (pos->slack_deadline));
2260           }
2261           else
2262           {
2263             slack =
2264                 GNUNET_TIME_relative_min (slack,
2265                                           GNUNET_TIME_absolute_get_difference
2266                                           (now, pos->deadline));
2267             pos->got_slack = GNUNET_YES;
2268             pos->slack_deadline =
2269                 GNUNET_TIME_absolute_min (pos->deadline,
2270                                           GNUNET_TIME_relative_to_absolute
2271                                           (GNUNET_CONSTANTS_MAX_CORK_DELAY));
2272           }
2273         }
2274       }
2275       off += pos->size;
2276       t = GNUNET_TIME_absolute_max (pos->deadline, t);  // HUH? Check!
2277       if (pos->priority <= min_prio)
2278       {
2279         /* update min for discard */
2280         min_prio = pos->priority;
2281         min = pos;
2282       }
2283       pos = pos->next;
2284     }
2285     if (discard_low_prio)
2286     {
2287       GNUNET_assert (min != NULL);
2288       /* remove lowest-priority entry from consideration */
2289       min->do_transmit = GNUNET_YES;    /* means: discard (for now) */
2290     }
2291     last = pos;
2292   }
2293   /* guard against sending "tiny" messages with large headers without
2294    * urgent deadlines */
2295   if ((slack.rel_value > GNUNET_CONSTANTS_MAX_CORK_DELAY.rel_value) &&
2296       (size > 4 * off) && (queue_size <= MAX_PEER_QUEUE_SIZE - 2))
2297   {
2298     /* less than 25% of message would be filled with deadlines still
2299      * being met if we delay by one second or more; so just wait for
2300      * more data; but do not wait longer than 1s (since we don't want
2301      * to delay messages for a really long time either). */
2302     *retry_time = GNUNET_CONSTANTS_MAX_CORK_DELAY;
2303     /* reset do_transmit values for next time */
2304     while (pos != last)
2305     {
2306       pos->do_transmit = GNUNET_NO;
2307       pos = pos->next;
2308     }
2309     GNUNET_STATISTICS_update (stats,
2310                               gettext_noop
2311                               ("# transmissions delayed due to corking"), 1,
2312                               GNUNET_NO);
2313 #if DEBUG_CORE
2314     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2315                 "Deferring transmission for %llums due to underfull message buffer size (%u/%u)\n",
2316                 (unsigned long long) retry_time->rel_value, (unsigned int) off,
2317                 (unsigned int) size);
2318 #endif
2319     return 0;
2320   }
2321   /* select marked messages (up to size) for transmission */
2322   off = 0;
2323   pos = n->messages;
2324   while (pos != last)
2325   {
2326     if ((pos->size <= size) && (pos->do_transmit == GNUNET_NO))
2327     {
2328       pos->do_transmit = GNUNET_YES;    /* mark for transmission */
2329       off += pos->size;
2330       size -= pos->size;
2331 #if DEBUG_CORE > 1
2332       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2333                   "Selecting message of size %u for transmission\n",
2334                   (unsigned int) pos->size);
2335 #endif
2336     }
2337     else
2338     {
2339 #if DEBUG_CORE > 1
2340       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2341                   "Not selecting message of size %u for transmission at this time (maximum is %u)\n",
2342                   (unsigned int) pos->size, size);
2343 #endif
2344       pos->do_transmit = GNUNET_NO;     /* mark for not transmitting! */
2345     }
2346     pos = pos->next;
2347   }
2348 #if DEBUG_CORE
2349   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2350               "Selected %llu/%llu bytes of %u/%u plaintext messages for transmission to `%4s'.\n",
2351               (unsigned long long) off, (unsigned long long) tsize, queue_size,
2352               (unsigned int) MAX_PEER_QUEUE_SIZE, GNUNET_i2s (&n->peer));
2353 #endif
2354   return off;
2355 }
2356
2357
2358 /**
2359  * Batch multiple messages into a larger buffer.
2360  *
2361  * @param n neighbour to take messages from
2362  * @param buf target buffer
2363  * @param size size of buf
2364  * @param deadline set to transmission deadline for the result
2365  * @param retry_time set to the time when we should try again
2366  *        (only valid if this function returns zero)
2367  * @param priority set to the priority of the batch
2368  * @return number of bytes written to buf (can be zero)
2369  */
2370 static size_t
2371 batch_message (struct Neighbour *n, char *buf, size_t size,
2372                struct GNUNET_TIME_Absolute *deadline,
2373                struct GNUNET_TIME_Relative *retry_time, unsigned int *priority)
2374 {
2375   char ntmb[GNUNET_SERVER_MAX_MESSAGE_SIZE - 1];
2376   struct NotifyTrafficMessage *ntm = (struct NotifyTrafficMessage *) ntmb;
2377   struct MessageEntry *pos;
2378   struct MessageEntry *prev;
2379   struct MessageEntry *next;
2380   size_t ret;
2381
2382   ret = 0;
2383   *priority = 0;
2384   *deadline = GNUNET_TIME_UNIT_FOREVER_ABS;
2385   *retry_time = GNUNET_TIME_UNIT_FOREVER_REL;
2386   if (0 == select_messages (n, size, retry_time))
2387   {
2388 #if DEBUG_CORE
2389     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2390                 "No messages selected, will try again in %llu ms\n",
2391                 retry_time->rel_value);
2392 #endif
2393     return 0;
2394   }
2395   ntm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_OUTBOUND);
2396   ntm->ats_count = htonl (0);
2397   ntm->ats.type = htonl (0);
2398   ntm->ats.value = htonl (0);
2399   ntm->peer = n->peer;
2400   pos = n->messages;
2401   prev = NULL;
2402   while ((pos != NULL) && (size >= sizeof (struct GNUNET_MessageHeader)))
2403   {
2404     next = pos->next;
2405     if (GNUNET_YES == pos->do_transmit)
2406     {
2407       GNUNET_assert (pos->size <= size);
2408       /* do notifications */
2409       /* FIXME: track if we have *any* client that wants
2410        * full notifications and only do this if that is
2411        * actually true */
2412       if (pos->size <
2413           GNUNET_SERVER_MAX_MESSAGE_SIZE - sizeof (struct NotifyTrafficMessage))
2414       {
2415         memcpy (&ntm[1], &pos[1], pos->size);
2416         ntm->header.size =
2417             htons (sizeof (struct NotifyTrafficMessage) +
2418                    sizeof (struct GNUNET_MessageHeader));
2419         send_to_all_clients (&ntm->header, GNUNET_YES,
2420                              GNUNET_CORE_OPTION_SEND_HDR_OUTBOUND);
2421       }
2422       else
2423       {
2424         /* message too large for 'full' notifications, we do at
2425          * least the 'hdr' type */
2426         memcpy (&ntm[1], &pos[1], sizeof (struct GNUNET_MessageHeader));
2427       }
2428       ntm->header.size =
2429           htons (sizeof (struct NotifyTrafficMessage) + pos->size);
2430       send_to_all_clients (&ntm->header, GNUNET_YES,
2431                            GNUNET_CORE_OPTION_SEND_FULL_OUTBOUND);
2432 #if DEBUG_HANDSHAKE
2433       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2434                   "Encrypting %u bytes with message of type %u and size %u\n",
2435                   pos->size,
2436                   (unsigned int)
2437                   ntohs (((const struct GNUNET_MessageHeader *) &pos[1])->type),
2438                   (unsigned int)
2439                   ntohs (((const struct GNUNET_MessageHeader *) &pos[1])->
2440                          size));
2441 #endif
2442       /* copy for encrypted transmission */
2443       memcpy (&buf[ret], &pos[1], pos->size);
2444       ret += pos->size;
2445       size -= pos->size;
2446       *priority += pos->priority;
2447 #if DEBUG_CORE > 1
2448       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2449                   "Adding plaintext message of size %u with deadline %llu ms to batch\n",
2450                   (unsigned int) pos->size,
2451                   (unsigned long long) GNUNET_TIME_absolute_get_remaining (pos->
2452                                                                            deadline).
2453                   rel_value);
2454 #endif
2455       deadline->abs_value =
2456           GNUNET_MIN (deadline->abs_value, pos->deadline.abs_value);
2457       GNUNET_free (pos);
2458       if (prev == NULL)
2459         n->messages = next;
2460       else
2461         prev->next = next;
2462     }
2463     else
2464     {
2465       prev = pos;
2466     }
2467     pos = next;
2468   }
2469 #if DEBUG_CORE > 1
2470   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2471               "Deadline for message batch is %llu ms\n",
2472               GNUNET_TIME_absolute_get_remaining (*deadline).rel_value);
2473 #endif
2474   return ret;
2475 }
2476
2477
2478 /**
2479  * Remove messages with deadlines that have long expired from
2480  * the queue.
2481  *
2482  * @param n neighbour to inspect
2483  */
2484 static void
2485 discard_expired_messages (struct Neighbour *n)
2486 {
2487   struct MessageEntry *prev;
2488   struct MessageEntry *next;
2489   struct MessageEntry *pos;
2490   struct GNUNET_TIME_Absolute now;
2491   struct GNUNET_TIME_Relative delta;
2492   int disc;
2493
2494   disc = GNUNET_NO;
2495   now = GNUNET_TIME_absolute_get ();
2496   prev = NULL;
2497   pos = n->messages;
2498   while (pos != NULL)
2499   {
2500     next = pos->next;
2501     delta = GNUNET_TIME_absolute_get_difference (pos->deadline, now);
2502     if (delta.rel_value > PAST_EXPIRATION_DISCARD_TIME.rel_value)
2503     {
2504 #if DEBUG_CORE
2505       GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2506                   "Message is %llu ms past due, discarding.\n",
2507                   delta.rel_value);
2508 #endif
2509       if (prev == NULL)
2510         n->messages = next;
2511       else
2512         prev->next = next;
2513       GNUNET_STATISTICS_update (stats,
2514                                 gettext_noop
2515                                 ("# messages discarded (expired prior to transmission)"),
2516                                 1, GNUNET_NO);
2517       disc = GNUNET_YES;
2518       GNUNET_free (pos);
2519     }
2520     else
2521       prev = pos;
2522     pos = next;
2523   }
2524   if (GNUNET_YES == disc)
2525     schedule_peer_messages (n);
2526 }
2527
2528
2529 /**
2530  * Signature of the main function of a task.
2531  *
2532  * @param cls closure
2533  * @param tc context information (why was this task triggered now)
2534  */
2535 static void
2536 retry_plaintext_processing (void *cls,
2537                             const struct GNUNET_SCHEDULER_TaskContext *tc)
2538 {
2539   struct Neighbour *n = cls;
2540
2541   n->retry_plaintext_task = GNUNET_SCHEDULER_NO_TASK;
2542   process_plaintext_neighbour_queue (n);
2543 }
2544
2545
2546 /**
2547  * Send our key (and encrypted PING) to the other peer.
2548  *
2549  * @param n the other peer
2550  */
2551 static void send_key (struct Neighbour *n);
2552
2553 /**
2554  * Task that will retry "send_key" if our previous attempt failed
2555  * to yield a PONG.
2556  */
2557 static void
2558 set_key_retry_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
2559 {
2560   struct Neighbour *n = cls;
2561
2562 #if DEBUG_CORE
2563   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Retrying key transmission to `%4s'\n",
2564               GNUNET_i2s (&n->peer));
2565 #endif
2566   n->retry_set_key_task = GNUNET_SCHEDULER_NO_TASK;
2567   n->set_key_retry_frequency =
2568       GNUNET_TIME_relative_multiply (n->set_key_retry_frequency, 2);
2569   send_key (n);
2570 }
2571
2572
2573 /**
2574  * Check if we have plaintext messages for the specified neighbour
2575  * pending, and if so, consider batching and encrypting them (and
2576  * then trigger processing of the encrypted queue if needed).
2577  *
2578  * @param n neighbour to check.
2579  */
2580 static void
2581 process_plaintext_neighbour_queue (struct Neighbour *n)
2582 {
2583   char pbuf[GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE + sizeof (struct EncryptedMessage)];    /* plaintext */
2584   size_t used;
2585   struct EncryptedMessage *em;  /* encrypted message */
2586   struct EncryptedMessage *ph;  /* plaintext header */
2587   struct MessageEntry *me;
2588   unsigned int priority;
2589   struct GNUNET_TIME_Absolute deadline;
2590   struct GNUNET_TIME_Relative retry_time;
2591   struct GNUNET_CRYPTO_AesInitializationVector iv;
2592   struct GNUNET_CRYPTO_AuthKey auth_key;
2593
2594   if (n->retry_plaintext_task != GNUNET_SCHEDULER_NO_TASK)
2595   {
2596     GNUNET_SCHEDULER_cancel (n->retry_plaintext_task);
2597     n->retry_plaintext_task = GNUNET_SCHEDULER_NO_TASK;
2598   }
2599   switch (n->status)
2600   {
2601   case PEER_STATE_DOWN:
2602     send_key (n);
2603 #if DEBUG_CORE
2604     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2605                 "Not yet connected to `%4s', deferring processing of plaintext messages.\n",
2606                 GNUNET_i2s (&n->peer));
2607 #endif
2608     return;
2609   case PEER_STATE_KEY_SENT:
2610     if (n->retry_set_key_task == GNUNET_SCHEDULER_NO_TASK)
2611       n->retry_set_key_task =
2612           GNUNET_SCHEDULER_add_delayed (n->set_key_retry_frequency,
2613                                         &set_key_retry_task, n);
2614 #if DEBUG_CORE
2615     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2616                 "Not yet connected to `%4s', deferring processing of plaintext messages.\n",
2617                 GNUNET_i2s (&n->peer));
2618 #endif
2619     return;
2620   case PEER_STATE_KEY_RECEIVED:
2621     if (n->retry_set_key_task == GNUNET_SCHEDULER_NO_TASK)
2622       n->retry_set_key_task =
2623           GNUNET_SCHEDULER_add_delayed (n->set_key_retry_frequency,
2624                                         &set_key_retry_task, n);
2625 #if DEBUG_CORE
2626     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2627                 "Not yet connected to `%4s', deferring processing of plaintext messages.\n",
2628                 GNUNET_i2s (&n->peer));
2629 #endif
2630     return;
2631   case PEER_STATE_KEY_CONFIRMED:
2632     /* ready to continue */
2633     break;
2634   }
2635   discard_expired_messages (n);
2636   if (n->messages == NULL)
2637   {
2638 #if DEBUG_CORE
2639     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2640                 "Plaintext message queue for `%4s' is empty.\n",
2641                 GNUNET_i2s (&n->peer));
2642 #endif
2643     return;                     /* no pending messages */
2644   }
2645   if (n->encrypted_head != NULL)
2646   {
2647 #if DEBUG_CORE > 2
2648     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2649                 "Encrypted message queue for `%4s' is still full, delaying plaintext processing.\n",
2650                 GNUNET_i2s (&n->peer));
2651 #endif
2652     return;                     /* wait for messages already encrypted to be
2653                                  * processed first! */
2654   }
2655   ph = (struct EncryptedMessage *) pbuf;
2656   deadline = GNUNET_TIME_UNIT_FOREVER_ABS;
2657   priority = 0;
2658   used = sizeof (struct EncryptedMessage);
2659   used +=
2660       batch_message (n, &pbuf[used],
2661                      GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE, &deadline,
2662                      &retry_time, &priority);
2663   if (used == sizeof (struct EncryptedMessage))
2664   {
2665 #if DEBUG_CORE > 1
2666     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2667                 "No messages selected for transmission to `%4s' at this time, will try again later.\n",
2668                 GNUNET_i2s (&n->peer));
2669 #endif
2670     /* no messages selected for sending, try again later... */
2671     n->retry_plaintext_task =
2672         GNUNET_SCHEDULER_add_delayed (retry_time, &retry_plaintext_processing,
2673                                       n);
2674     return;
2675   }
2676 #if DEBUG_CORE_QUOTA
2677   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2678               "Sending %u b/s as new limit to peer `%4s'\n",
2679               (unsigned int) ntohl (n->bw_in.value__), GNUNET_i2s (&n->peer));
2680 #endif
2681   ph->iv_seed =
2682       htonl (GNUNET_CRYPTO_random_u32
2683              (GNUNET_CRYPTO_QUALITY_NONCE, UINT32_MAX));
2684   ph->sequence_number = htonl (++n->last_sequence_number_sent);
2685   ph->inbound_bw_limit = n->bw_in;
2686   ph->timestamp = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get ());
2687
2688   /* setup encryption message header */
2689   me = GNUNET_malloc (sizeof (struct MessageEntry) + used);
2690   me->deadline = deadline;
2691   me->priority = priority;
2692   me->size = used;
2693   em = (struct EncryptedMessage *) &me[1];
2694   em->header.size = htons (used);
2695   em->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_ENCRYPTED_MESSAGE);
2696   em->iv_seed = ph->iv_seed;
2697   derive_iv (&iv, &n->encrypt_key, ph->iv_seed, &n->peer);
2698   /* encrypt */
2699 #if DEBUG_HANDSHAKE
2700   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2701               "Encrypting %u bytes of plaintext messages for `%4s' for transmission in %llums.\n",
2702               (unsigned int) used - ENCRYPTED_HEADER_SIZE,
2703               GNUNET_i2s (&n->peer),
2704               (unsigned long long)
2705               GNUNET_TIME_absolute_get_remaining (deadline).rel_value);
2706 #endif
2707   GNUNET_assert (GNUNET_OK ==
2708                  do_encrypt (n, &iv, &ph->sequence_number, &em->sequence_number,
2709                              used - ENCRYPTED_HEADER_SIZE));
2710   derive_auth_key (&auth_key, &n->encrypt_key, ph->iv_seed,
2711                    n->encrypt_key_created);
2712   GNUNET_CRYPTO_hmac (&auth_key, &em->sequence_number,
2713                       used - ENCRYPTED_HEADER_SIZE, &em->hmac);
2714 #if DEBUG_HANDSHAKE
2715   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2716               "Authenticated %u bytes of ciphertext %u: `%s'\n",
2717               used - ENCRYPTED_HEADER_SIZE,
2718               GNUNET_CRYPTO_crc32_n (&em->sequence_number,
2719                                      used - ENCRYPTED_HEADER_SIZE),
2720               GNUNET_h2s (&em->hmac));
2721 #endif
2722   /* append to transmission list */
2723   GNUNET_CONTAINER_DLL_insert_after (n->encrypted_head, n->encrypted_tail,
2724                                      n->encrypted_tail, me);
2725   process_encrypted_neighbour_queue (n);
2726   schedule_peer_messages (n);
2727 }
2728
2729
2730 /**
2731  * Function that recalculates the bandwidth quota for the
2732  * given neighbour and transmits it to the transport service.
2733  * 
2734  * @param cls neighbour for the quota update
2735  * @param tc context
2736  */
2737 static void neighbour_quota_update (void *cls,
2738                                     const struct GNUNET_SCHEDULER_TaskContext
2739                                     *tc);
2740
2741
2742 /**
2743  * Schedule the task that will recalculate the bandwidth
2744  * quota for this peer (and possibly force a disconnect of
2745  * idle peers by calculating a bandwidth of zero).
2746  */
2747 static void
2748 schedule_quota_update (struct Neighbour *n)
2749 {
2750   GNUNET_assert (n->quota_update_task == GNUNET_SCHEDULER_NO_TASK);
2751   n->quota_update_task =
2752       GNUNET_SCHEDULER_add_delayed (QUOTA_UPDATE_FREQUENCY,
2753                                     &neighbour_quota_update, n);
2754 }
2755
2756
2757 /**
2758  * Initialize a new 'struct Neighbour'.
2759  *
2760  * @param pid ID of the new neighbour
2761  * @return handle for the new neighbour
2762  */
2763 static struct Neighbour *
2764 create_neighbour (const struct GNUNET_PeerIdentity *pid)
2765 {
2766   struct Neighbour *n;
2767   struct GNUNET_TIME_Absolute now;
2768
2769 #if DEBUG_CORE
2770   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2771               "Creating neighbour entry for peer `%4s'\n", GNUNET_i2s (pid));
2772 #endif
2773   n = GNUNET_malloc (sizeof (struct Neighbour));
2774   n->peer = *pid;
2775   GNUNET_CRYPTO_aes_create_session_key (&n->encrypt_key);
2776   now = GNUNET_TIME_absolute_get ();
2777   n->encrypt_key_created = now;
2778   n->last_activity = now;
2779   n->set_key_retry_frequency = INITIAL_SET_KEY_RETRY_FREQUENCY;
2780   n->bw_in = GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT;
2781   n->bw_out = GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT;
2782   n->bw_out_internal_limit = GNUNET_BANDWIDTH_value_init (UINT32_MAX);
2783   n->bw_out_external_limit = GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT;
2784   n->ping_challenge =
2785       GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, UINT32_MAX);
2786   GNUNET_assert (GNUNET_OK ==
2787                  GNUNET_CONTAINER_multihashmap_put (neighbours,
2788                                                     &n->peer.hashPubKey, n,
2789                                                     GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
2790   GNUNET_STATISTICS_set (stats, gettext_noop ("# neighbour entries allocated"),
2791                          GNUNET_CONTAINER_multihashmap_size (neighbours),
2792                          GNUNET_NO);
2793   neighbour_quota_update (n, NULL);
2794   consider_free_neighbour (n);
2795   return n;
2796 }
2797
2798
2799 /**
2800  * Handle CORE_SEND request.
2801  *
2802  * @param cls unused
2803  * @param client the client issuing the request
2804  * @param message the "struct SendMessage"
2805  */
2806 static void
2807 handle_client_send (void *cls, struct GNUNET_SERVER_Client *client,
2808                     const struct GNUNET_MessageHeader *message)
2809 {
2810   const struct SendMessage *sm;
2811   struct Neighbour *n;
2812   struct MessageEntry *prev;
2813   struct MessageEntry *pos;
2814   struct MessageEntry *e;
2815   struct MessageEntry *min_prio_entry;
2816   struct MessageEntry *min_prio_prev;
2817   unsigned int min_prio;
2818   unsigned int queue_size;
2819   uint16_t msize;
2820
2821   msize = ntohs (message->size);
2822   if (msize <
2823       sizeof (struct SendMessage) + sizeof (struct GNUNET_MessageHeader))
2824   {
2825     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2826                 "msize is %u, should be at least %u (in %s:%d)\n", msize,
2827                 sizeof (struct SendMessage) +
2828                 sizeof (struct GNUNET_MessageHeader), __FILE__, __LINE__);
2829     GNUNET_break (0);
2830     if (client != NULL)
2831       GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
2832     return;
2833   }
2834   sm = (const struct SendMessage *) message;
2835   msize -= sizeof (struct SendMessage);
2836   if (0 ==
2837       memcmp (&sm->peer, &my_identity, sizeof (struct GNUNET_PeerIdentity)))
2838   {
2839     /* loopback */
2840     GNUNET_SERVER_mst_receive (mst, &self, (const char *) &sm[1], msize,
2841                                GNUNET_YES, GNUNET_NO);
2842     if (client != NULL)
2843       GNUNET_SERVER_receive_done (client, GNUNET_OK);
2844     return;
2845   }
2846   n = find_neighbour (&sm->peer);
2847   if ((n == NULL) || (GNUNET_YES != n->is_connected) ||
2848       (n->status != PEER_STATE_KEY_CONFIRMED))
2849   {
2850     /* attempt to send message to peer that is not connected anymore 
2851      * (can happen due to asynchrony) */
2852     GNUNET_STATISTICS_update (stats,
2853                               gettext_noop
2854                               ("# messages discarded (disconnected)"), 1,
2855                               GNUNET_NO);
2856     if (client != NULL)
2857       GNUNET_SERVER_receive_done (client, GNUNET_OK);
2858     return;
2859   }
2860 #if DEBUG_CORE
2861   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2862               "Core received `%s' request, queueing %u bytes of plaintext data for transmission to `%4s'.\n",
2863               "SEND", (unsigned int) msize, GNUNET_i2s (&sm->peer));
2864 #endif
2865   discard_expired_messages (n);
2866   /* bound queue size */
2867   /* NOTE: this entire block to bound the queue size should be
2868    * obsolete with the new client-request code and the
2869    * 'schedule_peer_messages' mechanism; we still have this code in
2870    * here for now as a sanity check for the new mechanmism;
2871    * ultimately, we should probably simply reject SEND messages that
2872    * are not 'approved' (or provide a new core API for very unreliable
2873    * delivery that always sends with priority 0).  Food for thought. */
2874   min_prio = UINT32_MAX;
2875   min_prio_entry = NULL;
2876   min_prio_prev = NULL;
2877   queue_size = 0;
2878   prev = NULL;
2879   pos = n->messages;
2880   while (pos != NULL)
2881   {
2882     if (pos->priority <= min_prio)
2883     {
2884       min_prio_entry = pos;
2885       min_prio_prev = prev;
2886       min_prio = pos->priority;
2887     }
2888     queue_size++;
2889     prev = pos;
2890     pos = pos->next;
2891   }
2892   if (queue_size >= MAX_PEER_QUEUE_SIZE)
2893   {
2894     /* queue full */
2895     if (ntohl (sm->priority) <= min_prio)
2896     {
2897       /* discard new entry; this should no longer happen! */
2898       GNUNET_break (0);
2899 #if DEBUG_CORE
2900       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2901                   "Queue full (%u/%u), discarding new request (%u bytes of type %u)\n",
2902                   queue_size, (unsigned int) MAX_PEER_QUEUE_SIZE,
2903                   (unsigned int) msize, (unsigned int) ntohs (message->type));
2904 #endif
2905       GNUNET_STATISTICS_update (stats,
2906                                 gettext_noop ("# discarded CORE_SEND requests"),
2907                                 1, GNUNET_NO);
2908
2909       if (client != NULL)
2910         GNUNET_SERVER_receive_done (client, GNUNET_OK);
2911       return;
2912     }
2913     GNUNET_assert (min_prio_entry != NULL);
2914     /* discard "min_prio_entry" */
2915 #if DEBUG_CORE
2916     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2917                 "Queue full, discarding existing older request\n");
2918 #endif
2919     GNUNET_STATISTICS_update (stats,
2920                               gettext_noop
2921                               ("# discarded lower priority CORE_SEND requests"),
2922                               1, GNUNET_NO);
2923     if (min_prio_prev == NULL)
2924       n->messages = min_prio_entry->next;
2925     else
2926       min_prio_prev->next = min_prio_entry->next;
2927     GNUNET_free (min_prio_entry);
2928   }
2929
2930 #if DEBUG_CORE
2931   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2932               "Adding transmission request for `%4s' of size %u to queue\n",
2933               GNUNET_i2s (&sm->peer), (unsigned int) msize);
2934 #endif
2935   GNUNET_break (0 == ntohl (sm->reserved));
2936   e = GNUNET_malloc (sizeof (struct MessageEntry) + msize);
2937   e->deadline = GNUNET_TIME_absolute_ntoh (sm->deadline);
2938   e->priority = ntohl (sm->priority);
2939   e->size = msize;
2940   if (GNUNET_YES != (int) ntohl (sm->cork))
2941     e->got_slack = GNUNET_YES;
2942   memcpy (&e[1], &sm[1], msize);
2943
2944   /* insert, keep list sorted by deadline */
2945   prev = NULL;
2946   pos = n->messages;
2947   while ((pos != NULL) && (pos->deadline.abs_value < e->deadline.abs_value))
2948   {
2949     prev = pos;
2950     pos = pos->next;
2951   }
2952   if (prev == NULL)
2953     n->messages = e;
2954   else
2955     prev->next = e;
2956   e->next = pos;
2957
2958   /* consider scheduling now */
2959   process_plaintext_neighbour_queue (n);
2960   if (client != NULL)
2961     GNUNET_SERVER_receive_done (client, GNUNET_OK);
2962 }
2963
2964
2965 /**
2966  * Handle CORE_REQUEST_CONNECT request.
2967  *
2968  * @param cls unused
2969  * @param client the client issuing the request
2970  * @param message the "struct ConnectMessage"
2971  */
2972 static void
2973 handle_client_request_connect (void *cls, struct GNUNET_SERVER_Client *client,
2974                                const struct GNUNET_MessageHeader *message)
2975 {
2976   const struct ConnectMessage *cm = (const struct ConnectMessage *) message;
2977   struct Neighbour *n;
2978
2979   if (0 ==
2980       memcmp (&cm->peer, &my_identity, sizeof (struct GNUNET_PeerIdentity)))
2981   {
2982     /* In this case a client has asked us to connect to ourselves, not really an error! */
2983     GNUNET_SERVER_receive_done (client, GNUNET_OK);
2984     return;
2985   }
2986   GNUNET_break (ntohl (cm->reserved) == 0);
2987 #if DEBUG_CORE
2988   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2989               "Core received `%s' request for `%4s', will try to establish connection\n",
2990               "REQUEST_CONNECT", GNUNET_i2s (&cm->peer));
2991 #endif
2992   GNUNET_STATISTICS_update (stats,
2993                             gettext_noop ("# connection requests received"), 1,
2994                             GNUNET_NO);
2995   GNUNET_SERVER_receive_done (client, GNUNET_OK);
2996   n = find_neighbour (&cm->peer);
2997   if ((n == NULL) || (GNUNET_YES != n->is_connected))
2998   {
2999     GNUNET_TRANSPORT_try_connect (transport, &cm->peer);
3000   }
3001   else
3002   {
3003     GNUNET_STATISTICS_update (stats,
3004                               gettext_noop
3005                               ("# connection requests ignored (already connected)"),
3006                               1, GNUNET_NO);
3007   }
3008 }
3009
3010
3011 /**
3012  * PEERINFO is giving us a HELLO for a peer.  Add the public key to
3013  * the neighbour's struct and retry send_key.  Or, if we did not get a
3014  * HELLO, just do nothing.
3015  *
3016  * @param cls the 'struct Neighbour' to retry sending the key for
3017  * @param peer the peer for which this is the HELLO
3018  * @param hello HELLO message of that peer
3019  * @param err_msg NULL if successful, otherwise contains error message
3020  */
3021 static void
3022 process_hello_retry_send_key (void *cls, const struct GNUNET_PeerIdentity *peer,
3023                               const struct GNUNET_HELLO_Message *hello,
3024                               const char *err_msg)
3025 {
3026   struct Neighbour *n = cls;
3027
3028   if (err_msg != NULL)
3029   {
3030     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3031                 _("Error in communication with PEERINFO service\n"));
3032     /* return; */
3033   }
3034
3035   if (peer == NULL)
3036   {
3037 #if DEBUG_CORE
3038     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Entered `%s' and `%s' is NULL!\n",
3039                 "process_hello_retry_send_key", "peer");
3040 #endif
3041     n->pitr = NULL;
3042     if (n->public_key != NULL)
3043     {
3044       if (n->retry_set_key_task != GNUNET_SCHEDULER_NO_TASK)
3045       {
3046         GNUNET_SCHEDULER_cancel (n->retry_set_key_task);
3047         n->retry_set_key_task = GNUNET_SCHEDULER_NO_TASK;
3048       }
3049       GNUNET_STATISTICS_update (stats,
3050                                 gettext_noop
3051                                 ("# SET_KEY messages deferred (need public key)"),
3052                                 -1, GNUNET_NO);
3053       send_key (n);
3054     }
3055     else
3056     {
3057 #if DEBUG_CORE
3058       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3059                   "Failed to obtain public key for peer `%4s', delaying processing of SET_KEY\n",
3060                   GNUNET_i2s (&n->peer));
3061 #endif
3062       GNUNET_STATISTICS_update (stats,
3063                                 gettext_noop
3064                                 ("# Delayed connecting due to lack of public key"),
3065                                 1, GNUNET_NO);
3066       if (GNUNET_SCHEDULER_NO_TASK == n->retry_set_key_task)
3067         n->retry_set_key_task =
3068             GNUNET_SCHEDULER_add_delayed (n->set_key_retry_frequency,
3069                                           &set_key_retry_task, n);
3070     }
3071     return;
3072   }
3073
3074 #if DEBUG_CORE
3075   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Entered `%s' for peer `%4s'\n",
3076               "process_hello_retry_send_key", GNUNET_i2s (peer));
3077 #endif
3078   if (n->public_key != NULL)
3079   {
3080     /* already have public key, why are we here? */
3081     GNUNET_break (0);
3082     return;
3083   }
3084
3085 #if DEBUG_CORE
3086   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3087               "Received new `%s' message for `%4s', initiating key exchange.\n",
3088               "HELLO", GNUNET_i2s (peer));
3089 #endif
3090   n->public_key =
3091       GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded));
3092   if (GNUNET_OK != GNUNET_HELLO_get_key (hello, n->public_key))
3093   {
3094     GNUNET_STATISTICS_update (stats,
3095                               gettext_noop
3096                               ("# Error extracting public key from HELLO"), 1,
3097                               GNUNET_NO);
3098     GNUNET_free (n->public_key);
3099     n->public_key = NULL;
3100 #if DEBUG_CORE
3101     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3102                 "GNUNET_HELLO_get_key returned awfully\n");
3103 #endif
3104     return;
3105   }
3106 }
3107
3108
3109 /**
3110  * Send our key (and encrypted PING) to the other peer.
3111  *
3112  * @param n the other peer
3113  */
3114 static void
3115 send_key (struct Neighbour *n)
3116 {
3117   struct MessageEntry *pos;
3118   struct SetKeyMessage *sm;
3119   struct MessageEntry *me;
3120   struct PingMessage pp;
3121   struct PingMessage *pm;
3122   struct GNUNET_CRYPTO_AesInitializationVector iv;
3123
3124   if (n->retry_set_key_task != GNUNET_SCHEDULER_NO_TASK)
3125   {
3126     GNUNET_SCHEDULER_cancel (n->retry_set_key_task);
3127     n->retry_set_key_task = GNUNET_SCHEDULER_NO_TASK;
3128   }
3129   if (n->pitr != NULL)
3130   {
3131 #if DEBUG_CORE
3132     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3133                 "Key exchange in progress with `%4s'.\n",
3134                 GNUNET_i2s (&n->peer));
3135 #endif
3136     return;                     /* already in progress */
3137   }
3138   if (GNUNET_YES != n->is_connected)
3139   {
3140     GNUNET_STATISTICS_update (stats,
3141                               gettext_noop
3142                               ("# Asking transport to connect (for SET_KEY)"),
3143                               1, GNUNET_NO);
3144     GNUNET_TRANSPORT_try_connect (transport, &n->peer);
3145     return;
3146   }
3147 #if DEBUG_CORE
3148   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3149               "Asked to perform key exchange with `%4s'.\n",
3150               GNUNET_i2s (&n->peer));
3151 #endif
3152   if (n->public_key == NULL)
3153   {
3154     /* lookup n's public key, then try again */
3155 #if DEBUG_CORE
3156     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3157                 "Lacking public key for `%4s', trying to obtain one (send_key).\n",
3158                 GNUNET_i2s (&n->peer));
3159 #endif
3160     GNUNET_assert (n->pitr == NULL);
3161     n->pitr =
3162         GNUNET_PEERINFO_iterate (peerinfo, &n->peer,
3163                                  GNUNET_TIME_relative_multiply
3164                                  (GNUNET_TIME_UNIT_SECONDS, 20),
3165                                  &process_hello_retry_send_key, n);
3166     return;
3167   }
3168   pos = n->encrypted_head;
3169   while (pos != NULL)
3170   {
3171     if (GNUNET_YES == pos->is_setkey)
3172     {
3173       if (pos->sender_status == n->status)
3174       {
3175 #if DEBUG_CORE
3176         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3177                     "`%s' message for `%4s' queued already\n", "SET_KEY",
3178                     GNUNET_i2s (&n->peer));
3179 #endif
3180         goto trigger_processing;
3181       }
3182       GNUNET_CONTAINER_DLL_remove (n->encrypted_head, n->encrypted_tail, pos);
3183       GNUNET_free (pos);
3184 #if DEBUG_CORE
3185       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3186                   "Removing queued `%s' message for `%4s', will create a new one\n",
3187                   "SET_KEY", GNUNET_i2s (&n->peer));
3188 #endif
3189       break;
3190     }
3191     pos = pos->next;
3192   }
3193
3194   /* update status */
3195   switch (n->status)
3196   {
3197   case PEER_STATE_DOWN:
3198     n->status = PEER_STATE_KEY_SENT;
3199     break;
3200   case PEER_STATE_KEY_SENT:
3201     break;
3202   case PEER_STATE_KEY_RECEIVED:
3203     break;
3204   case PEER_STATE_KEY_CONFIRMED:
3205     break;
3206   default:
3207     GNUNET_break (0);
3208     break;
3209   }
3210
3211
3212   /* first, set key message */
3213   me = GNUNET_malloc (sizeof (struct MessageEntry) +
3214                       sizeof (struct SetKeyMessage) +
3215                       sizeof (struct PingMessage));
3216   me->deadline = GNUNET_TIME_relative_to_absolute (MAX_SET_KEY_DELAY);
3217   me->priority = SET_KEY_PRIORITY;
3218   me->size = sizeof (struct SetKeyMessage) + sizeof (struct PingMessage);
3219   me->is_setkey = GNUNET_YES;
3220   me->got_slack = GNUNET_YES;   /* do not defer this one! */
3221   me->sender_status = n->status;
3222   GNUNET_CONTAINER_DLL_insert_after (n->encrypted_head, n->encrypted_tail,
3223                                      n->encrypted_tail, me);
3224   sm = (struct SetKeyMessage *) &me[1];
3225   sm->header.size = htons (sizeof (struct SetKeyMessage));
3226   sm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_SET_KEY);
3227   sm->sender_status =
3228       htonl ((int32_t)
3229              ((n->status ==
3230                PEER_STATE_DOWN) ? PEER_STATE_KEY_SENT : n->status));
3231   sm->purpose.size =
3232       htonl (sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) +
3233              sizeof (struct GNUNET_TIME_AbsoluteNBO) +
3234              sizeof (struct GNUNET_CRYPTO_RsaEncryptedData) +
3235              sizeof (struct GNUNET_PeerIdentity));
3236   sm->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_SET_KEY);
3237   sm->creation_time = GNUNET_TIME_absolute_hton (n->encrypt_key_created);
3238   sm->target = n->peer;
3239   GNUNET_assert (GNUNET_OK ==
3240                  GNUNET_CRYPTO_rsa_encrypt (&n->encrypt_key,
3241                                             sizeof (struct
3242                                                     GNUNET_CRYPTO_AesSessionKey),
3243                                             n->public_key, &sm->encrypted_key));
3244   GNUNET_assert (GNUNET_OK ==
3245                  GNUNET_CRYPTO_rsa_sign (my_private_key, &sm->purpose,
3246                                          &sm->signature));
3247   pm = (struct PingMessage *) &sm[1];
3248   pm->header.size = htons (sizeof (struct PingMessage));
3249   pm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_PING);
3250   pm->iv_seed =
3251       GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, UINT32_MAX);
3252   derive_iv (&iv, &n->encrypt_key, pm->iv_seed, &n->peer);
3253   pp.challenge = n->ping_challenge;
3254   pp.target = n->peer;
3255 #if DEBUG_HANDSHAKE
3256   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3257               "Encrypting `%s' and `%s' messages with challenge %u for `%4s' using key %u, IV %u (salt %u).\n",
3258               "SET_KEY", "PING", (unsigned int) n->ping_challenge,
3259               GNUNET_i2s (&n->peer), (unsigned int) n->encrypt_key.crc32,
3260               GNUNET_CRYPTO_crc32_n (&iv, sizeof (iv)), pm->iv_seed);
3261 #endif
3262   do_encrypt (n, &iv, &pp.target, &pm->target,
3263               sizeof (struct PingMessage) - ((void *) &pm->target -
3264                                              (void *) pm));
3265   GNUNET_STATISTICS_update (stats,
3266                             gettext_noop
3267                             ("# SET_KEY and PING messages created"), 1,
3268                             GNUNET_NO);
3269 #if DEBUG_CORE
3270   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3271               "Have %llu ms left for `%s' transmission.\n",
3272               (unsigned long long) GNUNET_TIME_absolute_get_remaining (me->
3273                                                                        deadline).
3274               rel_value, "SET_KEY");
3275 #endif
3276 trigger_processing:
3277   /* trigger queue processing */
3278   process_encrypted_neighbour_queue (n);
3279   if ((n->status != PEER_STATE_KEY_CONFIRMED) &&
3280       (GNUNET_SCHEDULER_NO_TASK == n->retry_set_key_task))
3281     n->retry_set_key_task =
3282         GNUNET_SCHEDULER_add_delayed (n->set_key_retry_frequency,
3283                                       &set_key_retry_task, n);
3284 }
3285
3286
3287 /**
3288  * We received a SET_KEY message.  Validate and update
3289  * our key material and status.
3290  *
3291  * @param n the neighbour from which we received message m
3292  * @param m the set key message we received
3293  * @param ats performance data
3294  * @param ats_count number of entries in ats (excluding 0-termination)
3295  */
3296 static void handle_set_key (struct Neighbour *n, const struct SetKeyMessage *m,
3297                             const struct GNUNET_TRANSPORT_ATS_Information *ats,
3298                             uint32_t ats_count);
3299
3300
3301
3302 /**
3303  * PEERINFO is giving us a HELLO for a peer.  Add the public key to
3304  * the neighbour's struct and retry handling the set_key message.  Or,
3305  * if we did not get a HELLO, just free the set key message.
3306  *
3307  * @param cls pointer to the set key message
3308  * @param peer the peer for which this is the HELLO
3309  * @param hello HELLO message of that peer
3310  * @param err_msg NULL if successful, otherwise contains error message
3311  */
3312 static void
3313 process_hello_retry_handle_set_key (void *cls,
3314                                     const struct GNUNET_PeerIdentity *peer,
3315                                     const struct GNUNET_HELLO_Message *hello,
3316                                     const char *err_msg)
3317 {
3318   struct Neighbour *n = cls;
3319   struct SetKeyMessage *sm = n->skm;
3320
3321   if (err_msg != NULL)
3322   {
3323     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3324                 _("Error in communication with PEERINFO service\n"));
3325     /* return; */
3326   }
3327
3328   if (peer == NULL)
3329   {
3330     n->skm = NULL;
3331     n->pitr = NULL;
3332     if (n->public_key != NULL)
3333     {
3334 #if DEBUG_CORE
3335       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3336                   "Received `%s' for `%4s', continuing processing of `%s' message.\n",
3337                   "HELLO", GNUNET_i2s (&n->peer), "SET_KEY");
3338 #endif
3339       handle_set_key (n, sm, NULL, 0);
3340     }
3341     else
3342     {
3343       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3344                   _
3345                   ("Ignoring `%s' message due to lack of public key for peer `%4s' (failed to obtain one).\n"),
3346                   "SET_KEY", GNUNET_i2s (&n->peer));
3347     }
3348     GNUNET_free (sm);
3349     return;
3350   }
3351   if (n->public_key != NULL)
3352     return;                     /* multiple HELLOs match!? */
3353   n->public_key =
3354       GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded));
3355   if (GNUNET_OK != GNUNET_HELLO_get_key (hello, n->public_key))
3356   {
3357     GNUNET_break_op (0);
3358     GNUNET_free (n->public_key);
3359     n->public_key = NULL;
3360   }
3361 }
3362
3363
3364 /**
3365  * Merge the given performance data with the data we currently
3366  * track for the given neighbour.
3367  *
3368  * @param n neighbour
3369  * @param ats new performance data
3370  * @param ats_count number of records in ats
3371  */
3372 static void
3373 update_neighbour_performance (struct Neighbour *n,
3374                               const struct GNUNET_TRANSPORT_ATS_Information
3375                               *ats, uint32_t ats_count)
3376 {
3377   uint32_t i;
3378   unsigned int j;
3379
3380   if (ats_count == 0)
3381     return;
3382   for (i = 0; i < ats_count; i++)
3383   {
3384     for (j = 0; j < n->ats_count; j++)
3385     {
3386       if (n->ats[j].type == ats[i].type)
3387       {
3388         n->ats[j].value = ats[i].value;
3389         break;
3390       }
3391     }
3392     if (j == n->ats_count)
3393     {
3394       GNUNET_array_append (n->ats, n->ats_count, ats[i]);
3395     }
3396   }
3397 }
3398
3399
3400 /**
3401  * We received a PING message.  Validate and transmit
3402  * PONG.
3403  *
3404  * @param n sender of the PING
3405  * @param m the encrypted PING message itself
3406  * @param ats performance data
3407  * @param ats_count number of entries in ats (excluding 0-termination)
3408  */
3409 static void
3410 handle_ping (struct Neighbour *n, const struct PingMessage *m,
3411              const struct GNUNET_TRANSPORT_ATS_Information *ats,
3412              uint32_t ats_count)
3413 {
3414   struct PingMessage t;
3415   struct PongMessage tx;
3416   struct PongMessage *tp;
3417   struct MessageEntry *me;
3418   struct GNUNET_CRYPTO_AesInitializationVector iv;
3419
3420 #if DEBUG_CORE
3421   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3422               "Core service receives `%s' request from `%4s'.\n", "PING",
3423               GNUNET_i2s (&n->peer));
3424 #endif
3425   derive_iv (&iv, &n->decrypt_key, m->iv_seed, &my_identity);
3426   if (GNUNET_OK !=
3427       do_decrypt (n, &iv, &m->target, &t.target,
3428                   sizeof (struct PingMessage) - ((void *) &m->target -
3429                                                  (void *) m)))
3430     return;
3431 #if DEBUG_HANDSHAKE
3432   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3433               "Decrypted `%s' to `%4s' with challenge %u decrypted using key %u, IV %u (salt %u)\n",
3434               "PING", GNUNET_i2s (&t.target), (unsigned int) t.challenge,
3435               (unsigned int) n->decrypt_key.crc32, GNUNET_CRYPTO_crc32_n (&iv,
3436                                                                           sizeof
3437                                                                           (iv)),
3438               m->iv_seed);
3439 #endif
3440   GNUNET_STATISTICS_update (stats, gettext_noop ("# PING messages decrypted"),
3441                             1, GNUNET_NO);
3442   if (0 !=
3443       memcmp (&t.target, &my_identity, sizeof (struct GNUNET_PeerIdentity)))
3444   {
3445     char sender[9];
3446     char peer[9];
3447
3448     GNUNET_snprintf (sender, sizeof (sender), "%8s", GNUNET_i2s (&n->peer));
3449     GNUNET_snprintf (peer, sizeof (peer), "%8s", GNUNET_i2s (&t.target));
3450     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3451                 _
3452                 ("Received PING from `%s' for different identity: I am `%s', PONG identity: `%s'\n"),
3453                 sender, GNUNET_i2s (&my_identity), peer);
3454     GNUNET_break_op (0);
3455     return;
3456   }
3457   update_neighbour_performance (n, ats, ats_count);
3458   me = GNUNET_malloc (sizeof (struct MessageEntry) +
3459                       sizeof (struct PongMessage));
3460   GNUNET_CONTAINER_DLL_insert_after (n->encrypted_head, n->encrypted_tail,
3461                                      n->encrypted_tail, me);
3462   me->deadline = GNUNET_TIME_relative_to_absolute (MAX_PONG_DELAY);
3463   me->priority = PONG_PRIORITY;
3464   me->size = sizeof (struct PongMessage);
3465   tx.inbound_bw_limit = n->bw_in;
3466   tx.challenge = t.challenge;
3467   tx.target = t.target;
3468   tp = (struct PongMessage *) &me[1];
3469   tp->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_PONG);
3470   tp->header.size = htons (sizeof (struct PongMessage));
3471   tp->iv_seed =
3472       GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, UINT32_MAX);
3473   derive_pong_iv (&iv, &n->encrypt_key, tp->iv_seed, t.challenge, &n->peer);
3474   do_encrypt (n, &iv, &tx.challenge, &tp->challenge,
3475               sizeof (struct PongMessage) - ((void *) &tp->challenge -
3476                                              (void *) tp));
3477   GNUNET_STATISTICS_update (stats, gettext_noop ("# PONG messages created"), 1,
3478                             GNUNET_NO);
3479 #if DEBUG_HANDSHAKE
3480   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3481               "Encrypting `%s' with challenge %u using key %u, IV %u (salt %u)\n",
3482               "PONG", (unsigned int) t.challenge,
3483               (unsigned int) n->encrypt_key.crc32, GNUNET_CRYPTO_crc32_n (&iv,
3484                                                                           sizeof
3485                                                                           (iv)),
3486               tp->iv_seed);
3487 #endif
3488   /* trigger queue processing */
3489   process_encrypted_neighbour_queue (n);
3490 }
3491
3492
3493 /**
3494  * We received a PONG message.  Validate and update our status.
3495  *
3496  * @param n sender of the PONG
3497  * @param m the encrypted PONG message itself
3498  * @param ats performance data
3499  * @param ats_count number of entries in ats (excluding 0-termination)
3500  */
3501 static void
3502 handle_pong (struct Neighbour *n, const struct PongMessage *m,
3503              const struct GNUNET_TRANSPORT_ATS_Information *ats,
3504              uint32_t ats_count)
3505 {
3506   struct PongMessage t;
3507   struct ConnectNotifyMessage *cnm;
3508   struct GNUNET_CRYPTO_AesInitializationVector iv;
3509   char buf[GNUNET_SERVER_MAX_MESSAGE_SIZE - 1];
3510   struct GNUNET_TRANSPORT_ATS_Information *mats;
3511   size_t size;
3512
3513 #if DEBUG_HANDSHAKE
3514   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3515               "Core service receives `%s' response from `%4s'.\n", "PONG",
3516               GNUNET_i2s (&n->peer));
3517 #endif
3518   /* mark as garbage, just to be sure */
3519   memset (&t, 255, sizeof (t));
3520   derive_pong_iv (&iv, &n->decrypt_key, m->iv_seed, n->ping_challenge,
3521                   &my_identity);
3522   if (GNUNET_OK !=
3523       do_decrypt (n, &iv, &m->challenge, &t.challenge,
3524                   sizeof (struct PongMessage) - ((void *) &m->challenge -
3525                                                  (void *) m)))
3526   {
3527     GNUNET_break_op (0);
3528     return;
3529   }
3530   GNUNET_STATISTICS_update (stats, gettext_noop ("# PONG messages decrypted"),
3531                             1, GNUNET_NO);
3532 #if DEBUG_HANDSHAKE
3533   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3534               "Decrypted `%s' from `%4s' with challenge %u using key %u, IV %u (salt %u)\n",
3535               "PONG", GNUNET_i2s (&t.target), (unsigned int) t.challenge,
3536               (unsigned int) n->decrypt_key.crc32, GNUNET_CRYPTO_crc32_n (&iv,
3537                                                                           sizeof
3538                                                                           (iv)),
3539               m->iv_seed);
3540 #endif
3541   if ((0 != memcmp (&t.target, &n->peer, sizeof (struct GNUNET_PeerIdentity)))
3542       || (n->ping_challenge != t.challenge))
3543   {
3544     /* PONG malformed */
3545 #if DEBUG_CORE
3546     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3547                 "Received malformed `%s' wanted sender `%4s' with challenge %u\n",
3548                 "PONG", GNUNET_i2s (&n->peer),
3549                 (unsigned int) n->ping_challenge);
3550     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3551                 "Received malformed `%s' received from `%4s' with challenge %u\n",
3552                 "PONG", GNUNET_i2s (&t.target), (unsigned int) t.challenge);
3553 #endif
3554     GNUNET_break_op (n->ping_challenge != t.challenge);
3555     return;
3556   }
3557   switch (n->status)
3558   {
3559   case PEER_STATE_DOWN:
3560     GNUNET_break (0);           /* should be impossible */
3561     return;
3562   case PEER_STATE_KEY_SENT:
3563     GNUNET_break (0);           /* should be impossible, how did we decrypt? */
3564     return;
3565   case PEER_STATE_KEY_RECEIVED:
3566     GNUNET_STATISTICS_update (stats,
3567                               gettext_noop
3568                               ("# Session keys confirmed via PONG"), 1,
3569                               GNUNET_NO);
3570     n->status = PEER_STATE_KEY_CONFIRMED;
3571     {
3572       struct GNUNET_MessageHeader *hdr;
3573
3574       hdr = compute_type_map_message ();
3575       send_type_map_to_neighbour (hdr, &n->peer.hashPubKey, n);
3576       GNUNET_free (hdr);
3577     }
3578     if (n->bw_out_external_limit.value__ != t.inbound_bw_limit.value__)
3579     {
3580       n->bw_out_external_limit = t.inbound_bw_limit;
3581       n->bw_out =
3582           GNUNET_BANDWIDTH_value_min (n->bw_out_external_limit,
3583                                       n->bw_out_internal_limit);
3584       GNUNET_BANDWIDTH_tracker_update_quota (&n->available_send_window,
3585                                              n->bw_out);
3586       GNUNET_TRANSPORT_set_quota (transport, &n->peer, n->bw_in, n->bw_out);
3587     }
3588 #if DEBUG_CORE
3589     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3590                 "Confirmed key via `%s' message for peer `%4s'\n", "PONG",
3591                 GNUNET_i2s (&n->peer));
3592 #endif
3593     if (n->retry_set_key_task != GNUNET_SCHEDULER_NO_TASK)
3594     {
3595       GNUNET_SCHEDULER_cancel (n->retry_set_key_task);
3596       n->retry_set_key_task = GNUNET_SCHEDULER_NO_TASK;
3597     }
3598     update_neighbour_performance (n, ats, ats_count);
3599     size =
3600         sizeof (struct ConnectNotifyMessage) +
3601         (n->ats_count) * sizeof (struct GNUNET_TRANSPORT_ATS_Information);
3602     if (size >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
3603     {
3604       GNUNET_break (0);
3605       /* recovery strategy: throw away performance data */
3606       GNUNET_array_grow (n->ats, n->ats_count, 0);
3607       size =
3608           sizeof (struct PeerStatusNotifyMessage) +
3609           n->ats_count * sizeof (struct GNUNET_TRANSPORT_ATS_Information);
3610     }
3611     cnm = (struct ConnectNotifyMessage *) buf;
3612     cnm->header.size = htons (size);
3613     cnm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT);
3614     cnm->ats_count = htonl (n->ats_count);
3615     cnm->peer = n->peer;
3616     mats = &cnm->ats;
3617     memcpy (mats, n->ats,
3618             n->ats_count * sizeof (struct GNUNET_TRANSPORT_ATS_Information));
3619     mats[n->ats_count].type = htonl (GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR);
3620     mats[n->ats_count].value = htonl (0);
3621     send_to_all_clients (&cnm->header, GNUNET_NO,
3622                          GNUNET_CORE_OPTION_SEND_CONNECT);
3623     process_encrypted_neighbour_queue (n);
3624     /* fall-through! */
3625   case PEER_STATE_KEY_CONFIRMED:
3626     n->last_activity = GNUNET_TIME_absolute_get ();
3627     if (n->keep_alive_task != GNUNET_SCHEDULER_NO_TASK)
3628       GNUNET_SCHEDULER_cancel (n->keep_alive_task);
3629     n->keep_alive_task =
3630         GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_divide
3631                                       (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
3632                                        2), &send_keep_alive, n);
3633     handle_peer_status_change (n);
3634     break;
3635   default:
3636     GNUNET_break (0);
3637     break;
3638   }
3639 }
3640
3641
3642 /**
3643  * We received a SET_KEY message.  Validate and update
3644  * our key material and status.
3645  *
3646  * @param n the neighbour from which we received message m
3647  * @param m the set key message we received
3648  * @param ats performance data
3649  * @param ats_count number of entries in ats (excluding 0-termination)
3650  */
3651 static void
3652 handle_set_key (struct Neighbour *n, const struct SetKeyMessage *m,
3653                 const struct GNUNET_TRANSPORT_ATS_Information *ats,
3654                 uint32_t ats_count)
3655 {
3656   struct SetKeyMessage *m_cpy;
3657   struct GNUNET_TIME_Absolute t;
3658   struct GNUNET_CRYPTO_AesSessionKey k;
3659   struct PingMessage *ping;
3660   struct PongMessage *pong;
3661   enum PeerStateMachine sender_status;
3662
3663 #if DEBUG_CORE
3664   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3665               "Core service receives `%s' request from `%4s'.\n", "SET_KEY",
3666               GNUNET_i2s (&n->peer));
3667 #endif
3668   if (n->public_key == NULL)
3669   {
3670     if (n->pitr != NULL)
3671     {
3672 #if DEBUG_CORE
3673       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3674                   "Ignoring `%s' message due to lack of public key for peer (still trying to obtain one).\n",
3675                   "SET_KEY");
3676 #endif
3677       return;
3678     }
3679 #if DEBUG_CORE
3680     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3681                 "Lacking public key for peer, trying to obtain one (handle_set_key).\n");
3682 #endif
3683     m_cpy = GNUNET_malloc (sizeof (struct SetKeyMessage));
3684     memcpy (m_cpy, m, sizeof (struct SetKeyMessage));
3685     /* lookup n's public key, then try again */
3686     GNUNET_assert (n->skm == NULL);
3687     n->skm = m_cpy;
3688     n->pitr =
3689         GNUNET_PEERINFO_iterate (peerinfo, &n->peer, GNUNET_TIME_UNIT_MINUTES,
3690                                  &process_hello_retry_handle_set_key, n);
3691     GNUNET_STATISTICS_update (stats,
3692                               gettext_noop
3693                               ("# SET_KEY messages deferred (need public key)"),
3694                               1, GNUNET_NO);
3695     return;
3696   }
3697   if (0 !=
3698       memcmp (&m->target, &my_identity, sizeof (struct GNUNET_PeerIdentity)))
3699   {
3700     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3701                 _
3702                 ("Received `%s' message that was for `%s', not for me.  Ignoring.\n"),
3703                 "SET_KEY", GNUNET_i2s (&m->target));
3704     return;
3705   }
3706   if ((ntohl (m->purpose.size) !=
3707        sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) +
3708        sizeof (struct GNUNET_TIME_AbsoluteNBO) +
3709        sizeof (struct GNUNET_CRYPTO_RsaEncryptedData) +
3710        sizeof (struct GNUNET_PeerIdentity)) ||
3711       (GNUNET_OK !=
3712        GNUNET_CRYPTO_rsa_verify (GNUNET_SIGNATURE_PURPOSE_SET_KEY, &m->purpose,
3713                                  &m->signature, n->public_key)))
3714   {
3715     /* invalid signature */
3716     GNUNET_break_op (0);
3717     return;
3718   }
3719   t = GNUNET_TIME_absolute_ntoh (m->creation_time);
3720   if (((n->status == PEER_STATE_KEY_RECEIVED) ||
3721        (n->status == PEER_STATE_KEY_CONFIRMED)) &&
3722       (t.abs_value < n->decrypt_key_created.abs_value))
3723   {
3724     /* this could rarely happen due to massive re-ordering of
3725      * messages on the network level, but is most likely either
3726      * a bug or some adversary messing with us.  Report. */
3727     GNUNET_break_op (0);
3728     return;
3729   }
3730 #if DEBUG_CORE
3731   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Decrypting key material.\n");
3732 #endif
3733   if ((GNUNET_CRYPTO_rsa_decrypt
3734        (my_private_key, &m->encrypted_key, &k,
3735         sizeof (struct GNUNET_CRYPTO_AesSessionKey)) !=
3736        sizeof (struct GNUNET_CRYPTO_AesSessionKey)) ||
3737       (GNUNET_OK != GNUNET_CRYPTO_aes_check_session_key (&k)))
3738   {
3739     /* failed to decrypt !? */
3740     GNUNET_break_op (0);
3741     return;
3742   }
3743   GNUNET_STATISTICS_update (stats,
3744                             gettext_noop ("# SET_KEY messages decrypted"), 1,
3745                             GNUNET_NO);
3746   n->decrypt_key = k;
3747   if (n->decrypt_key_created.abs_value != t.abs_value)
3748   {
3749     /* fresh key, reset sequence numbers */
3750     n->last_sequence_number_received = 0;
3751     n->last_packets_bitmap = 0;
3752     n->decrypt_key_created = t;
3753   }
3754   update_neighbour_performance (n, ats, ats_count);
3755   sender_status = (enum PeerStateMachine) ntohl (m->sender_status);
3756   switch (n->status)
3757   {
3758   case PEER_STATE_DOWN:
3759     n->status = PEER_STATE_KEY_RECEIVED;
3760 #if DEBUG_CORE
3761     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3762                 "Responding to `%s' with my own key.\n", "SET_KEY");
3763 #endif
3764     send_key (n);
3765     break;
3766   case PEER_STATE_KEY_SENT:
3767   case PEER_STATE_KEY_RECEIVED:
3768     n->status = PEER_STATE_KEY_RECEIVED;
3769     if ((sender_status != PEER_STATE_KEY_RECEIVED) &&
3770         (sender_status != PEER_STATE_KEY_CONFIRMED))
3771     {
3772 #if DEBUG_CORE
3773       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3774                   "Responding to `%s' with my own key (other peer has status %u).\n",
3775                   "SET_KEY", (unsigned int) sender_status);
3776 #endif
3777       send_key (n);
3778     }
3779     break;
3780   case PEER_STATE_KEY_CONFIRMED:
3781     if ((sender_status != PEER_STATE_KEY_RECEIVED) &&
3782         (sender_status != PEER_STATE_KEY_CONFIRMED))
3783     {
3784 #if DEBUG_CORE
3785       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3786                   "Responding to `%s' with my own key (other peer has status %u), I was already fully up.\n",
3787                   "SET_KEY", (unsigned int) sender_status);
3788 #endif
3789       send_key (n);
3790     }
3791     break;
3792   default:
3793     GNUNET_break (0);
3794     break;
3795   }
3796   if (n->pending_ping != NULL)
3797   {
3798     ping = n->pending_ping;
3799     n->pending_ping = NULL;
3800     handle_ping (n, ping, NULL, 0);
3801     GNUNET_free (ping);
3802   }
3803   if (n->pending_pong != NULL)
3804   {
3805     pong = n->pending_pong;
3806     n->pending_pong = NULL;
3807     handle_pong (n, pong, NULL, 0);
3808     GNUNET_free (pong);
3809   }
3810 }
3811
3812
3813 /**
3814  * Send a P2P message to a client.
3815  *
3816  * @param sender who sent us the message?
3817  * @param client who should we give the message to?
3818  * @param m contains the message to transmit
3819  * @param msize number of bytes in buf to transmit
3820  */
3821 static void
3822 send_p2p_message_to_client (struct Neighbour *sender, struct Client *client,
3823                             const void *m, size_t msize)
3824 {
3825   size_t size =
3826       msize + sizeof (struct NotifyTrafficMessage) +
3827       (sender->ats_count) * sizeof (struct GNUNET_TRANSPORT_ATS_Information);
3828   char buf[size];
3829   struct NotifyTrafficMessage *ntm;
3830   struct GNUNET_TRANSPORT_ATS_Information *ats;
3831
3832   GNUNET_assert (GNUNET_YES == sender->is_connected);
3833   if (size >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
3834   {
3835     GNUNET_break (0);
3836     /* recovery strategy: throw performance data away... */
3837     GNUNET_array_grow (sender->ats, sender->ats_count, 0);
3838     size =
3839         msize + sizeof (struct NotifyTrafficMessage) +
3840         (sender->ats_count) * sizeof (struct GNUNET_TRANSPORT_ATS_Information);
3841   }
3842 #if DEBUG_CORE
3843   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3844               "Core service passes message from `%4s' of type %u to client.\n",
3845               GNUNET_i2s (&sender->peer),
3846               (unsigned int) ntohs (((const struct GNUNET_MessageHeader *) m)->
3847                                     type));
3848 #endif
3849   ntm = (struct NotifyTrafficMessage *) buf;
3850   ntm->header.size = htons (size);
3851   ntm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_INBOUND);
3852   ntm->ats_count = htonl (sender->ats_count);
3853   ntm->peer = sender->peer;
3854   ats = &ntm->ats;
3855   memcpy (ats, sender->ats,
3856           sizeof (struct GNUNET_TRANSPORT_ATS_Information) * sender->ats_count);
3857   ats[sender->ats_count].type = htonl (GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR);
3858   ats[sender->ats_count].value = htonl (0);
3859   memcpy (&ats[sender->ats_count + 1], m, msize);
3860   send_to_client (client, &ntm->header, GNUNET_YES);
3861 }
3862
3863
3864 /**
3865  * Deliver P2P message to interested clients.
3866  *
3867  * @param cls always NULL
3868  * @param client who sent us the message (struct Neighbour)
3869  * @param m the message
3870  */
3871 static void
3872 deliver_message (void *cls, void *client, const struct GNUNET_MessageHeader *m)
3873 {
3874   struct Neighbour *sender = client;
3875   size_t msize = ntohs (m->size);
3876   char buf[256];
3877   struct Client *cpos;
3878   uint16_t type;
3879   unsigned int tpos;
3880   int deliver_full;
3881   int dropped;
3882
3883   type = ntohs (m->type);
3884 #if DEBUG_CORE > 1
3885   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3886               "Received encapsulated message of type %u and size %u from `%4s'\n",
3887               (unsigned int) type, ntohs (m->size), GNUNET_i2s (&sender->peer));
3888 #endif
3889   GNUNET_snprintf (buf, sizeof (buf),
3890                    gettext_noop ("# bytes of messages of type %u received"),
3891                    (unsigned int) type);
3892   GNUNET_STATISTICS_update (stats, buf, msize, GNUNET_NO);
3893   if ((GNUNET_MESSAGE_TYPE_CORE_BINARY_TYPE_MAP == type) ||
3894       (GNUNET_MESSAGE_TYPE_CORE_COMPRESSED_TYPE_MAP == type))
3895   {
3896     /* FIXME: update message type map for 'Neighbour' */
3897     return;
3898   }
3899   dropped = GNUNET_YES;
3900   cpos = clients;
3901   while (cpos != NULL)
3902   {
3903     deliver_full = GNUNET_NO;
3904     if (0 != (cpos->options & GNUNET_CORE_OPTION_SEND_FULL_INBOUND))
3905       deliver_full = GNUNET_YES;
3906     else
3907     {
3908       for (tpos = 0; tpos < cpos->tcnt; tpos++)
3909       {
3910         if (type != cpos->types[tpos])
3911           continue;
3912         deliver_full = GNUNET_YES;
3913         break;
3914       }
3915     }
3916     if (GNUNET_YES == deliver_full)
3917     {
3918       send_p2p_message_to_client (sender, cpos, m, msize);
3919       dropped = GNUNET_NO;
3920     }
3921     else if (cpos->options & GNUNET_CORE_OPTION_SEND_HDR_INBOUND)
3922     {
3923       send_p2p_message_to_client (sender, cpos, m,
3924                                   sizeof (struct GNUNET_MessageHeader));
3925     }
3926     cpos = cpos->next;
3927   }
3928   if (dropped == GNUNET_YES)
3929   {
3930 #if DEBUG_CORE
3931     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3932                 "Message of type %u from `%4s' not delivered to any client.\n",
3933                 (unsigned int) type, GNUNET_i2s (&sender->peer));
3934 #endif
3935     GNUNET_STATISTICS_update (stats,
3936                               gettext_noop
3937                               ("# messages not delivered to any client"), 1,
3938                               GNUNET_NO);
3939   }
3940 }
3941
3942
3943 /**
3944  * We received an encrypted message.  Decrypt, validate and
3945  * pass on to the appropriate clients.
3946  *
3947  * @param n target of the message
3948  * @param m encrypted message
3949  * @param ats performance data
3950  * @param ats_count number of entries in ats (excluding 0-termination)
3951  */
3952 static void
3953 handle_encrypted_message (struct Neighbour *n, const struct EncryptedMessage *m,
3954                           const struct GNUNET_TRANSPORT_ATS_Information *ats,
3955                           uint32_t ats_count)
3956 {
3957   size_t size = ntohs (m->header.size);
3958   char buf[size];
3959   struct EncryptedMessage *pt;  /* plaintext */
3960   GNUNET_HashCode ph;
3961   uint32_t snum;
3962   struct GNUNET_TIME_Absolute t;
3963   struct GNUNET_CRYPTO_AesInitializationVector iv;
3964   struct GNUNET_CRYPTO_AuthKey auth_key;
3965
3966 #if DEBUG_CORE
3967   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3968               "Core service receives `%s' request from `%4s'.\n",
3969               "ENCRYPTED_MESSAGE", GNUNET_i2s (&n->peer));
3970 #endif
3971   /* validate hash */
3972   derive_auth_key (&auth_key, &n->decrypt_key, m->iv_seed,
3973                    n->decrypt_key_created);
3974   GNUNET_CRYPTO_hmac (&auth_key, &m->sequence_number,
3975                       size - ENCRYPTED_HEADER_SIZE, &ph);
3976 #if DEBUG_HANDSHAKE
3977   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3978               "Re-Authenticated %u bytes of ciphertext (`%u'): `%s'\n",
3979               (unsigned int) size - ENCRYPTED_HEADER_SIZE,
3980               GNUNET_CRYPTO_crc32_n (&m->sequence_number,
3981                                      size - ENCRYPTED_HEADER_SIZE),
3982               GNUNET_h2s (&ph));
3983 #endif
3984
3985   if (0 != memcmp (&ph, &m->hmac, sizeof (GNUNET_HashCode)))
3986   {
3987     /* checksum failed */
3988     GNUNET_break_op (0);
3989     return;
3990   }
3991   derive_iv (&iv, &n->decrypt_key, m->iv_seed, &my_identity);
3992   /* decrypt */
3993   if (GNUNET_OK !=
3994       do_decrypt (n, &iv, &m->sequence_number, &buf[ENCRYPTED_HEADER_SIZE],
3995                   size - ENCRYPTED_HEADER_SIZE))
3996     return;
3997   pt = (struct EncryptedMessage *) buf;
3998
3999   /* validate sequence number */
4000   snum = ntohl (pt->sequence_number);
4001   if (n->last_sequence_number_received == snum)
4002   {
4003     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
4004                 "Received duplicate message, ignoring.\n");
4005     /* duplicate, ignore */
4006     GNUNET_STATISTICS_update (stats,
4007                               gettext_noop ("# bytes dropped (duplicates)"),
4008                               size, GNUNET_NO);
4009     return;
4010   }
4011   if ((n->last_sequence_number_received > snum) &&
4012       (n->last_sequence_number_received - snum > 32))
4013   {
4014     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
4015                 "Received ancient out of sequence message, ignoring.\n");
4016     /* ancient out of sequence, ignore */
4017     GNUNET_STATISTICS_update (stats,
4018                               gettext_noop
4019                               ("# bytes dropped (out of sequence)"), size,
4020                               GNUNET_NO);
4021     return;
4022   }
4023   if (n->last_sequence_number_received > snum)
4024   {
4025     unsigned int rotbit = 1 << (n->last_sequence_number_received - snum - 1);
4026
4027     if ((n->last_packets_bitmap & rotbit) != 0)
4028     {
4029       GNUNET_log (GNUNET_ERROR_TYPE_INFO,
4030                   "Received duplicate message, ignoring.\n");
4031       GNUNET_STATISTICS_update (stats,
4032                                 gettext_noop ("# bytes dropped (duplicates)"),
4033                                 size, GNUNET_NO);
4034       /* duplicate, ignore */
4035       return;
4036     }
4037     n->last_packets_bitmap |= rotbit;
4038   }
4039   if (n->last_sequence_number_received < snum)
4040   {
4041     int shift = (snum - n->last_sequence_number_received);
4042
4043     if (shift >= 8 * sizeof (n->last_packets_bitmap))
4044       n->last_packets_bitmap = 0;
4045     else
4046       n->last_packets_bitmap <<= shift;
4047     n->last_sequence_number_received = snum;
4048   }
4049
4050   /* check timestamp */
4051   t = GNUNET_TIME_absolute_ntoh (pt->timestamp);
4052   if (GNUNET_TIME_absolute_get_duration (t).rel_value >
4053       MAX_MESSAGE_AGE.rel_value)
4054   {
4055     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
4056                 _("Message received far too old (%llu ms). Content ignored.\n"),
4057                 GNUNET_TIME_absolute_get_duration (t).rel_value);
4058     GNUNET_STATISTICS_update (stats,
4059                               gettext_noop
4060                               ("# bytes dropped (ancient message)"), size,
4061                               GNUNET_NO);
4062     return;
4063   }
4064
4065   /* process decrypted message(s) */
4066   if (n->bw_out_external_limit.value__ != pt->inbound_bw_limit.value__)
4067   {
4068 #if DEBUG_CORE_SET_QUOTA
4069     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4070                 "Received %u b/s as new inbound limit for peer `%4s'\n",
4071                 (unsigned int) ntohl (pt->inbound_bw_limit.value__),
4072                 GNUNET_i2s (&n->peer));
4073 #endif
4074     n->bw_out_external_limit = pt->inbound_bw_limit;
4075     n->bw_out =
4076         GNUNET_BANDWIDTH_value_min (n->bw_out_external_limit,
4077                                     n->bw_out_internal_limit);
4078     GNUNET_BANDWIDTH_tracker_update_quota (&n->available_send_window,
4079                                            n->bw_out);
4080     GNUNET_TRANSPORT_set_quota (transport, &n->peer, n->bw_in, n->bw_out);
4081   }
4082   n->last_activity = GNUNET_TIME_absolute_get ();
4083   if (n->keep_alive_task != GNUNET_SCHEDULER_NO_TASK)
4084     GNUNET_SCHEDULER_cancel (n->keep_alive_task);
4085   n->keep_alive_task =
4086       GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_divide
4087                                     (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
4088                                      2), &send_keep_alive, n);
4089   GNUNET_STATISTICS_update (stats,
4090                             gettext_noop ("# bytes of payload decrypted"),
4091                             size - sizeof (struct EncryptedMessage), GNUNET_NO);
4092   handle_peer_status_change (n);
4093   update_neighbour_performance (n, ats, ats_count);
4094   if (GNUNET_OK !=
4095       GNUNET_SERVER_mst_receive (mst, n, &buf[sizeof (struct EncryptedMessage)],
4096                                  size - sizeof (struct EncryptedMessage),
4097                                  GNUNET_YES, GNUNET_NO))
4098     GNUNET_break_op (0);
4099 }
4100
4101
4102 /**
4103  * Function called by the transport for each received message.
4104  *
4105  * @param cls closure
4106  * @param peer (claimed) identity of the other peer
4107  * @param message the message
4108  * @param ats performance data
4109  * @param ats_count number of entries in ats (excluding 0-termination)
4110  */
4111 static void
4112 handle_transport_receive (void *cls, const struct GNUNET_PeerIdentity *peer,
4113                           const struct GNUNET_MessageHeader *message,
4114                           const struct GNUNET_TRANSPORT_ATS_Information *ats,
4115                           uint32_t ats_count)
4116 {
4117   struct Neighbour *n;
4118   struct GNUNET_TIME_Absolute now;
4119   int up;
4120   uint16_t type;
4121   uint16_t size;
4122   int changed;
4123
4124 #if DEBUG_CORE > 1
4125   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4126               "Received message of type %u from `%4s', demultiplexing.\n",
4127               (unsigned int) ntohs (message->type), GNUNET_i2s (peer));
4128 #endif
4129   if (0 == memcmp (peer, &my_identity, sizeof (struct GNUNET_PeerIdentity)))
4130   {
4131     GNUNET_break (0);
4132     return;
4133   }
4134   n = find_neighbour (peer);
4135   if ((n == NULL) || (GNUNET_NO == n->is_connected))
4136   {
4137     /* received message from peer that is not connected!? */
4138     GNUNET_break (0);
4139     return;
4140   }
4141   changed = GNUNET_NO;
4142   up = (n->status == PEER_STATE_KEY_CONFIRMED);
4143   type = ntohs (message->type);
4144   size = ntohs (message->size);
4145   switch (type)
4146   {
4147   case GNUNET_MESSAGE_TYPE_CORE_SET_KEY:
4148     if (size != sizeof (struct SetKeyMessage))
4149     {
4150       GNUNET_break_op (0);
4151       return;
4152     }
4153     GNUNET_STATISTICS_update (stats, gettext_noop ("# session keys received"),
4154                               1, GNUNET_NO);
4155     handle_set_key (n, (const struct SetKeyMessage *) message, ats, ats_count);
4156     break;
4157   case GNUNET_MESSAGE_TYPE_CORE_ENCRYPTED_MESSAGE:
4158     if (size <
4159         sizeof (struct EncryptedMessage) + sizeof (struct GNUNET_MessageHeader))
4160     {
4161       GNUNET_break_op (0);
4162       return;
4163     }
4164     if ((n->status != PEER_STATE_KEY_RECEIVED) &&
4165         (n->status != PEER_STATE_KEY_CONFIRMED))
4166     {
4167       GNUNET_STATISTICS_update (stats,
4168                                 gettext_noop
4169                                 ("# failed to decrypt message (no session key)"),
4170                                 1, GNUNET_NO);
4171       send_key (n);
4172       return;
4173     }
4174     handle_encrypted_message (n, (const struct EncryptedMessage *) message, ats,
4175                               ats_count);
4176     break;
4177   case GNUNET_MESSAGE_TYPE_CORE_PING:
4178     if (size != sizeof (struct PingMessage))
4179     {
4180       GNUNET_break_op (0);
4181       return;
4182     }
4183     GNUNET_STATISTICS_update (stats, gettext_noop ("# PING messages received"),
4184                               1, GNUNET_NO);
4185     if ((n->status != PEER_STATE_KEY_RECEIVED) &&
4186         (n->status != PEER_STATE_KEY_CONFIRMED))
4187     {
4188 #if DEBUG_CORE > 1
4189       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4190                   "Core service receives `%s' request from `%4s' but have not processed key; marking as pending.\n",
4191                   "PING", GNUNET_i2s (&n->peer));
4192 #endif
4193       GNUNET_free_non_null (n->pending_ping);
4194       n->pending_ping = GNUNET_malloc (sizeof (struct PingMessage));
4195       memcpy (n->pending_ping, message, sizeof (struct PingMessage));
4196       return;
4197     }
4198     handle_ping (n, (const struct PingMessage *) message, ats, ats_count);
4199     break;
4200   case GNUNET_MESSAGE_TYPE_CORE_PONG:
4201     if (size != sizeof (struct PongMessage))
4202     {
4203       GNUNET_break_op (0);
4204       return;
4205     }
4206     GNUNET_STATISTICS_update (stats, gettext_noop ("# PONG messages received"),
4207                               1, GNUNET_NO);
4208     if ((n->status != PEER_STATE_KEY_RECEIVED) &&
4209         (n->status != PEER_STATE_KEY_CONFIRMED))
4210     {
4211 #if DEBUG_CORE > 1
4212       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4213                   "Core service receives `%s' request from `%4s' but have not processed key; marking as pending.\n",
4214                   "PONG", GNUNET_i2s (&n->peer));
4215 #endif
4216       GNUNET_free_non_null (n->pending_pong);
4217       n->pending_pong = GNUNET_malloc (sizeof (struct PongMessage));
4218       memcpy (n->pending_pong, message, sizeof (struct PongMessage));
4219       return;
4220     }
4221     handle_pong (n, (const struct PongMessage *) message, ats, ats_count);
4222     break;
4223   default:
4224     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
4225                 _("Unsupported message of type %u received.\n"),
4226                 (unsigned int) type);
4227     return;
4228   }
4229   if (n->status == PEER_STATE_KEY_CONFIRMED)
4230   {
4231     now = GNUNET_TIME_absolute_get ();
4232     n->last_activity = now;
4233     changed = GNUNET_YES;
4234     if (!up)
4235     {
4236       GNUNET_STATISTICS_update (stats, gettext_noop ("# established sessions"),
4237                                 1, GNUNET_NO);
4238       n->time_established = now;
4239     }
4240     if (n->keep_alive_task != GNUNET_SCHEDULER_NO_TASK)
4241       GNUNET_SCHEDULER_cancel (n->keep_alive_task);
4242     n->keep_alive_task =
4243         GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_divide
4244                                       (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
4245                                        2), &send_keep_alive, n);
4246   }
4247   if (changed)
4248     handle_peer_status_change (n);
4249 }
4250
4251
4252 /**
4253  * Function that recalculates the bandwidth quota for the
4254  * given neighbour and transmits it to the transport service.
4255  * 
4256  * @param cls neighbour for the quota update
4257  * @param tc context
4258  */
4259 static void
4260 neighbour_quota_update (void *cls,
4261                         const struct GNUNET_SCHEDULER_TaskContext *tc)
4262 {
4263   struct Neighbour *n = cls;
4264   struct GNUNET_BANDWIDTH_Value32NBO q_in;
4265   struct GNUNET_BANDWIDTH_Value32NBO q_out;
4266   struct GNUNET_BANDWIDTH_Value32NBO q_out_min;
4267   double pref_rel;
4268   double share;
4269   unsigned long long distributable;
4270   uint64_t need_per_peer;
4271   uint64_t need_per_second;
4272   unsigned int neighbour_count;
4273
4274 #if DEBUG_CORE > 1
4275   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4276               "Neighbour quota update calculation running for peer `%4s'\n",
4277               GNUNET_i2s (&n->peer));
4278 #endif
4279   n->quota_update_task = GNUNET_SCHEDULER_NO_TASK;
4280   /* calculate relative preference among all neighbours;
4281    * divides by a bit more to avoid division by zero AND to
4282    * account for possibility of new neighbours joining any time 
4283    * AND to convert to double... */
4284   neighbour_count = GNUNET_CONTAINER_multihashmap_size (neighbours);
4285   if (neighbour_count == 0)
4286     return;
4287   if (preference_sum == 0)
4288   {
4289     pref_rel = 1.0 / (double) neighbour_count;
4290   }
4291   else
4292   {
4293     pref_rel = (double) n->current_preference / preference_sum;
4294   }
4295   need_per_peer =
4296       GNUNET_BANDWIDTH_value_get_available_until (MIN_BANDWIDTH_PER_PEER,
4297                                                   GNUNET_TIME_UNIT_SECONDS);
4298   need_per_second = need_per_peer * neighbour_count;
4299
4300   /* calculate inbound bandwidth per peer */
4301   distributable = 0;
4302   if (bandwidth_target_in_bps > need_per_second)
4303     distributable = bandwidth_target_in_bps - need_per_second;
4304   share = distributable * pref_rel;
4305   if (share + need_per_peer > UINT32_MAX)
4306     q_in = GNUNET_BANDWIDTH_value_init (UINT32_MAX);
4307   else
4308     q_in = GNUNET_BANDWIDTH_value_init (need_per_peer + (uint32_t) share);
4309
4310   /* calculate outbound bandwidth per peer */
4311   distributable = 0;
4312   if (bandwidth_target_out_bps > need_per_second)
4313     distributable = bandwidth_target_out_bps - need_per_second;
4314   share = distributable * pref_rel;
4315   if (share + need_per_peer > UINT32_MAX)
4316     q_out = GNUNET_BANDWIDTH_value_init (UINT32_MAX);
4317   else
4318     q_out = GNUNET_BANDWIDTH_value_init (need_per_peer + (uint32_t) share);
4319   n->bw_out_internal_limit = q_out;
4320
4321   q_out_min =
4322       GNUNET_BANDWIDTH_value_min (n->bw_out_external_limit,
4323                                   n->bw_out_internal_limit);
4324   GNUNET_BANDWIDTH_tracker_update_quota (&n->available_send_window, n->bw_out);
4325
4326   /* check if we want to disconnect for good due to inactivity */
4327   if ((GNUNET_TIME_absolute_get_duration (get_neighbour_timeout (n)).rel_value >
4328        0) &&
4329       (GNUNET_TIME_absolute_get_duration (n->time_established).rel_value >
4330        GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value))
4331   {
4332 #if DEBUG_CORE
4333     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4334                 "Forcing disconnect of `%4s' due to inactivity\n",
4335                 GNUNET_i2s (&n->peer));
4336 #endif
4337     q_in = GNUNET_BANDWIDTH_value_init (0);     /* force disconnect */
4338   }
4339 #if DEBUG_CORE_QUOTA
4340   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4341               "Current quota for `%4s' is %u/%llu b/s in (old: %u b/s) / %u out (%u internal)\n",
4342               GNUNET_i2s (&n->peer), (unsigned int) ntohl (q_in.value__),
4343               bandwidth_target_out_bps, (unsigned int) ntohl (n->bw_in.value__),
4344               (unsigned int) ntohl (n->bw_out.value__),
4345               (unsigned int) ntohl (n->bw_out_internal_limit.value__));
4346 #endif
4347   if ((n->bw_in.value__ != q_in.value__) ||
4348       (n->bw_out.value__ != q_out_min.value__))
4349   {
4350     if (n->bw_in.value__ != q_in.value__)
4351       n->bw_in = q_in;
4352     if (n->bw_out.value__ != q_out_min.value__)
4353       n->bw_out = q_out_min;
4354     if (GNUNET_YES == n->is_connected)
4355       GNUNET_TRANSPORT_set_quota (transport, &n->peer, n->bw_in, n->bw_out);
4356     handle_peer_status_change (n);
4357   }
4358   schedule_quota_update (n);
4359 }
4360
4361
4362 /**
4363  * Function called by transport to notify us that
4364  * a peer connected to us (on the network level).
4365  *
4366  * @param cls closure
4367  * @param peer the peer that connected
4368  * @param ats performance data
4369  * @param ats_count number of entries in ats (excluding 0-termination)
4370  */
4371 static void
4372 handle_transport_notify_connect (void *cls,
4373                                  const struct GNUNET_PeerIdentity *peer,
4374                                  const struct GNUNET_TRANSPORT_ATS_Information
4375                                  *ats, uint32_t ats_count)
4376 {
4377   struct Neighbour *n;
4378
4379   if (0 == memcmp (peer, &my_identity, sizeof (struct GNUNET_PeerIdentity)))
4380   {
4381     GNUNET_break (0);
4382     return;
4383   }
4384   n = find_neighbour (peer);
4385   if (n != NULL)
4386   {
4387     if (GNUNET_YES == n->is_connected)
4388     {
4389       /* duplicate connect notification!? */
4390       GNUNET_break (0);
4391       return;
4392     }
4393   }
4394   else
4395   {
4396     n = create_neighbour (peer);
4397   }
4398   GNUNET_STATISTICS_update (stats,
4399                             gettext_noop ("# peers connected (transport)"), 1,
4400                             GNUNET_NO);
4401   n->is_connected = GNUNET_YES;
4402   update_neighbour_performance (n, ats, ats_count);
4403   GNUNET_BANDWIDTH_tracker_init (&n->available_send_window, n->bw_out,
4404                                  MAX_WINDOW_TIME_S);
4405   GNUNET_BANDWIDTH_tracker_init (&n->available_recv_window, n->bw_in,
4406                                  MAX_WINDOW_TIME_S);
4407 #if DEBUG_CORE
4408   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received connection from `%4s'.\n",
4409               GNUNET_i2s (&n->peer));
4410 #endif
4411   GNUNET_TRANSPORT_set_quota (transport, &n->peer, n->bw_in, n->bw_out);
4412   send_key (n);
4413 }
4414
4415
4416 /**
4417  * Function called by transport telling us that a peer
4418  * disconnected.
4419  *
4420  * @param cls closure
4421  * @param peer the peer that disconnected
4422  */
4423 static void
4424 handle_transport_notify_disconnect (void *cls,
4425                                     const struct GNUNET_PeerIdentity *peer)
4426 {
4427   struct DisconnectNotifyMessage cnm;
4428   struct Neighbour *n;
4429   struct ClientActiveRequest *car;
4430   struct GNUNET_TIME_Relative left;
4431
4432 #if DEBUG_CORE
4433   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4434               "Peer `%4s' disconnected from us; received notification from transport.\n",
4435               GNUNET_i2s (peer));
4436 #endif
4437   n = find_neighbour (peer);
4438   if (n == NULL)
4439   {
4440     GNUNET_break (0);
4441     return;
4442   }
4443   GNUNET_break (n->is_connected == GNUNET_YES);
4444   if (n->status == PEER_STATE_KEY_CONFIRMED)
4445   {
4446     cnm.header.size = htons (sizeof (struct DisconnectNotifyMessage));
4447     cnm.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_DISCONNECT);
4448     cnm.reserved = htonl (0);
4449     cnm.peer = *peer;
4450     send_to_all_clients (&cnm.header, GNUNET_NO,
4451                          GNUNET_CORE_OPTION_SEND_DISCONNECT);
4452     GNUNET_STATISTICS_update (stats, gettext_noop ("# established sessions"),
4453                               -1, GNUNET_NO);
4454   }
4455
4456   /* On transport disconnect transport doesn't cancel requests, so must do so here. */
4457   if (n->th != NULL)
4458   {
4459     GNUNET_TRANSPORT_notify_transmit_ready_cancel (n->th);
4460     n->th = NULL;
4461   }
4462   if (GNUNET_SCHEDULER_NO_TASK != n->keep_alive_task)
4463   {
4464     GNUNET_SCHEDULER_cancel (n->keep_alive_task);
4465     n->keep_alive_task = GNUNET_SCHEDULER_NO_TASK;
4466   }
4467   n->is_connected = GNUNET_NO;
4468   n->status = PEER_STATE_DOWN;
4469   while (NULL != (car = n->active_client_request_head))
4470   {
4471     GNUNET_CONTAINER_DLL_remove (n->active_client_request_head,
4472                                  n->active_client_request_tail, car);
4473     GNUNET_assert (GNUNET_YES ==
4474                    GNUNET_CONTAINER_multihashmap_remove (car->client->requests,
4475                                                          &n->peer.hashPubKey,
4476                                                          car));
4477     GNUNET_free (car);
4478   }
4479
4480   GNUNET_STATISTICS_update (stats,
4481                             gettext_noop ("# peers connected (transport)"), -1,
4482                             GNUNET_NO);
4483   if (n->dead_clean_task != GNUNET_SCHEDULER_NO_TASK)
4484     GNUNET_SCHEDULER_cancel (n->dead_clean_task);
4485   left =
4486       GNUNET_TIME_relative_subtract (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
4487                                      GNUNET_CONSTANTS_DISCONNECT_SESSION_TIMEOUT);
4488   n->last_activity =
4489       GNUNET_TIME_absolute_subtract (GNUNET_TIME_absolute_get (), left);
4490   n->dead_clean_task =
4491       GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_DISCONNECT_SESSION_TIMEOUT,
4492                                     &consider_free_task, n);
4493 }
4494
4495
4496 /**
4497  * Wrapper around 'free_neighbour'; helper for 'cleaning_task'.
4498  */
4499 static int
4500 free_neighbour_helper (void *cls, const GNUNET_HashCode * key, void *value)
4501 {
4502   struct Neighbour *n = value;
4503
4504   free_neighbour (n);
4505   return GNUNET_OK;
4506 }
4507
4508
4509 /**
4510  * Last task run during shutdown.  Disconnects us from
4511  * the transport.
4512  */
4513 static void
4514 cleaning_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
4515 {
4516   struct Client *c;
4517
4518 #if DEBUG_CORE
4519   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Core service shutting down.\n");
4520 #endif
4521   GNUNET_assert (transport != NULL);
4522   GNUNET_TRANSPORT_disconnect (transport);
4523   transport = NULL;
4524   GNUNET_CONTAINER_multihashmap_iterate (neighbours, &free_neighbour_helper,
4525                                          NULL);
4526   GNUNET_CONTAINER_multihashmap_destroy (neighbours);
4527   neighbours = NULL;
4528   GNUNET_STATISTICS_set (stats, gettext_noop ("# neighbour entries allocated"),
4529                          0, GNUNET_NO);
4530   GNUNET_SERVER_notification_context_destroy (notifier);
4531   notifier = NULL;
4532   while (NULL != (c = clients))
4533     handle_client_disconnect (NULL, c->client_handle);
4534   if (my_private_key != NULL)
4535     GNUNET_CRYPTO_rsa_key_free (my_private_key);
4536   if (stats != NULL)
4537     GNUNET_STATISTICS_destroy (stats, GNUNET_NO);
4538   if (peerinfo != NULL)
4539     GNUNET_PEERINFO_disconnect (peerinfo);
4540   if (mst != NULL)
4541     GNUNET_SERVER_mst_destroy (mst);
4542 }
4543
4544
4545 /**
4546  * Initiate core service.
4547  *
4548  * @param cls closure
4549  * @param server the initialized server
4550  * @param c configuration to use
4551  */
4552 static void
4553 run (void *cls, struct GNUNET_SERVER_Handle *server,
4554      const struct GNUNET_CONFIGURATION_Handle *c)
4555 {
4556   static const struct GNUNET_SERVER_MessageHandler handlers[] = {
4557     {&handle_client_init, NULL,
4558      GNUNET_MESSAGE_TYPE_CORE_INIT, 0},
4559     {&handle_client_iterate_peers, NULL,
4560      GNUNET_MESSAGE_TYPE_CORE_ITERATE_PEERS,
4561      sizeof (struct GNUNET_MessageHeader)},
4562     {&handle_client_have_peer, NULL,
4563      GNUNET_MESSAGE_TYPE_CORE_PEER_CONNECTED,
4564      sizeof (struct GNUNET_MessageHeader) +
4565      sizeof (struct GNUNET_PeerIdentity)},
4566     {&handle_client_request_info, NULL,
4567      GNUNET_MESSAGE_TYPE_CORE_REQUEST_INFO,
4568      sizeof (struct RequestInfoMessage)},
4569     {&handle_client_send_request, NULL,
4570      GNUNET_MESSAGE_TYPE_CORE_SEND_REQUEST,
4571      sizeof (struct SendMessageRequest)},
4572     {&handle_client_send, NULL,
4573      GNUNET_MESSAGE_TYPE_CORE_SEND, 0},
4574     {&handle_client_request_connect, NULL,
4575      GNUNET_MESSAGE_TYPE_CORE_REQUEST_CONNECT,
4576      sizeof (struct ConnectMessage)},
4577     {NULL, NULL, 0, 0}
4578   };
4579   char *keyfile;
4580
4581   cfg = c;
4582   /* parse configuration */
4583   if ((GNUNET_OK !=
4584        GNUNET_CONFIGURATION_get_value_number (c, "CORE", "TOTAL_QUOTA_IN",
4585                                               &bandwidth_target_in_bps)) ||
4586       (GNUNET_OK !=
4587        GNUNET_CONFIGURATION_get_value_number (c, "CORE", "TOTAL_QUOTA_OUT",
4588                                               &bandwidth_target_out_bps)) ||
4589       (GNUNET_OK !=
4590        GNUNET_CONFIGURATION_get_value_filename (c, "GNUNETD", "HOSTKEY",
4591                                                 &keyfile)))
4592   {
4593     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
4594                 _
4595                 ("Core service is lacking key configuration settings.  Exiting.\n"));
4596     GNUNET_SCHEDULER_shutdown ();
4597     return;
4598   }
4599   peerinfo = GNUNET_PEERINFO_connect (cfg);
4600   if (NULL == peerinfo)
4601   {
4602     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
4603                 _("Could not access PEERINFO service.  Exiting.\n"));
4604     GNUNET_SCHEDULER_shutdown ();
4605     GNUNET_free (keyfile);
4606     return;
4607   }
4608   my_private_key = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile);
4609   GNUNET_free (keyfile);
4610   if (my_private_key == NULL)
4611   {
4612     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
4613                 _("Core service could not access hostkey.  Exiting.\n"));
4614     GNUNET_PEERINFO_disconnect (peerinfo);
4615     GNUNET_SCHEDULER_shutdown ();
4616     return;
4617   }
4618   neighbours = GNUNET_CONTAINER_multihashmap_create (128);
4619   GNUNET_CRYPTO_rsa_key_get_public (my_private_key, &my_public_key);
4620   GNUNET_CRYPTO_hash (&my_public_key, sizeof (my_public_key),
4621                       &my_identity.hashPubKey);
4622   self.public_key = &my_public_key;
4623   self.peer = my_identity;
4624   self.last_activity = GNUNET_TIME_UNIT_FOREVER_ABS;
4625   self.status = PEER_STATE_KEY_CONFIRMED;
4626   self.is_connected = GNUNET_YES;
4627   /* setup notification */
4628   notifier =
4629       GNUNET_SERVER_notification_context_create (server, MAX_NOTIFY_QUEUE);
4630   GNUNET_SERVER_disconnect_notify (server, &handle_client_disconnect, NULL);
4631   /* setup transport connection */
4632   transport =
4633       GNUNET_TRANSPORT_connect (cfg, &my_identity, NULL,
4634                                 &handle_transport_receive,
4635                                 &handle_transport_notify_connect,
4636                                 &handle_transport_notify_disconnect);
4637   GNUNET_assert (NULL != transport);
4638   stats = GNUNET_STATISTICS_create ("core", cfg);
4639
4640   GNUNET_STATISTICS_set (stats, gettext_noop ("# discarded CORE_SEND requests"),
4641                          0, GNUNET_NO);
4642   GNUNET_STATISTICS_set (stats,
4643                          gettext_noop
4644                          ("# discarded lower priority CORE_SEND requests"), 0,
4645                          GNUNET_NO);
4646
4647   mst = GNUNET_SERVER_mst_create (&deliver_message, NULL);
4648   GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &cleaning_task,
4649                                 NULL);
4650   /* process client requests */
4651   GNUNET_SERVER_add_handlers (server, handlers);
4652   GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Core service of `%4s' ready.\n"),
4653               GNUNET_i2s (&my_identity));
4654 }
4655
4656
4657
4658 /**
4659  * The main function for the transport service.
4660  *
4661  * @param argc number of arguments from the command line
4662  * @param argv command line arguments
4663  * @return 0 ok, 1 on error
4664  */
4665 int
4666 main (int argc, char *const *argv)
4667 {
4668   return (GNUNET_OK ==
4669           GNUNET_SERVICE_run (argc, argv, "core", GNUNET_SERVICE_OPTION_NONE,
4670                               &run, NULL)) ? 0 : 1;
4671 }
4672
4673 /* end of gnunet-service-core.c */