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