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