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