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