stuff
[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  * TODO:
27  * - not all GNUNET_CORE_OPTION_SEND_* flags are fully supported yet
28  *   (i.e. no SEND_XXX_OUTBOUND).
29  * - 'REQUEST_DISCONNECT' is not implemented (transport API is lacking!)
30  *
31  * Considerations for later:
32  * - check that hostkey used by transport (for HELLOs) is the
33  *   same as the hostkey that we are using!
34  * - add code to send PINGs if we are about to time-out otherwise
35  * - optimize lookup (many O(n) list traversals
36  *   could ideally be changed to O(1) hash map lookups)
37  */
38 #include "platform.h"
39 #include "gnunet_constants.h"
40 #include "gnunet_util_lib.h"
41 #include "gnunet_hello_lib.h"
42 #include "gnunet_peerinfo_service.h"
43 #include "gnunet_protocols.h"
44 #include "gnunet_signatures.h"
45 #include "gnunet_transport_service.h"
46 #include "core.h"
47
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 ms).
53  */
54 #define MAX_WINDOW_TIME (5 * 60 * 1000)
55
56 /**
57  * Minimum of bytes per minute (out) to assign to any connected peer.
58  * Should be rather low; values larger than DEFAULT_BPM_IN_OUT make no
59  * sense.
60  */
61 #define MIN_BPM_PER_PEER GNUNET_CONSTANTS_DEFAULT_BPM_IN_OUT
62
63 /**
64  * What is the smallest change (in number of bytes per minute)
65  * that we consider significant enough to bother triggering?
66  */
67 #define MIN_BPM_CHANGE 32
68
69 /**
70  * After how much time past the "official" expiration time do
71  * we discard messages?  Should not be zero since we may 
72  * intentionally defer transmission until close to the deadline
73  * and then may be slightly past the deadline due to inaccuracy
74  * in sleep and our own CPU consumption.
75  */
76 #define PAST_EXPIRATION_DISCARD_TIME GNUNET_TIME_UNIT_SECONDS
77
78 /**
79  * What is the maximum delay for a SET_KEY message?
80  */
81 #define MAX_SET_KEY_DELAY GNUNET_TIME_UNIT_SECONDS
82
83 /**
84  * What how long do we wait for SET_KEY confirmation initially?
85  */
86 #define INITIAL_SET_KEY_RETRY_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 3)
87
88 /**
89  * What is the maximum delay for a PING message?
90  */
91 #define MAX_PING_DELAY GNUNET_TIME_UNIT_SECONDS
92
93 /**
94  * What is the maximum delay for a PONG message?
95  */
96 #define MAX_PONG_DELAY GNUNET_TIME_UNIT_SECONDS
97
98 /**
99  * How often do we recalculate bandwidth quotas?
100  */
101 #define QUOTA_UPDATE_FREQUENCY GNUNET_TIME_UNIT_SECONDS
102
103 /**
104  * What is the priority for a SET_KEY message?
105  */
106 #define SET_KEY_PRIORITY 0xFFFFFF
107
108 /**
109  * What is the priority for a PING message?
110  */
111 #define PING_PRIORITY 0xFFFFFF
112
113 /**
114  * What is the priority for a PONG message?
115  */
116 #define PONG_PRIORITY 0xFFFFFF
117
118 /**
119  * How many messages do we queue per peer at most?
120  */
121 #define MAX_PEER_QUEUE_SIZE 16
122
123 /**
124  * How many non-mandatory messages do we queue per client at most?
125  */
126 #define MAX_CLIENT_QUEUE_SIZE 32
127
128 /**
129  * What is the maximum age of a message for us to consider
130  * processing it?  Note that this looks at the timestamp used
131  * by the other peer, so clock skew between machines does
132  * come into play here.  So this should be picked high enough
133  * so that a little bit of clock skew does not prevent peers
134  * from connecting to us.
135  */
136 #define MAX_MESSAGE_AGE GNUNET_TIME_UNIT_DAYS
137
138 /**
139  * What is the maximum size for encrypted messages?  Note that this
140  * number imposes a clear limit on the maximum size of any message.
141  * Set to a value close to 64k but not so close that transports will
142  * have trouble with their headers.
143  */
144 #define MAX_ENCRYPTED_MESSAGE_SIZE (63 * 1024)
145
146
147 /**
148  * State machine for our P2P encryption handshake.  Everyone starts in
149  * "DOWN", if we receive the other peer's key (other peer initiated)
150  * we start in state RECEIVED (since we will immediately send our
151  * own); otherwise we start in SENT.  If we get back a PONG from
152  * within either state, we move up to CONFIRMED (the PONG will always
153  * be sent back encrypted with the key we sent to the other peer).
154  */
155 enum PeerStateMachine
156 {
157   PEER_STATE_DOWN,
158   PEER_STATE_KEY_SENT,
159   PEER_STATE_KEY_RECEIVED,
160   PEER_STATE_KEY_CONFIRMED
161 };
162
163
164 /**
165  * Number of bytes (at the beginning) of "struct EncryptedMessage"
166  * that are NOT encrypted.
167  */
168 #define ENCRYPTED_HEADER_SIZE (sizeof(struct GNUNET_MessageHeader) + sizeof(uint32_t) + sizeof(GNUNET_HashCode))
169
170
171 /**
172  * Encapsulation for encrypted messages exchanged between
173  * peers.  Followed by the actual encrypted data.
174  */
175 struct EncryptedMessage
176 {
177   /**
178    * Message type is either CORE_ENCRYPTED_MESSAGE.
179    */
180   struct GNUNET_MessageHeader header;
181
182   /**
183    * Always zero.
184    */
185   uint32_t reserved GNUNET_PACKED;
186
187   /**
188    * Hash of the plaintext, used to verify message integrity;
189    * ALSO used as the IV for the symmetric cipher!  Everything
190    * after this hash will be encrypted.  ENCRYPTED_HEADER_SIZE
191    * must be set to the offset of the next field.
192    */
193   GNUNET_HashCode plaintext_hash;
194
195   /**
196    * Sequence number, in network byte order.  This field
197    * must be the first encrypted/decrypted field and the
198    * first byte that is hashed for the plaintext hash.
199    */
200   uint32_t sequence_number GNUNET_PACKED;
201
202   /**
203    * Desired bandwidth (how much we should send to this
204    * peer / how much is the sender willing to receive),
205    * in bytes per minute.
206    */
207   uint32_t inbound_bpm_limit GNUNET_PACKED;
208
209   /**
210    * Timestamp.  Used to prevent reply of ancient messages
211    * (recent messages are caught with the sequence number).
212    */
213   struct GNUNET_TIME_AbsoluteNBO timestamp;
214
215 };
216
217 /**
218  * We're sending an (encrypted) PING to the other peer to check if he
219  * can decrypt.  The other peer should respond with a PONG with the
220  * same content, except this time encrypted with the receiver's key.
221  */
222 struct PingMessage
223 {
224   /**
225    * Message type is either CORE_PING or CORE_PONG.
226    */
227   struct GNUNET_MessageHeader header;
228
229   /**
230    * Random number chosen to make reply harder.
231    */
232   uint32_t challenge GNUNET_PACKED;
233
234   /**
235    * Intended target of the PING, used primarily to check
236    * that decryption actually worked.
237    */
238   struct GNUNET_PeerIdentity target;
239 };
240
241
242 /**
243  * Message transmitted to set (or update) a session key.
244  */
245 struct SetKeyMessage
246 {
247
248   /**
249    * Message type is either CORE_SET_KEY.
250    */
251   struct GNUNET_MessageHeader header;
252
253   /**
254    * Status of the sender (should be in "enum PeerStateMachine"), nbo.
255    */
256   int32_t sender_status GNUNET_PACKED;
257
258   /**
259    * Purpose of the signature, will be
260    * GNUNET_SIGNATURE_PURPOSE_SET_KEY.
261    */
262   struct GNUNET_CRYPTO_RsaSignaturePurpose purpose;
263
264   /**
265    * At what time was this key created?
266    */
267   struct GNUNET_TIME_AbsoluteNBO creation_time;
268
269   /**
270    * The encrypted session key.
271    */
272   struct GNUNET_CRYPTO_RsaEncryptedData encrypted_key;
273
274   /**
275    * Who is the intended recipient?
276    */
277   struct GNUNET_PeerIdentity target;
278
279   /**
280    * Signature of the stuff above (starting at purpose).
281    */
282   struct GNUNET_CRYPTO_RsaSignature signature;
283
284 };
285
286
287 /**
288  * Message waiting for transmission. This struct
289  * is followed by the actual content of the message.
290  */
291 struct MessageEntry
292 {
293
294   /**
295    * We keep messages in a linked list (for now).
296    */
297   struct MessageEntry *next;
298
299   /**
300    * By when are we supposed to transmit this message?
301    */
302   struct GNUNET_TIME_Absolute deadline;
303
304   /**
305    * How important is this message to us?
306    */
307   unsigned int priority;
308
309   /**
310    * How long is the message? (number of bytes following
311    * the "struct MessageEntry", but not including the
312    * size of "struct MessageEntry" itself!)
313    */
314   uint16_t size;
315
316   /**
317    * Was this message selected for transmission in the
318    * current round? GNUNET_YES or GNUNET_NO.
319    */
320   int16_t do_transmit;
321
322 };
323
324
325 struct Neighbour
326 {
327   /**
328    * We keep neighbours in a linked list (for now).
329    */
330   struct Neighbour *next;
331
332   /**
333    * Unencrypted messages destined for this peer.
334    */
335   struct MessageEntry *messages;
336
337   /**
338    * Head of the batched, encrypted message queue (already ordered,
339    * transmit starting with the head).
340    */
341   struct MessageEntry *encrypted_head;
342
343   /**
344    * Tail of the batched, encrypted message queue (already ordered,
345    * append new messages to tail)
346    */
347   struct MessageEntry *encrypted_tail;
348
349   /**
350    * Handle for pending requests for transmission to this peer
351    * with the transport service.  NULL if no request is pending.
352    */
353   struct GNUNET_TRANSPORT_TransmitHandle *th;
354
355   /**
356    * Public key of the neighbour, NULL if we don't have it yet.
357    */
358   struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *public_key;
359
360   /**
361    * We received a PING message before we got the "public_key"
362    * (or the SET_KEY).  We keep it here until we have a key
363    * to decrypt it.  NULL if no PING is pending.
364    */
365   struct PingMessage *pending_ping;
366
367   /**
368    * Non-NULL if we are currently looking up HELLOs for this peer.
369    * for this peer.
370    */
371   struct GNUNET_PEERINFO_IteratorContext *pitr;
372
373   /**
374    * SetKeyMessage to transmit, NULL if we are not currently trying
375    * to send one.
376    */
377   struct SetKeyMessage *skm;
378
379   /**
380    * Identity of the neighbour.
381    */
382   struct GNUNET_PeerIdentity peer;
383
384   /**
385    * Key we use to encrypt our messages for the other peer
386    * (initialized by us when we do the handshake).
387    */
388   struct GNUNET_CRYPTO_AesSessionKey encrypt_key;
389
390   /**
391    * Key we use to decrypt messages from the other peer
392    * (given to us by the other peer during the handshake).
393    */
394   struct GNUNET_CRYPTO_AesSessionKey decrypt_key;
395
396   /**
397    * ID of task used for re-trying plaintext scheduling.
398    */
399   GNUNET_SCHEDULER_TaskIdentifier retry_plaintext_task;
400
401   /**
402    * ID of task used for re-trying SET_KEY and PING message.
403    */
404   GNUNET_SCHEDULER_TaskIdentifier retry_set_key_task;
405
406   /**
407    * ID of task used for updating bandwidth quota for this neighbour.
408    */
409   GNUNET_SCHEDULER_TaskIdentifier quota_update_task;
410
411   /**
412    * At what time did we generate our encryption key?
413    */
414   struct GNUNET_TIME_Absolute encrypt_key_created;
415
416   /**
417    * At what time did the other peer generate the decryption key?
418    */
419   struct GNUNET_TIME_Absolute decrypt_key_created;
420
421   /**
422    * At what time did we initially establish (as in, complete session
423    * key handshake) this connection?  Should be zero if status != KEY_CONFIRMED.
424    */
425   struct GNUNET_TIME_Absolute time_established;
426
427   /**
428    * At what time did we last receive an encrypted message from the
429    * other peer?  Should be zero if status != KEY_CONFIRMED.
430    */
431   struct GNUNET_TIME_Absolute last_activity;
432
433   /**
434    * Last latency observed from this peer.
435    */
436   struct GNUNET_TIME_Relative last_latency;
437
438   /**
439    * At what frequency are we currently re-trying SET_KEY messages?
440    */
441   struct GNUNET_TIME_Relative set_key_retry_frequency;
442
443   /**
444    * Time of our last update to the "available_send_window".
445    */
446   struct GNUNET_TIME_Absolute last_asw_update;
447
448   /**
449    * Time of our last update to the "available_recv_window".
450    */
451   struct GNUNET_TIME_Absolute last_arw_update;
452
453   /**
454    * Number of bytes that we are eligible to transmit to this
455    * peer at this point.  Incremented every minute by max_out_bpm,
456    * bounded by max_bpm (no back-log larger than MAX_BUF_FACT minutes,
457    * bandwidth-hogs are sampled at a frequency of about 78s!);
458    * may get negative if we have VERY high priority content.
459    */
460   long long available_send_window; 
461
462   /**
463    * How much downstream capacity of this peer has been reserved for
464    * our traffic?  (Our clients can request that a certain amount of
465    * bandwidth is available for replies to them; this value is used to
466    * make sure that this reserved amount of bandwidth is actually
467    * available).
468    */
469   long long available_recv_window; 
470
471   /**
472    * How valueable were the messages of this peer recently?
473    */
474   unsigned long long current_preference;
475
476   /**
477    * Bit map indicating which of the 32 sequence numbers before the last
478    * were received (good for accepting out-of-order packets and
479    * estimating reliability of the connection)
480    */
481   unsigned int last_packets_bitmap;
482
483   /**
484    * Number of messages in the message queue for this peer.
485    */
486   unsigned int message_queue_size;
487
488   /**
489    * last sequence number received on this connection (highest)
490    */
491   uint32_t last_sequence_number_received;
492
493   /**
494    * last sequence number transmitted
495    */
496   uint32_t last_sequence_number_sent;
497
498   /**
499    * Available bandwidth in for this peer (current target).
500    */
501   uint32_t bpm_in;
502
503   /**
504    * Available bandwidth out for this peer (current target).
505    */
506   uint32_t bpm_out;
507
508   /**
509    * Internal bandwidth limit set for this peer (initially
510    * typically set to "-1").  "bpm_out" is MAX of
511    * "bpm_out_internal_limit" and "bpm_out_external_limit".
512    */
513   uint32_t bpm_out_internal_limit;
514
515   /**
516    * External bandwidth limit set for this peer by the
517    * peer that we are communicating with.  "bpm_out" is MAX of
518    * "bpm_out_internal_limit" and "bpm_out_external_limit".
519    */
520   uint32_t bpm_out_external_limit;
521
522   /**
523    * What was our PING challenge number (for this peer)?
524    */
525   uint32_t ping_challenge;
526
527   /**
528    * What was the last distance to this peer as reported by the transports?
529    * (FIXME: actually set this!)
530    */
531   uint32_t last_distance;
532
533   /**
534    * What is our connection status?
535    */
536   enum PeerStateMachine status;
537
538 };
539
540
541 /**
542  * Data structure for each client connected to the core service.
543  */
544 struct Client
545 {
546   /**
547    * Clients are kept in a linked list.
548    */
549   struct Client *next;
550
551   /**
552    * Handle for the client with the server API.
553    */
554   struct GNUNET_SERVER_Client *client_handle;
555
556   /**
557    * Array of the types of messages this peer cares
558    * about (with "tcnt" entries).  Allocated as part
559    * of this client struct, do not free!
560    */
561   uint16_t *types;
562
563   /**
564    * Options for messages this client cares about,
565    * see GNUNET_CORE_OPTION_ values.
566    */
567   uint32_t options;
568
569   /**
570    * Number of types of incoming messages this client
571    * specifically cares about.  Size of the "types" array.
572    */
573   unsigned int tcnt;
574
575 };
576
577
578 /**
579  * Our public key.
580  */
581 static struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded my_public_key;
582
583 /**
584  * Our identity.
585  */
586 static struct GNUNET_PeerIdentity my_identity;
587
588 /**
589  * Our private key.
590  */
591 static struct GNUNET_CRYPTO_RsaPrivateKey *my_private_key;
592
593 /**
594  * Our scheduler.
595  */
596 struct GNUNET_SCHEDULER_Handle *sched;
597
598 /**
599  * Our configuration.
600  */
601 const struct GNUNET_CONFIGURATION_Handle *cfg;
602
603 /**
604  * Our server.
605  */
606 static struct GNUNET_SERVER_Handle *server;
607
608 /**
609  * Transport service.
610  */
611 static struct GNUNET_TRANSPORT_Handle *transport;
612
613 /**
614  * Linked list of our clients.
615  */
616 static struct Client *clients;
617
618 /**
619  * Context for notifications we need to send to our clients.
620  */
621 static struct GNUNET_SERVER_NotificationContext *notifier;
622
623 /**
624  * We keep neighbours in a linked list (for now).
625  */
626 static struct Neighbour *neighbours;
627
628 /**
629  * Sum of all preferences among all neighbours.
630  */
631 static unsigned long long preference_sum;
632
633 /**
634  * Total number of neighbours we have.
635  */
636 static unsigned int neighbour_count;
637
638 /**
639  * How much inbound bandwidth are we supposed to be using?
640  */
641 static unsigned long long bandwidth_target_in;
642
643 /**
644  * How much outbound bandwidth are we supposed to be using?
645  */
646 static unsigned long long bandwidth_target_out;
647
648
649
650 /**
651  * A preference value for a neighbour was update.  Update
652  * the preference sum accordingly.
653  *
654  * @param inc how much was a preference value increased?
655  */
656 static void
657 update_preference_sum (unsigned long long inc)
658 {
659   struct Neighbour *n;
660   unsigned long long os;
661
662   os = preference_sum;
663   preference_sum += inc;
664   if (preference_sum >= os)
665     return; /* done! */
666   /* overflow! compensate by cutting all values in half! */
667   preference_sum = 0;
668   n = neighbours;
669   while (n != NULL)
670     {
671       n->current_preference /= 2;
672       preference_sum += n->current_preference;
673       n = n->next;
674     }    
675 }
676
677
678 /**
679  * Recalculate the number of bytes we expect to
680  * receive or transmit in a given window.
681  *
682  * @param force force an update now (even if not much time has passed)
683  * @param window pointer to the byte counter (updated)
684  * @param ts pointer to the timestamp (updated)
685  * @param bpm number of bytes per minute that should
686  *        be added to the window.
687  */
688 static void
689 update_window (int force,
690                long long *window,
691                struct GNUNET_TIME_Absolute *ts, unsigned int bpm)
692 {
693   struct GNUNET_TIME_Relative since;
694
695   since = GNUNET_TIME_absolute_get_duration (*ts);
696   if ( (force == GNUNET_NO) &&
697        (since.value < 60 * 1000) )
698     return;                     /* not even a minute has passed */
699   *ts = GNUNET_TIME_absolute_get ();
700   *window += (bpm * since.value) / 60 / 1000;
701   if (*window > MAX_WINDOW_TIME * bpm)
702     *window = MAX_WINDOW_TIME * bpm;
703 }
704
705
706 /**
707  * Find the entry for the given neighbour.
708  *
709  * @param peer identity of the neighbour
710  * @return NULL if we are not connected, otherwise the
711  *         neighbour's entry.
712  */
713 static struct Neighbour *
714 find_neighbour (const struct GNUNET_PeerIdentity *peer)
715 {
716   struct Neighbour *ret;
717
718   ret = neighbours;
719   while ((ret != NULL) &&
720          (0 != memcmp (&ret->peer,
721                        peer, sizeof (struct GNUNET_PeerIdentity))))
722     ret = ret->next;
723   return ret;
724 }
725
726
727 /**
728  * Send a message to one of our clients.
729  *
730  * @param client target for the message
731  * @param msg message to transmit
732  * @param can_drop could this message be dropped if the
733  *        client's queue is getting too large?
734  */
735 static void
736 send_to_client (struct Client *client,
737                 const struct GNUNET_MessageHeader *msg, 
738                 int can_drop)
739 {
740 #if DEBUG_CORE_CLIENT
741   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
742               "Preparing to send message of type %u to client.\n",
743               ntohs (msg->type));
744 #endif  
745   GNUNET_SERVER_notification_context_unicast (notifier,
746                                               client->client_handle,
747                                               msg,
748                                               can_drop);
749 }
750
751
752 /**
753  * Send a message to all of our current clients that have
754  * the right options set.
755  * 
756  * @param msg message to multicast
757  * @param can_drop can this message be discarded if the queue is too long
758  * @param options mask to use 
759  */
760 static void
761 send_to_all_clients (const struct GNUNET_MessageHeader *msg, 
762                      int can_drop,
763                      int options)
764 {
765   struct Client *c;
766
767   c = clients;
768   while (c != NULL)
769     {
770       if (0 != (c->options & options))
771         send_to_client (c, msg, can_drop);
772       c = c->next;
773     }
774 }
775
776
777 /**
778  * Handle CORE_INIT request.
779  */
780 static void
781 handle_client_init (void *cls,
782                     struct GNUNET_SERVER_Client *client,
783                     const struct GNUNET_MessageHeader *message)
784 {
785   const struct InitMessage *im;
786   struct InitReplyMessage irm;
787   struct Client *c;
788   uint16_t msize;
789   const uint16_t *types;
790   struct Neighbour *n;
791   struct ConnectNotifyMessage cnm;
792
793 #if DEBUG_CORE_CLIENT
794   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
795               "Client connecting to core service with `%s' message\n",
796               "INIT");
797 #endif
798   /* check that we don't have an entry already */
799   c = clients;
800   while (c != NULL)
801     {
802       if (client == c->client_handle)
803         {
804           GNUNET_break (0);
805           GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
806           return;
807         }
808       c = c->next;
809     }
810   msize = ntohs (message->size);
811   if (msize < sizeof (struct InitMessage))
812     {
813       GNUNET_break (0);
814       GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
815       return;
816     }
817   GNUNET_SERVER_notification_context_add (notifier, client);
818   im = (const struct InitMessage *) message;
819   types = (const uint16_t *) &im[1];
820   msize -= sizeof (struct InitMessage);
821   c = GNUNET_malloc (sizeof (struct Client) + msize);
822   c->client_handle = client;
823   c->next = clients;
824   clients = c;
825   memcpy (&c[1], types, msize);
826   c->types = (uint16_t *) & c[1];
827   c->options = ntohl (im->options);
828   c->tcnt = msize / sizeof (uint16_t);
829   /* send init reply message */
830   irm.header.size = htons (sizeof (struct InitReplyMessage));
831   irm.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_INIT_REPLY);
832   irm.reserved = htonl (0);
833   memcpy (&irm.publicKey,
834           &my_public_key,
835           sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded));
836 #if DEBUG_CORE_CLIENT
837   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
838               "Sending `%s' message to client.\n", "INIT_REPLY");
839 #endif
840   send_to_client (c, &irm.header, GNUNET_NO);
841   /* notify new client about existing neighbours */
842   cnm.header.size = htons (sizeof (struct ConnectNotifyMessage));
843   cnm.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT);
844   n = neighbours;
845   while (n != NULL)
846     {
847 #if DEBUG_CORE_CLIENT
848       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
849                   "Sending `%s' message to client.\n", "NOTIFY_CONNECT");
850 #endif
851       cnm.distance = htonl (n->last_distance);
852       cnm.latency = GNUNET_TIME_relative_hton (n->last_latency);
853       cnm.peer = n->peer;
854       send_to_client (c, &cnm.header, GNUNET_NO);
855       n = n->next;
856     }
857 }
858
859
860 /**
861  * A client disconnected, clean up.
862  *
863  * @param cls closure
864  * @param client identification of the client
865  */
866 static void
867 handle_client_disconnect (void *cls, struct GNUNET_SERVER_Client *client)
868 {
869   struct Client *pos;
870   struct Client *prev;
871
872   if (client == NULL)
873     return;
874 #if DEBUG_CORE_CLIENT
875   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
876               "Client has disconnected from core service.\n");
877 #endif
878   prev = NULL;
879   pos = clients;
880   while (pos != NULL)
881     {
882       if (client == pos->client_handle)
883         {
884           if (prev == NULL)
885             clients = pos->next;
886           else
887             prev->next = pos->next;
888           GNUNET_free (pos);
889           return;
890         }
891       prev = pos;
892       pos = pos->next;
893     }
894   /* client never sent INIT */
895 }
896
897
898 /**
899  * Handle REQUEST_INFO request.
900  */
901 static void
902 handle_client_request_info (void *cls,
903                             struct GNUNET_SERVER_Client *client,
904                             const struct GNUNET_MessageHeader *message)
905 {
906   const struct RequestInfoMessage *rcm;
907   struct Neighbour *n;
908   struct ConfigurationInfoMessage cim;
909   int reserv;
910   unsigned long long old_preference;
911   struct GNUNET_SERVER_TransmitContext *tc;
912
913 #if DEBUG_CORE_CLIENT
914   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
915               "Core service receives `%s' request.\n", "REQUEST_INFO");
916 #endif
917   rcm = (const struct RequestInfoMessage *) message;
918   n = find_neighbour (&rcm->peer);
919   memset (&cim, 0, sizeof (cim));
920   if ((n != NULL) && (n->status == PEER_STATE_KEY_CONFIRMED))
921     {
922       update_window (GNUNET_YES,
923                      &n->available_send_window,
924                      &n->last_asw_update,
925                      n->bpm_out);
926       n->bpm_out_internal_limit = ntohl (rcm->limit_outbound_bpm);
927       n->bpm_out = GNUNET_MAX (n->bpm_out_internal_limit,
928                                n->bpm_out_external_limit);
929       reserv = ntohl (rcm->reserve_inbound);
930       if (reserv < 0)
931         {
932           n->available_recv_window += reserv;
933         }
934       else if (reserv > 0)
935         {
936           update_window (GNUNET_NO,
937                          &n->available_recv_window,
938                          &n->last_arw_update, n->bpm_in);
939           if (n->available_recv_window < reserv)
940             reserv = n->available_recv_window;
941           n->available_recv_window -= reserv;
942         }
943       old_preference = n->current_preference;
944       n->current_preference += GNUNET_ntohll(rcm->preference_change);
945       if (old_preference > n->current_preference) 
946         {
947           /* overflow; cap at maximum value */
948           n->current_preference = (unsigned long long) -1;
949         }
950       update_preference_sum (n->current_preference - old_preference);
951       cim.reserved_amount = htonl (reserv);
952       cim.bpm_in = htonl (n->bpm_in);
953       cim.bpm_out = htonl (n->bpm_out);
954       cim.preference = n->current_preference;
955     }
956   cim.header.size = htons (sizeof (struct ConfigurationInfoMessage));
957   cim.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_CONFIGURATION_INFO);
958   cim.peer = rcm->peer;
959
960 #if DEBUG_CORE_CLIENT
961   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
962               "Sending `%s' message to client.\n", "CONFIGURATION_INFO");
963 #endif
964   tc = GNUNET_SERVER_transmit_context_create (client);
965   GNUNET_SERVER_transmit_context_append_message (tc, &cim.header);
966   GNUNET_SERVER_transmit_context_run (tc,
967                                       GNUNET_TIME_UNIT_FOREVER_REL);
968 }
969
970
971 /**
972  * Check if we have encrypted messages for the specified neighbour
973  * pending, and if so, check with the transport about sending them
974  * out.
975  *
976  * @param n neighbour to check.
977  */
978 static void process_encrypted_neighbour_queue (struct Neighbour *n);
979
980
981 /**
982  * Function called when the transport service is ready to
983  * receive an encrypted message for the respective peer
984  *
985  * @param cls neighbour to use message from
986  * @param size number of bytes we can transmit
987  * @param buf where to copy the message
988  * @return number of bytes transmitted
989  */
990 static size_t
991 notify_encrypted_transmit_ready (void *cls, size_t size, void *buf)
992 {
993   struct Neighbour *n = cls;
994   struct MessageEntry *m;
995   size_t ret;
996   char *cbuf;
997
998   n->th = NULL;
999   GNUNET_assert (NULL != (m = n->encrypted_head));
1000   n->encrypted_head = m->next;
1001   if (m->next == NULL)
1002     n->encrypted_tail = NULL;
1003   ret = 0;
1004   cbuf = buf;
1005   if (buf != NULL)
1006     {
1007       GNUNET_assert (size >= m->size);
1008       memcpy (cbuf, &m[1], m->size);
1009       ret = m->size;
1010       n->available_send_window -= m->size;
1011       process_encrypted_neighbour_queue (n);
1012 #if DEBUG_CORE
1013       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1014                   "Copied message of type %u and size %u into transport buffer for `%4s'\n",
1015                   ntohs (((struct GNUNET_MessageHeader *) &m[1])->type),
1016                   ret, GNUNET_i2s (&n->peer));
1017 #endif
1018     }
1019   else
1020     {
1021       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1022                   "Transmission for message of type %u and size %u failed\n",
1023                   ntohs (((struct GNUNET_MessageHeader *) &m[1])->type),
1024                   m->size);
1025     }
1026   GNUNET_free (m);
1027   return ret;
1028 }
1029
1030
1031 /**
1032  * Check if we have plaintext messages for the specified neighbour
1033  * pending, and if so, consider batching and encrypting them (and
1034  * then trigger processing of the encrypted queue if needed).
1035  *
1036  * @param n neighbour to check.
1037  */
1038 static void process_plaintext_neighbour_queue (struct Neighbour *n);
1039
1040
1041 /**
1042  * Check if we have encrypted messages for the specified neighbour
1043  * pending, and if so, check with the transport about sending them
1044  * out.
1045  *
1046  * @param n neighbour to check.
1047  */
1048 static void
1049 process_encrypted_neighbour_queue (struct Neighbour *n)
1050 {
1051   struct MessageEntry *m;
1052  
1053   if (n->th != NULL)
1054     return;  /* request already pending */
1055   if (n->encrypted_head == NULL)
1056     {
1057       /* encrypted queue empty, try plaintext instead */
1058       process_plaintext_neighbour_queue (n);
1059       return;
1060     }
1061 #if DEBUG_CORE
1062   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1063               "Asking transport for transmission of %u bytes to `%4s' in next %llu ms\n",
1064               n->encrypted_head->size,
1065               GNUNET_i2s (&n->peer),
1066               GNUNET_TIME_absolute_get_remaining (n->
1067                                                   encrypted_head->deadline).
1068               value);
1069 #endif
1070   n->th =
1071     GNUNET_TRANSPORT_notify_transmit_ready (transport, &n->peer,
1072                                             n->encrypted_head->size,
1073                                             n->encrypted_head->priority,
1074                                             GNUNET_TIME_absolute_get_remaining
1075                                             (n->encrypted_head->deadline),
1076                                             &notify_encrypted_transmit_ready,
1077                                             n);
1078   if (n->th == NULL)
1079     {
1080       /* message request too large (oops) */
1081       GNUNET_break (0);
1082       /* discard encrypted message */
1083       GNUNET_assert (NULL != (m = n->encrypted_head));
1084       n->encrypted_head = m->next;
1085       if (m->next == NULL)
1086         n->encrypted_tail = NULL;
1087       GNUNET_free (m);
1088       process_encrypted_neighbour_queue (n);
1089     }
1090 }
1091
1092
1093 /**
1094  * Decrypt size bytes from in and write the result to out.  Use the
1095  * key for inbound traffic of the given neighbour.  This function does
1096  * NOT do any integrity-checks on the result.
1097  *
1098  * @param n neighbour we are receiving from
1099  * @param iv initialization vector to use
1100  * @param in ciphertext
1101  * @param out plaintext
1102  * @param size size of in/out
1103  * @return GNUNET_OK on success
1104  */
1105 static int
1106 do_decrypt (struct Neighbour *n,
1107             const GNUNET_HashCode * iv,
1108             const void *in, void *out, size_t size)
1109 {
1110   if (size != (uint16_t) size)
1111     {
1112       GNUNET_break (0);
1113       return GNUNET_NO;
1114     }
1115   if ((n->status != PEER_STATE_KEY_RECEIVED) &&
1116       (n->status != PEER_STATE_KEY_CONFIRMED))
1117     {
1118       GNUNET_break_op (0);
1119       return GNUNET_SYSERR;
1120     }
1121   if (size !=
1122       GNUNET_CRYPTO_aes_decrypt (in,
1123                                  (uint16_t) size,
1124                                  &n->decrypt_key,
1125                                  (const struct
1126                                   GNUNET_CRYPTO_AesInitializationVector *) iv,
1127                                  out))
1128     {
1129       GNUNET_break (0);
1130       return GNUNET_SYSERR;
1131     }
1132 #if DEBUG_CORE
1133   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1134               "Decrypted %u bytes from `%4s' using key %u\n",
1135               size, GNUNET_i2s (&n->peer), n->decrypt_key.crc32);
1136 #endif
1137   return GNUNET_OK;
1138 }
1139
1140
1141 /**
1142  * Encrypt size bytes from in and write the result to out.  Use the
1143  * key for outbound traffic of the given neighbour.
1144  *
1145  * @param n neighbour we are sending to
1146  * @param iv initialization vector to use
1147  * @param in ciphertext
1148  * @param out plaintext
1149  * @param size size of in/out
1150  * @return GNUNET_OK on success
1151  */
1152 static int
1153 do_encrypt (struct Neighbour *n,
1154             const GNUNET_HashCode * iv,
1155             const void *in, void *out, size_t size)
1156 {
1157   if (size != (uint16_t) size)
1158     {
1159       GNUNET_break (0);
1160       return GNUNET_NO;
1161     }
1162   GNUNET_assert (size ==
1163                  GNUNET_CRYPTO_aes_encrypt (in,
1164                                             (uint16_t) size,
1165                                             &n->encrypt_key,
1166                                             (const struct
1167                                              GNUNET_CRYPTO_AesInitializationVector
1168                                              *) iv, out));
1169 #if DEBUG_CORE
1170   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1171               "Encrypted %u bytes for `%4s' using key %u\n", size,
1172               GNUNET_i2s (&n->peer), n->encrypt_key.crc32);
1173 #endif
1174   return GNUNET_OK;
1175 }
1176
1177
1178 /**
1179  * Select messages for transmission.  This heuristic uses a combination
1180  * of earliest deadline first (EDF) scheduling (with bounded horizon)
1181  * and priority-based discard (in case no feasible schedule exist) and
1182  * speculative optimization (defer any kind of transmission until
1183  * we either create a batch of significant size, 25% of max, or until
1184  * we are close to a deadline).  Furthermore, when scheduling the
1185  * heuristic also packs as many messages into the batch as possible,
1186  * starting with those with the earliest deadline.  Yes, this is fun.
1187  *
1188  * @param n neighbour to select messages from
1189  * @param size number of bytes to select for transmission
1190  * @param retry_time set to the time when we should try again
1191  *        (only valid if this function returns zero)
1192  * @return number of bytes selected, or 0 if we decided to
1193  *         defer scheduling overall; in that case, retry_time is set.
1194  */
1195 static size_t
1196 select_messages (struct Neighbour *n,
1197                  size_t size, struct GNUNET_TIME_Relative *retry_time)
1198 {
1199   struct MessageEntry *pos;
1200   struct MessageEntry *min;
1201   struct MessageEntry *last;
1202   unsigned int min_prio;
1203   struct GNUNET_TIME_Absolute t;
1204   struct GNUNET_TIME_Absolute now;
1205   uint64_t delta;
1206   uint64_t avail;
1207   unsigned long long slack;     /* how long could we wait before missing deadlines? */
1208   size_t off;
1209   int discard_low_prio;
1210
1211   GNUNET_assert (NULL != n->messages);
1212   now = GNUNET_TIME_absolute_get ();
1213   /* last entry in linked list of messages processed */
1214   last = NULL;
1215   /* should we remove the entry with the lowest
1216      priority from consideration for scheduling at the
1217      end of the loop? */
1218   discard_low_prio = GNUNET_YES;
1219   while (GNUNET_YES == discard_low_prio)
1220     {
1221       min = NULL;
1222       min_prio = -1;
1223       discard_low_prio = GNUNET_NO;
1224       /* calculate number of bytes available for transmission at time "t" */
1225       update_window (GNUNET_NO,
1226                      &n->available_send_window,
1227                      &n->last_asw_update,
1228                      n->bpm_out);
1229       avail = n->available_send_window;
1230       t = n->last_asw_update;
1231       /* how many bytes have we (hypothetically) scheduled so far */
1232       off = 0;
1233       /* maximum time we can wait before transmitting anything
1234          and still make all of our deadlines */
1235       slack = -1;
1236
1237       pos = n->messages;
1238       /* note that we use "*2" here because we want to look
1239          a bit further into the future; much more makes no
1240          sense since new message might be scheduled in the
1241          meantime... */
1242       while ((pos != NULL) && (off < size * 2))
1243         {
1244           if (pos->do_transmit == GNUNET_YES)
1245             {
1246               /* already removed from consideration */
1247               pos = pos->next;
1248               continue;
1249             }
1250           if (discard_low_prio == GNUNET_NO)
1251             {
1252               delta = pos->deadline.value;
1253               if (delta < t.value)
1254                 delta = 0;
1255               else
1256                 delta = t.value - delta;
1257               avail += delta * n->bpm_out / 1000 / 60;
1258               if (avail < pos->size)
1259                 {
1260                   discard_low_prio = GNUNET_YES;        /* we could not schedule this one! */
1261                 }
1262               else
1263                 {
1264                   avail -= pos->size;
1265                   /* update slack, considering both its absolute deadline
1266                      and relative deadlines caused by other messages
1267                      with their respective load */
1268                   slack = GNUNET_MIN (slack, avail / n->bpm_out);
1269                   if (pos->deadline.value < now.value)
1270                     slack = 0;
1271                   else
1272                     slack =
1273                       GNUNET_MIN (slack, pos->deadline.value - now.value);
1274                 }
1275             }
1276           off += pos->size;
1277           t.value = GNUNET_MAX (pos->deadline.value, t.value);
1278           if (pos->priority <= min_prio)
1279             {
1280               /* update min for discard */
1281               min_prio = pos->priority;
1282               min = pos;
1283             }
1284           pos = pos->next;
1285         }
1286       if (discard_low_prio)
1287         {
1288           GNUNET_assert (min != NULL);
1289           /* remove lowest-priority entry from consideration */
1290           min->do_transmit = GNUNET_YES;        /* means: discard (for now) */
1291         }
1292       last = pos;
1293     }
1294   /* guard against sending "tiny" messages with large headers without
1295      urgent deadlines */
1296   if ( (slack > 1000) && (size > 4 * off) )
1297     {
1298       /* less than 25% of message would be filled with
1299          deadlines still being met if we delay by one
1300          second or more; so just wait for more data */
1301       retry_time->value = slack / 2;
1302       /* reset do_transmit values for next time */
1303       while (pos != last)
1304         {
1305           pos->do_transmit = GNUNET_NO;
1306           pos = pos->next;
1307         }
1308       return 0;
1309     }
1310   /* select marked messages (up to size) for transmission */
1311   off = 0;
1312   pos = n->messages;
1313   while (pos != last)
1314     {
1315       if ((pos->size <= size) && (pos->do_transmit == GNUNET_NO))
1316         {
1317           pos->do_transmit = GNUNET_YES;        /* mark for transmission */
1318           off += pos->size;
1319           size -= pos->size;
1320         }
1321       else
1322         pos->do_transmit = GNUNET_NO;   /* mark for not transmitting! */
1323       pos = pos->next;
1324     }
1325 #if DEBUG_CORE
1326   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1327               "Selected %u bytes of plaintext messages for transmission to `%4s'.\n",
1328               off, GNUNET_i2s (&n->peer));
1329 #endif
1330   return off;
1331 }
1332
1333
1334 /**
1335  * Batch multiple messages into a larger buffer.
1336  *
1337  * @param n neighbour to take messages from
1338  * @param buf target buffer
1339  * @param size size of buf
1340  * @param deadline set to transmission deadline for the result
1341  * @param retry_time set to the time when we should try again
1342  *        (only valid if this function returns zero)
1343  * @param priority set to the priority of the batch
1344  * @return number of bytes written to buf (can be zero)
1345  */
1346 static size_t
1347 batch_message (struct Neighbour *n,
1348                char *buf,
1349                size_t size,
1350                struct GNUNET_TIME_Absolute *deadline,
1351                struct GNUNET_TIME_Relative *retry_time,
1352                unsigned int *priority)
1353 {
1354   struct MessageEntry *pos;
1355   struct MessageEntry *prev;
1356   struct MessageEntry *next;
1357   size_t ret;
1358
1359   ret = 0;
1360   *priority = 0;
1361   *deadline = GNUNET_TIME_UNIT_FOREVER_ABS;
1362   *retry_time = GNUNET_TIME_UNIT_FOREVER_REL;
1363   if (0 == select_messages (n, size, retry_time))
1364     {
1365       GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1366                   "No messages selected, will try again in %llu ms\n",
1367                   retry_time->value);
1368       return 0;
1369     }
1370   pos = n->messages;
1371   prev = NULL;
1372   while ((pos != NULL) && (size >= sizeof (struct GNUNET_MessageHeader)))
1373     {
1374       next = pos->next;
1375       if (GNUNET_YES == pos->do_transmit)
1376         {
1377           GNUNET_assert (pos->size <= size);
1378           memcpy (&buf[ret], &pos[1], pos->size);
1379           ret += pos->size;
1380           size -= pos->size;
1381           *priority += pos->priority;
1382 #if DEBUG_CORE
1383           GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1384                       "Adding plaintext message with deadline %llu ms to batch\n",
1385                       GNUNET_TIME_absolute_get_remaining (pos->deadline).value);
1386 #endif
1387           deadline->value = GNUNET_MIN (deadline->value, pos->deadline.value);
1388           GNUNET_free (pos);
1389           if (prev == NULL)
1390             n->messages = next;
1391           else
1392             prev->next = next;
1393         }
1394       else
1395         {
1396           prev = pos;
1397         }
1398       pos = next;
1399     }
1400 #if DEBUG_CORE
1401   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1402               "Deadline for message batch is %llu ms\n",
1403               GNUNET_TIME_absolute_get_remaining (*deadline).value);
1404 #endif
1405   return ret;
1406 }
1407
1408
1409 /**
1410  * Remove messages with deadlines that have long expired from
1411  * the queue.
1412  *
1413  * @param n neighbour to inspect
1414  */
1415 static void
1416 discard_expired_messages (struct Neighbour *n)
1417 {
1418   struct MessageEntry *prev;
1419   struct MessageEntry *next;
1420   struct MessageEntry *pos;
1421   struct GNUNET_TIME_Absolute now;
1422   struct GNUNET_TIME_Relative delta;
1423
1424   now = GNUNET_TIME_absolute_get ();
1425   prev = NULL;
1426   pos = n->messages;
1427   while (pos != NULL) 
1428     {
1429       next = pos->next;
1430       delta = GNUNET_TIME_absolute_get_difference (pos->deadline, now);
1431       if (delta.value > PAST_EXPIRATION_DISCARD_TIME.value)
1432         {
1433 #if DEBUG_CORE
1434           GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1435                       "Message is %llu ms past due, discarding.\n",
1436                       delta.value);
1437 #endif
1438           if (prev == NULL)
1439             n->messages = next;
1440           else
1441             prev->next = next;
1442           GNUNET_free (pos);
1443         }
1444       else
1445         prev = pos;
1446       pos = next;
1447     }
1448 }
1449
1450
1451 /**
1452  * Signature of the main function of a task.
1453  *
1454  * @param cls closure
1455  * @param tc context information (why was this task triggered now)
1456  */
1457 static void
1458 retry_plaintext_processing (void *cls,
1459                             const struct GNUNET_SCHEDULER_TaskContext *tc)
1460 {
1461   struct Neighbour *n = cls;
1462
1463   n->retry_plaintext_task = GNUNET_SCHEDULER_NO_TASK;
1464   process_plaintext_neighbour_queue (n);
1465 }
1466
1467
1468 /**
1469  * Send our key (and encrypted PING) to the other peer.
1470  *
1471  * @param n the other peer
1472  */
1473 static void send_key (struct Neighbour *n);
1474
1475
1476 /**
1477  * Check if we have plaintext messages for the specified neighbour
1478  * pending, and if so, consider batching and encrypting them (and
1479  * then trigger processing of the encrypted queue if needed).
1480  *
1481  * @param n neighbour to check.
1482  */
1483 static void
1484 process_plaintext_neighbour_queue (struct Neighbour *n)
1485 {
1486   char pbuf[MAX_ENCRYPTED_MESSAGE_SIZE];        /* plaintext */
1487   size_t used;
1488   size_t esize;
1489   struct EncryptedMessage *em;  /* encrypted message */
1490   struct EncryptedMessage *ph;  /* plaintext header */
1491   struct MessageEntry *me;
1492   unsigned int priority;
1493   struct GNUNET_TIME_Absolute deadline;
1494   struct GNUNET_TIME_Relative retry_time;
1495
1496   if (n->retry_plaintext_task != GNUNET_SCHEDULER_NO_TASK)
1497     {
1498       GNUNET_SCHEDULER_cancel (sched, n->retry_plaintext_task);
1499       n->retry_plaintext_task = GNUNET_SCHEDULER_NO_TASK;
1500     }
1501   switch (n->status)
1502     {
1503     case PEER_STATE_DOWN:
1504       send_key (n);
1505 #if DEBUG_CORE
1506       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1507                   "Not yet connected to `%4s', deferring processing of plaintext messages.\n",
1508                   GNUNET_i2s(&n->peer));
1509 #endif
1510       return;
1511     case PEER_STATE_KEY_SENT:
1512       GNUNET_assert (n->retry_set_key_task !=
1513                      GNUNET_SCHEDULER_NO_TASK);
1514 #if DEBUG_CORE
1515       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1516                   "Not yet connected to `%4s', deferring processing of plaintext messages.\n",
1517                   GNUNET_i2s(&n->peer));
1518 #endif
1519       return;
1520     case PEER_STATE_KEY_RECEIVED:
1521       GNUNET_assert (n->retry_set_key_task !=
1522                      GNUNET_SCHEDULER_NO_TASK);
1523 #if DEBUG_CORE
1524       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1525                   "Not yet connected to `%4s', deferring processing of plaintext messages.\n",
1526                   GNUNET_i2s(&n->peer));
1527 #endif
1528       return;
1529     case PEER_STATE_KEY_CONFIRMED:
1530       /* ready to continue */
1531       break;
1532     }
1533   discard_expired_messages (n);
1534   if (n->messages == NULL)
1535     {
1536 #if DEBUG_CORE
1537       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1538                   "Plaintext message queue for `%4s' is empty.\n",
1539                   GNUNET_i2s(&n->peer));
1540 #endif
1541       return;                   /* no pending messages */
1542     }
1543   if (n->encrypted_head != NULL)
1544     {
1545 #if DEBUG_CORE
1546       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1547                   "Encrypted message queue for `%4s' is still full, delaying plaintext processing.\n",
1548                   GNUNET_i2s(&n->peer));
1549 #endif
1550       return;                   /* wait for messages already encrypted to be
1551                                    processed first! */
1552     }
1553   ph = (struct EncryptedMessage *) pbuf;
1554   deadline = GNUNET_TIME_UNIT_FOREVER_ABS;
1555   priority = 0;
1556   used = sizeof (struct EncryptedMessage);
1557   used += batch_message (n,
1558                          &pbuf[used],
1559                          MAX_ENCRYPTED_MESSAGE_SIZE - used,
1560                          &deadline, &retry_time, &priority);
1561   if (used == sizeof (struct EncryptedMessage))
1562     {
1563 #if DEBUG_CORE
1564       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1565                   "No messages selected for transmission to `%4s' at this time, will try again later.\n",
1566                   GNUNET_i2s(&n->peer));
1567 #endif
1568       /* no messages selected for sending, try again later... */
1569       n->retry_plaintext_task =
1570         GNUNET_SCHEDULER_add_delayed (sched,
1571                                       retry_time,
1572                                       &retry_plaintext_processing, n);
1573       return;
1574     }
1575   ph->sequence_number = htonl (++n->last_sequence_number_sent);
1576   ph->inbound_bpm_limit = htonl (n->bpm_in);
1577   ph->timestamp = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get ());
1578
1579   /* setup encryption message header */
1580   me = GNUNET_malloc (sizeof (struct MessageEntry) + used);
1581   me->deadline = deadline;
1582   me->priority = priority;
1583   me->size = used;
1584   em = (struct EncryptedMessage *) &me[1];
1585   em->header.size = htons (used);
1586   em->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_ENCRYPTED_MESSAGE);
1587   em->reserved = htonl (0);
1588   esize = used - ENCRYPTED_HEADER_SIZE;
1589   GNUNET_CRYPTO_hash (&ph->sequence_number, esize, &em->plaintext_hash);
1590   /* encrypt */
1591 #if DEBUG_CORE
1592   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1593               "Encrypting %u bytes of plaintext messages for `%4s' for transmission in %llums.\n",
1594               esize,
1595               GNUNET_i2s(&n->peer),
1596               (unsigned long long) GNUNET_TIME_absolute_get_remaining (deadline).value);
1597 #endif
1598   GNUNET_assert (GNUNET_OK ==
1599                  do_encrypt (n,
1600                              &em->plaintext_hash,
1601                              &ph->sequence_number,
1602                              &em->sequence_number, esize));
1603   /* append to transmission list */
1604   if (n->encrypted_tail == NULL)
1605     n->encrypted_head = me;
1606   else
1607     n->encrypted_tail->next = me;
1608   n->encrypted_tail = me;
1609   process_encrypted_neighbour_queue (n);
1610 }
1611
1612
1613 /**
1614  * Handle CORE_SEND request.
1615  *
1616  * @param cls unused
1617  * @param client the client issuing the request
1618  * @param message the "struct SendMessage"
1619  */
1620 static void
1621 handle_client_send (void *cls,
1622                     struct GNUNET_SERVER_Client *client,
1623                     const struct GNUNET_MessageHeader *message);
1624
1625
1626 /**
1627  * Function called to notify us that we either succeeded
1628  * or failed to connect (at the transport level) to another
1629  * peer.  We should either free the message we were asked
1630  * to transmit or re-try adding it to the queue.
1631  *
1632  * @param cls closure
1633  * @param size number of bytes available in buf
1634  * @param buf where the callee should write the message
1635  * @return number of bytes written to buf
1636  */
1637 static size_t
1638 send_connect_continuation (void *cls, size_t size, void *buf)
1639 {
1640   struct SendMessage *sm = cls;
1641
1642   if (buf == NULL)
1643     {
1644 #if DEBUG_CORE
1645       GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1646                   "Asked to send message to disconnected peer `%4s' and connection failed.  Discarding message.\n",
1647                   GNUNET_i2s (&sm->peer));
1648 #endif
1649       GNUNET_free (sm);
1650       return 0;
1651     }
1652 #if DEBUG_CORE
1653   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1654               "Connection to peer `%4s' succeeded, retrying original transmission request\n",
1655               GNUNET_i2s (&sm->peer));
1656 #endif
1657   handle_client_send (NULL, NULL, &sm->header);
1658   GNUNET_free (sm);
1659   return 0;
1660 }
1661
1662
1663 /**
1664  * Handle CORE_SEND request.
1665  *
1666  * @param cls unused
1667  * @param client the client issuing the request
1668  * @param message the "struct SendMessage"
1669  */
1670 static void
1671 handle_client_send (void *cls,
1672                     struct GNUNET_SERVER_Client *client,
1673                     const struct GNUNET_MessageHeader *message)
1674 {
1675   const struct SendMessage *sm;
1676   struct SendMessage *smc;
1677   const struct GNUNET_MessageHeader *mh;
1678   struct Neighbour *n;
1679   struct MessageEntry *prev;
1680   struct MessageEntry *pos;
1681   struct MessageEntry *e; 
1682   struct MessageEntry *min_prio_entry;
1683   struct MessageEntry *min_prio_prev;
1684   unsigned int min_prio;
1685   unsigned int queue_size;
1686   uint16_t msize;
1687
1688   msize = ntohs (message->size);
1689   if (msize <
1690       sizeof (struct SendMessage) + sizeof (struct GNUNET_MessageHeader))
1691     {
1692       GNUNET_break (0);
1693       if (client != NULL)
1694         GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1695       return;
1696     }
1697   sm = (const struct SendMessage *) message;
1698   msize -= sizeof (struct SendMessage);
1699   mh = (const struct GNUNET_MessageHeader *) &sm[1];
1700   if (msize != ntohs (mh->size))
1701     {
1702       GNUNET_break (0);
1703       if (client != NULL)
1704         GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1705       return;
1706     }
1707   n = find_neighbour (&sm->peer);
1708   if (n == NULL)
1709     {
1710 #if DEBUG_CORE
1711       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1712                   "Core received `%s' request for `%4s', will try to establish connection within %llu ms\n",
1713                   "SEND",
1714                   GNUNET_i2s (&sm->peer),
1715                   GNUNET_TIME_absolute_get_remaining
1716                   (GNUNET_TIME_absolute_ntoh(sm->deadline)).value);
1717 #endif
1718       msize += sizeof (struct SendMessage);
1719       /* ask transport to connect to the peer */
1720       smc = GNUNET_malloc (msize);
1721       memcpy (smc, sm, msize);
1722       if (NULL ==
1723           GNUNET_TRANSPORT_notify_transmit_ready (transport,
1724                                                   &sm->peer,
1725                                                   0, 0,
1726                                                   GNUNET_TIME_absolute_get_remaining
1727                                                   (GNUNET_TIME_absolute_ntoh
1728                                                    (sm->deadline)),
1729                                                   &send_connect_continuation,
1730                                                   smc))
1731         {
1732           /* transport has already a request pending for this peer! */
1733 #if DEBUG_CORE
1734           GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1735                       "Dropped second message destined for `%4s' since connection is still down.\n",
1736                       GNUNET_i2s(&sm->peer));
1737 #endif
1738           GNUNET_free (smc);
1739         }
1740       if (client != NULL)
1741         GNUNET_SERVER_receive_done (client, GNUNET_OK);
1742       return;
1743     }
1744 #if DEBUG_CORE
1745   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1746               "Core received `%s' request, queueing %u bytes of plaintext data for transmission to `%4s'.\n",
1747               "SEND",
1748               msize, 
1749               GNUNET_i2s (&sm->peer));
1750 #endif
1751   /* bound queue size */
1752   discard_expired_messages (n);
1753   min_prio = (unsigned int) -1;
1754   min_prio_entry = NULL;
1755   min_prio_prev = NULL;
1756   queue_size = 0;
1757   prev = NULL;
1758   pos = n->messages;
1759   while (pos != NULL) 
1760     {
1761       if (pos->priority < min_prio)
1762         {
1763           min_prio_entry = pos;
1764           min_prio_prev = prev;
1765           min_prio = pos->priority;
1766         }
1767       queue_size++;
1768       prev = pos;
1769       pos = pos->next;
1770     }
1771   if (queue_size >= MAX_PEER_QUEUE_SIZE)
1772     {
1773       /* queue full */
1774       if (ntohl(sm->priority) <= min_prio)
1775         {
1776           /* discard new entry */
1777 #if DEBUG_CORE
1778           GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1779                       "Queue full, discarding new request\n");
1780 #endif
1781           if (client != NULL)
1782             GNUNET_SERVER_receive_done (client, GNUNET_OK);
1783           return;
1784         }
1785       /* discard "min_prio_entry" */
1786 #if DEBUG_CORE
1787       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1788                   "Queue full, discarding existing older request\n");
1789 #endif
1790       if (min_prio_prev == NULL)
1791         n->messages = min_prio_entry->next;
1792       else
1793         min_prio_prev->next = min_prio_entry->next;      
1794       GNUNET_free (min_prio_entry);     
1795     }
1796
1797 #if DEBUG_CORE
1798   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1799               "Adding transmission request for `%4s' to queue\n",
1800               GNUNET_i2s (&sm->peer));
1801 #endif  
1802   e = GNUNET_malloc (sizeof (struct MessageEntry) + msize);
1803   e->deadline = GNUNET_TIME_absolute_ntoh (sm->deadline);
1804   e->priority = ntohl (sm->priority);
1805   e->size = msize;
1806   memcpy (&e[1], mh, msize);
1807
1808   /* insert, keep list sorted by deadline */
1809   prev = NULL;
1810   pos = n->messages;
1811   while ((pos != NULL) && (pos->deadline.value < e->deadline.value))
1812     {
1813       prev = pos;
1814       pos = pos->next;
1815     }
1816   if (prev == NULL)
1817     n->messages = e;
1818   else
1819     prev->next = e;
1820   e->next = pos;
1821
1822   /* consider scheduling now */
1823   process_plaintext_neighbour_queue (n);
1824   if (client != NULL)
1825     GNUNET_SERVER_receive_done (client, GNUNET_OK);
1826 }
1827
1828
1829 /**
1830  * Handle CORE_REQUEST_CONNECT request.
1831  *
1832  * @param cls unused
1833  * @param client the client issuing the request
1834  * @param message the "struct ConnectMessage"
1835  */
1836 static void
1837 handle_client_request_connect (void *cls,
1838                                struct GNUNET_SERVER_Client *client,
1839                                const struct GNUNET_MessageHeader *message)
1840 {
1841   const struct ConnectMessage *cm = (const struct ConnectMessage*) message;
1842   struct Neighbour *n;
1843
1844   GNUNET_SERVER_receive_done (client, GNUNET_OK);
1845   n = find_neighbour (&cm->peer);
1846   if (n != NULL)
1847     return; /* already connected, or at least trying */
1848 #if DEBUG_CORE
1849   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1850               "Core received `%s' request for `%4s', will try to establish connection\n",
1851               "REQUEST_CONNECT",
1852               GNUNET_i2s (&cm->peer));
1853 #endif
1854   /* ask transport to connect to the peer */
1855   /* FIXME: timeout zero OK? need for cancellation? */
1856   GNUNET_TRANSPORT_notify_transmit_ready (transport,
1857                                           &cm->peer,
1858                                           0, 0,
1859                                           GNUNET_TIME_UNIT_ZERO,
1860                                           NULL,
1861                                           NULL);
1862 }
1863
1864
1865 /**
1866  * Handle CORE_REQUEST_DISCONNECT request.
1867  *
1868  * @param cls unused
1869  * @param client the client issuing the request
1870  * @param message the "struct ConnectMessage"
1871  */
1872 static void
1873 handle_client_request_disconnect (void *cls,
1874                                   struct GNUNET_SERVER_Client *client,
1875                                   const struct GNUNET_MessageHeader *message)
1876 {
1877   const struct ConnectMessage *cm = (const struct ConnectMessage*) message;
1878   struct Neighbour *n;
1879
1880   GNUNET_SERVER_receive_done (client, GNUNET_OK);
1881   n = find_neighbour (&cm->peer);
1882   if (n == NULL)
1883     return; /* done */
1884   /* FIXME: implement disconnect! */
1885 }
1886
1887
1888
1889 /**
1890  * List of handlers for the messages understood by this
1891  * service.
1892  */
1893 static struct GNUNET_SERVER_MessageHandler handlers[] = {
1894   {&handle_client_init, NULL,
1895    GNUNET_MESSAGE_TYPE_CORE_INIT, 0},
1896   {&handle_client_request_info, NULL,
1897    GNUNET_MESSAGE_TYPE_CORE_REQUEST_INFO,
1898    sizeof (struct RequestInfoMessage)},
1899   {&handle_client_send, NULL,
1900    GNUNET_MESSAGE_TYPE_CORE_SEND, 0},
1901   {&handle_client_request_connect, NULL,
1902    GNUNET_MESSAGE_TYPE_CORE_REQUEST_CONNECT,
1903    sizeof (struct ConnectMessage)},
1904   {&handle_client_request_disconnect, NULL,
1905    GNUNET_MESSAGE_TYPE_CORE_REQUEST_DISCONNECT,
1906    sizeof (struct ConnectMessage)},
1907   {NULL, NULL, 0, 0}
1908 };
1909
1910
1911 /**
1912  * PEERINFO is giving us a HELLO for a peer.  Add the public key to
1913  * the neighbour's struct and retry send_key.  Or, if we did not get a
1914  * HELLO, just do nothing.
1915  *
1916  * @param cls NULL
1917  * @param peer the peer for which this is the HELLO
1918  * @param hello HELLO message of that peer
1919  * @param trust amount of trust we currently have in that peer
1920  */
1921 static void
1922 process_hello_retry_send_key (void *cls,
1923                               const struct GNUNET_PeerIdentity *peer,
1924                               const struct GNUNET_HELLO_Message *hello,
1925                               uint32_t trust)
1926 {
1927   struct Neighbour *n = cls;
1928
1929   if (peer == NULL)
1930     {
1931       n->pitr = NULL;
1932       return;
1933     }
1934   if (n->public_key != NULL)
1935     return;
1936 #if DEBUG_CORE
1937   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1938               "Received new `%s' message for `%4s', initiating key exchange.\n",
1939               "HELLO",
1940               GNUNET_i2s (peer));
1941 #endif
1942   n->public_key =
1943     GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded));
1944   if (GNUNET_OK != GNUNET_HELLO_get_key (hello, n->public_key))
1945     {
1946       GNUNET_free (n->public_key);
1947       n->public_key = NULL;
1948       return;
1949     }
1950   send_key (n);
1951 }
1952
1953
1954 /**
1955  * Task that will retry "send_key" if our previous attempt failed
1956  * to yield a PONG.
1957  */
1958 static void
1959 set_key_retry_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1960 {
1961   struct Neighbour *n = cls;
1962
1963   n->retry_set_key_task = GNUNET_SCHEDULER_NO_TASK;
1964   n->set_key_retry_frequency =
1965     GNUNET_TIME_relative_multiply (n->set_key_retry_frequency, 2);
1966   send_key (n);
1967 }
1968
1969
1970 /**
1971  * Send our key (and encrypted PING) to the other peer.
1972  *
1973  * @param n the other peer
1974  */
1975 static void
1976 send_key (struct Neighbour *n)
1977 {
1978   struct SetKeyMessage *sm;
1979   struct MessageEntry *me;
1980   struct PingMessage pp;
1981   struct PingMessage *pm;
1982
1983   if ( (n->retry_set_key_task != GNUNET_SCHEDULER_NO_TASK) ||
1984        (n->pitr != NULL) )
1985     return; /* already in progress */
1986 #if DEBUG_CORE
1987   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1988               "Asked to perform key exchange with `%4s'.\n",
1989               GNUNET_i2s (&n->peer));
1990 #endif
1991   if (n->public_key == NULL)
1992     {
1993       /* lookup n's public key, then try again */
1994 #if DEBUG_CORE
1995       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1996                   "Lacking public key for `%4s', trying to obtain one.\n",
1997                   GNUNET_i2s (&n->peer));
1998 #endif
1999       GNUNET_assert (n->pitr == NULL);
2000       n->pitr = GNUNET_PEERINFO_iterate (cfg,
2001                                          sched,
2002                                          &n->peer,
2003                                          0,
2004                                          GNUNET_TIME_UNIT_MINUTES,
2005                                          &process_hello_retry_send_key, n);
2006       return;
2007     }
2008   /* first, set key message */
2009   me = GNUNET_malloc (sizeof (struct MessageEntry) +
2010                       sizeof (struct SetKeyMessage));
2011   me->deadline = GNUNET_TIME_relative_to_absolute (MAX_SET_KEY_DELAY);
2012   me->priority = SET_KEY_PRIORITY;
2013   me->size = sizeof (struct SetKeyMessage);
2014   if (n->encrypted_head == NULL)
2015     n->encrypted_head = me;
2016   else
2017     n->encrypted_tail->next = me;
2018   n->encrypted_tail = me;
2019   sm = (struct SetKeyMessage *) &me[1];
2020   sm->header.size = htons (sizeof (struct SetKeyMessage));
2021   sm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_SET_KEY);
2022   sm->sender_status = htonl ((int32_t) ((n->status == PEER_STATE_DOWN) ?
2023                                         PEER_STATE_KEY_SENT : n->status));
2024   sm->purpose.size =
2025     htonl (sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) +
2026            sizeof (struct GNUNET_TIME_AbsoluteNBO) +
2027            sizeof (struct GNUNET_CRYPTO_RsaEncryptedData) +
2028            sizeof (struct GNUNET_PeerIdentity));
2029   sm->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_SET_KEY);
2030   sm->creation_time = GNUNET_TIME_absolute_hton (n->encrypt_key_created);
2031   sm->target = n->peer;
2032   GNUNET_assert (GNUNET_OK ==
2033                  GNUNET_CRYPTO_rsa_encrypt (&n->encrypt_key,
2034                                             sizeof (struct
2035                                                     GNUNET_CRYPTO_AesSessionKey),
2036                                             n->public_key,
2037                                             &sm->encrypted_key));
2038   GNUNET_assert (GNUNET_OK ==
2039                  GNUNET_CRYPTO_rsa_sign (my_private_key, &sm->purpose,
2040                                          &sm->signature));
2041
2042   /* second, encrypted PING message */
2043   me = GNUNET_malloc (sizeof (struct MessageEntry) +
2044                       sizeof (struct PingMessage));
2045   me->deadline = GNUNET_TIME_relative_to_absolute (MAX_PING_DELAY);
2046   me->priority = PING_PRIORITY;
2047   me->size = sizeof (struct PingMessage);
2048   n->encrypted_tail->next = me;
2049   n->encrypted_tail = me;
2050   pm = (struct PingMessage *) &me[1];
2051   pm->header.size = htons (sizeof (struct PingMessage));
2052   pm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_PING);
2053   pp.challenge = htonl (n->ping_challenge);
2054   pp.target = n->peer;
2055 #if DEBUG_CORE
2056   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2057               "Encrypting `%s' and `%s' messages for `%4s'.\n",
2058               "SET_KEY", "PING", GNUNET_i2s (&n->peer));
2059   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2060               "Sending `%s' to `%4s' with challenge %u encrypted using key %u\n",
2061               "PING",
2062               GNUNET_i2s (&n->peer), n->ping_challenge, n->encrypt_key.crc32);
2063 #endif
2064   do_encrypt (n,
2065               &n->peer.hashPubKey,
2066               &pp.challenge,
2067               &pm->challenge,
2068               sizeof (struct PingMessage) -
2069               sizeof (struct GNUNET_MessageHeader));
2070   /* update status */
2071   switch (n->status)
2072     {
2073     case PEER_STATE_DOWN:
2074       n->status = PEER_STATE_KEY_SENT;
2075       break;
2076     case PEER_STATE_KEY_SENT:
2077       break;
2078     case PEER_STATE_KEY_RECEIVED:
2079       break;
2080     case PEER_STATE_KEY_CONFIRMED:
2081       break;
2082     default:
2083       GNUNET_break (0);
2084       break;
2085     }
2086 #if DEBUG_CORE
2087   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2088               "Have %llu ms left for `%s' transmission.\n",
2089               (unsigned long long) GNUNET_TIME_absolute_get_remaining (me->deadline).value,
2090               "SET_KEY");
2091 #endif
2092   /* trigger queue processing */
2093   process_encrypted_neighbour_queue (n);
2094   if (n->status != PEER_STATE_KEY_CONFIRMED)
2095     {
2096       GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == n->retry_set_key_task);
2097       n->retry_set_key_task
2098         = GNUNET_SCHEDULER_add_delayed (sched,
2099                                         n->set_key_retry_frequency,
2100                                         &set_key_retry_task, n);
2101     }
2102 }
2103
2104
2105 /**
2106  * We received a SET_KEY message.  Validate and update
2107  * our key material and status.
2108  *
2109  * @param n the neighbour from which we received message m
2110  * @param m the set key message we received
2111  */
2112 static void
2113 handle_set_key (struct Neighbour *n, const struct SetKeyMessage *m);
2114
2115
2116 /**
2117  * PEERINFO is giving us a HELLO for a peer.  Add the public key to
2118  * the neighbour's struct and retry handling the set_key message.  Or,
2119  * if we did not get a HELLO, just free the set key message.
2120  *
2121  * @param cls pointer to the set key message
2122  * @param peer the peer for which this is the HELLO
2123  * @param hello HELLO message of that peer
2124  * @param trust amount of trust we currently have in that peer
2125  */
2126 static void
2127 process_hello_retry_handle_set_key (void *cls,
2128                                     const struct GNUNET_PeerIdentity *peer,
2129                                     const struct GNUNET_HELLO_Message *hello,
2130                                     uint32_t trust)
2131 {
2132   struct Neighbour *n = cls;
2133   struct SetKeyMessage *sm = n->skm;
2134
2135   if (peer == NULL)
2136     {
2137       GNUNET_free (sm);
2138       n->skm = NULL;
2139       n->pitr = NULL;
2140       return;
2141     }
2142   if (n->public_key != NULL)
2143     return;                     /* multiple HELLOs match!? */
2144   n->public_key =
2145     GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded));
2146   if (GNUNET_OK != GNUNET_HELLO_get_key (hello, n->public_key))
2147     {
2148       GNUNET_break_op (0);
2149       GNUNET_free (n->public_key);
2150       n->public_key = NULL;
2151       return;
2152     }
2153 #if DEBUG_CORE
2154   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2155               "Received `%s' for `%4s', continuing processing of `%s' message.\n",
2156               "HELLO", GNUNET_i2s (peer), "SET_KEY");
2157 #endif
2158   handle_set_key (n, sm);
2159 }
2160
2161
2162 /**
2163  * We received a PING message.  Validate and transmit
2164  * PONG.
2165  *
2166  * @param n sender of the PING
2167  * @param m the encrypted PING message itself
2168  */
2169 static void
2170 handle_ping (struct Neighbour *n, const struct PingMessage *m)
2171 {
2172   struct PingMessage t;
2173   struct PingMessage *tp;
2174   struct MessageEntry *me;
2175
2176 #if DEBUG_CORE
2177   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2178               "Core service receives `%s' request from `%4s'.\n",
2179               "PING", GNUNET_i2s (&n->peer));
2180 #endif
2181   if (GNUNET_OK !=
2182       do_decrypt (n,
2183                   &my_identity.hashPubKey,
2184                   &m->challenge,
2185                   &t.challenge,
2186                   sizeof (struct PingMessage) -
2187                   sizeof (struct GNUNET_MessageHeader)))
2188     return;
2189 #if DEBUG_CORE
2190   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2191               "Decrypted `%s' to `%4s' with challenge %u decrypted using key %u\n",
2192               "PING",
2193               GNUNET_i2s (&t.target),
2194               ntohl (t.challenge), n->decrypt_key.crc32);
2195   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2196               "Target of `%s' request is `%4s'.\n",
2197               "PING", GNUNET_i2s (&t.target));
2198 #endif
2199   if (0 != memcmp (&t.target,
2200                    &my_identity, sizeof (struct GNUNET_PeerIdentity)))
2201     {
2202       GNUNET_break_op (0);
2203       return;
2204     }
2205   me = GNUNET_malloc (sizeof (struct MessageEntry) +
2206                       sizeof (struct PingMessage));
2207   if (n->encrypted_tail != NULL)
2208     n->encrypted_tail->next = me;
2209   else
2210     {
2211       n->encrypted_tail = me;
2212       n->encrypted_head = me;
2213     }
2214   me->deadline = GNUNET_TIME_relative_to_absolute (MAX_PONG_DELAY);
2215   me->priority = PONG_PRIORITY;
2216   me->size = sizeof (struct PingMessage);
2217   tp = (struct PingMessage *) &me[1];
2218   tp->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_PONG);
2219   tp->header.size = htons (sizeof (struct PingMessage));
2220   do_encrypt (n,
2221               &my_identity.hashPubKey,
2222               &t.challenge,
2223               &tp->challenge,
2224               sizeof (struct PingMessage) -
2225               sizeof (struct GNUNET_MessageHeader));
2226 #if DEBUG_CORE
2227   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2228               "Encrypting `%s' with challenge %u using key %u\n", "PONG",
2229               ntohl (t.challenge), n->encrypt_key.crc32);
2230 #endif
2231   /* trigger queue processing */
2232   process_encrypted_neighbour_queue (n);
2233 }
2234
2235
2236 /**
2237  * We received a SET_KEY message.  Validate and update
2238  * our key material and status.
2239  *
2240  * @param n the neighbour from which we received message m
2241  * @param m the set key message we received
2242  */
2243 static void
2244 handle_set_key (struct Neighbour *n, const struct SetKeyMessage *m)
2245 {
2246   struct SetKeyMessage *m_cpy;
2247   struct GNUNET_TIME_Absolute t;
2248   struct GNUNET_CRYPTO_AesSessionKey k;
2249   struct PingMessage *ping;
2250   enum PeerStateMachine sender_status;
2251
2252 #if DEBUG_CORE
2253   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2254               "Core service receives `%s' request from `%4s'.\n",
2255               "SET_KEY", GNUNET_i2s (&n->peer));
2256 #endif
2257   if (n->public_key == NULL)
2258     {
2259 #if DEBUG_CORE
2260       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2261                   "Lacking public key for peer, trying to obtain one.\n");
2262 #endif
2263       m_cpy = GNUNET_malloc (sizeof (struct SetKeyMessage));
2264       memcpy (m_cpy, m, sizeof (struct SetKeyMessage));
2265       /* lookup n's public key, then try again */
2266       GNUNET_assert (n->pitr == NULL);
2267       GNUNET_assert (n->skm == NULL);
2268       n->skm = m_cpy;
2269       n->pitr = GNUNET_PEERINFO_iterate (cfg,
2270                                          sched,
2271                                          &n->peer,
2272                                          0,
2273                                          GNUNET_TIME_UNIT_MINUTES,
2274                                          &process_hello_retry_handle_set_key, n);
2275       return;
2276     }
2277   if (0 != memcmp (&m->target,
2278                    &my_identity,
2279                    sizeof (struct GNUNET_PeerIdentity)))
2280     {
2281       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2282                   _("Received `%s' message that was not for me.  Ignoring.\n"));
2283       return;
2284     }
2285   if ((ntohl (m->purpose.size) !=
2286        sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) +
2287        sizeof (struct GNUNET_TIME_AbsoluteNBO) +
2288        sizeof (struct GNUNET_CRYPTO_RsaEncryptedData) +
2289        sizeof (struct GNUNET_PeerIdentity)) ||
2290       (GNUNET_OK !=
2291        GNUNET_CRYPTO_rsa_verify (GNUNET_SIGNATURE_PURPOSE_SET_KEY,
2292                                  &m->purpose, &m->signature, n->public_key)))
2293     {
2294       /* invalid signature */
2295       GNUNET_break_op (0);
2296       return;
2297     }
2298   t = GNUNET_TIME_absolute_ntoh (m->creation_time);
2299   if (((n->status == PEER_STATE_KEY_RECEIVED) ||
2300        (n->status == PEER_STATE_KEY_CONFIRMED)) &&
2301       (t.value < n->decrypt_key_created.value))
2302     {
2303       /* this could rarely happen due to massive re-ordering of
2304          messages on the network level, but is most likely either
2305          a bug or some adversary messing with us.  Report. */
2306       GNUNET_break_op (0);
2307       return;
2308     }
2309 #if DEBUG_CORE
2310   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Decrypting key material.\n");
2311 #endif  
2312   if ((GNUNET_CRYPTO_rsa_decrypt (my_private_key,
2313                                   &m->encrypted_key,
2314                                   &k,
2315                                   sizeof (struct GNUNET_CRYPTO_AesSessionKey))
2316        != sizeof (struct GNUNET_CRYPTO_AesSessionKey)) ||
2317       (GNUNET_OK != GNUNET_CRYPTO_aes_check_session_key (&k)))
2318     {
2319       /* failed to decrypt !? */
2320       GNUNET_break_op (0);
2321       return;
2322     }
2323
2324   n->decrypt_key = k;
2325   if (n->decrypt_key_created.value != t.value)
2326     {
2327       /* fresh key, reset sequence numbers */
2328       n->last_sequence_number_received = 0;
2329       n->last_packets_bitmap = 0;
2330       n->decrypt_key_created = t;
2331     }
2332   sender_status = (enum PeerStateMachine) ntohl (m->sender_status);
2333   switch (n->status)
2334     {
2335     case PEER_STATE_DOWN:
2336       n->status = PEER_STATE_KEY_RECEIVED;
2337 #if DEBUG_CORE
2338       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2339                   "Responding to `%s' with my own key.\n", "SET_KEY");
2340 #endif
2341       send_key (n);
2342       break;
2343     case PEER_STATE_KEY_SENT:
2344     case PEER_STATE_KEY_RECEIVED:
2345       n->status = PEER_STATE_KEY_RECEIVED;
2346       if ((sender_status != PEER_STATE_KEY_RECEIVED) &&
2347           (sender_status != PEER_STATE_KEY_CONFIRMED))
2348         {
2349 #if DEBUG_CORE
2350           GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2351                       "Responding to `%s' with my own key (other peer has status %u).\n",
2352                       "SET_KEY", sender_status);
2353 #endif
2354           send_key (n);
2355         }
2356       break;
2357     case PEER_STATE_KEY_CONFIRMED:
2358       if ((sender_status != PEER_STATE_KEY_RECEIVED) &&
2359           (sender_status != PEER_STATE_KEY_CONFIRMED))
2360         {         
2361 #if DEBUG_CORE
2362           GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2363                       "Responding to `%s' with my own key (other peer has status %u), I was already fully up.\n",
2364                       "SET_KEY", sender_status);
2365 #endif
2366           send_key (n);
2367         }
2368       break;
2369     default:
2370       GNUNET_break (0);
2371       break;
2372     }
2373   if (n->pending_ping != NULL)
2374     {
2375       ping = n->pending_ping;
2376       n->pending_ping = NULL;
2377       handle_ping (n, ping);
2378       GNUNET_free (ping);
2379     }
2380 }
2381
2382
2383 /**
2384  * We received a PONG message.  Validate and update our status.
2385  *
2386  * @param n sender of the PONG
2387  * @param m the encrypted PONG message itself
2388  */
2389 static void
2390 handle_pong (struct Neighbour *n, const struct PingMessage *m)
2391 {
2392   struct PingMessage t;
2393   struct ConnectNotifyMessage cnm;
2394
2395 #if DEBUG_CORE
2396   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2397               "Core service receives `%s' request from `%4s'.\n",
2398               "PONG", GNUNET_i2s (&n->peer));
2399 #endif
2400   if (GNUNET_OK !=
2401       do_decrypt (n,
2402                   &n->peer.hashPubKey,
2403                   &m->challenge,
2404                   &t.challenge,
2405                   sizeof (struct PingMessage) -
2406                   sizeof (struct GNUNET_MessageHeader)))
2407     return;
2408 #if DEBUG_CORE
2409   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2410               "Decrypted `%s' from `%4s' with challenge %u using key %u\n",
2411               "PONG",
2412               GNUNET_i2s (&t.target),
2413               ntohl (t.challenge), n->decrypt_key.crc32);
2414 #endif
2415   if ((0 != memcmp (&t.target,
2416                     &n->peer,
2417                     sizeof (struct GNUNET_PeerIdentity))) ||
2418       (n->ping_challenge != ntohl (t.challenge)))
2419     {
2420       /* PONG malformed */
2421 #if DEBUG_CORE
2422       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2423                   "Received malfromed `%s' wanted sender `%4s' with challenge %u\n",
2424                   "PONG", GNUNET_i2s (&n->peer), n->ping_challenge);
2425       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2426                   "Received malfromed `%s' received from `%4s' with challenge %u\n",
2427                   "PONG", GNUNET_i2s (&t.target), ntohl (t.challenge));
2428 #endif
2429       GNUNET_break_op (0);
2430       return;
2431     }
2432   switch (n->status)
2433     {
2434     case PEER_STATE_DOWN:
2435       GNUNET_break (0);         /* should be impossible */
2436       return;
2437     case PEER_STATE_KEY_SENT:
2438       GNUNET_break (0);         /* should be impossible, how did we decrypt? */
2439       return;
2440     case PEER_STATE_KEY_RECEIVED:
2441       n->status = PEER_STATE_KEY_CONFIRMED;
2442       if (n->retry_set_key_task != GNUNET_SCHEDULER_NO_TASK)
2443         {
2444           GNUNET_SCHEDULER_cancel (sched, n->retry_set_key_task);
2445           n->retry_set_key_task = GNUNET_SCHEDULER_NO_TASK;
2446         }      
2447       cnm.header.size = htons (sizeof (struct ConnectNotifyMessage));
2448       cnm.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT);
2449       cnm.distance = htonl (n->last_distance);
2450       cnm.latency = GNUNET_TIME_relative_hton (n->last_latency);
2451       cnm.peer = n->peer;
2452       send_to_all_clients (&cnm.header, GNUNET_YES, GNUNET_CORE_OPTION_SEND_CONNECT);
2453       process_encrypted_neighbour_queue (n);
2454       break;
2455     case PEER_STATE_KEY_CONFIRMED:
2456       /* duplicate PONG? */
2457       break;
2458     default:
2459       GNUNET_break (0);
2460       break;
2461     }
2462 }
2463
2464
2465 /**
2466  * Send a P2P message to a client.
2467  *
2468  * @param sender who sent us the message?
2469  * @param client who should we give the message to?
2470  * @param m contains the message to transmit
2471  * @param msize number of bytes in buf to transmit
2472  */
2473 static void
2474 send_p2p_message_to_client (struct Neighbour *sender,
2475                             struct Client *client,
2476                             const void *m, size_t msize)
2477 {
2478   char buf[msize + sizeof (struct NotifyTrafficMessage)];
2479   struct NotifyTrafficMessage *ntm;
2480
2481 #if DEBUG_CORE
2482   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2483               "Core service passes message from `%4s' of type %u to client.\n",
2484               GNUNET_i2s(&sender->peer),
2485               ntohs (((const struct GNUNET_MessageHeader *) m)->type));
2486 #endif
2487   ntm = (struct NotifyTrafficMessage *) buf;
2488   ntm->header.size = htons (msize + sizeof (struct NotifyTrafficMessage));
2489   ntm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_INBOUND);
2490   ntm->distance = htonl (sender->last_distance);
2491   ntm->latency = GNUNET_TIME_relative_hton (sender->last_latency);
2492   ntm->peer = sender->peer;
2493   memcpy (&ntm[1], m, msize);
2494   send_to_client (client, &ntm->header, GNUNET_YES);
2495 }
2496
2497
2498 /**
2499  * Deliver P2P message to interested clients.
2500  *
2501  * @param sender who sent us the message?
2502  * @param m the message
2503  * @param msize size of the message (including header)
2504  */
2505 static void
2506 deliver_message (struct Neighbour *sender,
2507                  const struct GNUNET_MessageHeader *m, size_t msize)
2508 {
2509   struct Client *cpos;
2510   uint16_t type;
2511   unsigned int tpos;
2512   int deliver_full;
2513
2514   type = ntohs (m->type);
2515   cpos = clients;
2516   while (cpos != NULL)
2517     {
2518       deliver_full = GNUNET_NO;
2519       if (0 != (cpos->options & GNUNET_CORE_OPTION_SEND_FULL_INBOUND))
2520         deliver_full = GNUNET_YES;
2521       else
2522         {
2523           for (tpos = 0; tpos < cpos->tcnt; tpos++)
2524             {
2525               if (type != cpos->types[tpos])
2526                 continue;
2527               deliver_full = GNUNET_YES;
2528               break;
2529             }
2530         }
2531       if (GNUNET_YES == deliver_full)
2532         send_p2p_message_to_client (sender, cpos, m, msize);
2533       else if (cpos->options & GNUNET_CORE_OPTION_SEND_HDR_INBOUND)
2534         send_p2p_message_to_client (sender, cpos, m,
2535                                     sizeof (struct GNUNET_MessageHeader));
2536       cpos = cpos->next;
2537     }
2538 }
2539
2540
2541 /**
2542  * Align P2P message and then deliver to interested clients.
2543  *
2544  * @param sender who sent us the message?
2545  * @param buffer unaligned (!) buffer containing message
2546  * @param msize size of the message (including header)
2547  */
2548 static void
2549 align_and_deliver (struct Neighbour *sender, const char *buffer, size_t msize)
2550 {
2551   char abuf[msize];
2552
2553   /* TODO: call to statistics? */
2554   memcpy (abuf, buffer, msize);
2555   deliver_message (sender, (const struct GNUNET_MessageHeader *) abuf, msize);
2556 }
2557
2558
2559 /**
2560  * Deliver P2P messages to interested clients.
2561  *
2562  * @param sender who sent us the message?
2563  * @param buffer buffer containing messages, can be modified
2564  * @param buffer_size size of the buffer (overall)
2565  * @param offset offset where messages in the buffer start
2566  */
2567 static void
2568 deliver_messages (struct Neighbour *sender,
2569                   const char *buffer, size_t buffer_size, size_t offset)
2570 {
2571   struct GNUNET_MessageHeader *mhp;
2572   struct GNUNET_MessageHeader mh;
2573   uint16_t msize;
2574   int need_align;
2575
2576   while (offset + sizeof (struct GNUNET_MessageHeader) <= buffer_size)
2577     {
2578       if (0 != offset % sizeof (uint16_t))
2579         {
2580           /* outch, need to copy to access header */
2581           memcpy (&mh, &buffer[offset], sizeof (struct GNUNET_MessageHeader));
2582           mhp = &mh;
2583         }
2584       else
2585         {
2586           /* can access header directly */
2587           mhp = (struct GNUNET_MessageHeader *) &buffer[offset];
2588         }
2589       msize = ntohs (mhp->size);
2590       if (msize + offset > buffer_size)
2591         {
2592           /* malformed message, header says it is larger than what
2593              would fit into the overall buffer */
2594           GNUNET_break_op (0);
2595           break;
2596         }
2597 #if HAVE_UNALIGNED_64_ACCESS
2598       need_align = (0 != offset % 4) ? GNUNET_YES : GNUNET_NO;
2599 #else
2600       need_align = (0 != offset % 8) ? GNUNET_YES : GNUNET_NO;
2601 #endif
2602       if (GNUNET_YES == need_align)
2603         align_and_deliver (sender, &buffer[offset], msize);
2604       else
2605         deliver_message (sender,
2606                          (const struct GNUNET_MessageHeader *)
2607                          &buffer[offset], msize);
2608       offset += msize;
2609     }
2610 }
2611
2612
2613 /**
2614  * We received an encrypted message.  Decrypt, validate and
2615  * pass on to the appropriate clients.
2616  */
2617 static void
2618 handle_encrypted_message (struct Neighbour *n,
2619                           const struct EncryptedMessage *m)
2620 {
2621   size_t size = ntohs (m->header.size);
2622   char buf[size];
2623   struct EncryptedMessage *pt;  /* plaintext */
2624   GNUNET_HashCode ph;
2625   size_t off;
2626   uint32_t snum;
2627   struct GNUNET_TIME_Absolute t;
2628
2629 #if DEBUG_CORE
2630   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2631               "Core service receives `%s' request from `%4s'.\n",
2632               "ENCRYPTED_MESSAGE", GNUNET_i2s (&n->peer));
2633 #endif  
2634   /* decrypt */
2635   if (GNUNET_OK !=
2636       do_decrypt (n,
2637                   &m->plaintext_hash,
2638                   &m->sequence_number,
2639                   &buf[ENCRYPTED_HEADER_SIZE], size - ENCRYPTED_HEADER_SIZE))
2640     return;
2641   pt = (struct EncryptedMessage *) buf;
2642
2643   /* validate hash */
2644   GNUNET_CRYPTO_hash (&pt->sequence_number,
2645                       size - ENCRYPTED_HEADER_SIZE, &ph);
2646   if (0 != memcmp (&ph, &m->plaintext_hash, sizeof (GNUNET_HashCode)))
2647     {
2648       /* checksum failed */
2649       GNUNET_break_op (0);
2650       return;
2651     }
2652
2653   /* validate sequence number */
2654   snum = ntohl (pt->sequence_number);
2655   if (n->last_sequence_number_received == snum)
2656     {
2657       GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2658                   "Received duplicate message, ignoring.\n");
2659       /* duplicate, ignore */
2660       return;
2661     }
2662   if ((n->last_sequence_number_received > snum) &&
2663       (n->last_sequence_number_received - snum > 32))
2664     {
2665       GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2666                   "Received ancient out of sequence message, ignoring.\n");
2667       /* ancient out of sequence, ignore */
2668       return;
2669     }
2670   if (n->last_sequence_number_received > snum)
2671     {
2672       unsigned int rotbit =
2673         1 << (n->last_sequence_number_received - snum - 1);
2674       if ((n->last_packets_bitmap & rotbit) != 0)
2675         {
2676           GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2677                       "Received duplicate message, ignoring.\n");
2678           /* duplicate, ignore */
2679           return;
2680         }
2681       n->last_packets_bitmap |= rotbit;
2682     }
2683   if (n->last_sequence_number_received < snum)
2684     {
2685       n->last_packets_bitmap <<= (snum - n->last_sequence_number_received);
2686       n->last_sequence_number_received = snum;
2687     }
2688
2689   /* check timestamp */
2690   t = GNUNET_TIME_absolute_ntoh (pt->timestamp);
2691   if (GNUNET_TIME_absolute_get_duration (t).value > MAX_MESSAGE_AGE.value)
2692     {
2693       GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2694                   _
2695                   ("Message received far too old (%llu ms). Content ignored.\n"),
2696                   GNUNET_TIME_absolute_get_duration (t).value);
2697       return;
2698     }
2699
2700   /* process decrypted message(s) */
2701   update_window (GNUNET_YES,
2702                  &n->available_send_window,
2703                  &n->last_asw_update,
2704                  n->bpm_out);
2705   n->bpm_out_external_limit = ntohl (pt->inbound_bpm_limit);
2706   n->bpm_out = GNUNET_MAX (n->bpm_out_external_limit,
2707                            n->bpm_out_internal_limit);
2708   n->last_activity = GNUNET_TIME_absolute_get ();
2709   off = sizeof (struct EncryptedMessage);
2710   deliver_messages (n, buf, size, off);
2711 }
2712
2713
2714 /**
2715  * Function called by the transport for each received message.
2716  *
2717  * @param cls closure
2718  * @param peer (claimed) identity of the other peer
2719  * @param message the message
2720  * @param latency estimated latency for communicating with the
2721  *             given peer (round-trip)
2722  * @param distance in overlay hops, as given by transport plugin
2723  */
2724 static void
2725 handle_transport_receive (void *cls,
2726                           const struct GNUNET_PeerIdentity *peer,
2727                           const struct GNUNET_MessageHeader *message,
2728                           struct GNUNET_TIME_Relative latency,
2729                           unsigned int distance)
2730 {
2731   struct Neighbour *n;
2732   struct GNUNET_TIME_Absolute now;
2733   int up;
2734   uint16_t type;
2735   uint16_t size;
2736
2737 #if DEBUG_CORE
2738   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2739               "Received message of type %u from `%4s', demultiplexing.\n",
2740               ntohs (message->type), GNUNET_i2s (peer));
2741 #endif
2742   n = find_neighbour (peer);
2743   if (n == NULL)
2744     {
2745       GNUNET_break (0);
2746       return;
2747     }
2748   n->last_latency = latency;
2749   up = (n->status == PEER_STATE_KEY_CONFIRMED);
2750   type = ntohs (message->type);
2751   size = ntohs (message->size);
2752   switch (type)
2753     {
2754     case GNUNET_MESSAGE_TYPE_CORE_SET_KEY:
2755       if (size != sizeof (struct SetKeyMessage))
2756         {
2757           GNUNET_break_op (0);
2758           return;
2759         }
2760       handle_set_key (n, (const struct SetKeyMessage *) message);
2761       break;
2762     case GNUNET_MESSAGE_TYPE_CORE_ENCRYPTED_MESSAGE:
2763       if (size < sizeof (struct EncryptedMessage) +
2764           sizeof (struct GNUNET_MessageHeader))
2765         {
2766           GNUNET_break_op (0);
2767           return;
2768         }
2769       if ((n->status != PEER_STATE_KEY_RECEIVED) &&
2770           (n->status != PEER_STATE_KEY_CONFIRMED))
2771         {
2772           GNUNET_break_op (0);
2773           return;
2774         }
2775       handle_encrypted_message (n, (const struct EncryptedMessage *) message);
2776       break;
2777     case GNUNET_MESSAGE_TYPE_CORE_PING:
2778       if (size != sizeof (struct PingMessage))
2779         {
2780           GNUNET_break_op (0);
2781           return;
2782         }
2783       if ((n->status != PEER_STATE_KEY_RECEIVED) &&
2784           (n->status != PEER_STATE_KEY_CONFIRMED))
2785         {
2786 #if DEBUG_CORE
2787           GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2788                       "Core service receives `%s' request from `%4s' but have not processed key; marking as pending.\n",
2789                       "PING", GNUNET_i2s (&n->peer));
2790 #endif
2791           GNUNET_free_non_null (n->pending_ping);
2792           n->pending_ping = GNUNET_malloc (sizeof (struct PingMessage));
2793           memcpy (n->pending_ping, message, sizeof (struct PingMessage));
2794           return;
2795         }
2796       handle_ping (n, (const struct PingMessage *) message);
2797       break;
2798     case GNUNET_MESSAGE_TYPE_CORE_PONG:
2799       if (size != sizeof (struct PingMessage))
2800         {
2801           GNUNET_break_op (0);
2802           return;
2803         }
2804       if ((n->status != PEER_STATE_KEY_SENT) &&
2805           (n->status != PEER_STATE_KEY_RECEIVED) &&
2806           (n->status != PEER_STATE_KEY_CONFIRMED))
2807         {
2808           /* could not decrypt pong, oops! */
2809           GNUNET_break_op (0);
2810           return;
2811         }
2812       handle_pong (n, (const struct PingMessage *) message);
2813       break;
2814     default:
2815       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2816                   _("Unsupported message of type %u received.\n"), type);
2817       return;
2818     }
2819   if (n->status == PEER_STATE_KEY_CONFIRMED)
2820     {
2821       now = GNUNET_TIME_absolute_get ();
2822       n->last_activity = now;
2823       if (!up)
2824         n->time_established = now;
2825     }
2826 }
2827
2828
2829 /**
2830  * Function that recalculates the bandwidth quota for the
2831  * given neighbour and transmits it to the transport service.
2832  * 
2833  * @param cls neighbour for the quota update
2834  * @param tc context
2835  */
2836 static void
2837 neighbour_quota_update (void *cls,
2838                         const struct GNUNET_SCHEDULER_TaskContext *tc);
2839
2840
2841 /**
2842  * Schedule the task that will recalculate the bandwidth
2843  * quota for this peer (and possibly force a disconnect of
2844  * idle peers by calculating a bandwidth of zero).
2845  */
2846 static void
2847 schedule_quota_update (struct Neighbour *n)
2848 {
2849   GNUNET_assert (n->quota_update_task ==
2850                  GNUNET_SCHEDULER_NO_TASK);
2851   n->quota_update_task
2852     = GNUNET_SCHEDULER_add_delayed (sched,
2853                                     QUOTA_UPDATE_FREQUENCY,
2854                                     &neighbour_quota_update,
2855                                     n);
2856 }
2857
2858
2859 /**
2860  * Function that recalculates the bandwidth quota for the
2861  * given neighbour and transmits it to the transport service.
2862  * 
2863  * @param cls neighbour for the quota update
2864  * @param tc context
2865  */
2866 static void
2867 neighbour_quota_update (void *cls,
2868                         const struct GNUNET_SCHEDULER_TaskContext *tc)
2869 {
2870   struct Neighbour *n = cls;
2871   uint32_t q_in;
2872   double pref_rel;
2873   double share;
2874   unsigned long long distributable;
2875   
2876   n->quota_update_task = GNUNET_SCHEDULER_NO_TASK;
2877   /* calculate relative preference among all neighbours;
2878      divides by a bit more to avoid division by zero AND to
2879      account for possibility of new neighbours joining any time 
2880      AND to convert to double... */
2881   pref_rel = n->current_preference / (1.0 + preference_sum);
2882   distributable = 0;
2883   if (bandwidth_target_out > neighbour_count * MIN_BPM_PER_PEER)
2884     distributable = bandwidth_target_out - neighbour_count * MIN_BPM_PER_PEER;
2885   share = distributable * pref_rel;
2886   q_in = MIN_BPM_PER_PEER + (unsigned long long) share;
2887   /* check if we want to disconnect for good due to inactivity */
2888   if ( (GNUNET_TIME_absolute_get_duration (n->last_activity).value > GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.value) &&
2889        (GNUNET_TIME_absolute_get_duration (n->time_established).value > GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.value) )
2890     q_in = 0; /* force disconnect */
2891   if ( (n->bpm_in + MIN_BPM_CHANGE < q_in) ||
2892        (n->bpm_in - MIN_BPM_CHANGE > q_in) ) 
2893     {
2894       n->bpm_in = q_in;
2895       GNUNET_TRANSPORT_set_quota (transport,
2896                                   &n->peer,
2897                                   n->bpm_in, 
2898                                   n->bpm_out,
2899                                   GNUNET_TIME_UNIT_FOREVER_REL,
2900                                   NULL, NULL);
2901     }
2902   schedule_quota_update (n);
2903 }
2904
2905
2906 /**
2907  * Function called by transport to notify us that
2908  * a peer connected to us (on the network level).
2909  *
2910  * @param cls closure
2911  * @param peer the peer that connected
2912  * @param latency current latency of the connection
2913  * @param distance in overlay hops, as given by transport plugin
2914  */
2915 static void
2916 handle_transport_notify_connect (void *cls,
2917                                  const struct GNUNET_PeerIdentity *peer,
2918                                  struct GNUNET_TIME_Relative latency,
2919                                  unsigned int distance)
2920 {
2921   struct Neighbour *n;
2922   struct GNUNET_TIME_Absolute now;
2923   struct ConnectNotifyMessage cnm;
2924
2925   n = find_neighbour (peer);
2926   if (n != NULL)
2927     {
2928       /* duplicate connect notification!? */
2929       GNUNET_break (0);
2930       return;
2931     }
2932   now = GNUNET_TIME_absolute_get ();
2933   n = GNUNET_malloc (sizeof (struct Neighbour));
2934   n->next = neighbours;
2935   neighbours = n;
2936   neighbour_count++;
2937   n->peer = *peer;
2938   n->last_latency = latency;
2939   GNUNET_CRYPTO_aes_create_session_key (&n->encrypt_key);
2940   n->encrypt_key_created = now;
2941   n->set_key_retry_frequency = INITIAL_SET_KEY_RETRY_FREQUENCY;
2942   n->last_asw_update = now;
2943   n->last_arw_update = now;
2944   n->bpm_in = GNUNET_CONSTANTS_DEFAULT_BPM_IN_OUT;
2945   n->bpm_out = GNUNET_CONSTANTS_DEFAULT_BPM_IN_OUT;
2946   n->bpm_out_internal_limit = (uint32_t) - 1;
2947   n->bpm_out_external_limit = GNUNET_CONSTANTS_DEFAULT_BPM_IN_OUT;
2948   n->ping_challenge = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
2949                                                 (uint32_t) - 1);
2950 #if DEBUG_CORE
2951   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2952               "Received connection from `%4s'.\n",
2953               GNUNET_i2s (&n->peer));
2954 #endif
2955   schedule_quota_update (n);
2956   cnm.header.size = htons (sizeof (struct ConnectNotifyMessage));
2957   cnm.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_PRE_CONNECT);
2958   cnm.distance = htonl (n->last_distance);
2959   cnm.latency = GNUNET_TIME_relative_hton (n->last_latency);
2960   cnm.peer = *peer;
2961   send_to_all_clients (&cnm.header, GNUNET_YES, GNUNET_CORE_OPTION_SEND_PRE_CONNECT);
2962   send_key (n);
2963 }
2964
2965
2966 /**
2967  * Free the given entry for the neighbour (it has
2968  * already been removed from the list at this point).
2969  *
2970  * @param n neighbour to free
2971  */
2972 static void
2973 free_neighbour (struct Neighbour *n)
2974 {
2975   struct MessageEntry *m;
2976
2977   if (n->pitr != NULL)
2978     {
2979       GNUNET_PEERINFO_iterate_cancel (n->pitr);
2980       n->pitr = NULL;
2981     }
2982   if (n->skm != NULL)
2983     {
2984       GNUNET_free (n->skm);
2985       n->skm = NULL;
2986     }
2987   while (NULL != (m = n->messages))
2988     {
2989       n->messages = m->next;
2990       GNUNET_free (m);
2991     }
2992   while (NULL != (m = n->encrypted_head))
2993     {
2994       n->encrypted_head = m->next;
2995       GNUNET_free (m);
2996     }
2997   if (NULL != n->th)
2998     GNUNET_TRANSPORT_notify_transmit_ready_cancel (n->th);
2999   if (n->retry_plaintext_task != GNUNET_SCHEDULER_NO_TASK)
3000     GNUNET_SCHEDULER_cancel (sched, n->retry_plaintext_task);
3001   if (n->retry_set_key_task != GNUNET_SCHEDULER_NO_TASK)
3002     GNUNET_SCHEDULER_cancel (sched, n->retry_set_key_task);
3003   if (n->quota_update_task != GNUNET_SCHEDULER_NO_TASK)
3004     GNUNET_SCHEDULER_cancel (sched, n->quota_update_task);
3005   GNUNET_free_non_null (n->public_key);
3006   GNUNET_free_non_null (n->pending_ping);
3007   GNUNET_free (n);
3008 }
3009
3010
3011 /**
3012  * Function called by transport telling us that a peer
3013  * disconnected.
3014  *
3015  * @param cls closure
3016  * @param peer the peer that disconnected
3017  */
3018 static void
3019 handle_transport_notify_disconnect (void *cls,
3020                                     const struct GNUNET_PeerIdentity *peer)
3021 {
3022   struct DisconnectNotifyMessage cnm;
3023   struct Neighbour *n;
3024   struct Neighbour *p;
3025
3026 #if DEBUG_CORE
3027   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3028               "Peer `%4s' disconnected from us.\n", GNUNET_i2s (peer));
3029 #endif
3030   p = NULL;
3031   n = neighbours;
3032   while ((n != NULL) &&
3033          (0 != memcmp (&n->peer, peer, sizeof (struct GNUNET_PeerIdentity))))
3034     {
3035       p = n;
3036       n = n->next;
3037     }
3038   if (n == NULL)
3039     {
3040       GNUNET_break (0);
3041       return;
3042     }
3043   if (p == NULL)
3044     neighbours = n->next;
3045   else
3046     p->next = n->next;
3047   GNUNET_assert (neighbour_count > 0);
3048   neighbour_count--;
3049   cnm.header.size = htons (sizeof (struct DisconnectNotifyMessage));
3050   cnm.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_DISCONNECT);
3051   cnm.peer = *peer;
3052   send_to_all_clients (&cnm.header, GNUNET_YES, GNUNET_CORE_OPTION_SEND_DISCONNECT);
3053   free_neighbour (n);
3054 }
3055
3056
3057 /**
3058  * Last task run during shutdown.  Disconnects us from
3059  * the transport.
3060  */
3061 static void
3062 cleaning_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
3063 {
3064   struct Neighbour *n;
3065   struct Client *c;
3066
3067 #if DEBUG_CORE
3068   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3069               "Core service shutting down.\n");
3070 #endif
3071   GNUNET_assert (transport != NULL);
3072   GNUNET_TRANSPORT_disconnect (transport);
3073   transport = NULL;
3074   while (NULL != (n = neighbours))
3075     {
3076       neighbours = n->next;
3077       GNUNET_assert (neighbour_count > 0);
3078       neighbour_count--;
3079       free_neighbour (n);
3080     }
3081   GNUNET_SERVER_notification_context_destroy (notifier);
3082   notifier = NULL;
3083   while (NULL != (c = clients))
3084     handle_client_disconnect (NULL, c->client_handle);
3085   if (my_private_key != NULL)
3086     GNUNET_CRYPTO_rsa_key_free (my_private_key);
3087 }
3088
3089
3090 /**
3091  * Initiate core service.
3092  *
3093  * @param cls closure
3094  * @param s scheduler to use
3095  * @param serv the initialized server
3096  * @param c configuration to use
3097  */
3098 static void
3099 run (void *cls,
3100      struct GNUNET_SCHEDULER_Handle *s,
3101      struct GNUNET_SERVER_Handle *serv,
3102      const struct GNUNET_CONFIGURATION_Handle *c)
3103 {
3104 #if 0
3105   unsigned long long qin;
3106   unsigned long long qout;
3107   unsigned long long tneigh;
3108 #endif
3109   char *keyfile;
3110
3111   sched = s;
3112   cfg = c;  
3113   /* parse configuration */
3114   if (
3115        (GNUNET_OK !=
3116         GNUNET_CONFIGURATION_get_value_number (c,
3117                                                "CORE",
3118                                                "TOTAL_QUOTA_IN",
3119                                                &bandwidth_target_in)) ||
3120        (GNUNET_OK !=
3121         GNUNET_CONFIGURATION_get_value_number (c,
3122                                                "CORE",
3123                                                "TOTAL_QUOTA_OUT",
3124                                                &bandwidth_target_out)) ||
3125 #if 0
3126        (GNUNET_OK !=
3127         GNUNET_CONFIGURATION_get_value_number (c,
3128                                                "CORE",
3129                                                "YY",
3130                                                &qout)) ||
3131        (GNUNET_OK !=
3132         GNUNET_CONFIGURATION_get_value_number (c,
3133                                                "CORE",
3134                                                "ZZ_LIMIT", &tneigh)) ||
3135 #endif
3136        (GNUNET_OK !=
3137         GNUNET_CONFIGURATION_get_value_filename (c,
3138                                                  "GNUNETD",
3139                                                  "HOSTKEY", &keyfile)))
3140     {
3141       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3142                   _
3143                   ("Core service is lacking key configuration settings.  Exiting.\n"));
3144       GNUNET_SCHEDULER_shutdown (s);
3145       return;
3146     }
3147   my_private_key = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile);
3148   GNUNET_free (keyfile);
3149   if (my_private_key == NULL)
3150     {
3151       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3152                   _("Core service could not access hostkey.  Exiting.\n"));
3153       GNUNET_SCHEDULER_shutdown (s);
3154       return;
3155     }
3156   GNUNET_CRYPTO_rsa_key_get_public (my_private_key, &my_public_key);
3157   GNUNET_CRYPTO_hash (&my_public_key,
3158                       sizeof (my_public_key), &my_identity.hashPubKey);
3159   /* setup notification */
3160   server = serv;
3161   notifier = GNUNET_SERVER_notification_context_create (server, 0);
3162   GNUNET_SERVER_disconnect_notify (server, &handle_client_disconnect, NULL);
3163   /* setup transport connection */
3164   transport = GNUNET_TRANSPORT_connect (sched,
3165                                         cfg,
3166                                         NULL,
3167                                         &handle_transport_receive,
3168                                         &handle_transport_notify_connect,
3169                                         &handle_transport_notify_disconnect);
3170   GNUNET_assert (NULL != transport);
3171   GNUNET_SCHEDULER_add_delayed (sched,
3172                                 GNUNET_TIME_UNIT_FOREVER_REL,
3173                                 &cleaning_task, NULL);
3174   /* process client requests */
3175   GNUNET_SERVER_add_handlers (server, handlers);
3176   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
3177               _("Core service of `%4s' ready.\n"), GNUNET_i2s (&my_identity));
3178 }
3179
3180
3181
3182 /**
3183  * The main function for the transport service.
3184  *
3185  * @param argc number of arguments from the command line
3186  * @param argv command line arguments
3187  * @return 0 ok, 1 on error
3188  */
3189 int
3190 main (int argc, char *const *argv)
3191 {
3192   return (GNUNET_OK ==
3193           GNUNET_SERVICE_run (argc,
3194                               argv,
3195                               "core",
3196                               GNUNET_SERVICE_OPTION_NONE,
3197                               &run, NULL)) ? 0 : 1;
3198 }
3199
3200 /* end of gnunet-service-core.c */