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