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