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