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