4a9790b08809f8575f9b3412d7271148f961ca60
[oweals/gnunet.git] / src / core / gnunet-service-core.c
1 /*
2      This file is part of GNUnet.
3      (C) 2009, 2010 Christian Grothoff (and other contributing authors)
4
5      GNUnet is free software; you can redistribute it and/or modify
6      it under the terms of the GNU General Public License as published
7      by the Free Software Foundation; either version 3, or (at your
8      option) any later version.
9
10      GNUnet is distributed in the hope that it will be useful, but
11      WITHOUT ANY WARRANTY; without even the implied warranty of
12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13      General Public License for more details.
14
15      You should have received a copy of the GNU General Public License
16      along with GNUnet; see the file COPYING.  If not, write to the
17      Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18      Boston, MA 02111-1307, USA.
19 */
20
21 /**
22  * @file core/gnunet-service-core.c
23  * @brief high-level P2P messaging
24  * @author Christian Grothoff
25  *
26  * Type map implementation:
27  * - track type maps for neighbours (can wait)
28  * - only notify clients about peers with matching type maps (can wait)
29  *
30  * Considerations for later:
31  * - check that hostkey used by transport (for HELLOs) is the
32  *   same as the hostkey that we are using!
33  */
34 #include "platform.h"
35 #include <zlib.h>
36 #include "gnunet_constants.h"
37 #include "gnunet_util_lib.h"
38 #include "gnunet_hello_lib.h"
39 #include "gnunet_peerinfo_service.h"
40 #include "gnunet_protocols.h"
41 #include "gnunet_signatures.h"
42 #include "gnunet_statistics_service.h"
43 #include "gnunet_transport_service.h"
44 #include "core.h"
45
46
47 #define DEBUG_HANDSHAKE GNUNET_EXTRA_LOGGING
48
49 #define DEBUG_CORE_QUOTA GNUNET_EXTRA_LOGGING
50
51 /**
52  * Receive and send buffer windows grow over time.  For
53  * how long can 'unused' bandwidth accumulate before we
54  * need to cap it?  (specified in seconds).
55  */
56 #define MAX_WINDOW_TIME_S (5 * 60)
57
58 /**
59  * How many messages do we queue up at most for optional
60  * notifications to a client?  (this can cause notifications
61  * about outgoing messages to be dropped).
62  */
63 #define MAX_NOTIFY_QUEUE 1024
64
65 /**
66  * Minimum bandwidth (out) to assign to any connected peer.
67  * Should be rather low; values larger than DEFAULT_BW_IN_OUT make no
68  * sense.
69  */
70 #define MIN_BANDWIDTH_PER_PEER GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT
71
72 /**
73  * After how much time past the "official" expiration time do
74  * we discard messages?  Should not be zero since we may
75  * intentionally defer transmission until close to the deadline
76  * and then may be slightly past the deadline due to inaccuracy
77  * in sleep and our own CPU consumption.
78  */
79 #define PAST_EXPIRATION_DISCARD_TIME GNUNET_TIME_UNIT_SECONDS
80
81 /**
82  * What is the maximum delay for a SET_KEY message?
83  */
84 #define MAX_SET_KEY_DELAY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10)
85
86 /**
87  * How long do we wait for SET_KEY confirmation initially?
88  */
89 #define INITIAL_SET_KEY_RETRY_FREQUENCY GNUNET_TIME_relative_multiply (MAX_SET_KEY_DELAY, 1)
90
91 /**
92  * What is the maximum delay for a PING message?
93  */
94 #define MAX_PING_DELAY GNUNET_TIME_relative_multiply (MAX_SET_KEY_DELAY, 2)
95
96 /**
97  * What is the maximum delay for a PONG message?
98  */
99 #define MAX_PONG_DELAY GNUNET_TIME_relative_multiply (MAX_PING_DELAY, 2)
100
101 /**
102  * What is the minimum frequency for a PING message?
103  */
104 #define MIN_PING_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5)
105
106 /**
107  * How often do we recalculate bandwidth quotas?
108  */
109 #define QUOTA_UPDATE_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5)
110
111 /**
112  * What is the priority for a SET_KEY message?
113  */
114 #define SET_KEY_PRIORITY 0xFFFFFF
115
116 /**
117  * What is the priority for a PING message?
118  */
119 #define PING_PRIORITY 0xFFFFFF
120
121 /**
122  * What is the priority for a PONG message?
123  */
124 #define PONG_PRIORITY 0xFFFFFF
125
126 /**
127  * How many messages do we queue per peer at most?  Must be at
128  * least two.
129  */
130 #define MAX_PEER_QUEUE_SIZE 16
131
132 /**
133  * How many non-mandatory messages do we queue per client at most?
134  */
135 #define MAX_CLIENT_QUEUE_SIZE 32
136
137 /**
138  * What is the maximum age of a message for us to consider
139  * processing it?  Note that this looks at the timestamp used
140  * by the other peer, so clock skew between machines does
141  * come into play here.  So this should be picked high enough
142  * so that a little bit of clock skew does not prevent peers
143  * from connecting to us.
144  */
145 #define MAX_MESSAGE_AGE GNUNET_TIME_UNIT_DAYS
146
147
148 /**
149  * State machine for our P2P encryption handshake.  Everyone starts in
150  * "DOWN", if we receive the other peer's key (other peer initiated)
151  * we start in state RECEIVED (since we will immediately send our
152  * own); otherwise we start in SENT.  If we get back a PONG from
153  * within either state, we move up to CONFIRMED (the PONG will always
154  * be sent back encrypted with the key we sent to the other peer).
155  */
156 enum PeerStateMachine
157 {
158   /**
159    * No handshake yet.
160    */
161   PEER_STATE_DOWN,
162
163   /**
164    * We've sent our session key.
165    */
166   PEER_STATE_KEY_SENT,
167
168   /**
169    * We've received the other peers session key.
170    */
171   PEER_STATE_KEY_RECEIVED,
172
173   /**
174    * The other peer has confirmed our session key with a message
175    * encrypted with his session key (which we got).  Session is now fully up.
176    */
177   PEER_STATE_KEY_CONFIRMED
178 };
179
180
181 /**
182  * Encapsulation for encrypted messages exchanged between
183  * peers.  Followed by the actual encrypted data.
184  */
185 struct EncryptedMessage
186 {
187   /**
188    * Message type is either CORE_ENCRYPTED_MESSAGE.
189    */
190   struct GNUNET_MessageHeader header;
191
192   /**
193    * Random value used for IV generation.
194    */
195   uint32_t iv_seed GNUNET_PACKED;
196
197   /**
198    * MAC of the encrypted message (starting at 'sequence_number'),
199    * used to verify message integrity. Everything after this value
200    * (excluding this value itself) will be encrypted and authenticated.
201    * ENCRYPTED_HEADER_SIZE must be set to the offset of the *next* field.
202    */
203   GNUNET_HashCode hmac;
204
205   /**
206    * Sequence number, in network byte order.  This field
207    * must be the first encrypted/decrypted field
208    */
209   uint32_t sequence_number GNUNET_PACKED;
210
211   /**
212    * Desired bandwidth (how much we should send to this peer / how
213    * much is the sender willing to receive)?
214    */
215   struct GNUNET_BANDWIDTH_Value32NBO inbound_bw_limit;
216
217   /**
218    * Timestamp.  Used to prevent reply of ancient messages
219    * (recent messages are caught with the sequence number).
220    */
221   struct GNUNET_TIME_AbsoluteNBO timestamp;
222
223 };
224
225
226 /**
227  * Number of bytes (at the beginning) of "struct EncryptedMessage"
228  * that are NOT encrypted.
229  */
230 #define ENCRYPTED_HEADER_SIZE (offsetof(struct EncryptedMessage, sequence_number))
231
232
233 /**
234  * We're sending an (encrypted) PING to the other peer to check if he
235  * can decrypt.  The other peer should respond with a PONG with the
236  * same content, except this time encrypted with the receiver's key.
237  */
238 struct PingMessage
239 {
240   /**
241    * Message type is CORE_PING.
242    */
243   struct GNUNET_MessageHeader header;
244
245   /**
246    * Seed for the IV
247    */
248   uint32_t iv_seed GNUNET_PACKED;
249
250   /**
251    * Intended target of the PING, used primarily to check
252    * that decryption actually worked.
253    */
254   struct GNUNET_PeerIdentity target;
255
256   /**
257    * Random number chosen to make reply harder.
258    */
259   uint32_t challenge GNUNET_PACKED;
260 };
261
262
263
264 /**
265  * Response to a PING.  Includes data from the original PING
266  * plus initial bandwidth quota information.
267  */
268 struct PongMessage
269 {
270   /**
271    * Message type is CORE_PONG.
272    */
273   struct GNUNET_MessageHeader header;
274
275   /**
276    * Seed for the IV
277    */
278   uint32_t iv_seed GNUNET_PACKED;
279
280   /**
281    * Random number to make faking the reply harder.  Must be
282    * first field after header (this is where we start to encrypt!).
283    */
284   uint32_t challenge GNUNET_PACKED;
285
286   /**
287    * Desired bandwidth (how much we should send to this
288    * peer / how much is the sender willing to receive).
289    */
290   struct GNUNET_BANDWIDTH_Value32NBO inbound_bw_limit;
291
292   /**
293    * Intended target of the PING, used primarily to check
294    * that decryption actually worked.
295    */
296   struct GNUNET_PeerIdentity target;
297 };
298
299
300 /**
301  * Message transmitted to set (or update) a session key.
302  */
303 struct SetKeyMessage
304 {
305
306   /**
307    * Message type is either CORE_SET_KEY.
308    */
309   struct GNUNET_MessageHeader header;
310
311   /**
312    * Status of the sender (should be in "enum PeerStateMachine"), nbo.
313    */
314   int32_t sender_status GNUNET_PACKED;
315
316   /**
317    * Purpose of the signature, will be
318    * GNUNET_SIGNATURE_PURPOSE_SET_KEY.
319    */
320   struct GNUNET_CRYPTO_RsaSignaturePurpose purpose;
321
322   /**
323    * At what time was this key created?
324    */
325   struct GNUNET_TIME_AbsoluteNBO creation_time;
326
327   /**
328    * The encrypted session key.
329    */
330   struct GNUNET_CRYPTO_RsaEncryptedData encrypted_key;
331
332   /**
333    * Who is the intended recipient?
334    */
335   struct GNUNET_PeerIdentity target;
336
337   /**
338    * Signature of the stuff above (starting at purpose).
339    */
340   struct GNUNET_CRYPTO_RsaSignature signature;
341
342 };
343
344
345 /**
346  * Message waiting for transmission. This struct
347  * is followed by the actual content of the message.
348  */
349 struct MessageEntry
350 {
351
352   /**
353    * We keep messages in a doubly linked list.
354    */
355   struct MessageEntry *next;
356
357   /**
358    * We keep messages in a doubly linked list.
359    */
360   struct MessageEntry *prev;
361
362   /**
363    * By when are we supposed to transmit this message?
364    */
365   struct GNUNET_TIME_Absolute deadline;
366
367   /**
368    * By when are we supposed to transmit this message (after
369    * giving slack)?
370    */
371   struct GNUNET_TIME_Absolute slack_deadline;
372
373   /**
374    * How important is this message to us?
375    */
376   unsigned int priority;
377
378   /**
379    * If this is a SET_KEY message, what was our connection status when this
380    * message was queued?
381    */
382   enum PeerStateMachine sender_status;
383
384   /**
385    * Is this a SET_KEY message?
386    */
387   int is_setkey;
388
389   /**
390    * How long is the message? (number of bytes following
391    * the "struct MessageEntry", but not including the
392    * size of "struct MessageEntry" itself!)
393    */
394   uint16_t size;
395
396   /**
397    * Was this message selected for transmission in the
398    * current round? GNUNET_YES or GNUNET_NO.
399    */
400   int8_t do_transmit;
401
402   /**
403    * Did we give this message some slack (delayed sending) previously
404    * (and hence should not give it any more slack)? GNUNET_YES or
405    * GNUNET_NO.
406    */
407   int8_t got_slack;
408
409 };
410
411
412 /**
413  * Record kept for each request for transmission issued by a
414  * client that is still pending.
415  */
416 struct ClientActiveRequest;
417
418 /**
419  * Data kept per neighbouring peer.
420  */
421 struct Neighbour
422 {
423
424   /**
425    * Unencrypted messages destined for this peer.
426    */
427   struct MessageEntry *messages;
428
429   /**
430    * Head of the batched, encrypted message queue (already ordered,
431    * transmit starting with the head).
432    */
433   struct MessageEntry *encrypted_head;
434
435   /**
436    * Tail of the batched, encrypted message queue (already ordered,
437    * append new messages to tail)
438    */
439   struct MessageEntry *encrypted_tail;
440
441   /**
442    * Head of list of requests from clients for transmission to
443    * this peer.
444    */
445   struct ClientActiveRequest *active_client_request_head;
446
447   /**
448    * Tail of list of requests from clients for transmission to
449    * this peer.
450    */
451   struct ClientActiveRequest *active_client_request_tail;
452
453   /**
454    * Handle for pending requests for transmission to this peer
455    * with the transport service.  NULL if no request is pending.
456    */
457   struct GNUNET_TRANSPORT_TransmitHandle *th;
458
459   /**
460    * Public key of the neighbour, NULL if we don't have it yet.
461    */
462   struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *public_key;
463
464   /**
465    * We received a PING message before we got the "public_key"
466    * (or the SET_KEY).  We keep it here until we have a key
467    * to decrypt it.  NULL if no PING is pending.
468    */
469   struct PingMessage *pending_ping;
470
471   /**
472    * We received a PONG message before we got the "public_key"
473    * (or the SET_KEY).  We keep it here until we have a key
474    * to decrypt it.  NULL if no PONG is pending.
475    */
476   struct PongMessage *pending_pong;
477
478   /**
479    * Non-NULL if we are currently looking up HELLOs for this peer.
480    * for this peer.
481    */
482   struct GNUNET_PEERINFO_IteratorContext *pitr;
483
484   /**
485    * SetKeyMessage to transmit, NULL if we are not currently trying
486    * to send one.
487    */
488   struct SetKeyMessage *skm;
489
490   /**
491    * Performance data for the peer.
492    */
493   struct GNUNET_TRANSPORT_ATS_Information *ats;
494
495   /**
496    * Identity of the neighbour.
497    */
498   struct GNUNET_PeerIdentity peer;
499
500   /**
501    * Key we use to encrypt our messages for the other peer
502    * (initialized by us when we do the handshake).
503    */
504   struct GNUNET_CRYPTO_AesSessionKey encrypt_key;
505
506   /**
507    * Key we use to decrypt messages from the other peer
508    * (given to us by the other peer during the handshake).
509    */
510   struct GNUNET_CRYPTO_AesSessionKey decrypt_key;
511
512   /**
513    * ID of task used for re-trying plaintext scheduling.
514    */
515   GNUNET_SCHEDULER_TaskIdentifier retry_plaintext_task;
516
517   /**
518    * ID of task used for re-trying SET_KEY and PING message.
519    */
520   GNUNET_SCHEDULER_TaskIdentifier retry_set_key_task;
521
522   /**
523    * ID of task used for updating bandwidth quota for this neighbour.
524    */
525   GNUNET_SCHEDULER_TaskIdentifier quota_update_task;
526
527   /**
528    * ID of task used for sending keep-alive pings.
529    */
530   GNUNET_SCHEDULER_TaskIdentifier keep_alive_task;
531
532   /**
533    * ID of task used for cleaning up dead neighbour entries.
534    */
535   GNUNET_SCHEDULER_TaskIdentifier dead_clean_task;
536
537   /**
538    * At what time did we generate our encryption key?
539    */
540   struct GNUNET_TIME_Absolute encrypt_key_created;
541
542   /**
543    * At what time did the other peer generate the decryption key?
544    */
545   struct GNUNET_TIME_Absolute decrypt_key_created;
546
547   /**
548    * At what time did we initially establish (as in, complete session
549    * key handshake) this connection?  Should be zero if status != KEY_CONFIRMED.
550    */
551   struct GNUNET_TIME_Absolute time_established;
552
553   /**
554    * At what time did we last receive an encrypted message from the
555    * other peer?  Should be zero if status != KEY_CONFIRMED.
556    */
557   struct GNUNET_TIME_Absolute last_activity;
558
559   /**
560    * At what frequency are we currently re-trying SET_KEY messages?
561    */
562   struct GNUNET_TIME_Relative set_key_retry_frequency;
563
564   /**
565    * Tracking bandwidth for sending to this peer.
566    */
567   struct GNUNET_BANDWIDTH_Tracker available_send_window;
568
569   /**
570    * Tracking bandwidth for receiving from this peer.
571    */
572   struct GNUNET_BANDWIDTH_Tracker available_recv_window;
573
574   /**
575    * How valueable were the messages of this peer recently?
576    */
577   unsigned long long current_preference;
578
579   /**
580    * Number of entries in 'ats'.
581    */
582   unsigned int ats_count;
583
584   /**
585    * Bit map indicating which of the 32 sequence numbers before the last
586    * were received (good for accepting out-of-order packets and
587    * estimating reliability of the connection)
588    */
589   unsigned int last_packets_bitmap;
590
591   /**
592    * last sequence number received on this connection (highest)
593    */
594   uint32_t last_sequence_number_received;
595
596   /**
597    * last sequence number transmitted
598    */
599   uint32_t last_sequence_number_sent;
600
601   /**
602    * Available bandwidth in for this peer (current target).
603    */
604   struct GNUNET_BANDWIDTH_Value32NBO bw_in;
605
606   /**
607    * Available bandwidth out for this peer (current target).
608    */
609   struct GNUNET_BANDWIDTH_Value32NBO bw_out;
610
611   /**
612    * Internal bandwidth limit set for this peer (initially typically
613    * set to "-1").  Actual "bw_out" is MIN of
614    * "bpm_out_internal_limit" and "bw_out_external_limit".
615    */
616   struct GNUNET_BANDWIDTH_Value32NBO bw_out_internal_limit;
617
618   /**
619    * External bandwidth limit set for this peer by the
620    * peer that we are communicating with.  "bw_out" is MIN of
621    * "bw_out_internal_limit" and "bw_out_external_limit".
622    */
623   struct GNUNET_BANDWIDTH_Value32NBO bw_out_external_limit;
624
625   /**
626    * What was our PING challenge number (for this peer)?
627    */
628   uint32_t ping_challenge;
629
630   /**
631    * What is our connection status?
632    */
633   enum PeerStateMachine status;
634
635   /**
636    * Are we currently connected to this neighbour?
637    */
638   int is_connected;
639
640 };
641
642
643 /**
644  * Data structure for each client connected to the core service.
645  */
646 struct Client
647 {
648   /**
649    * Clients are kept in a linked list.
650    */
651   struct Client *next;
652
653   /**
654    * Handle for the client with the server API.
655    */
656   struct GNUNET_SERVER_Client *client_handle;
657
658   /**
659    * Array of the types of messages this peer cares
660    * about (with "tcnt" entries).  Allocated as part
661    * of this client struct, do not free!
662    */
663   const uint16_t *types;
664
665   /**
666    * Map of peer identities to active transmission requests of this
667    * client to the peer (of type 'struct ClientActiveRequest').
668    */
669   struct GNUNET_CONTAINER_MultiHashMap *requests;
670
671   /**
672    * Options for messages this client cares about,
673    * see GNUNET_CORE_OPTION_ values.
674    */
675   uint32_t options;
676
677   /**
678    * Number of types of incoming messages this client
679    * specifically cares about.  Size of the "types" array.
680    */
681   unsigned int tcnt;
682
683 };
684
685
686 /**
687  * Record kept for each request for transmission issued by a
688  * client that is still pending.
689  */
690 struct ClientActiveRequest
691 {
692
693   /**
694    * Active requests are kept in a doubly-linked list of
695    * the respective target peer.
696    */
697   struct ClientActiveRequest *next;
698
699   /**
700    * Active requests are kept in a doubly-linked list of
701    * the respective target peer.
702    */
703   struct ClientActiveRequest *prev;
704
705   /**
706    * Handle to the client.
707    */
708   struct Client *client;
709
710   /**
711    * By what time would the client want to see this message out?
712    */
713   struct GNUNET_TIME_Absolute deadline;
714
715   /**
716    * How important is this request.
717    */
718   uint32_t priority;
719
720   /**
721    * How many more requests does this client have?
722    */
723   uint32_t queue_size;
724
725   /**
726    * How many bytes does the client intend to send?
727    */
728   uint16_t msize;
729
730   /**
731    * Unique request ID (in big endian).
732    */
733   uint16_t smr_id;
734
735 };
736
737
738
739 /**
740  * Our public key.
741  */
742 static struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded my_public_key;
743
744 /**
745  * Our identity.
746  */
747 static struct GNUNET_PeerIdentity my_identity;
748
749 /**
750  * Our private key.
751  */
752 static struct GNUNET_CRYPTO_RsaPrivateKey *my_private_key;
753
754 /**
755  * Bitmap of message types this peer is able to handle.
756  */
757 static uint32_t my_type_map[(UINT16_MAX + 1) / 32];
758
759 /**
760  * Handle to peerinfo service.
761  */
762 static struct GNUNET_PEERINFO_Handle *peerinfo;
763
764 /**
765  * Our message stream tokenizer (for encrypted payload).
766  */
767 static struct GNUNET_SERVER_MessageStreamTokenizer *mst;
768
769 /**
770  * Our configuration.
771  */
772 const struct GNUNET_CONFIGURATION_Handle *cfg;
773
774 /**
775  * Transport service.
776  */
777 static struct GNUNET_TRANSPORT_Handle *transport;
778
779 /**
780  * Linked list of our clients.
781  */
782 static struct Client *clients;
783
784 /**
785  * Context for notifications we need to send to our clients.
786  */
787 static struct GNUNET_SERVER_NotificationContext *notifier;
788
789 /**
790  * Map of peer identities to 'struct Neighbour'.
791  */
792 static struct GNUNET_CONTAINER_MultiHashMap *neighbours;
793
794 /**
795  * Neighbour entry for "this" peer.
796  */
797 static struct Neighbour self;
798
799 /**
800  * For creating statistics.
801  */
802 static struct GNUNET_STATISTICS_Handle *stats;
803
804 /**
805  * Sum of all preferences among all neighbours.
806  */
807 static unsigned long long preference_sum;
808
809 /**
810  * How much inbound bandwidth are we supposed to be using per second?
811  */
812 static unsigned long long bandwidth_target_in_bps;
813
814 /**
815  * How much outbound bandwidth are we supposed to be using per second?
816  */
817 static unsigned long long bandwidth_target_out_bps;
818
819 /**
820  * Derive an authentication key from "set key" information
821  */
822 static void
823 derive_auth_key (struct GNUNET_CRYPTO_AuthKey *akey,
824                  const struct GNUNET_CRYPTO_AesSessionKey *skey, uint32_t seed,
825                  struct GNUNET_TIME_Absolute creation_time)
826 {
827   static const char ctx[] = "authentication key";
828   struct GNUNET_TIME_AbsoluteNBO ctbe;
829
830
831   ctbe = GNUNET_TIME_absolute_hton (creation_time);
832   GNUNET_CRYPTO_hmac_derive_key (akey, skey, &seed, sizeof (seed), &skey->key,
833                                  sizeof (skey->key), &ctbe, sizeof (ctbe), ctx,
834                                  sizeof (ctx), NULL);
835 }
836
837
838 /**
839  * Derive an IV from packet information
840  */
841 static void
842 derive_iv (struct GNUNET_CRYPTO_AesInitializationVector *iv,
843            const struct GNUNET_CRYPTO_AesSessionKey *skey, uint32_t seed,
844            const struct GNUNET_PeerIdentity *identity)
845 {
846   static const char ctx[] = "initialization vector";
847
848   GNUNET_CRYPTO_aes_derive_iv (iv, skey, &seed, sizeof (seed),
849                                &identity->hashPubKey.bits,
850                                sizeof (identity->hashPubKey.bits), ctx,
851                                sizeof (ctx), NULL);
852 }
853
854 /**
855  * Derive an IV from pong packet information
856  */
857 static void
858 derive_pong_iv (struct GNUNET_CRYPTO_AesInitializationVector *iv,
859                 const struct GNUNET_CRYPTO_AesSessionKey *skey, uint32_t seed,
860                 uint32_t challenge, const struct GNUNET_PeerIdentity *identity)
861 {
862   static const char ctx[] = "pong initialization vector";
863
864   GNUNET_CRYPTO_aes_derive_iv (iv, skey, &seed, sizeof (seed),
865                                &identity->hashPubKey.bits,
866                                sizeof (identity->hashPubKey.bits), &challenge,
867                                sizeof (challenge), ctx, sizeof (ctx), NULL);
868 }
869
870
871 /**
872  * At what time should the connection to the given neighbour
873  * time out (given no further activity?)
874  *
875  * @param n neighbour in question
876  * @return absolute timeout
877  */
878 static struct GNUNET_TIME_Absolute
879 get_neighbour_timeout (struct Neighbour *n)
880 {
881   return GNUNET_TIME_absolute_add (n->last_activity,
882                                    GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT);
883 }
884
885
886 /**
887  * Helper function for update_preference_sum.
888  */
889 static int
890 update_preference (void *cls, const GNUNET_HashCode * key, void *value)
891 {
892   unsigned long long *ps = cls;
893   struct Neighbour *n = value;
894
895   n->current_preference /= 2;
896   *ps += n->current_preference;
897   return GNUNET_OK;
898 }
899
900
901 /**
902  * A preference value for a neighbour was update.  Update
903  * the preference sum accordingly.
904  *
905  * @param inc how much was a preference value increased?
906  */
907 static void
908 update_preference_sum (unsigned long long inc)
909 {
910   unsigned long long os;
911
912   os = preference_sum;
913   preference_sum += inc;
914   if (preference_sum >= os)
915     return;                     /* done! */
916   /* overflow! compensate by cutting all values in half! */
917   preference_sum = 0;
918   GNUNET_CONTAINER_multihashmap_iterate (neighbours, &update_preference,
919                                          &preference_sum);
920   GNUNET_STATISTICS_set (stats, gettext_noop ("# total peer preference"),
921                          preference_sum, GNUNET_NO);
922 }
923
924
925 /**
926  * Find the entry for the given neighbour.
927  *
928  * @param peer identity of the neighbour
929  * @return NULL if we are not connected, otherwise the
930  *         neighbour's entry.
931  */
932 static struct Neighbour *
933 find_neighbour (const struct GNUNET_PeerIdentity *peer)
934 {
935   return GNUNET_CONTAINER_multihashmap_get (neighbours, &peer->hashPubKey);
936 }
937
938
939 /**
940  * Send a message to one of our clients.
941  *
942  * @param client target for the message
943  * @param msg message to transmit
944  * @param can_drop could this message be dropped if the
945  *        client's queue is getting too large?
946  */
947 static void
948 send_to_client (struct Client *client, const struct GNUNET_MessageHeader *msg,
949                 int can_drop)
950 {
951 #if DEBUG_CORE_CLIENT
952   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
953               "Preparing to send %u bytes of message of type %u to client.\n",
954               (unsigned int) ntohs (msg->size),
955               (unsigned int) ntohs (msg->type));
956 #endif
957   GNUNET_SERVER_notification_context_unicast (notifier, client->client_handle,
958                                               msg, can_drop);
959 }
960
961
962 /**
963  * Send a message to all of our current clients that have
964  * the right options set.
965  *
966  * @param msg message to multicast
967  * @param can_drop can this message be discarded if the queue is too long
968  * @param options mask to use
969  */
970 static void
971 send_to_all_clients (const struct GNUNET_MessageHeader *msg, int can_drop,
972                      int options)
973 {
974   struct Client *c;
975
976   c = clients;
977   while (c != NULL)
978   {
979     if (0 != (c->options & options))
980     {
981 #if DEBUG_CORE_CLIENT > 1
982       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
983                   "Sending message of type %u to client.\n",
984                   (unsigned int) ntohs (msg->type));
985 #endif
986       send_to_client (c, msg, can_drop);
987     }
988     c = c->next;
989   }
990 }
991
992
993 /**
994  * Function called by transport telling us that a peer
995  * changed status.
996  *
997  * @param n the peer that changed status
998  */
999 static void
1000 handle_peer_status_change (struct Neighbour *n)
1001 {
1002   struct PeerStatusNotifyMessage *psnm;
1003   char buf[GNUNET_SERVER_MAX_MESSAGE_SIZE - 1];
1004   struct GNUNET_TRANSPORT_ATS_Information *ats;
1005   size_t size;
1006
1007   if ((!n->is_connected) || (n->status != PEER_STATE_KEY_CONFIRMED))
1008     return;
1009 #if DEBUG_CORE > 1
1010   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer `%4s' changed status\n",
1011               GNUNET_i2s (&n->peer));
1012 #endif
1013   size =
1014       sizeof (struct PeerStatusNotifyMessage) +
1015       n->ats_count * sizeof (struct GNUNET_TRANSPORT_ATS_Information);
1016   if (size >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
1017   {
1018     GNUNET_break (0);
1019     /* recovery strategy: throw away performance data */
1020     GNUNET_array_grow (n->ats, n->ats_count, 0);
1021     size =
1022         sizeof (struct PeerStatusNotifyMessage) +
1023         n->ats_count * sizeof (struct GNUNET_TRANSPORT_ATS_Information);
1024   }
1025   psnm = (struct PeerStatusNotifyMessage *) buf;
1026   psnm->header.size = htons (size);
1027   psnm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_STATUS_CHANGE);
1028   psnm->timeout = GNUNET_TIME_absolute_hton (get_neighbour_timeout (n));
1029   psnm->bandwidth_in = n->bw_in;
1030   psnm->bandwidth_out = n->bw_out;
1031   psnm->peer = n->peer;
1032   psnm->ats_count = htonl (n->ats_count);
1033   ats = &psnm->ats;
1034   memcpy (ats, n->ats,
1035           n->ats_count * sizeof (struct GNUNET_TRANSPORT_ATS_Information));
1036   ats[n->ats_count].type = htonl (0);
1037   ats[n->ats_count].value = htonl (0);
1038   send_to_all_clients (&psnm->header, GNUNET_YES,
1039                        GNUNET_CORE_OPTION_SEND_STATUS_CHANGE);
1040   GNUNET_STATISTICS_update (stats, gettext_noop ("# peer status changes"), 1,
1041                             GNUNET_NO);
1042 }
1043
1044
1045 /**
1046  * Go over our message queue and if it is not too long, go
1047  * over the pending requests from clients for this
1048  * neighbour and send some clients a 'READY' notification.
1049  *
1050  * @param n which peer to process
1051  */
1052 static void
1053 schedule_peer_messages (struct Neighbour *n)
1054 {
1055   struct SendMessageReady smr;
1056   struct ClientActiveRequest *car;
1057   struct ClientActiveRequest *pos;
1058   struct Client *c;
1059   struct MessageEntry *mqe;
1060   unsigned int queue_size;
1061
1062   /* check if neighbour queue is empty enough! */
1063   if (n != &self)
1064   {
1065     queue_size = 0;
1066     mqe = n->messages;
1067     while (mqe != NULL)
1068     {
1069       queue_size++;
1070       mqe = mqe->next;
1071     }
1072     if (queue_size >= MAX_PEER_QUEUE_SIZE)
1073     {
1074 #if DEBUG_CORE_CLIENT
1075       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1076                   "Not considering client transmission requests: queue full\n");
1077 #endif
1078       return;                   /* queue still full */
1079     }
1080     /* find highest priority request */
1081     pos = n->active_client_request_head;
1082     car = NULL;
1083     while (pos != NULL)
1084     {
1085       if ((car == NULL) || (pos->priority > car->priority))
1086         car = pos;
1087       pos = pos->next;
1088     }
1089   }
1090   else
1091   {
1092     car = n->active_client_request_head;
1093   }
1094   if (car == NULL)
1095     return;                     /* no pending requests */
1096 #if DEBUG_CORE_CLIENT
1097   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1098               "Permitting client transmission request to `%s'\n",
1099               GNUNET_i2s (&n->peer));
1100 #endif
1101   c = car->client;
1102   GNUNET_CONTAINER_DLL_remove (n->active_client_request_head,
1103                                n->active_client_request_tail, car);
1104   GNUNET_assert (GNUNET_YES ==
1105                  GNUNET_CONTAINER_multihashmap_remove (c->requests,
1106                                                        &n->peer.hashPubKey,
1107                                                        car));
1108   smr.header.size = htons (sizeof (struct SendMessageReady));
1109   smr.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_SEND_READY);
1110   smr.size = htons (car->msize);
1111   smr.smr_id = car->smr_id;
1112   smr.peer = n->peer;
1113   send_to_client (c, &smr.header, GNUNET_NO);
1114   GNUNET_free (car);
1115 }
1116
1117
1118 /**
1119  * Compute a type map message for this peer.
1120  *
1121  * @return this peers current type map message.
1122  */
1123 static struct GNUNET_MessageHeader *
1124 compute_type_map_message ()
1125 {
1126   char *tmp;
1127   uLongf dlen;
1128   struct GNUNET_MessageHeader *hdr;
1129
1130 #ifdef compressBound
1131   dlen = compressBound (sizeof (my_type_map));
1132 #else
1133   dlen = sizeof (my_type_map) + (sizeof (my_type_map) / 100) + 20;
1134   /* documentation says 100.1% oldSize + 12 bytes, but we
1135    * should be able to overshoot by more to be safe */
1136 #endif
1137   hdr = GNUNET_malloc (dlen + sizeof (struct GNUNET_MessageHeader));
1138   hdr->size = htons ((uint16_t) dlen + sizeof (struct GNUNET_MessageHeader));
1139   tmp = (char *) &hdr[1];
1140   if ((Z_OK !=
1141        compress2 ((Bytef *) tmp, &dlen, (const Bytef *) my_type_map,
1142                   sizeof (my_type_map), 9)) || (dlen >= sizeof (my_type_map)))
1143   {
1144     dlen = sizeof (my_type_map);
1145     memcpy (tmp, my_type_map, sizeof (my_type_map));
1146     hdr->type = htons (GNUNET_MESSAGE_TYPE_CORE_BINARY_TYPE_MAP);
1147   }
1148   else
1149   {
1150     hdr->type = htons (GNUNET_MESSAGE_TYPE_CORE_COMPRESSED_TYPE_MAP);
1151   }
1152   return hdr;
1153 }
1154
1155
1156 /**
1157  * Send a type map message to the neighbour.
1158  *
1159  * @param cls the type map message
1160  * @param key neighbour's identity
1161  * @param value 'struct Neighbour' of the target
1162  * @return always GNUNET_OK
1163  */
1164 static int
1165 send_type_map_to_neighbour (void *cls, const GNUNET_HashCode * key, void *value)
1166 {
1167   struct GNUNET_MessageHeader *hdr = cls;
1168   struct Neighbour *n = value;
1169   struct MessageEntry *m;
1170   uint16_t size;
1171
1172   if (n == &self)
1173     return GNUNET_OK;
1174   size = ntohs (hdr->size);
1175   m = GNUNET_malloc (sizeof (struct MessageEntry) + size);
1176   memcpy (&m[1], hdr, size);
1177   m->deadline = GNUNET_TIME_UNIT_FOREVER_ABS;
1178   m->slack_deadline = GNUNET_TIME_UNIT_FOREVER_ABS;
1179   m->priority = UINT_MAX;
1180   m->sender_status = n->status;
1181   m->size = size;
1182   m->next = n->messages;
1183   n->messages = m;
1184   return GNUNET_OK;
1185 }
1186
1187
1188
1189 /**
1190  * Send my type map to all connected peers (it got changed).
1191  */
1192 static void
1193 broadcast_my_type_map ()
1194 {
1195   struct GNUNET_MessageHeader *hdr;
1196
1197   if (NULL == neighbours)
1198     return;
1199   hdr = compute_type_map_message ();
1200   GNUNET_CONTAINER_multihashmap_iterate (neighbours,
1201                                          &send_type_map_to_neighbour, hdr);
1202   GNUNET_free (hdr);
1203 }
1204
1205
1206 /**
1207  * Handle CORE_SEND_REQUEST message.
1208  */
1209 static void
1210 handle_client_send_request (void *cls, struct GNUNET_SERVER_Client *client,
1211                             const struct GNUNET_MessageHeader *message)
1212 {
1213   const struct SendMessageRequest *req;
1214   struct Neighbour *n;
1215   struct Client *c;
1216   struct ClientActiveRequest *car;
1217
1218   req = (const struct SendMessageRequest *) message;
1219   if (0 ==
1220       memcmp (&req->peer, &my_identity, sizeof (struct GNUNET_PeerIdentity)))
1221     n = &self;
1222   else
1223     n = find_neighbour (&req->peer);
1224   if ((n == NULL) || (GNUNET_YES != n->is_connected) ||
1225       (n->status != PEER_STATE_KEY_CONFIRMED))
1226   {
1227     /* neighbour must have disconnected since request was issued,
1228      * ignore (client will realize it once it processes the
1229      * disconnect notification) */
1230 #if DEBUG_CORE_CLIENT
1231     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1232                 "Dropped client request for transmission (am disconnected)\n");
1233 #endif
1234     GNUNET_STATISTICS_update (stats,
1235                               gettext_noop
1236                               ("# send requests dropped (disconnected)"), 1,
1237                               GNUNET_NO);
1238     GNUNET_SERVER_receive_done (client, GNUNET_OK);
1239     return;
1240   }
1241   c = clients;
1242   while ((c != NULL) && (c->client_handle != client))
1243     c = c->next;
1244   if (c == NULL)
1245   {
1246     /* client did not send INIT first! */
1247     GNUNET_break (0);
1248     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1249     return;
1250   }
1251   if (c->requests == NULL)
1252     c->requests = GNUNET_CONTAINER_multihashmap_create (16);
1253 #if DEBUG_CORE_CLIENT
1254   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1255               "Received client transmission request. queueing\n");
1256 #endif
1257   car = GNUNET_CONTAINER_multihashmap_get (c->requests, &req->peer.hashPubKey);
1258   if (car == NULL)
1259   {
1260     /* create new entry */
1261     car = GNUNET_malloc (sizeof (struct ClientActiveRequest));
1262     GNUNET_assert (GNUNET_OK ==
1263                    GNUNET_CONTAINER_multihashmap_put (c->requests,
1264                                                       &req->peer.hashPubKey,
1265                                                       car,
1266                                                       GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST));
1267     GNUNET_CONTAINER_DLL_insert (n->active_client_request_head,
1268                                  n->active_client_request_tail, car);
1269     car->client = c;
1270   }
1271   car->deadline = GNUNET_TIME_absolute_ntoh (req->deadline);
1272   car->priority = ntohl (req->priority);
1273   car->queue_size = ntohl (req->queue_size);
1274   car->msize = ntohs (req->size);
1275   car->smr_id = req->smr_id;
1276   schedule_peer_messages (n);
1277   GNUNET_SERVER_receive_done (client, GNUNET_OK);
1278 }
1279
1280
1281 /**
1282  * Notify client about an existing connection to one of our neighbours.
1283  */
1284 static int
1285 notify_client_about_neighbour (void *cls, const GNUNET_HashCode * key,
1286                                void *value)
1287 {
1288   struct Client *c = cls;
1289   struct Neighbour *n = value;
1290   size_t size;
1291   char buf[GNUNET_SERVER_MAX_MESSAGE_SIZE - 1];
1292   struct GNUNET_TRANSPORT_ATS_Information *ats;
1293   struct ConnectNotifyMessage *cnm;
1294
1295   size =
1296       sizeof (struct ConnectNotifyMessage) +
1297       (n->ats_count) * sizeof (struct GNUNET_TRANSPORT_ATS_Information);
1298   if (size >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
1299   {
1300     GNUNET_break (0);
1301     /* recovery strategy: throw away performance data */
1302     GNUNET_array_grow (n->ats, n->ats_count, 0);
1303     size =
1304         sizeof (struct ConnectNotifyMessage) +
1305         (n->ats_count) * sizeof (struct GNUNET_TRANSPORT_ATS_Information);
1306   }
1307   cnm = (struct ConnectNotifyMessage *) buf;
1308   cnm->header.size = htons (size);
1309   cnm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT);
1310   cnm->ats_count = htonl (n->ats_count);
1311   ats = &cnm->ats;
1312   memcpy (ats, n->ats,
1313           sizeof (struct GNUNET_TRANSPORT_ATS_Information) * n->ats_count);
1314   ats[n->ats_count].type = htonl (GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR);
1315   ats[n->ats_count].value = htonl (0);
1316   if (n->status == PEER_STATE_KEY_CONFIRMED)
1317   {
1318 #if DEBUG_CORE_CLIENT
1319     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message to client.\n",
1320                 "NOTIFY_CONNECT");
1321 #endif
1322     cnm->peer = n->peer;
1323     send_to_client (c, &cnm->header, GNUNET_NO);
1324   }
1325   return GNUNET_OK;
1326 }
1327
1328
1329
1330 /**
1331  * Handle CORE_INIT request.
1332  */
1333 static void
1334 handle_client_init (void *cls, struct GNUNET_SERVER_Client *client,
1335                     const struct GNUNET_MessageHeader *message)
1336 {
1337   const struct InitMessage *im;
1338   struct InitReplyMessage irm;
1339   struct Client *c;
1340   uint16_t msize;
1341   const uint16_t *types;
1342   uint16_t *wtypes;
1343   unsigned int i;
1344
1345 #if DEBUG_CORE_CLIENT
1346   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1347               "Client connecting to core service with `%s' message\n", "INIT");
1348 #endif
1349   /* check that we don't have an entry already */
1350   c = clients;
1351   while (c != NULL)
1352   {
1353     if (client == c->client_handle)
1354     {
1355       GNUNET_break (0);
1356       GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1357       return;
1358     }
1359     c = c->next;
1360   }
1361   msize = ntohs (message->size);
1362   if (msize < sizeof (struct InitMessage))
1363   {
1364     GNUNET_break (0);
1365     GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1366     return;
1367   }
1368   GNUNET_SERVER_notification_context_add (notifier, client);
1369   im = (const struct InitMessage *) message;
1370   types = (const uint16_t *) &im[1];
1371   msize -= sizeof (struct InitMessage);
1372   c = GNUNET_malloc (sizeof (struct Client) + msize);
1373   c->client_handle = client;
1374   c->next = clients;
1375   clients = c;
1376   c->tcnt = msize / sizeof (uint16_t);
1377   c->types = (const uint16_t *) &c[1];
1378   wtypes = (uint16_t *) & c[1];
1379   for (i = 0; i < c->tcnt; i++)
1380   {
1381     wtypes[i] = ntohs (types[i]);
1382     my_type_map[wtypes[i] / 32] |= (1 << (wtypes[i] % 32));
1383   }
1384   if (c->tcnt > 0)
1385     broadcast_my_type_map ();
1386   c->options = ntohl (im->options);
1387 #if DEBUG_CORE_CLIENT
1388   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1389               "Client %p is interested in %u message types\n", c,
1390               (unsigned int) c->tcnt);
1391 #endif
1392   /* send init reply message */
1393   irm.header.size = htons (sizeof (struct InitReplyMessage));
1394   irm.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_INIT_REPLY);
1395   irm.reserved = htonl (0);
1396   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   unsigned int queue_length;
2496
2497   disc = GNUNET_NO;
2498   now = GNUNET_TIME_absolute_get ();
2499   prev = NULL;
2500   queue_length = 0;
2501   pos = n->messages;
2502   while (pos != NULL)
2503   {
2504     queue_length++;
2505     next = pos->next;
2506     delta = GNUNET_TIME_absolute_get_difference (pos->deadline, now);
2507     if (delta.rel_value > PAST_EXPIRATION_DISCARD_TIME.rel_value)
2508     {
2509 #if DEBUG_CORE
2510       GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2511                   "Message is %llu ms past due, discarding.\n",
2512                   delta.rel_value);
2513 #endif
2514       if (prev == NULL)
2515         n->messages = next;
2516       else
2517         prev->next = next;
2518       GNUNET_STATISTICS_update (stats,
2519                                 gettext_noop
2520                                 ("# messages discarded (expired prior to transmission)"),
2521                                 1, GNUNET_NO);
2522       disc = GNUNET_YES;
2523       GNUNET_free (pos);
2524     }
2525     else
2526       prev = pos;
2527     pos = next;
2528   }
2529   if ( (GNUNET_YES == disc) &&
2530        (queue_length == MAX_PEER_QUEUE_SIZE) )
2531     schedule_peer_messages (n);
2532 }
2533
2534
2535 /**
2536  * Signature of the main function of a task.
2537  *
2538  * @param cls closure
2539  * @param tc context information (why was this task triggered now)
2540  */
2541 static void
2542 retry_plaintext_processing (void *cls,
2543                             const struct GNUNET_SCHEDULER_TaskContext *tc)
2544 {
2545   struct Neighbour *n = cls;
2546
2547   n->retry_plaintext_task = GNUNET_SCHEDULER_NO_TASK;
2548   process_plaintext_neighbour_queue (n);
2549 }
2550
2551
2552 /**
2553  * Send our key (and encrypted PING) to the other peer.
2554  *
2555  * @param n the other peer
2556  */
2557 static void
2558 send_key (struct Neighbour *n);
2559
2560 /**
2561  * Task that will retry "send_key" if our previous attempt failed
2562  * to yield a PONG.
2563  */
2564 static void
2565 set_key_retry_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
2566 {
2567   struct Neighbour *n = cls;
2568
2569 #if DEBUG_CORE
2570   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Retrying key transmission to `%4s'\n",
2571               GNUNET_i2s (&n->peer));
2572 #endif
2573   n->retry_set_key_task = GNUNET_SCHEDULER_NO_TASK;
2574   n->set_key_retry_frequency =
2575       GNUNET_TIME_relative_multiply (n->set_key_retry_frequency, 2);
2576   send_key (n);
2577 }
2578
2579
2580 /**
2581  * Check if we have plaintext messages for the specified neighbour
2582  * pending, and if so, consider batching and encrypting them (and
2583  * then trigger processing of the encrypted queue if needed).
2584  *
2585  * @param n neighbour to check.
2586  */
2587 static void
2588 process_plaintext_neighbour_queue (struct Neighbour *n)
2589 {
2590   char pbuf[GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE + sizeof (struct EncryptedMessage)];    /* plaintext */
2591   size_t used;
2592   struct EncryptedMessage *em;  /* encrypted message */
2593   struct EncryptedMessage *ph;  /* plaintext header */
2594   struct MessageEntry *me;
2595   unsigned int priority;
2596   struct GNUNET_TIME_Absolute deadline;
2597   struct GNUNET_TIME_Relative retry_time;
2598   struct GNUNET_CRYPTO_AesInitializationVector iv;
2599   struct GNUNET_CRYPTO_AuthKey auth_key;
2600
2601   if (n->retry_plaintext_task != GNUNET_SCHEDULER_NO_TASK)
2602   {
2603     GNUNET_SCHEDULER_cancel (n->retry_plaintext_task);
2604     n->retry_plaintext_task = GNUNET_SCHEDULER_NO_TASK;
2605   }
2606   switch (n->status)
2607   {
2608   case PEER_STATE_DOWN:
2609     send_key (n);
2610 #if DEBUG_CORE
2611     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2612                 "Not yet connected to `%4s', deferring processing of plaintext messages.\n",
2613                 GNUNET_i2s (&n->peer));
2614 #endif
2615     return;
2616   case PEER_STATE_KEY_SENT:
2617     if (n->retry_set_key_task == GNUNET_SCHEDULER_NO_TASK)
2618       n->retry_set_key_task =
2619           GNUNET_SCHEDULER_add_delayed (n->set_key_retry_frequency,
2620                                         &set_key_retry_task, n);
2621 #if DEBUG_CORE
2622     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2623                 "Not yet connected to `%4s', deferring processing of plaintext messages.\n",
2624                 GNUNET_i2s (&n->peer));
2625 #endif
2626     return;
2627   case PEER_STATE_KEY_RECEIVED:
2628     if (n->retry_set_key_task == GNUNET_SCHEDULER_NO_TASK)
2629       n->retry_set_key_task =
2630           GNUNET_SCHEDULER_add_delayed (n->set_key_retry_frequency,
2631                                         &set_key_retry_task, n);
2632 #if DEBUG_CORE
2633     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2634                 "Not yet connected to `%4s', deferring processing of plaintext messages.\n",
2635                 GNUNET_i2s (&n->peer));
2636 #endif
2637     return;
2638   case PEER_STATE_KEY_CONFIRMED:
2639     /* ready to continue */
2640     break;
2641   }
2642   discard_expired_messages (n);
2643   if (n->messages == NULL)
2644   {
2645 #if DEBUG_CORE
2646     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2647                 "Plaintext message queue for `%4s' is empty.\n",
2648                 GNUNET_i2s (&n->peer));
2649 #endif
2650     return;                     /* no pending messages */
2651   }
2652   if (n->encrypted_head != NULL)
2653   {
2654 #if DEBUG_CORE > 2
2655     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2656                 "Encrypted message queue for `%4s' is still full, delaying plaintext processing.\n",
2657                 GNUNET_i2s (&n->peer));
2658 #endif
2659     return;                     /* wait for messages already encrypted to be
2660                                  * processed first! */
2661   }
2662   ph = (struct EncryptedMessage *) pbuf;
2663   deadline = GNUNET_TIME_UNIT_FOREVER_ABS;
2664   priority = 0;
2665   used = sizeof (struct EncryptedMessage);
2666   used +=
2667       batch_message (n, &pbuf[used],
2668                      GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE, &deadline,
2669                      &retry_time, &priority);
2670   if (used == sizeof (struct EncryptedMessage))
2671   {
2672 #if DEBUG_CORE > 1
2673     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2674                 "No messages selected for transmission to `%4s' at this time, will try again later.\n",
2675                 GNUNET_i2s (&n->peer));
2676 #endif
2677     /* no messages selected for sending, try again later... */
2678     n->retry_plaintext_task =
2679         GNUNET_SCHEDULER_add_delayed (retry_time, &retry_plaintext_processing,
2680                                       n);
2681     return;
2682   }
2683 #if DEBUG_CORE_QUOTA
2684   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2685               "Sending %u b/s as new limit to peer `%4s'\n",
2686               (unsigned int) ntohl (n->bw_in.value__), GNUNET_i2s (&n->peer));
2687 #endif
2688   ph->iv_seed =
2689       htonl (GNUNET_CRYPTO_random_u32
2690              (GNUNET_CRYPTO_QUALITY_NONCE, UINT32_MAX));
2691   ph->sequence_number = htonl (++n->last_sequence_number_sent);
2692   ph->inbound_bw_limit = n->bw_in;
2693   ph->timestamp = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get ());
2694
2695   /* setup encryption message header */
2696   me = GNUNET_malloc (sizeof (struct MessageEntry) + used);
2697   me->deadline = deadline;
2698   me->priority = priority;
2699   me->size = used;
2700   em = (struct EncryptedMessage *) &me[1];
2701   em->header.size = htons (used);
2702   em->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_ENCRYPTED_MESSAGE);
2703   em->iv_seed = ph->iv_seed;
2704   derive_iv (&iv, &n->encrypt_key, ph->iv_seed, &n->peer);
2705   /* encrypt */
2706 #if DEBUG_HANDSHAKE
2707   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2708               "Encrypting %u bytes of plaintext messages for `%4s' for transmission in %llums.\n",
2709               (unsigned int) used - ENCRYPTED_HEADER_SIZE,
2710               GNUNET_i2s (&n->peer),
2711               (unsigned long long)
2712               GNUNET_TIME_absolute_get_remaining (deadline).rel_value);
2713 #endif
2714   GNUNET_assert (GNUNET_OK ==
2715                  do_encrypt (n, &iv, &ph->sequence_number, &em->sequence_number,
2716                              used - ENCRYPTED_HEADER_SIZE));
2717   derive_auth_key (&auth_key, &n->encrypt_key, ph->iv_seed,
2718                    n->encrypt_key_created);
2719   GNUNET_CRYPTO_hmac (&auth_key, &em->sequence_number,
2720                       used - ENCRYPTED_HEADER_SIZE, &em->hmac);
2721 #if DEBUG_HANDSHAKE
2722   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2723               "Authenticated %u bytes of ciphertext %u: `%s'\n",
2724               used - ENCRYPTED_HEADER_SIZE,
2725               GNUNET_CRYPTO_crc32_n (&em->sequence_number,
2726                                      used - ENCRYPTED_HEADER_SIZE),
2727               GNUNET_h2s (&em->hmac));
2728 #endif
2729   /* append to transmission list */
2730   GNUNET_CONTAINER_DLL_insert_after (n->encrypted_head, n->encrypted_tail,
2731                                      n->encrypted_tail, me);
2732   process_encrypted_neighbour_queue (n);
2733   schedule_peer_messages (n);
2734 }
2735
2736
2737 /**
2738  * Function that recalculates the bandwidth quota for the
2739  * given neighbour and transmits it to the transport service.
2740  *
2741  * @param cls neighbour for the quota update
2742  * @param tc context
2743  */
2744 static void
2745 neighbour_quota_update (void *cls,
2746                         const struct GNUNET_SCHEDULER_TaskContext *tc);
2747
2748
2749 /**
2750  * Schedule the task that will recalculate the bandwidth
2751  * quota for this peer (and possibly force a disconnect of
2752  * idle peers by calculating a bandwidth of zero).
2753  */
2754 static void
2755 schedule_quota_update (struct Neighbour *n)
2756 {
2757   GNUNET_assert (n->quota_update_task == GNUNET_SCHEDULER_NO_TASK);
2758   n->quota_update_task =
2759       GNUNET_SCHEDULER_add_delayed (QUOTA_UPDATE_FREQUENCY,
2760                                     &neighbour_quota_update, n);
2761 }
2762
2763
2764 /**
2765  * Initialize a new 'struct Neighbour'.
2766  *
2767  * @param pid ID of the new neighbour
2768  * @return handle for the new neighbour
2769  */
2770 static struct Neighbour *
2771 create_neighbour (const struct GNUNET_PeerIdentity *pid)
2772 {
2773   struct Neighbour *n;
2774   struct GNUNET_TIME_Absolute now;
2775
2776 #if DEBUG_CORE
2777   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2778               "Creating neighbour entry for peer `%4s'\n", GNUNET_i2s (pid));
2779 #endif
2780   n = GNUNET_malloc (sizeof (struct Neighbour));
2781   n->peer = *pid;
2782   GNUNET_CRYPTO_aes_create_session_key (&n->encrypt_key);
2783   now = GNUNET_TIME_absolute_get ();
2784   n->encrypt_key_created = now;
2785   n->last_activity = now;
2786   n->set_key_retry_frequency = INITIAL_SET_KEY_RETRY_FREQUENCY;
2787   n->bw_in = GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT;
2788   n->bw_out = GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT;
2789   n->bw_out_internal_limit = GNUNET_BANDWIDTH_value_init (UINT32_MAX);
2790   n->bw_out_external_limit = GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT;
2791   n->ping_challenge =
2792       GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, UINT32_MAX);
2793   GNUNET_assert (GNUNET_OK ==
2794                  GNUNET_CONTAINER_multihashmap_put (neighbours,
2795                                                     &n->peer.hashPubKey, n,
2796                                                     GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
2797   GNUNET_STATISTICS_set (stats, gettext_noop ("# neighbour entries allocated"),
2798                          GNUNET_CONTAINER_multihashmap_size (neighbours),
2799                          GNUNET_NO);
2800   neighbour_quota_update (n, NULL);
2801   consider_free_neighbour (n);
2802   return n;
2803 }
2804
2805
2806 /**
2807  * Handle CORE_SEND request.
2808  *
2809  * @param cls unused
2810  * @param client the client issuing the request
2811  * @param message the "struct SendMessage"
2812  */
2813 static void
2814 handle_client_send (void *cls, struct GNUNET_SERVER_Client *client,
2815                     const struct GNUNET_MessageHeader *message)
2816 {
2817   const struct SendMessage *sm;
2818   struct Neighbour *n;
2819   struct MessageEntry *prev;
2820   struct MessageEntry *pos;
2821   struct MessageEntry *e;
2822   struct MessageEntry *min_prio_entry;
2823   struct MessageEntry *min_prio_prev;
2824   unsigned int min_prio;
2825   unsigned int queue_size;
2826   uint16_t msize;
2827
2828   msize = ntohs (message->size);
2829   if (msize <
2830       sizeof (struct SendMessage) + sizeof (struct GNUNET_MessageHeader))
2831   {
2832     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2833                 "msize is %u, should be at least %u (in %s:%d)\n", msize,
2834                 sizeof (struct SendMessage) +
2835                 sizeof (struct GNUNET_MessageHeader), __FILE__, __LINE__);
2836     GNUNET_break (0);
2837     if (client != NULL)
2838       GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
2839     return;
2840   }
2841   sm = (const struct SendMessage *) message;
2842   msize -= sizeof (struct SendMessage);
2843   if (0 ==
2844       memcmp (&sm->peer, &my_identity, sizeof (struct GNUNET_PeerIdentity)))
2845   {
2846     /* loopback */
2847     GNUNET_SERVER_mst_receive (mst, &self, (const char *) &sm[1], msize,
2848                                GNUNET_YES, GNUNET_NO);
2849     if (client != NULL)
2850       GNUNET_SERVER_receive_done (client, GNUNET_OK);
2851     return;
2852   }
2853   n = find_neighbour (&sm->peer);
2854   if ((n == NULL) || (GNUNET_YES != n->is_connected) ||
2855       (n->status != PEER_STATE_KEY_CONFIRMED))
2856   {
2857     /* attempt to send message to peer that is not connected anymore
2858      * (can happen due to asynchrony) */
2859     GNUNET_STATISTICS_update (stats,
2860                               gettext_noop
2861                               ("# messages discarded (disconnected)"), 1,
2862                               GNUNET_NO);
2863     if (client != NULL)
2864       GNUNET_SERVER_receive_done (client, GNUNET_OK);
2865     return;
2866   }
2867 #if DEBUG_CORE
2868   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2869               "Core received `%s' request, queueing %u bytes of plaintext data for transmission to `%4s'.\n",
2870               "SEND", (unsigned int) msize, GNUNET_i2s (&sm->peer));
2871 #endif
2872   discard_expired_messages (n);
2873   /* bound queue size */
2874   /* NOTE: this entire block to bound the queue size should be
2875    * obsolete with the new client-request code and the
2876    * 'schedule_peer_messages' mechanism; we still have this code in
2877    * here for now as a sanity check for the new mechanmism;
2878    * ultimately, we should probably simply reject SEND messages that
2879    * are not 'approved' (or provide a new core API for very unreliable
2880    * delivery that always sends with priority 0).  Food for thought. */
2881   min_prio = UINT32_MAX;
2882   min_prio_entry = NULL;
2883   min_prio_prev = NULL;
2884   queue_size = 0;
2885   prev = NULL;
2886   pos = n->messages;
2887   while (pos != NULL)
2888   {
2889     if (pos->priority <= min_prio)
2890     {
2891       min_prio_entry = pos;
2892       min_prio_prev = prev;
2893       min_prio = pos->priority;
2894     }
2895     queue_size++;
2896     prev = pos;
2897     pos = pos->next;
2898   }
2899   if (queue_size >= MAX_PEER_QUEUE_SIZE)
2900   {
2901     /* queue full */
2902     if (ntohl (sm->priority) <= min_prio)
2903     {
2904       /* discard new entry; this should no longer happen! */
2905       GNUNET_break (0);
2906 #if DEBUG_CORE
2907       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2908                   "Queue full (%u/%u), discarding new request (%u bytes of type %u)\n",
2909                   queue_size, (unsigned int) MAX_PEER_QUEUE_SIZE,
2910                   (unsigned int) msize, (unsigned int) ntohs (message->type));
2911 #endif
2912       GNUNET_STATISTICS_update (stats,
2913                                 gettext_noop ("# discarded CORE_SEND requests"),
2914                                 1, GNUNET_NO);
2915
2916       if (client != NULL)
2917         GNUNET_SERVER_receive_done (client, GNUNET_OK);
2918       return;
2919     }
2920     GNUNET_assert (min_prio_entry != NULL);
2921     /* discard "min_prio_entry" */
2922 #if DEBUG_CORE
2923     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2924                 "Queue full, discarding existing older request\n");
2925 #endif
2926     GNUNET_STATISTICS_update (stats,
2927                               gettext_noop
2928                               ("# discarded lower priority CORE_SEND requests"),
2929                               1, GNUNET_NO);
2930     if (min_prio_prev == NULL)
2931       n->messages = min_prio_entry->next;
2932     else
2933       min_prio_prev->next = min_prio_entry->next;
2934     GNUNET_free (min_prio_entry);
2935   }
2936
2937 #if DEBUG_CORE
2938   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2939               "Adding transmission request for `%4s' of size %u to queue\n",
2940               GNUNET_i2s (&sm->peer), (unsigned int) msize);
2941 #endif
2942   GNUNET_break (0 == ntohl (sm->reserved));
2943   e = GNUNET_malloc (sizeof (struct MessageEntry) + msize);
2944   e->deadline = GNUNET_TIME_absolute_ntoh (sm->deadline);
2945   e->priority = ntohl (sm->priority);
2946   e->size = msize;
2947   if (GNUNET_YES != (int) ntohl (sm->cork))
2948     e->got_slack = GNUNET_YES;
2949   memcpy (&e[1], &sm[1], msize);
2950
2951   /* insert, keep list sorted by deadline */
2952   prev = NULL;
2953   pos = n->messages;
2954   while ((pos != NULL) && (pos->deadline.abs_value < e->deadline.abs_value))
2955   {
2956     prev = pos;
2957     pos = pos->next;
2958   }
2959   if (prev == NULL)
2960     n->messages = e;
2961   else
2962     prev->next = e;
2963   e->next = pos;
2964
2965   /* consider scheduling now */
2966   process_plaintext_neighbour_queue (n);
2967   if (client != NULL)
2968     GNUNET_SERVER_receive_done (client, GNUNET_OK);
2969 }
2970
2971
2972 /**
2973  * Handle CORE_REQUEST_CONNECT request.
2974  *
2975  * @param cls unused
2976  * @param client the client issuing the request
2977  * @param message the "struct ConnectMessage"
2978  */
2979 static void
2980 handle_client_request_connect (void *cls, struct GNUNET_SERVER_Client *client,
2981                                const struct GNUNET_MessageHeader *message)
2982 {
2983   const struct ConnectMessage *cm = (const struct ConnectMessage *) message;
2984   struct Neighbour *n;
2985
2986   if (0 ==
2987       memcmp (&cm->peer, &my_identity, sizeof (struct GNUNET_PeerIdentity)))
2988   {
2989     /* In this case a client has asked us to connect to ourselves, not really an error! */
2990     GNUNET_SERVER_receive_done (client, GNUNET_OK);
2991     return;
2992   }
2993   GNUNET_break (ntohl (cm->reserved) == 0);
2994 #if DEBUG_CORE
2995   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2996               "Core received `%s' request for `%4s', will try to establish connection\n",
2997               "REQUEST_CONNECT", GNUNET_i2s (&cm->peer));
2998 #endif
2999   GNUNET_STATISTICS_update (stats,
3000                             gettext_noop ("# connection requests received"), 1,
3001                             GNUNET_NO);
3002   GNUNET_SERVER_receive_done (client, GNUNET_OK);
3003   n = find_neighbour (&cm->peer);
3004   if ((n == NULL) || (GNUNET_YES != n->is_connected))
3005   {
3006     GNUNET_TRANSPORT_try_connect (transport, &cm->peer);
3007   }
3008   else
3009   {
3010     GNUNET_STATISTICS_update (stats,
3011                               gettext_noop
3012                               ("# connection requests ignored (already connected)"),
3013                               1, GNUNET_NO);
3014   }
3015 }
3016
3017
3018 /**
3019  * PEERINFO is giving us a HELLO for a peer.  Add the public key to
3020  * the neighbour's struct and retry send_key.  Or, if we did not get a
3021  * HELLO, just do nothing.
3022  *
3023  * @param cls the 'struct Neighbour' to retry sending the key for
3024  * @param peer the peer for which this is the HELLO
3025  * @param hello HELLO message of that peer
3026  * @param err_msg NULL if successful, otherwise contains error message
3027  */
3028 static void
3029 process_hello_retry_send_key (void *cls, const struct GNUNET_PeerIdentity *peer,
3030                               const struct GNUNET_HELLO_Message *hello,
3031                               const char *err_msg)
3032 {
3033   struct Neighbour *n = cls;
3034
3035   if (err_msg != NULL)
3036   {
3037     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3038                 _("Error in communication with PEERINFO service\n"));
3039     /* return; */
3040   }
3041
3042   if (peer == NULL)
3043   {
3044 #if DEBUG_CORE
3045     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Entered `%s' and `%s' is NULL!\n",
3046                 "process_hello_retry_send_key", "peer");
3047 #endif
3048     n->pitr = NULL;
3049     if (n->public_key != NULL)
3050     {
3051       if (n->retry_set_key_task != GNUNET_SCHEDULER_NO_TASK)
3052       {
3053         GNUNET_SCHEDULER_cancel (n->retry_set_key_task);
3054         n->retry_set_key_task = GNUNET_SCHEDULER_NO_TASK;
3055       }
3056       GNUNET_STATISTICS_update (stats,
3057                                 gettext_noop
3058                                 ("# SET_KEY messages deferred (need public key)"),
3059                                 -1, GNUNET_NO);
3060       send_key (n);
3061     }
3062     else
3063     {
3064 #if DEBUG_CORE
3065       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3066                   "Failed to obtain public key for peer `%4s', delaying processing of SET_KEY\n",
3067                   GNUNET_i2s (&n->peer));
3068 #endif
3069       GNUNET_STATISTICS_update (stats,
3070                                 gettext_noop
3071                                 ("# Delayed connecting due to lack of public key"),
3072                                 1, GNUNET_NO);
3073       if (GNUNET_SCHEDULER_NO_TASK == n->retry_set_key_task)
3074         n->retry_set_key_task =
3075             GNUNET_SCHEDULER_add_delayed (n->set_key_retry_frequency,
3076                                           &set_key_retry_task, n);
3077     }
3078     return;
3079   }
3080
3081 #if DEBUG_CORE
3082   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Entered `%s' for peer `%4s'\n",
3083               "process_hello_retry_send_key", GNUNET_i2s (peer));
3084 #endif
3085   if (n->public_key != NULL)
3086   {
3087     /* already have public key, why are we here? */
3088     GNUNET_break (0);
3089     return;
3090   }
3091
3092 #if DEBUG_CORE
3093   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3094               "Received new `%s' message for `%4s', initiating key exchange.\n",
3095               "HELLO", GNUNET_i2s (peer));
3096 #endif
3097   n->public_key =
3098       GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded));
3099   if (GNUNET_OK != GNUNET_HELLO_get_key (hello, n->public_key))
3100   {
3101     GNUNET_STATISTICS_update (stats,
3102                               gettext_noop
3103                               ("# Error extracting public key from HELLO"), 1,
3104                               GNUNET_NO);
3105     GNUNET_free (n->public_key);
3106     n->public_key = NULL;
3107 #if DEBUG_CORE
3108     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3109                 "GNUNET_HELLO_get_key returned awfully\n");
3110 #endif
3111     return;
3112   }
3113 }
3114
3115
3116 /**
3117  * Send our key (and encrypted PING) to the other peer.
3118  *
3119  * @param n the other peer
3120  */
3121 static void
3122 send_key (struct Neighbour *n)
3123 {
3124   struct MessageEntry *pos;
3125   struct SetKeyMessage *sm;
3126   struct MessageEntry *me;
3127   struct PingMessage pp;
3128   struct PingMessage *pm;
3129   struct GNUNET_CRYPTO_AesInitializationVector iv;
3130
3131   if (n->retry_set_key_task != GNUNET_SCHEDULER_NO_TASK)
3132   {
3133     GNUNET_SCHEDULER_cancel (n->retry_set_key_task);
3134     n->retry_set_key_task = GNUNET_SCHEDULER_NO_TASK;
3135   }
3136   if (n->pitr != NULL)
3137   {
3138 #if DEBUG_CORE
3139     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3140                 "Key exchange in progress with `%4s'.\n",
3141                 GNUNET_i2s (&n->peer));
3142 #endif
3143     return;                     /* already in progress */
3144   }
3145   if (GNUNET_YES != n->is_connected)
3146   {
3147     GNUNET_STATISTICS_update (stats,
3148                               gettext_noop
3149                               ("# Asking transport to connect (for SET_KEY)"),
3150                               1, GNUNET_NO);
3151     GNUNET_TRANSPORT_try_connect (transport, &n->peer);
3152     return;
3153   }
3154 #if DEBUG_CORE
3155   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3156               "Asked to perform key exchange with `%4s'.\n",
3157               GNUNET_i2s (&n->peer));
3158 #endif
3159   if (n->public_key == NULL)
3160   {
3161     /* lookup n's public key, then try again */
3162 #if DEBUG_CORE
3163     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3164                 "Lacking public key for `%4s', trying to obtain one (send_key).\n",
3165                 GNUNET_i2s (&n->peer));
3166 #endif
3167     GNUNET_assert (n->pitr == NULL);
3168     n->pitr =
3169         GNUNET_PEERINFO_iterate (peerinfo, &n->peer,
3170                                  GNUNET_TIME_relative_multiply
3171                                  (GNUNET_TIME_UNIT_SECONDS, 20),
3172                                  &process_hello_retry_send_key, n);
3173     return;
3174   }
3175   pos = n->encrypted_head;
3176   while (pos != NULL)
3177   {
3178     if (GNUNET_YES == pos->is_setkey)
3179     {
3180       if (pos->sender_status == n->status)
3181       {
3182 #if DEBUG_CORE
3183         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3184                     "`%s' message for `%4s' queued already\n", "SET_KEY",
3185                     GNUNET_i2s (&n->peer));
3186 #endif
3187         goto trigger_processing;
3188       }
3189       GNUNET_CONTAINER_DLL_remove (n->encrypted_head, n->encrypted_tail, pos);
3190       GNUNET_free (pos);
3191 #if DEBUG_CORE
3192       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3193                   "Removing queued `%s' message for `%4s', will create a new one\n",
3194                   "SET_KEY", GNUNET_i2s (&n->peer));
3195 #endif
3196       break;
3197     }
3198     pos = pos->next;
3199   }
3200
3201   /* update status */
3202   switch (n->status)
3203   {
3204   case PEER_STATE_DOWN:
3205     n->status = PEER_STATE_KEY_SENT;
3206     break;
3207   case PEER_STATE_KEY_SENT:
3208     break;
3209   case PEER_STATE_KEY_RECEIVED:
3210     break;
3211   case PEER_STATE_KEY_CONFIRMED:
3212     break;
3213   default:
3214     GNUNET_break (0);
3215     break;
3216   }
3217
3218
3219   /* first, set key message */
3220   me = GNUNET_malloc (sizeof (struct MessageEntry) +
3221                       sizeof (struct SetKeyMessage) +
3222                       sizeof (struct PingMessage));
3223   me->deadline = GNUNET_TIME_relative_to_absolute (MAX_SET_KEY_DELAY);
3224   me->priority = SET_KEY_PRIORITY;
3225   me->size = sizeof (struct SetKeyMessage) + sizeof (struct PingMessage);
3226   me->is_setkey = GNUNET_YES;
3227   me->got_slack = GNUNET_YES;   /* do not defer this one! */
3228   me->sender_status = n->status;
3229   GNUNET_CONTAINER_DLL_insert_after (n->encrypted_head, n->encrypted_tail,
3230                                      n->encrypted_tail, me);
3231   sm = (struct SetKeyMessage *) &me[1];
3232   sm->header.size = htons (sizeof (struct SetKeyMessage));
3233   sm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_SET_KEY);
3234   sm->sender_status =
3235       htonl ((int32_t)
3236              ((n->status ==
3237                PEER_STATE_DOWN) ? PEER_STATE_KEY_SENT : n->status));
3238   sm->purpose.size =
3239       htonl (sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) +
3240              sizeof (struct GNUNET_TIME_AbsoluteNBO) +
3241              sizeof (struct GNUNET_CRYPTO_RsaEncryptedData) +
3242              sizeof (struct GNUNET_PeerIdentity));
3243   sm->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_SET_KEY);
3244   sm->creation_time = GNUNET_TIME_absolute_hton (n->encrypt_key_created);
3245   sm->target = n->peer;
3246   GNUNET_assert (GNUNET_OK ==
3247                  GNUNET_CRYPTO_rsa_encrypt (&n->encrypt_key,
3248                                             sizeof (struct
3249                                                     GNUNET_CRYPTO_AesSessionKey),
3250                                             n->public_key, &sm->encrypted_key));
3251   GNUNET_assert (GNUNET_OK ==
3252                  GNUNET_CRYPTO_rsa_sign (my_private_key, &sm->purpose,
3253                                          &sm->signature));
3254   pm = (struct PingMessage *) &sm[1];
3255   pm->header.size = htons (sizeof (struct PingMessage));
3256   pm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_PING);
3257   pm->iv_seed =
3258       GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, UINT32_MAX);
3259   derive_iv (&iv, &n->encrypt_key, pm->iv_seed, &n->peer);
3260   pp.challenge = n->ping_challenge;
3261   pp.target = n->peer;
3262 #if DEBUG_HANDSHAKE
3263   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3264               "Encrypting `%s' and `%s' messages with challenge %u for `%4s' using key %u, IV %u (salt %u).\n",
3265               "SET_KEY", "PING", (unsigned int) n->ping_challenge,
3266               GNUNET_i2s (&n->peer), (unsigned int) n->encrypt_key.crc32,
3267               GNUNET_CRYPTO_crc32_n (&iv, sizeof (iv)), pm->iv_seed);
3268 #endif
3269   do_encrypt (n, &iv, &pp.target, &pm->target,
3270               sizeof (struct PingMessage) - ((void *) &pm->target -
3271                                              (void *) pm));
3272   GNUNET_STATISTICS_update (stats,
3273                             gettext_noop
3274                             ("# SET_KEY and PING messages created"), 1,
3275                             GNUNET_NO);
3276 #if DEBUG_CORE
3277   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3278               "Have %llu ms left for `%s' transmission.\n",
3279               (unsigned long long)
3280               GNUNET_TIME_absolute_get_remaining (me->deadline).rel_value,
3281               "SET_KEY");
3282 #endif
3283 trigger_processing:
3284   /* trigger queue processing */
3285   process_encrypted_neighbour_queue (n);
3286   if ((n->status != PEER_STATE_KEY_CONFIRMED) &&
3287       (GNUNET_SCHEDULER_NO_TASK == n->retry_set_key_task))
3288     n->retry_set_key_task =
3289         GNUNET_SCHEDULER_add_delayed (n->set_key_retry_frequency,
3290                                       &set_key_retry_task, n);
3291 }
3292
3293
3294 /**
3295  * We received a SET_KEY message.  Validate and update
3296  * our key material and status.
3297  *
3298  * @param n the neighbour from which we received message m
3299  * @param m the set key message we received
3300  * @param ats performance data
3301  * @param ats_count number of entries in ats (excluding 0-termination)
3302  */
3303 static void
3304 handle_set_key (struct Neighbour *n, const struct SetKeyMessage *m,
3305                 const struct GNUNET_TRANSPORT_ATS_Information *ats,
3306                 uint32_t ats_count);
3307
3308
3309
3310 /**
3311  * PEERINFO is giving us a HELLO for a peer.  Add the public key to
3312  * the neighbour's struct and retry handling the set_key message.  Or,
3313  * if we did not get a HELLO, just free the set key message.
3314  *
3315  * @param cls pointer to the set key message
3316  * @param peer the peer for which this is the HELLO
3317  * @param hello HELLO message of that peer
3318  * @param err_msg NULL if successful, otherwise contains error message
3319  */
3320 static void
3321 process_hello_retry_handle_set_key (void *cls,
3322                                     const struct GNUNET_PeerIdentity *peer,
3323                                     const struct GNUNET_HELLO_Message *hello,
3324                                     const char *err_msg)
3325 {
3326   struct Neighbour *n = cls;
3327   struct SetKeyMessage *sm = n->skm;
3328
3329   if (err_msg != NULL)
3330   {
3331     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3332                 _("Error in communication with PEERINFO service\n"));
3333     /* return; */
3334   }
3335
3336   if (peer == NULL)
3337   {
3338     n->skm = NULL;
3339     n->pitr = NULL;
3340     if (n->public_key != NULL)
3341     {
3342 #if DEBUG_CORE
3343       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3344                   "Received `%s' for `%4s', continuing processing of `%s' message.\n",
3345                   "HELLO", GNUNET_i2s (&n->peer), "SET_KEY");
3346 #endif
3347       handle_set_key (n, sm, NULL, 0);
3348     }
3349     else
3350     {
3351       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3352                   _
3353                   ("Ignoring `%s' message due to lack of public key for peer `%4s' (failed to obtain one).\n"),
3354                   "SET_KEY", GNUNET_i2s (&n->peer));
3355     }
3356     GNUNET_free (sm);
3357     return;
3358   }
3359   if (n->public_key != NULL)
3360     return;                     /* multiple HELLOs match!? */
3361   n->public_key =
3362       GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded));
3363   if (GNUNET_OK != GNUNET_HELLO_get_key (hello, n->public_key))
3364   {
3365     GNUNET_break_op (0);
3366     GNUNET_free (n->public_key);
3367     n->public_key = NULL;
3368   }
3369 }
3370
3371
3372 /**
3373  * Merge the given performance data with the data we currently
3374  * track for the given neighbour.
3375  *
3376  * @param n neighbour
3377  * @param ats new performance data
3378  * @param ats_count number of records in ats
3379  */
3380 static void
3381 update_neighbour_performance (struct Neighbour *n,
3382                               const struct GNUNET_TRANSPORT_ATS_Information
3383                               *ats, uint32_t ats_count)
3384 {
3385   uint32_t i;
3386   unsigned int j;
3387
3388   if (ats_count == 0)
3389     return;
3390   for (i = 0; i < ats_count; i++)
3391   {
3392     for (j = 0; j < n->ats_count; j++)
3393     {
3394       if (n->ats[j].type == ats[i].type)
3395       {
3396         n->ats[j].value = ats[i].value;
3397         break;
3398       }
3399     }
3400     if (j == n->ats_count)
3401     {
3402       GNUNET_array_append (n->ats, n->ats_count, ats[i]);
3403     }
3404   }
3405 }
3406
3407
3408 /**
3409  * We received a PING message.  Validate and transmit
3410  * PONG.
3411  *
3412  * @param n sender of the PING
3413  * @param m the encrypted PING message itself
3414  * @param ats performance data
3415  * @param ats_count number of entries in ats (excluding 0-termination)
3416  */
3417 static void
3418 handle_ping (struct Neighbour *n, const struct PingMessage *m,
3419              const struct GNUNET_TRANSPORT_ATS_Information *ats,
3420              uint32_t ats_count)
3421 {
3422   struct PingMessage t;
3423   struct PongMessage tx;
3424   struct PongMessage *tp;
3425   struct MessageEntry *me;
3426   struct GNUNET_CRYPTO_AesInitializationVector iv;
3427
3428 #if DEBUG_CORE
3429   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3430               "Core service receives `%s' request from `%4s'.\n", "PING",
3431               GNUNET_i2s (&n->peer));
3432 #endif
3433   derive_iv (&iv, &n->decrypt_key, m->iv_seed, &my_identity);
3434   if (GNUNET_OK !=
3435       do_decrypt (n, &iv, &m->target, &t.target,
3436                   sizeof (struct PingMessage) - ((void *) &m->target -
3437                                                  (void *) m)))
3438     return;
3439 #if DEBUG_HANDSHAKE
3440   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3441               "Decrypted `%s' to `%4s' with challenge %u decrypted using key %u, IV %u (salt %u)\n",
3442               "PING", GNUNET_i2s (&t.target), (unsigned int) t.challenge,
3443               (unsigned int) n->decrypt_key.crc32, GNUNET_CRYPTO_crc32_n (&iv,
3444                                                                           sizeof
3445                                                                           (iv)),
3446               m->iv_seed);
3447 #endif
3448   GNUNET_STATISTICS_update (stats, gettext_noop ("# PING messages decrypted"),
3449                             1, GNUNET_NO);
3450   if (0 !=
3451       memcmp (&t.target, &my_identity, sizeof (struct GNUNET_PeerIdentity)))
3452   {
3453     char sender[9];
3454     char peer[9];
3455
3456     GNUNET_snprintf (sender, sizeof (sender), "%8s", GNUNET_i2s (&n->peer));
3457     GNUNET_snprintf (peer, sizeof (peer), "%8s", GNUNET_i2s (&t.target));
3458     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3459                 _
3460                 ("Received PING from `%s' for different identity: I am `%s', PONG identity: `%s'\n"),
3461                 sender, GNUNET_i2s (&my_identity), peer);
3462     GNUNET_break_op (0);
3463     return;
3464   }
3465   update_neighbour_performance (n, ats, ats_count);
3466   me = GNUNET_malloc (sizeof (struct MessageEntry) +
3467                       sizeof (struct PongMessage));
3468   GNUNET_CONTAINER_DLL_insert_after (n->encrypted_head, n->encrypted_tail,
3469                                      n->encrypted_tail, me);
3470   me->deadline = GNUNET_TIME_relative_to_absolute (MAX_PONG_DELAY);
3471   me->priority = PONG_PRIORITY;
3472   me->size = sizeof (struct PongMessage);
3473   tx.inbound_bw_limit = n->bw_in;
3474   tx.challenge = t.challenge;
3475   tx.target = t.target;
3476   tp = (struct PongMessage *) &me[1];
3477   tp->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_PONG);
3478   tp->header.size = htons (sizeof (struct PongMessage));
3479   tp->iv_seed =
3480       GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, UINT32_MAX);
3481   derive_pong_iv (&iv, &n->encrypt_key, tp->iv_seed, t.challenge, &n->peer);
3482   do_encrypt (n, &iv, &tx.challenge, &tp->challenge,
3483               sizeof (struct PongMessage) - ((void *) &tp->challenge -
3484                                              (void *) tp));
3485   GNUNET_STATISTICS_update (stats, gettext_noop ("# PONG messages created"), 1,
3486                             GNUNET_NO);
3487 #if DEBUG_HANDSHAKE
3488   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3489               "Encrypting `%s' with challenge %u using key %u, IV %u (salt %u)\n",
3490               "PONG", (unsigned int) t.challenge,
3491               (unsigned int) n->encrypt_key.crc32, GNUNET_CRYPTO_crc32_n (&iv,
3492                                                                           sizeof
3493                                                                           (iv)),
3494               tp->iv_seed);
3495 #endif
3496   /* trigger queue processing */
3497   process_encrypted_neighbour_queue (n);
3498 }
3499
3500
3501 /**
3502  * We received a PONG message.  Validate and update our status.
3503  *
3504  * @param n sender of the PONG
3505  * @param m the encrypted PONG message itself
3506  * @param ats performance data
3507  * @param ats_count number of entries in ats (excluding 0-termination)
3508  */
3509 static void
3510 handle_pong (struct Neighbour *n, const struct PongMessage *m,
3511              const struct GNUNET_TRANSPORT_ATS_Information *ats,
3512              uint32_t ats_count)
3513 {
3514   struct PongMessage t;
3515   struct ConnectNotifyMessage *cnm;
3516   struct GNUNET_CRYPTO_AesInitializationVector iv;
3517   char buf[GNUNET_SERVER_MAX_MESSAGE_SIZE - 1];
3518   struct GNUNET_TRANSPORT_ATS_Information *mats;
3519   size_t size;
3520
3521 #if DEBUG_HANDSHAKE
3522   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3523               "Core service receives `%s' response from `%4s'.\n", "PONG",
3524               GNUNET_i2s (&n->peer));
3525 #endif
3526   /* mark as garbage, just to be sure */
3527   memset (&t, 255, sizeof (t));
3528   derive_pong_iv (&iv, &n->decrypt_key, m->iv_seed, n->ping_challenge,
3529                   &my_identity);
3530   if (GNUNET_OK !=
3531       do_decrypt (n, &iv, &m->challenge, &t.challenge,
3532                   sizeof (struct PongMessage) - ((void *) &m->challenge -
3533                                                  (void *) m)))
3534   {
3535     GNUNET_break_op (0);
3536     return;
3537   }
3538   GNUNET_STATISTICS_update (stats, gettext_noop ("# PONG messages decrypted"),
3539                             1, GNUNET_NO);
3540 #if DEBUG_HANDSHAKE
3541   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3542               "Decrypted `%s' from `%4s' with challenge %u using key %u, IV %u (salt %u)\n",
3543               "PONG", GNUNET_i2s (&t.target), (unsigned int) t.challenge,
3544               (unsigned int) n->decrypt_key.crc32, GNUNET_CRYPTO_crc32_n (&iv,
3545                                                                           sizeof
3546                                                                           (iv)),
3547               m->iv_seed);
3548 #endif
3549   if ((0 != memcmp (&t.target, &n->peer, sizeof (struct GNUNET_PeerIdentity)))
3550       || (n->ping_challenge != t.challenge))
3551   {
3552     /* PONG malformed */
3553 #if DEBUG_CORE
3554     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3555                 "Received malformed `%s' wanted sender `%4s' with challenge %u\n",
3556                 "PONG", GNUNET_i2s (&n->peer),
3557                 (unsigned int) n->ping_challenge);
3558     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3559                 "Received malformed `%s' received from `%4s' with challenge %u\n",
3560                 "PONG", GNUNET_i2s (&t.target), (unsigned int) t.challenge);
3561 #endif
3562     GNUNET_break_op (n->ping_challenge != t.challenge);
3563     return;
3564   }
3565   switch (n->status)
3566   {
3567   case PEER_STATE_DOWN:
3568     GNUNET_break (0);           /* should be impossible */
3569     return;
3570   case PEER_STATE_KEY_SENT:
3571     GNUNET_break (0);           /* should be impossible, how did we decrypt? */
3572     return;
3573   case PEER_STATE_KEY_RECEIVED:
3574     GNUNET_STATISTICS_update (stats,
3575                               gettext_noop
3576                               ("# Session keys confirmed via PONG"), 1,
3577                               GNUNET_NO);
3578     n->status = PEER_STATE_KEY_CONFIRMED;
3579     {
3580       struct GNUNET_MessageHeader *hdr;
3581
3582       hdr = compute_type_map_message ();
3583       send_type_map_to_neighbour (hdr, &n->peer.hashPubKey, n);
3584       GNUNET_free (hdr);
3585     }
3586     if (n->bw_out_external_limit.value__ != t.inbound_bw_limit.value__)
3587     {
3588       n->bw_out_external_limit = t.inbound_bw_limit;
3589       n->bw_out =
3590           GNUNET_BANDWIDTH_value_min (n->bw_out_external_limit,
3591                                       n->bw_out_internal_limit);
3592       GNUNET_BANDWIDTH_tracker_update_quota (&n->available_send_window,
3593                                              n->bw_out);
3594       GNUNET_TRANSPORT_set_quota (transport, &n->peer, n->bw_in, n->bw_out);
3595     }
3596 #if DEBUG_CORE
3597     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3598                 "Confirmed key via `%s' message for peer `%4s'\n", "PONG",
3599                 GNUNET_i2s (&n->peer));
3600 #endif
3601     if (n->retry_set_key_task != GNUNET_SCHEDULER_NO_TASK)
3602     {
3603       GNUNET_SCHEDULER_cancel (n->retry_set_key_task);
3604       n->retry_set_key_task = GNUNET_SCHEDULER_NO_TASK;
3605     }
3606     update_neighbour_performance (n, ats, ats_count);
3607     size =
3608         sizeof (struct ConnectNotifyMessage) +
3609         (n->ats_count) * sizeof (struct GNUNET_TRANSPORT_ATS_Information);
3610     if (size >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
3611     {
3612       GNUNET_break (0);
3613       /* recovery strategy: throw away performance data */
3614       GNUNET_array_grow (n->ats, n->ats_count, 0);
3615       size =
3616           sizeof (struct PeerStatusNotifyMessage) +
3617           n->ats_count * sizeof (struct GNUNET_TRANSPORT_ATS_Information);
3618     }
3619     cnm = (struct ConnectNotifyMessage *) buf;
3620     cnm->header.size = htons (size);
3621     cnm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT);
3622     cnm->ats_count = htonl (n->ats_count);
3623     cnm->peer = n->peer;
3624     mats = &cnm->ats;
3625     memcpy (mats, n->ats,
3626             n->ats_count * sizeof (struct GNUNET_TRANSPORT_ATS_Information));
3627     mats[n->ats_count].type = htonl (GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR);
3628     mats[n->ats_count].value = htonl (0);
3629     send_to_all_clients (&cnm->header, GNUNET_NO,
3630                          GNUNET_CORE_OPTION_SEND_CONNECT);
3631     process_encrypted_neighbour_queue (n);
3632     /* fall-through! */
3633   case PEER_STATE_KEY_CONFIRMED:
3634     n->last_activity = GNUNET_TIME_absolute_get ();
3635     if (n->keep_alive_task != GNUNET_SCHEDULER_NO_TASK)
3636       GNUNET_SCHEDULER_cancel (n->keep_alive_task);
3637     n->keep_alive_task =
3638         GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_divide
3639                                       (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
3640                                        2), &send_keep_alive, n);
3641     handle_peer_status_change (n);
3642     break;
3643   default:
3644     GNUNET_break (0);
3645     break;
3646   }
3647 }
3648
3649
3650 /**
3651  * We received a SET_KEY message.  Validate and update
3652  * our key material and status.
3653  *
3654  * @param n the neighbour from which we received message m
3655  * @param m the set key message we received
3656  * @param ats performance data
3657  * @param ats_count number of entries in ats (excluding 0-termination)
3658  */
3659 static void
3660 handle_set_key (struct Neighbour *n, const struct SetKeyMessage *m,
3661                 const struct GNUNET_TRANSPORT_ATS_Information *ats,
3662                 uint32_t ats_count)
3663 {
3664   struct SetKeyMessage *m_cpy;
3665   struct GNUNET_TIME_Absolute t;
3666   struct GNUNET_CRYPTO_AesSessionKey k;
3667   struct PingMessage *ping;
3668   struct PongMessage *pong;
3669   enum PeerStateMachine sender_status;
3670
3671 #if DEBUG_CORE
3672   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3673               "Core service receives `%s' request from `%4s'.\n", "SET_KEY",
3674               GNUNET_i2s (&n->peer));
3675 #endif
3676   if (n->public_key == NULL)
3677   {
3678     if (n->pitr != NULL)
3679     {
3680 #if DEBUG_CORE
3681       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3682                   "Ignoring `%s' message due to lack of public key for peer (still trying to obtain one).\n",
3683                   "SET_KEY");
3684 #endif
3685       return;
3686     }
3687 #if DEBUG_CORE
3688     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3689                 "Lacking public key for peer, trying to obtain one (handle_set_key).\n");
3690 #endif
3691     m_cpy = GNUNET_malloc (sizeof (struct SetKeyMessage));
3692     memcpy (m_cpy, m, sizeof (struct SetKeyMessage));
3693     /* lookup n's public key, then try again */
3694     GNUNET_assert (n->skm == NULL);
3695     n->skm = m_cpy;
3696     n->pitr =
3697         GNUNET_PEERINFO_iterate (peerinfo, &n->peer, GNUNET_TIME_UNIT_MINUTES,
3698                                  &process_hello_retry_handle_set_key, n);
3699     GNUNET_STATISTICS_update (stats,
3700                               gettext_noop
3701                               ("# SET_KEY messages deferred (need public key)"),
3702                               1, GNUNET_NO);
3703     return;
3704   }
3705   if (0 !=
3706       memcmp (&m->target, &my_identity, sizeof (struct GNUNET_PeerIdentity)))
3707   {
3708     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3709                 _
3710                 ("Received `%s' message that was for `%s', not for me.  Ignoring.\n"),
3711                 "SET_KEY", GNUNET_i2s (&m->target));
3712     return;
3713   }
3714   if ((ntohl (m->purpose.size) !=
3715        sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) +
3716        sizeof (struct GNUNET_TIME_AbsoluteNBO) +
3717        sizeof (struct GNUNET_CRYPTO_RsaEncryptedData) +
3718        sizeof (struct GNUNET_PeerIdentity)) ||
3719       (GNUNET_OK !=
3720        GNUNET_CRYPTO_rsa_verify (GNUNET_SIGNATURE_PURPOSE_SET_KEY, &m->purpose,
3721                                  &m->signature, n->public_key)))
3722   {
3723     /* invalid signature */
3724     GNUNET_break_op (0);
3725     return;
3726   }
3727   t = GNUNET_TIME_absolute_ntoh (m->creation_time);
3728   if (((n->status == PEER_STATE_KEY_RECEIVED) ||
3729        (n->status == PEER_STATE_KEY_CONFIRMED)) &&
3730       (t.abs_value < n->decrypt_key_created.abs_value))
3731   {
3732     /* this could rarely happen due to massive re-ordering of
3733      * messages on the network level, but is most likely either
3734      * a bug or some adversary messing with us.  Report. */
3735     GNUNET_break_op (0);
3736     return;
3737   }
3738 #if DEBUG_CORE
3739   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Decrypting key material.\n");
3740 #endif
3741   if ((GNUNET_CRYPTO_rsa_decrypt
3742        (my_private_key, &m->encrypted_key, &k,
3743         sizeof (struct GNUNET_CRYPTO_AesSessionKey)) !=
3744        sizeof (struct GNUNET_CRYPTO_AesSessionKey)) ||
3745       (GNUNET_OK != GNUNET_CRYPTO_aes_check_session_key (&k)))
3746   {
3747     /* failed to decrypt !? */
3748     GNUNET_break_op (0);
3749     return;
3750   }
3751   GNUNET_STATISTICS_update (stats,
3752                             gettext_noop ("# SET_KEY messages decrypted"), 1,
3753                             GNUNET_NO);
3754   n->decrypt_key = k;
3755   if (n->decrypt_key_created.abs_value != t.abs_value)
3756   {
3757     /* fresh key, reset sequence numbers */
3758     n->last_sequence_number_received = 0;
3759     n->last_packets_bitmap = 0;
3760     n->decrypt_key_created = t;
3761   }
3762   update_neighbour_performance (n, ats, ats_count);
3763   sender_status = (enum PeerStateMachine) ntohl (m->sender_status);
3764   switch (n->status)
3765   {
3766   case PEER_STATE_DOWN:
3767     n->status = PEER_STATE_KEY_RECEIVED;
3768 #if DEBUG_CORE
3769     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3770                 "Responding to `%s' with my own key.\n", "SET_KEY");
3771 #endif
3772     send_key (n);
3773     break;
3774   case PEER_STATE_KEY_SENT:
3775   case PEER_STATE_KEY_RECEIVED:
3776     n->status = PEER_STATE_KEY_RECEIVED;
3777     if ((sender_status != PEER_STATE_KEY_RECEIVED) &&
3778         (sender_status != PEER_STATE_KEY_CONFIRMED))
3779     {
3780 #if DEBUG_CORE
3781       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3782                   "Responding to `%s' with my own key (other peer has status %u).\n",
3783                   "SET_KEY", (unsigned int) sender_status);
3784 #endif
3785       send_key (n);
3786     }
3787     break;
3788   case PEER_STATE_KEY_CONFIRMED:
3789     if ((sender_status != PEER_STATE_KEY_RECEIVED) &&
3790         (sender_status != PEER_STATE_KEY_CONFIRMED))
3791     {
3792 #if DEBUG_CORE
3793       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3794                   "Responding to `%s' with my own key (other peer has status %u), I was already fully up.\n",
3795                   "SET_KEY", (unsigned int) sender_status);
3796 #endif
3797       send_key (n);
3798     }
3799     break;
3800   default:
3801     GNUNET_break (0);
3802     break;
3803   }
3804   if (n->pending_ping != NULL)
3805   {
3806     ping = n->pending_ping;
3807     n->pending_ping = NULL;
3808     handle_ping (n, ping, NULL, 0);
3809     GNUNET_free (ping);
3810   }
3811   if (n->pending_pong != NULL)
3812   {
3813     pong = n->pending_pong;
3814     n->pending_pong = NULL;
3815     handle_pong (n, pong, NULL, 0);
3816     GNUNET_free (pong);
3817   }
3818 }
3819
3820
3821 /**
3822  * Send a P2P message to a client.
3823  *
3824  * @param sender who sent us the message?
3825  * @param client who should we give the message to?
3826  * @param m contains the message to transmit
3827  * @param msize number of bytes in buf to transmit
3828  */
3829 static void
3830 send_p2p_message_to_client (struct Neighbour *sender, struct Client *client,
3831                             const void *m, size_t msize)
3832 {
3833   size_t size =
3834       msize + sizeof (struct NotifyTrafficMessage) +
3835       (sender->ats_count) * sizeof (struct GNUNET_TRANSPORT_ATS_Information);
3836   char buf[size];
3837   struct NotifyTrafficMessage *ntm;
3838   struct GNUNET_TRANSPORT_ATS_Information *ats;
3839
3840   GNUNET_assert (GNUNET_YES == sender->is_connected);
3841   if (size >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
3842   {
3843     GNUNET_break (0);
3844     /* recovery strategy: throw performance data away... */
3845     GNUNET_array_grow (sender->ats, sender->ats_count, 0);
3846     size =
3847         msize + sizeof (struct NotifyTrafficMessage) +
3848         (sender->ats_count) * sizeof (struct GNUNET_TRANSPORT_ATS_Information);
3849   }
3850 #if DEBUG_CORE
3851   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3852               "Core service passes message from `%4s' of type %u to client.\n",
3853               GNUNET_i2s (&sender->peer),
3854               (unsigned int)
3855               ntohs (((const struct GNUNET_MessageHeader *) m)->type));
3856 #endif
3857   ntm = (struct NotifyTrafficMessage *) buf;
3858   ntm->header.size = htons (size);
3859   ntm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_INBOUND);
3860   ntm->ats_count = htonl (sender->ats_count);
3861   ntm->peer = sender->peer;
3862   ats = &ntm->ats;
3863   memcpy (ats, sender->ats,
3864           sizeof (struct GNUNET_TRANSPORT_ATS_Information) * sender->ats_count);
3865   ats[sender->ats_count].type = htonl (GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR);
3866   ats[sender->ats_count].value = htonl (0);
3867   memcpy (&ats[sender->ats_count + 1], m, msize);
3868   send_to_client (client, &ntm->header, GNUNET_YES);
3869 }
3870
3871
3872 /**
3873  * Deliver P2P message to interested clients.
3874  *
3875  * @param cls always NULL
3876  * @param client who sent us the message (struct Neighbour)
3877  * @param m the message
3878  */
3879 static void
3880 deliver_message (void *cls, void *client, const struct GNUNET_MessageHeader *m)
3881 {
3882   struct Neighbour *sender = client;
3883   size_t msize = ntohs (m->size);
3884   char buf[256];
3885   struct Client *cpos;
3886   uint16_t type;
3887   unsigned int tpos;
3888   int deliver_full;
3889   int dropped;
3890
3891   type = ntohs (m->type);
3892 #if DEBUG_CORE > 1
3893   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3894               "Received encapsulated message of type %u and size %u from `%4s'\n",
3895               (unsigned int) type, ntohs (m->size), GNUNET_i2s (&sender->peer));
3896 #endif
3897   GNUNET_snprintf (buf, sizeof (buf),
3898                    gettext_noop ("# bytes of messages of type %u received"),
3899                    (unsigned int) type);
3900   GNUNET_STATISTICS_update (stats, buf, msize, GNUNET_NO);
3901   if ((GNUNET_MESSAGE_TYPE_CORE_BINARY_TYPE_MAP == type) ||
3902       (GNUNET_MESSAGE_TYPE_CORE_COMPRESSED_TYPE_MAP == type))
3903   {
3904     /* FIXME: update message type map for 'Neighbour' */
3905     return;
3906   }
3907   dropped = GNUNET_YES;
3908   cpos = clients;
3909   while (cpos != NULL)
3910   {
3911     deliver_full = GNUNET_NO;
3912     if (0 != (cpos->options & GNUNET_CORE_OPTION_SEND_FULL_INBOUND))
3913       deliver_full = GNUNET_YES;
3914     else
3915     {
3916       for (tpos = 0; tpos < cpos->tcnt; tpos++)
3917       {
3918         if (type != cpos->types[tpos])
3919           continue;
3920         deliver_full = GNUNET_YES;
3921         break;
3922       }
3923     }
3924     if (GNUNET_YES == deliver_full)
3925     {
3926       send_p2p_message_to_client (sender, cpos, m, msize);
3927       dropped = GNUNET_NO;
3928     }
3929     else if (cpos->options & GNUNET_CORE_OPTION_SEND_HDR_INBOUND)
3930     {
3931       send_p2p_message_to_client (sender, cpos, m,
3932                                   sizeof (struct GNUNET_MessageHeader));
3933     }
3934     cpos = cpos->next;
3935   }
3936   if (dropped == GNUNET_YES)
3937   {
3938 #if DEBUG_CORE
3939     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3940                 "Message of type %u from `%4s' not delivered to any client.\n",
3941                 (unsigned int) type, GNUNET_i2s (&sender->peer));
3942 #endif
3943     GNUNET_STATISTICS_update (stats,
3944                               gettext_noop
3945                               ("# messages not delivered to any client"), 1,
3946                               GNUNET_NO);
3947   }
3948 }
3949
3950
3951 /**
3952  * We received an encrypted message.  Decrypt, validate and
3953  * pass on to the appropriate clients.
3954  *
3955  * @param n target of the message
3956  * @param m encrypted message
3957  * @param ats performance data
3958  * @param ats_count number of entries in ats (excluding 0-termination)
3959  */
3960 static void
3961 handle_encrypted_message (struct Neighbour *n, const struct EncryptedMessage *m,
3962                           const struct GNUNET_TRANSPORT_ATS_Information *ats,
3963                           uint32_t ats_count)
3964 {
3965   size_t size = ntohs (m->header.size);
3966   char buf[size];
3967   struct EncryptedMessage *pt;  /* plaintext */
3968   GNUNET_HashCode ph;
3969   uint32_t snum;
3970   struct GNUNET_TIME_Absolute t;
3971   struct GNUNET_CRYPTO_AesInitializationVector iv;
3972   struct GNUNET_CRYPTO_AuthKey auth_key;
3973
3974 #if DEBUG_CORE
3975   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3976               "Core service receives `%s' request from `%4s'.\n",
3977               "ENCRYPTED_MESSAGE", GNUNET_i2s (&n->peer));
3978 #endif
3979   /* validate hash */
3980   derive_auth_key (&auth_key, &n->decrypt_key, m->iv_seed,
3981                    n->decrypt_key_created);
3982   GNUNET_CRYPTO_hmac (&auth_key, &m->sequence_number,
3983                       size - ENCRYPTED_HEADER_SIZE, &ph);
3984 #if DEBUG_HANDSHAKE
3985   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3986               "Re-Authenticated %u bytes of ciphertext (`%u'): `%s'\n",
3987               (unsigned int) size - ENCRYPTED_HEADER_SIZE,
3988               GNUNET_CRYPTO_crc32_n (&m->sequence_number,
3989                                      size - ENCRYPTED_HEADER_SIZE),
3990               GNUNET_h2s (&ph));
3991 #endif
3992
3993   if (0 != memcmp (&ph, &m->hmac, sizeof (GNUNET_HashCode)))
3994   {
3995     /* checksum failed */
3996     GNUNET_break_op (0);
3997     return;
3998   }
3999   derive_iv (&iv, &n->decrypt_key, m->iv_seed, &my_identity);
4000   /* decrypt */
4001   if (GNUNET_OK !=
4002       do_decrypt (n, &iv, &m->sequence_number, &buf[ENCRYPTED_HEADER_SIZE],
4003                   size - ENCRYPTED_HEADER_SIZE))
4004     return;
4005   pt = (struct EncryptedMessage *) buf;
4006
4007   /* validate sequence number */
4008   snum = ntohl (pt->sequence_number);
4009   if (n->last_sequence_number_received == snum)
4010   {
4011     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
4012                 "Received duplicate message, ignoring.\n");
4013     /* duplicate, ignore */
4014     GNUNET_STATISTICS_update (stats,
4015                               gettext_noop ("# bytes dropped (duplicates)"),
4016                               size, GNUNET_NO);
4017     return;
4018   }
4019   if ((n->last_sequence_number_received > snum) &&
4020       (n->last_sequence_number_received - snum > 32))
4021   {
4022     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
4023                 "Received ancient out of sequence message, ignoring.\n");
4024     /* ancient out of sequence, ignore */
4025     GNUNET_STATISTICS_update (stats,
4026                               gettext_noop
4027                               ("# bytes dropped (out of sequence)"), size,
4028                               GNUNET_NO);
4029     return;
4030   }
4031   if (n->last_sequence_number_received > snum)
4032   {
4033     unsigned int rotbit = 1 << (n->last_sequence_number_received - snum - 1);
4034
4035     if ((n->last_packets_bitmap & rotbit) != 0)
4036     {
4037       GNUNET_log (GNUNET_ERROR_TYPE_INFO,
4038                   "Received duplicate message, ignoring.\n");
4039       GNUNET_STATISTICS_update (stats,
4040                                 gettext_noop ("# bytes dropped (duplicates)"),
4041                                 size, GNUNET_NO);
4042       /* duplicate, ignore */
4043       return;
4044     }
4045     n->last_packets_bitmap |= rotbit;
4046   }
4047   if (n->last_sequence_number_received < snum)
4048   {
4049     int shift = (snum - n->last_sequence_number_received);
4050
4051     if (shift >= 8 * sizeof (n->last_packets_bitmap))
4052       n->last_packets_bitmap = 0;
4053     else
4054       n->last_packets_bitmap <<= shift;
4055     n->last_sequence_number_received = snum;
4056   }
4057
4058   /* check timestamp */
4059   t = GNUNET_TIME_absolute_ntoh (pt->timestamp);
4060   if (GNUNET_TIME_absolute_get_duration (t).rel_value >
4061       MAX_MESSAGE_AGE.rel_value)
4062   {
4063     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
4064                 _("Message received far too old (%llu ms). Content ignored.\n"),
4065                 GNUNET_TIME_absolute_get_duration (t).rel_value);
4066     GNUNET_STATISTICS_update (stats,
4067                               gettext_noop
4068                               ("# bytes dropped (ancient message)"), size,
4069                               GNUNET_NO);
4070     return;
4071   }
4072
4073   /* process decrypted message(s) */
4074   if (n->bw_out_external_limit.value__ != pt->inbound_bw_limit.value__)
4075   {
4076 #if DEBUG_CORE_SET_QUOTA
4077     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4078                 "Received %u b/s as new inbound limit for peer `%4s'\n",
4079                 (unsigned int) ntohl (pt->inbound_bw_limit.value__),
4080                 GNUNET_i2s (&n->peer));
4081 #endif
4082     n->bw_out_external_limit = pt->inbound_bw_limit;
4083     n->bw_out =
4084         GNUNET_BANDWIDTH_value_min (n->bw_out_external_limit,
4085                                     n->bw_out_internal_limit);
4086     GNUNET_BANDWIDTH_tracker_update_quota (&n->available_send_window,
4087                                            n->bw_out);
4088     GNUNET_TRANSPORT_set_quota (transport, &n->peer, n->bw_in, n->bw_out);
4089   }
4090   n->last_activity = GNUNET_TIME_absolute_get ();
4091   if (n->keep_alive_task != GNUNET_SCHEDULER_NO_TASK)
4092     GNUNET_SCHEDULER_cancel (n->keep_alive_task);
4093   n->keep_alive_task =
4094       GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_divide
4095                                     (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
4096                                      2), &send_keep_alive, n);
4097   GNUNET_STATISTICS_update (stats,
4098                             gettext_noop ("# bytes of payload decrypted"),
4099                             size - sizeof (struct EncryptedMessage), GNUNET_NO);
4100   handle_peer_status_change (n);
4101   update_neighbour_performance (n, ats, ats_count);
4102   if (GNUNET_OK !=
4103       GNUNET_SERVER_mst_receive (mst, n, &buf[sizeof (struct EncryptedMessage)],
4104                                  size - sizeof (struct EncryptedMessage),
4105                                  GNUNET_YES, GNUNET_NO))
4106     GNUNET_break_op (0);
4107 }
4108
4109
4110 /**
4111  * Function called by the transport for each received message.
4112  *
4113  * @param cls closure
4114  * @param peer (claimed) identity of the other peer
4115  * @param message the message
4116  * @param ats performance data
4117  * @param ats_count number of entries in ats (excluding 0-termination)
4118  */
4119 static void
4120 handle_transport_receive (void *cls, const struct GNUNET_PeerIdentity *peer,
4121                           const struct GNUNET_MessageHeader *message,
4122                           const struct GNUNET_TRANSPORT_ATS_Information *ats,
4123                           uint32_t ats_count)
4124 {
4125   struct Neighbour *n;
4126   struct GNUNET_TIME_Absolute now;
4127   int up;
4128   uint16_t type;
4129   uint16_t size;
4130   int changed;
4131
4132 #if DEBUG_CORE > 1
4133   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4134               "Received message of type %u from `%4s', demultiplexing.\n",
4135               (unsigned int) ntohs (message->type), GNUNET_i2s (peer));
4136 #endif
4137   if (0 == memcmp (peer, &my_identity, sizeof (struct GNUNET_PeerIdentity)))
4138   {
4139     GNUNET_break (0);
4140     return;
4141   }
4142   n = find_neighbour (peer);
4143   if ((n == NULL) || (GNUNET_NO == n->is_connected))
4144   {
4145     /* received message from peer that is not connected!? */
4146     GNUNET_break (0);
4147     return;
4148   }
4149   changed = GNUNET_NO;
4150   up = (n->status == PEER_STATE_KEY_CONFIRMED);
4151   type = ntohs (message->type);
4152   size = ntohs (message->size);
4153   switch (type)
4154   {
4155   case GNUNET_MESSAGE_TYPE_CORE_SET_KEY:
4156     if (size != sizeof (struct SetKeyMessage))
4157     {
4158       GNUNET_break_op (0);
4159       return;
4160     }
4161     GNUNET_STATISTICS_update (stats, gettext_noop ("# session keys received"),
4162                               1, GNUNET_NO);
4163     handle_set_key (n, (const struct SetKeyMessage *) message, ats, ats_count);
4164     break;
4165   case GNUNET_MESSAGE_TYPE_CORE_ENCRYPTED_MESSAGE:
4166     if (size <
4167         sizeof (struct EncryptedMessage) + sizeof (struct GNUNET_MessageHeader))
4168     {
4169       GNUNET_break_op (0);
4170       return;
4171     }
4172     if ((n->status != PEER_STATE_KEY_RECEIVED) &&
4173         (n->status != PEER_STATE_KEY_CONFIRMED))
4174     {
4175       GNUNET_STATISTICS_update (stats,
4176                                 gettext_noop
4177                                 ("# failed to decrypt message (no session key)"),
4178                                 1, GNUNET_NO);
4179       send_key (n);
4180       return;
4181     }
4182     handle_encrypted_message (n, (const struct EncryptedMessage *) message, ats,
4183                               ats_count);
4184     break;
4185   case GNUNET_MESSAGE_TYPE_CORE_PING:
4186     if (size != sizeof (struct PingMessage))
4187     {
4188       GNUNET_break_op (0);
4189       return;
4190     }
4191     GNUNET_STATISTICS_update (stats, gettext_noop ("# PING messages received"),
4192                               1, GNUNET_NO);
4193     if ((n->status != PEER_STATE_KEY_RECEIVED) &&
4194         (n->status != PEER_STATE_KEY_CONFIRMED))
4195     {
4196 #if DEBUG_CORE > 1
4197       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4198                   "Core service receives `%s' request from `%4s' but have not processed key; marking as pending.\n",
4199                   "PING", GNUNET_i2s (&n->peer));
4200 #endif
4201       GNUNET_free_non_null (n->pending_ping);
4202       n->pending_ping = GNUNET_malloc (sizeof (struct PingMessage));
4203       memcpy (n->pending_ping, message, sizeof (struct PingMessage));
4204       return;
4205     }
4206     handle_ping (n, (const struct PingMessage *) message, ats, ats_count);
4207     break;
4208   case GNUNET_MESSAGE_TYPE_CORE_PONG:
4209     if (size != sizeof (struct PongMessage))
4210     {
4211       GNUNET_break_op (0);
4212       return;
4213     }
4214     GNUNET_STATISTICS_update (stats, gettext_noop ("# PONG messages received"),
4215                               1, GNUNET_NO);
4216     if ((n->status != PEER_STATE_KEY_RECEIVED) &&
4217         (n->status != PEER_STATE_KEY_CONFIRMED))
4218     {
4219 #if DEBUG_CORE > 1
4220       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4221                   "Core service receives `%s' request from `%4s' but have not processed key; marking as pending.\n",
4222                   "PONG", GNUNET_i2s (&n->peer));
4223 #endif
4224       GNUNET_free_non_null (n->pending_pong);
4225       n->pending_pong = GNUNET_malloc (sizeof (struct PongMessage));
4226       memcpy (n->pending_pong, message, sizeof (struct PongMessage));
4227       return;
4228     }
4229     handle_pong (n, (const struct PongMessage *) message, ats, ats_count);
4230     break;
4231   default:
4232     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
4233                 _("Unsupported message of type %u received.\n"),
4234                 (unsigned int) type);
4235     return;
4236   }
4237   if (n->status == PEER_STATE_KEY_CONFIRMED)
4238   {
4239     now = GNUNET_TIME_absolute_get ();
4240     n->last_activity = now;
4241     changed = GNUNET_YES;
4242     if (!up)
4243     {
4244       GNUNET_STATISTICS_update (stats, gettext_noop ("# established sessions"),
4245                                 1, GNUNET_NO);
4246       n->time_established = now;
4247     }
4248     if (n->keep_alive_task != GNUNET_SCHEDULER_NO_TASK)
4249       GNUNET_SCHEDULER_cancel (n->keep_alive_task);
4250     n->keep_alive_task =
4251         GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_divide
4252                                       (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
4253                                        2), &send_keep_alive, n);
4254   }
4255   if (changed)
4256     handle_peer_status_change (n);
4257 }
4258
4259
4260 /**
4261  * Function that recalculates the bandwidth quota for the
4262  * given neighbour and transmits it to the transport service.
4263  *
4264  * @param cls neighbour for the quota update
4265  * @param tc context
4266  */
4267 static void
4268 neighbour_quota_update (void *cls,
4269                         const struct GNUNET_SCHEDULER_TaskContext *tc)
4270 {
4271   struct Neighbour *n = cls;
4272   struct GNUNET_BANDWIDTH_Value32NBO q_in;
4273   struct GNUNET_BANDWIDTH_Value32NBO q_out;
4274   struct GNUNET_BANDWIDTH_Value32NBO q_out_min;
4275   double pref_rel;
4276   double share;
4277   unsigned long long distributable;
4278   uint64_t need_per_peer;
4279   uint64_t need_per_second;
4280   unsigned int neighbour_count;
4281
4282 #if DEBUG_CORE > 1
4283   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4284               "Neighbour quota update calculation running for peer `%4s'\n",
4285               GNUNET_i2s (&n->peer));
4286 #endif
4287   n->quota_update_task = GNUNET_SCHEDULER_NO_TASK;
4288   /* calculate relative preference among all neighbours;
4289    * divides by a bit more to avoid division by zero AND to
4290    * account for possibility of new neighbours joining any time
4291    * AND to convert to double... */
4292   neighbour_count = GNUNET_CONTAINER_multihashmap_size (neighbours);
4293   if (neighbour_count == 0)
4294     return;
4295   if (preference_sum == 0)
4296   {
4297     pref_rel = 1.0 / (double) neighbour_count;
4298   }
4299   else
4300   {
4301     pref_rel = (double) n->current_preference / preference_sum;
4302   }
4303   need_per_peer =
4304       GNUNET_BANDWIDTH_value_get_available_until (MIN_BANDWIDTH_PER_PEER,
4305                                                   GNUNET_TIME_UNIT_SECONDS);
4306   need_per_second = need_per_peer * neighbour_count;
4307
4308   /* calculate inbound bandwidth per peer */
4309   distributable = 0;
4310   if (bandwidth_target_in_bps > need_per_second)
4311     distributable = bandwidth_target_in_bps - need_per_second;
4312   share = distributable * pref_rel;
4313   if (share + need_per_peer > UINT32_MAX)
4314     q_in = GNUNET_BANDWIDTH_value_init (UINT32_MAX);
4315   else
4316     q_in = GNUNET_BANDWIDTH_value_init (need_per_peer + (uint32_t) share);
4317
4318   /* calculate outbound bandwidth per peer */
4319   distributable = 0;
4320   if (bandwidth_target_out_bps > need_per_second)
4321     distributable = bandwidth_target_out_bps - need_per_second;
4322   share = distributable * pref_rel;
4323   if (share + need_per_peer > UINT32_MAX)
4324     q_out = GNUNET_BANDWIDTH_value_init (UINT32_MAX);
4325   else
4326     q_out = GNUNET_BANDWIDTH_value_init (need_per_peer + (uint32_t) share);
4327   n->bw_out_internal_limit = q_out;
4328
4329   q_out_min =
4330       GNUNET_BANDWIDTH_value_min (n->bw_out_external_limit,
4331                                   n->bw_out_internal_limit);
4332   GNUNET_BANDWIDTH_tracker_update_quota (&n->available_send_window, n->bw_out);
4333
4334   /* check if we want to disconnect for good due to inactivity */
4335   if ((GNUNET_TIME_absolute_get_duration (get_neighbour_timeout (n)).rel_value >
4336        0) &&
4337       (GNUNET_TIME_absolute_get_duration (n->time_established).rel_value >
4338        GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value))
4339   {
4340 #if DEBUG_CORE
4341     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4342                 "Forcing disconnect of `%4s' due to inactivity\n",
4343                 GNUNET_i2s (&n->peer));
4344 #endif
4345     GNUNET_STATISTICS_update (stats,
4346                               gettext_noop ("# peers disconnected due to inactivity"), 1,
4347                               GNUNET_NO);
4348     q_in = GNUNET_BANDWIDTH_value_init (0);     /* force disconnect */
4349   }
4350 #if DEBUG_CORE_QUOTA
4351   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4352               "Current quota for `%4s' is %u/%llu b/s in (old: %u b/s) / %u out (%u internal)\n",
4353               GNUNET_i2s (&n->peer), (unsigned int) ntohl (q_in.value__),
4354               bandwidth_target_out_bps, (unsigned int) ntohl (n->bw_in.value__),
4355               (unsigned int) ntohl (n->bw_out.value__),
4356               (unsigned int) ntohl (n->bw_out_internal_limit.value__));
4357 #endif
4358   if ((n->bw_in.value__ != q_in.value__) ||
4359       (n->bw_out.value__ != q_out_min.value__))
4360   {
4361     if (n->bw_in.value__ != q_in.value__)
4362       n->bw_in = q_in;
4363     if (n->bw_out.value__ != q_out_min.value__)
4364       n->bw_out = q_out_min;
4365     if (GNUNET_YES == n->is_connected)
4366       GNUNET_TRANSPORT_set_quota (transport, &n->peer, n->bw_in, n->bw_out);
4367     handle_peer_status_change (n);
4368   }
4369   schedule_quota_update (n);
4370 }
4371
4372
4373 /**
4374  * Function called by transport to notify us that
4375  * a peer connected to us (on the network level).
4376  *
4377  * @param cls closure
4378  * @param peer the peer that connected
4379  * @param ats performance data
4380  * @param ats_count number of entries in ats (excluding 0-termination)
4381  */
4382 static void
4383 handle_transport_notify_connect (void *cls,
4384                                  const struct GNUNET_PeerIdentity *peer,
4385                                  const struct GNUNET_TRANSPORT_ATS_Information
4386                                  *ats, uint32_t ats_count)
4387 {
4388   struct Neighbour *n;
4389
4390   if (0 == memcmp (peer, &my_identity, sizeof (struct GNUNET_PeerIdentity)))
4391   {
4392     GNUNET_break (0);
4393     return;
4394   }
4395   n = find_neighbour (peer);
4396   if (n != NULL)
4397   {
4398     if (GNUNET_YES == n->is_connected)
4399     {
4400       /* duplicate connect notification!? */
4401       GNUNET_break (0);
4402       return;
4403     }
4404   }
4405   else
4406   {
4407     n = create_neighbour (peer);
4408   }
4409   GNUNET_STATISTICS_update (stats,
4410                             gettext_noop ("# peers connected (transport)"), 1,
4411                             GNUNET_NO);
4412   n->is_connected = GNUNET_YES;
4413   update_neighbour_performance (n, ats, ats_count);
4414   GNUNET_BANDWIDTH_tracker_init (&n->available_send_window, n->bw_out,
4415                                  MAX_WINDOW_TIME_S);
4416   GNUNET_BANDWIDTH_tracker_init (&n->available_recv_window, n->bw_in,
4417                                  MAX_WINDOW_TIME_S);
4418 #if DEBUG_CORE
4419   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received connection from `%4s'.\n",
4420               GNUNET_i2s (&n->peer));
4421 #endif
4422   GNUNET_TRANSPORT_set_quota (transport, &n->peer, n->bw_in, n->bw_out);
4423   send_key (n);
4424 }
4425
4426
4427 /**
4428  * Function called by transport telling us that a peer
4429  * disconnected.
4430  *
4431  * @param cls closure
4432  * @param peer the peer that disconnected
4433  */
4434 static void
4435 handle_transport_notify_disconnect (void *cls,
4436                                     const struct GNUNET_PeerIdentity *peer)
4437 {
4438   struct DisconnectNotifyMessage cnm;
4439   struct Neighbour *n;
4440   struct ClientActiveRequest *car;
4441   struct GNUNET_TIME_Relative left;
4442
4443 #if DEBUG_CORE
4444   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4445               "Peer `%4s' disconnected from us; received notification from transport.\n",
4446               GNUNET_i2s (peer));
4447 #endif
4448   n = find_neighbour (peer);
4449   if (n == NULL)
4450   {
4451     GNUNET_break (0);
4452     return;
4453   }
4454   GNUNET_break (n->is_connected == GNUNET_YES);
4455   if (n->status == PEER_STATE_KEY_CONFIRMED)
4456   {
4457     GNUNET_STATISTICS_update (stats,
4458                               gettext_noop ("# peers disconnected due to transport disconnect"), 1,
4459                               GNUNET_NO);
4460     cnm.header.size = htons (sizeof (struct DisconnectNotifyMessage));
4461     cnm.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_DISCONNECT);
4462     cnm.reserved = htonl (0);
4463     cnm.peer = *peer;
4464     send_to_all_clients (&cnm.header, GNUNET_NO,
4465                          GNUNET_CORE_OPTION_SEND_DISCONNECT);
4466     GNUNET_STATISTICS_update (stats, gettext_noop ("# established sessions"),
4467                               -1, GNUNET_NO);
4468   }
4469
4470   /* On transport disconnect transport doesn't cancel requests, so must do so here. */
4471   if (n->th != NULL)
4472   {
4473     GNUNET_TRANSPORT_notify_transmit_ready_cancel (n->th);
4474     n->th = NULL;
4475   }
4476   if (GNUNET_SCHEDULER_NO_TASK != n->keep_alive_task)
4477   {
4478     GNUNET_SCHEDULER_cancel (n->keep_alive_task);
4479     n->keep_alive_task = GNUNET_SCHEDULER_NO_TASK;
4480   }
4481   n->is_connected = GNUNET_NO;
4482   n->status = PEER_STATE_DOWN;
4483   while (NULL != (car = n->active_client_request_head))
4484   {
4485     GNUNET_CONTAINER_DLL_remove (n->active_client_request_head,
4486                                  n->active_client_request_tail, car);
4487     GNUNET_assert (GNUNET_YES ==
4488                    GNUNET_CONTAINER_multihashmap_remove (car->client->requests,
4489                                                          &n->peer.hashPubKey,
4490                                                          car));
4491     GNUNET_free (car);
4492   }
4493
4494   GNUNET_STATISTICS_update (stats,
4495                             gettext_noop ("# peers connected (transport)"), -1,
4496                             GNUNET_NO);
4497   if (n->dead_clean_task != GNUNET_SCHEDULER_NO_TASK)
4498     GNUNET_SCHEDULER_cancel (n->dead_clean_task);
4499   left =
4500       GNUNET_TIME_relative_subtract (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
4501                                      GNUNET_CONSTANTS_DISCONNECT_SESSION_TIMEOUT);
4502   n->last_activity =
4503       GNUNET_TIME_absolute_subtract (GNUNET_TIME_absolute_get (), left);
4504   n->dead_clean_task =
4505       GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_DISCONNECT_SESSION_TIMEOUT,
4506                                     &consider_free_task, n);
4507 }
4508
4509
4510 /**
4511  * Wrapper around 'free_neighbour'; helper for 'cleaning_task'.
4512  */
4513 static int
4514 free_neighbour_helper (void *cls, const GNUNET_HashCode * key, void *value)
4515 {
4516   struct Neighbour *n = value;
4517
4518   free_neighbour (n);
4519   return GNUNET_OK;
4520 }
4521
4522
4523 /**
4524  * Last task run during shutdown.  Disconnects us from
4525  * the transport.
4526  */
4527 static void
4528 cleaning_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
4529 {
4530   struct Client *c;
4531
4532 #if DEBUG_CORE
4533   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Core service shutting down.\n");
4534 #endif
4535   GNUNET_assert (transport != NULL);
4536   GNUNET_TRANSPORT_disconnect (transport);
4537   transport = NULL;
4538   GNUNET_CONTAINER_multihashmap_iterate (neighbours, &free_neighbour_helper,
4539                                          NULL);
4540   GNUNET_CONTAINER_multihashmap_destroy (neighbours);
4541   neighbours = NULL;
4542   GNUNET_STATISTICS_set (stats, gettext_noop ("# neighbour entries allocated"),
4543                          0, GNUNET_NO);
4544   GNUNET_SERVER_notification_context_destroy (notifier);
4545   notifier = NULL;
4546   while (NULL != (c = clients))
4547     handle_client_disconnect (NULL, c->client_handle);
4548   if (my_private_key != NULL)
4549     GNUNET_CRYPTO_rsa_key_free (my_private_key);
4550   if (stats != NULL)
4551     GNUNET_STATISTICS_destroy (stats, GNUNET_NO);
4552   if (peerinfo != NULL)
4553     GNUNET_PEERINFO_disconnect (peerinfo);
4554   if (mst != NULL)
4555     GNUNET_SERVER_mst_destroy (mst);
4556 }
4557
4558
4559 /**
4560  * Initiate core service.
4561  *
4562  * @param cls closure
4563  * @param server the initialized server
4564  * @param c configuration to use
4565  */
4566 static void
4567 run (void *cls, struct GNUNET_SERVER_Handle *server,
4568      const struct GNUNET_CONFIGURATION_Handle *c)
4569 {
4570   static const struct GNUNET_SERVER_MessageHandler handlers[] = {
4571     {&handle_client_init, NULL,
4572      GNUNET_MESSAGE_TYPE_CORE_INIT, 0},
4573     {&handle_client_iterate_peers, NULL,
4574      GNUNET_MESSAGE_TYPE_CORE_ITERATE_PEERS,
4575      sizeof (struct GNUNET_MessageHeader)},
4576     {&handle_client_have_peer, NULL,
4577      GNUNET_MESSAGE_TYPE_CORE_PEER_CONNECTED,
4578      sizeof (struct GNUNET_MessageHeader) +
4579      sizeof (struct GNUNET_PeerIdentity)},
4580     {&handle_client_request_info, NULL,
4581      GNUNET_MESSAGE_TYPE_CORE_REQUEST_INFO,
4582      sizeof (struct RequestInfoMessage)},
4583     {&handle_client_send_request, NULL,
4584      GNUNET_MESSAGE_TYPE_CORE_SEND_REQUEST,
4585      sizeof (struct SendMessageRequest)},
4586     {&handle_client_send, NULL,
4587      GNUNET_MESSAGE_TYPE_CORE_SEND, 0},
4588     {&handle_client_request_connect, NULL,
4589      GNUNET_MESSAGE_TYPE_CORE_REQUEST_CONNECT,
4590      sizeof (struct ConnectMessage)},
4591     {NULL, NULL, 0, 0}
4592   };
4593   char *keyfile;
4594
4595   cfg = c;
4596   /* parse configuration */
4597   if ((GNUNET_OK !=
4598        GNUNET_CONFIGURATION_get_value_number (c, "CORE", "TOTAL_QUOTA_IN",
4599                                               &bandwidth_target_in_bps)) ||
4600       (GNUNET_OK !=
4601        GNUNET_CONFIGURATION_get_value_number (c, "CORE", "TOTAL_QUOTA_OUT",
4602                                               &bandwidth_target_out_bps)) ||
4603       (GNUNET_OK !=
4604        GNUNET_CONFIGURATION_get_value_filename (c, "GNUNETD", "HOSTKEY",
4605                                                 &keyfile)))
4606   {
4607     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
4608                 _
4609                 ("Core service is lacking key configuration settings.  Exiting.\n"));
4610     GNUNET_SCHEDULER_shutdown ();
4611     return;
4612   }
4613   peerinfo = GNUNET_PEERINFO_connect (cfg);
4614   if (NULL == peerinfo)
4615   {
4616     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
4617                 _("Could not access PEERINFO service.  Exiting.\n"));
4618     GNUNET_SCHEDULER_shutdown ();
4619     GNUNET_free (keyfile);
4620     return;
4621   }
4622   my_private_key = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile);
4623   GNUNET_free (keyfile);
4624   if (my_private_key == NULL)
4625   {
4626     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
4627                 _("Core service could not access hostkey.  Exiting.\n"));
4628     GNUNET_PEERINFO_disconnect (peerinfo);
4629     GNUNET_SCHEDULER_shutdown ();
4630     return;
4631   }
4632   neighbours = GNUNET_CONTAINER_multihashmap_create (128);
4633   GNUNET_CRYPTO_rsa_key_get_public (my_private_key, &my_public_key);
4634   GNUNET_CRYPTO_hash (&my_public_key, sizeof (my_public_key),
4635                       &my_identity.hashPubKey);
4636   self.public_key = &my_public_key;
4637   self.peer = my_identity;
4638   self.last_activity = GNUNET_TIME_UNIT_FOREVER_ABS;
4639   self.status = PEER_STATE_KEY_CONFIRMED;
4640   self.is_connected = GNUNET_YES;
4641   /* setup notification */
4642   notifier =
4643       GNUNET_SERVER_notification_context_create (server, MAX_NOTIFY_QUEUE);
4644   GNUNET_SERVER_disconnect_notify (server, &handle_client_disconnect, NULL);
4645   /* setup transport connection */
4646   transport =
4647       GNUNET_TRANSPORT_connect (cfg, &my_identity, NULL,
4648                                 &handle_transport_receive,
4649                                 &handle_transport_notify_connect,
4650                                 &handle_transport_notify_disconnect);
4651   GNUNET_assert (NULL != transport);
4652   stats = GNUNET_STATISTICS_create ("core", cfg);
4653   mst = GNUNET_SERVER_mst_create (&deliver_message, NULL);
4654   GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &cleaning_task,
4655                                 NULL);
4656   /* process client requests */
4657   GNUNET_SERVER_add_handlers (server, handlers);
4658   GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Core service of `%4s' ready.\n"),
4659               GNUNET_i2s (&my_identity));
4660 }
4661
4662
4663
4664 /**
4665  * The main function for the transport service.
4666  *
4667  * @param argc number of arguments from the command line
4668  * @param argv command line arguments
4669  * @return 0 ok, 1 on error
4670  */
4671 int
4672 main (int argc, char *const *argv)
4673 {
4674   return (GNUNET_OK ==
4675           GNUNET_SERVICE_run (argc, argv, "core", GNUNET_SERVICE_OPTION_NONE,
4676                               &run, NULL)) ? 0 : 1;
4677 }
4678
4679 /* end of gnunet-service-core.c */