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