removing server from argument list, other minor fixes
[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       return 0;
1610     }
1611   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1612               "Connection to peer `%4s' succeeded, retrying original send request\n",
1613               GNUNET_i2s (&sm->peer));
1614   handle_client_send (NULL, NULL, &sm->header);
1615   GNUNET_free (sm);
1616   return 0;
1617 }
1618
1619
1620 /**
1621  * Handle CORE_SEND request.
1622  */
1623 static void
1624 handle_client_send (void *cls,
1625                     struct GNUNET_SERVER_Client *client,
1626                     const struct GNUNET_MessageHeader *message)
1627 {
1628   const struct SendMessage *sm;
1629   struct SendMessage *smc;
1630   const struct GNUNET_MessageHeader *mh;
1631   struct Neighbour *n;
1632   struct MessageEntry *pred;
1633   struct MessageEntry *pos;
1634   struct MessageEntry *e;
1635   uint16_t msize;
1636
1637   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1638               "Core service receives `%s' request.\n", "SEND");
1639   msize = ntohs (message->size);
1640   if (msize <
1641       sizeof (struct SendMessage) + sizeof (struct GNUNET_MessageHeader))
1642     {
1643       GNUNET_break (0);
1644       if (client != NULL)
1645         GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1646       return;
1647     }
1648   sm = (const struct SendMessage *) message;
1649   msize -= sizeof (struct SendMessage);
1650   mh = (const struct GNUNET_MessageHeader *) &sm[1];
1651   if (msize != ntohs (mh->size))
1652     {
1653       GNUNET_break (0);
1654       if (client != NULL)
1655         GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1656       return;
1657     }
1658   n = find_neighbour (&sm->peer);
1659   if (n == NULL)
1660     {
1661       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1662                   "Not yet connected to `%4s', will try to establish connection\n",
1663                   GNUNET_i2s (&sm->peer));
1664       msize += sizeof (struct SendMessage);
1665       /* ask transport to connect to the peer */
1666       /* FIXME: this code does not handle the
1667          case where we get multiple SendMessages before
1668          transport responds to this request;
1669          => need to track pending requests! */
1670       smc = GNUNET_malloc (msize);
1671       memcpy (smc, sm, msize);
1672       GNUNET_TRANSPORT_notify_transmit_ready (transport,
1673                                               &sm->peer,
1674                                               0,
1675                                               GNUNET_TIME_absolute_get_remaining
1676                                               (GNUNET_TIME_absolute_ntoh
1677                                                (sm->deadline)),
1678                                               &send_connect_continuation,
1679                                               smc);
1680       if (client != NULL)
1681         GNUNET_SERVER_receive_done (client, GNUNET_OK);
1682       return;
1683     }
1684   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1685               "Core queues %u bytes of plaintext data for transmission to `%4s'.\n",
1686               msize, GNUNET_i2s (&sm->peer));
1687   /* FIXME: consider bounding queue size */
1688   e = GNUNET_malloc (sizeof (struct MessageEntry) + msize);
1689   e->deadline = GNUNET_TIME_absolute_ntoh (sm->deadline);
1690   e->priority = ntohl (sm->priority);
1691   e->size = msize;
1692   memcpy (&e[1], mh, msize);
1693
1694   /* insert, keep list sorted by deadline */
1695   pred = NULL;
1696   pos = n->messages;
1697   while ((pos != NULL) && (pos->deadline.value < e->deadline.value))
1698     {
1699       pred = pos;
1700       pos = pos->next;
1701     }
1702   if (pred == NULL)
1703     n->messages = e;
1704   else
1705     pred->next = e;
1706   e->next = pos;
1707
1708   /* consider scheduling now */
1709   process_plaintext_neighbour_queue (n);
1710   if (client != NULL)
1711     GNUNET_SERVER_receive_done (client, GNUNET_OK);
1712 }
1713
1714
1715 /**
1716  * List of handlers for the messages understood by this
1717  * service.
1718  */
1719 static struct GNUNET_SERVER_MessageHandler handlers[] = {
1720   {&handle_client_init, NULL,
1721    GNUNET_MESSAGE_TYPE_CORE_INIT, 0},
1722   {&handle_client_request_configure, NULL,
1723    GNUNET_MESSAGE_TYPE_CORE_REQUEST_CONFIGURE,
1724    sizeof (struct RequestConfigureMessage)},
1725   {&handle_client_send, NULL,
1726    GNUNET_MESSAGE_TYPE_CORE_SEND, 0},
1727   {NULL, NULL, 0, 0}
1728 };
1729
1730
1731 /**
1732  * PEERINFO is giving us a HELLO for a peer.  Add the
1733  * public key to the neighbour's struct and retry
1734  * send_key.  Or, if we did not get a HELLO, just do
1735  * nothing.
1736  *
1737  * @param cls NULL
1738  * @param peer the peer for which this is the HELLO
1739  * @param hello HELLO message of that peer
1740  * @param trust amount of trust we currently have in that peer
1741  */
1742 static void
1743 process_hello_retry_send_key (void *cls,
1744                               const struct GNUNET_PeerIdentity *peer,
1745                               const struct GNUNET_HELLO_Message *hello,
1746                               uint32_t trust)
1747 {
1748   struct Neighbour *n;
1749
1750   if (peer == NULL)
1751     return;
1752   n = find_neighbour (peer);
1753   if (n == NULL)
1754     return;
1755   if (n->public_key != NULL)
1756     return;
1757   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1758               "Received new HELLO for `%4s', initiating key exchange.\n",
1759               GNUNET_i2s (peer));
1760   n->public_key =
1761     GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded));
1762   if (GNUNET_OK != GNUNET_HELLO_get_key (hello, n->public_key))
1763     {
1764       GNUNET_free (n->public_key);
1765       n->public_key = NULL;
1766       return;
1767     }
1768   send_key (n);
1769 }
1770
1771
1772 /**
1773  * Task that will retry "send_key" if our previous attempt failed
1774  * to yield a PONG.
1775  */
1776 static void
1777 set_key_retry_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1778 {
1779   struct Neighbour *n = cls;
1780
1781   GNUNET_assert (n->status != PEER_STATE_KEY_CONFIRMED);
1782   n->retry_set_key_task = GNUNET_SCHEDULER_NO_PREREQUISITE_TASK;
1783   n->set_key_retry_frequency =
1784     GNUNET_TIME_relative_multiply (n->set_key_retry_frequency, 2);
1785   send_key (n);
1786 }
1787
1788
1789 /**
1790  * Send our key (and encrypted PING) to the other peer.
1791  *
1792  * @param n the other peer
1793  */
1794 static void
1795 send_key (struct Neighbour *n)
1796 {
1797   struct SetKeyMessage *sm;
1798   struct MessageEntry *me;
1799   struct PingMessage pp;
1800   struct PingMessage *pm;
1801
1802   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1803               "Asked to perform key exchange with `%4s'.\n",
1804               GNUNET_i2s (&n->peer));
1805   if (n->public_key == NULL)
1806     {
1807       /* lookup n's public key, then try again */
1808       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1809                   "Lacking public key for `%4s', trying to obtain one.\n",
1810                   GNUNET_i2s (&n->peer));
1811       GNUNET_PEERINFO_for_all (cfg,
1812                                sched,
1813                                &n->peer,
1814                                0,
1815                                GNUNET_TIME_UNIT_MINUTES,
1816                                &process_hello_retry_send_key, NULL);
1817       return;
1818     }
1819   /* first, set key message */
1820   me = GNUNET_malloc (sizeof (struct MessageEntry) +
1821                       sizeof (struct SetKeyMessage));
1822   me->deadline = GNUNET_TIME_relative_to_absolute (MAX_SET_KEY_DELAY);
1823   me->priority = SET_KEY_PRIORITY;
1824   me->size = sizeof (struct SetKeyMessage);
1825   if (n->encrypted_head == NULL)
1826     n->encrypted_head = me;
1827   else
1828     n->encrypted_tail->next = me;
1829   n->encrypted_tail = me;
1830   sm = (struct SetKeyMessage *) &me[1];
1831   sm->header.size = htons (sizeof (struct SetKeyMessage));
1832   sm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_SET_KEY);
1833   sm->sender_status = htonl ((int32_t) ((n->status == PEER_STATE_DOWN) ?
1834                                         PEER_STATE_KEY_SENT : n->status));
1835   sm->purpose.size =
1836     htonl (sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) +
1837            sizeof (struct GNUNET_TIME_AbsoluteNBO) +
1838            sizeof (struct GNUNET_CRYPTO_RsaEncryptedData) +
1839            sizeof (struct GNUNET_PeerIdentity));
1840   sm->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_SET_KEY);
1841   sm->creation_time = GNUNET_TIME_absolute_hton (n->encrypt_key_created);
1842   sm->target = n->peer;
1843   GNUNET_assert (GNUNET_OK ==
1844                  GNUNET_CRYPTO_rsa_encrypt (&n->encrypt_key,
1845                                             sizeof (struct
1846                                                     GNUNET_CRYPTO_AesSessionKey),
1847                                             n->public_key,
1848                                             &sm->encrypted_key));
1849   GNUNET_assert (GNUNET_OK ==
1850                  GNUNET_CRYPTO_rsa_sign (my_private_key, &sm->purpose,
1851                                          &sm->signature));
1852
1853   /* second, encrypted PING message */
1854   me = GNUNET_malloc (sizeof (struct MessageEntry) +
1855                       sizeof (struct PingMessage));
1856   me->deadline = GNUNET_TIME_relative_to_absolute (MAX_PING_DELAY);
1857   me->priority = PING_PRIORITY;
1858   me->size = sizeof (struct PingMessage);
1859   n->encrypted_tail->next = me;
1860   n->encrypted_tail = me;
1861   pm = (struct PingMessage *) &me[1];
1862   pm->header.size = htons (sizeof (struct PingMessage));
1863   pm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_PING);
1864   pp.challenge = htonl (n->ping_challenge);
1865   pp.target = n->peer;
1866   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1867               "Encrypting `%s' and `%s' messages for `%4s'.\n",
1868               "SET_KEY", "PING", GNUNET_i2s (&n->peer));
1869   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1870               "Sending `%s' to `%4s' with challenge %u encrypted using key %u\n",
1871               "PING",
1872               GNUNET_i2s (&n->peer), n->ping_challenge, n->encrypt_key.crc32);
1873   do_encrypt (n,
1874               &n->peer.hashPubKey,
1875               &pp.challenge,
1876               &pm->challenge,
1877               sizeof (struct PingMessage) -
1878               sizeof (struct GNUNET_MessageHeader));
1879   /* update status */
1880   switch (n->status)
1881     {
1882     case PEER_STATE_DOWN:
1883       n->status = PEER_STATE_KEY_SENT;
1884       break;
1885     case PEER_STATE_KEY_SENT:
1886       break;
1887     case PEER_STATE_KEY_RECEIVED:
1888       break;
1889     case PEER_STATE_KEY_CONFIRMED:
1890       GNUNET_break (0);
1891       break;
1892     default:
1893       GNUNET_break (0);
1894       break;
1895     }
1896   /* trigger queue processing */
1897   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1898               "Triggering processing of encrypted message queue.\n");
1899   process_encrypted_neighbour_queue (n);
1900   if (n->status != PEER_STATE_KEY_CONFIRMED)
1901     n->retry_set_key_task
1902       = GNUNET_SCHEDULER_add_delayed (sched,
1903                                       GNUNET_NO,
1904                                       GNUNET_SCHEDULER_PRIORITY_KEEP,
1905                                       GNUNET_SCHEDULER_NO_PREREQUISITE_TASK,
1906                                       n->set_key_retry_frequency,
1907                                       &set_key_retry_task, n);
1908 }
1909
1910
1911 /**
1912  * We received a SET_KEY message.  Validate and update
1913  * our key material and status.
1914  *
1915  * @param n the neighbour from which we received message m
1916  * @param m the set key message we received
1917  */
1918 static void
1919 handle_set_key (struct Neighbour *n, const struct SetKeyMessage *m);
1920
1921
1922 /**
1923  * PEERINFO is giving us a HELLO for a peer.  Add the public key to
1924  * the neighbour's struct and retry handling the set_key message.  Or,
1925  * if we did not get a HELLO, just free the set key message.
1926  *
1927  * @param cls pointer to the set key message
1928  * @param peer the peer for which this is the HELLO
1929  * @param hello HELLO message of that peer
1930  * @param trust amount of trust we currently have in that peer
1931  */
1932 static void
1933 process_hello_retry_handle_set_key (void *cls,
1934                                     const struct GNUNET_PeerIdentity *peer,
1935                                     const struct GNUNET_HELLO_Message *hello,
1936                                     uint32_t trust)
1937 {
1938   struct SetKeyMessage *sm = cls;
1939   struct Neighbour *n;
1940
1941   if (peer == NULL)
1942     {
1943       GNUNET_free (sm);
1944       return;
1945     }
1946   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1947               "Looking for peer `%4s' to handle `%s' message.\n",
1948               GNUNET_i2s (peer), "SET_KEY");
1949   n = find_neighbour (peer);
1950   if (n == NULL)
1951     {
1952       GNUNET_break (0);
1953       return;
1954     }
1955   if (n->public_key != NULL)
1956     return;                     /* multiple HELLOs match!? */
1957   n->public_key =
1958     GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded));
1959   if (GNUNET_OK != GNUNET_HELLO_get_key (hello, n->public_key))
1960     {
1961       GNUNET_free (n->public_key);
1962       n->public_key = NULL;
1963       return;
1964     }
1965   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1966               "Received `%s' for `%4s', continuing processing of `%s' message.\n",
1967               "HELLO", GNUNET_i2s (peer), "SET_KEY");
1968   handle_set_key (n, sm);
1969 }
1970
1971
1972 /**
1973  * We received a PING message.  Validate and transmit
1974  * PONG.
1975  *
1976  * @param n sender of the PING
1977  * @param m the encrypted PING message itself
1978  */
1979 static void
1980 handle_ping (struct Neighbour *n, const struct PingMessage *m)
1981 {
1982   struct PingMessage t;
1983   struct PingMessage *tp;
1984   struct MessageEntry *me;
1985
1986   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1987               "Core service receives `%s' request from `%4s'.\n",
1988               "PING", GNUNET_i2s (&n->peer));
1989   if (GNUNET_OK !=
1990       do_decrypt (n,
1991                   &my_identity.hashPubKey,
1992                   &m->challenge,
1993                   &t.challenge,
1994                   sizeof (struct PingMessage) -
1995                   sizeof (struct GNUNET_MessageHeader)))
1996     return;
1997   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1998               "Decrypted `%s' to `%4s' with challenge %u decrypted using key %u\n",
1999               "PING",
2000               GNUNET_i2s (&t.target),
2001               ntohl (t.challenge), n->decrypt_key.crc32);
2002   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2003               "Target of `%s' request is `%4s'.\n",
2004               "PING", GNUNET_i2s (&t.target));
2005   if (0 != memcmp (&t.target,
2006                    &my_identity, sizeof (struct GNUNET_PeerIdentity)))
2007     {
2008       GNUNET_break_op (0);
2009       return;
2010     }
2011   me = GNUNET_malloc (sizeof (struct MessageEntry) +
2012                       sizeof (struct PingMessage));
2013   if (n->encrypted_tail != NULL)
2014     n->encrypted_tail->next = me;
2015   else
2016     {
2017       n->encrypted_tail = me;
2018       n->encrypted_head = me;
2019     }
2020   me->deadline = GNUNET_TIME_relative_to_absolute (MAX_PONG_DELAY);
2021   me->priority = PONG_PRIORITY;
2022   me->size = sizeof (struct PingMessage);
2023   tp = (struct PingMessage *) &me[1];
2024   tp->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_PONG);
2025   tp->header.size = htons (sizeof (struct PingMessage));
2026   do_encrypt (n,
2027               &my_identity.hashPubKey,
2028               &t.challenge,
2029               &tp->challenge,
2030               sizeof (struct PingMessage) -
2031               sizeof (struct GNUNET_MessageHeader));
2032   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2033               "Encrypting `%s' with challenge %u using key %u\n", "PONG",
2034               ntohl (t.challenge), n->encrypt_key.crc32);
2035   /* trigger queue processing */
2036   process_encrypted_neighbour_queue (n);
2037 }
2038
2039
2040 /**
2041  * We received a SET_KEY message.  Validate and update
2042  * our key material and status.
2043  *
2044  * @param n the neighbour from which we received message m
2045  * @param m the set key message we received
2046  */
2047 static void
2048 handle_set_key (struct Neighbour *n, const struct SetKeyMessage *m)
2049 {
2050   struct SetKeyMessage *m_cpy;
2051   struct GNUNET_TIME_Absolute t;
2052   struct GNUNET_CRYPTO_AesSessionKey k;
2053   struct PingMessage *ping;
2054   enum PeerStateMachine sender_status;
2055
2056   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2057               "Core service receives `%s' request from `%4s'.\n",
2058               "SET_KEY", GNUNET_i2s (&n->peer));
2059   if (n->public_key == NULL)
2060     {
2061       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2062                   "Lacking public key for peer, trying to obtain one.\n");
2063       m_cpy = GNUNET_malloc (sizeof (struct SetKeyMessage));
2064       memcpy (m_cpy, m, sizeof (struct SetKeyMessage));
2065       /* lookup n's public key, then try again */
2066       GNUNET_PEERINFO_for_all (cfg,
2067                                sched,
2068                                &n->peer,
2069                                0,
2070                                GNUNET_TIME_UNIT_MINUTES,
2071                                &process_hello_retry_handle_set_key, m_cpy);
2072       return;
2073     }
2074   if ((ntohl (m->purpose.size) !=
2075        sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) +
2076        sizeof (struct GNUNET_TIME_AbsoluteNBO) +
2077        sizeof (struct GNUNET_CRYPTO_RsaEncryptedData) +
2078        sizeof (struct GNUNET_PeerIdentity)) ||
2079       (GNUNET_OK !=
2080        GNUNET_CRYPTO_rsa_verify (GNUNET_SIGNATURE_PURPOSE_SET_KEY,
2081                                  &m->purpose, &m->signature, n->public_key)))
2082     {
2083       /* invalid signature */
2084       GNUNET_break_op (0);
2085       return;
2086     }
2087   t = GNUNET_TIME_absolute_ntoh (m->creation_time);
2088   if (((n->status == PEER_STATE_KEY_RECEIVED) ||
2089        (n->status == PEER_STATE_KEY_CONFIRMED)) &&
2090       (t.value < n->decrypt_key_created.value))
2091     {
2092       /* this could rarely happen due to massive re-ordering of
2093          messages on the network level, but is most likely either
2094          a bug or some adversary messing with us.  Report. */
2095       GNUNET_break_op (0);
2096       return;
2097     }
2098   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Decrypting key material.\n");
2099   if ((GNUNET_CRYPTO_rsa_decrypt (my_private_key,
2100                                   &m->encrypted_key,
2101                                   &k,
2102                                   sizeof (struct GNUNET_CRYPTO_AesSessionKey))
2103        != sizeof (struct GNUNET_CRYPTO_AesSessionKey)) ||
2104       (GNUNET_OK != GNUNET_CRYPTO_aes_check_session_key (&k)))
2105     {
2106       /* failed to decrypt !? */
2107       GNUNET_break_op (0);
2108       return;
2109     }
2110
2111   n->decrypt_key = k;
2112   if (n->decrypt_key_created.value != t.value)
2113     {
2114       /* fresh key, reset sequence numbers */
2115       n->last_sequence_number_received = 0;
2116       n->last_packets_bitmap = 0;
2117       n->decrypt_key_created = t;
2118     }
2119   sender_status = (enum PeerStateMachine) ntohl (m->sender_status);
2120   switch (n->status)
2121     {
2122     case PEER_STATE_DOWN:
2123       n->status = PEER_STATE_KEY_RECEIVED;
2124       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2125                   "Responding to `%s' with my own key.\n", "SET_KEY");
2126       send_key (n);
2127       break;
2128     case PEER_STATE_KEY_SENT:
2129     case PEER_STATE_KEY_RECEIVED:
2130       n->status = PEER_STATE_KEY_RECEIVED;
2131       if ((sender_status != PEER_STATE_KEY_RECEIVED) &&
2132           (sender_status != PEER_STATE_KEY_CONFIRMED))
2133         {
2134           GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2135                       "Responding to `%s' with my own key (other peer has status %u).\n",
2136                       "SET_KEY", sender_status);
2137           send_key (n);
2138         }
2139       break;
2140     case PEER_STATE_KEY_CONFIRMED:
2141       if ((sender_status != PEER_STATE_KEY_RECEIVED) &&
2142           (sender_status != PEER_STATE_KEY_CONFIRMED))
2143         {
2144           GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2145                       "Responding to `%s' with my own key (other peer has status %u), I was already fully up.\n",
2146                       "SET_KEY", sender_status);
2147           send_key (n);
2148         }
2149       break;
2150     default:
2151       GNUNET_break (0);
2152       break;
2153     }
2154   if (n->pending_ping != NULL)
2155     {
2156       ping = n->pending_ping;
2157       n->pending_ping = NULL;
2158       handle_ping (n, ping);
2159       GNUNET_free (ping);
2160     }
2161 }
2162
2163
2164 /**
2165  * We received a PONG message.  Validate and update
2166  * our status.
2167  *
2168  * @param n sender of the PONG
2169  * @param m the encrypted PONG message itself
2170  */
2171 static void
2172 handle_pong (struct Neighbour *n, const struct PingMessage *m)
2173 {
2174   struct PingMessage t;
2175
2176   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2177               "Core service receives `%s' request from `%4s'.\n",
2178               "PONG", GNUNET_i2s (&n->peer));
2179   if (GNUNET_OK !=
2180       do_decrypt (n,
2181                   &n->peer.hashPubKey,
2182                   &m->challenge,
2183                   &t.challenge,
2184                   sizeof (struct PingMessage) -
2185                   sizeof (struct GNUNET_MessageHeader)))
2186     return;
2187   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2188               "Decrypted `%s' from `%4s' with challenge %u using key %u\n",
2189               "PONG",
2190               GNUNET_i2s (&t.target),
2191               ntohl (t.challenge), n->decrypt_key.crc32);
2192   if ((0 != memcmp (&t.target,
2193                     &n->peer,
2194                     sizeof (struct GNUNET_PeerIdentity))) ||
2195       (n->ping_challenge != ntohl (t.challenge)))
2196     {
2197       /* PONG malformed */
2198       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2199                   "Received malfromed `%s' wanted sender `%4s' with challenge %u\n",
2200                   "PONG", GNUNET_i2s (&n->peer), n->ping_challenge);
2201       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2202                   "Received malfromed `%s' received from `%4s' with challenge %u\n",
2203                   "PONG", GNUNET_i2s (&t.target), ntohl (t.challenge));
2204       GNUNET_break_op (0);
2205       return;
2206     }
2207   switch (n->status)
2208     {
2209     case PEER_STATE_DOWN:
2210       GNUNET_break (0);         /* should be impossible */
2211       return;
2212     case PEER_STATE_KEY_SENT:
2213       GNUNET_break (0);         /* should be impossible, how did we decrypt? */
2214       return;
2215     case PEER_STATE_KEY_RECEIVED:
2216       n->status = PEER_STATE_KEY_CONFIRMED;
2217       if (n->retry_set_key_task != GNUNET_SCHEDULER_NO_PREREQUISITE_TASK)
2218         {
2219           GNUNET_SCHEDULER_cancel (sched, n->retry_set_key_task);
2220           n->retry_set_key_task = GNUNET_SCHEDULER_NO_PREREQUISITE_TASK;
2221         }
2222       process_encrypted_neighbour_queue (n);
2223       break;
2224     case PEER_STATE_KEY_CONFIRMED:
2225       /* duplicate PONG? */
2226       break;
2227     default:
2228       GNUNET_break (0);
2229       break;
2230     }
2231 }
2232
2233
2234 /**
2235  * Send a P2P message to a client.
2236  *
2237  * @param sender who sent us the message?
2238  * @param client who should we give the message to?
2239  * @param m contains the message to transmit
2240  * @param msize number of bytes in buf to transmit
2241  */
2242 static void
2243 send_p2p_message_to_client (struct Neighbour *sender,
2244                             struct Client *client,
2245                             const void *m, size_t msize)
2246 {
2247   char buf[msize + sizeof (struct NotifyTrafficMessage)];
2248   struct NotifyTrafficMessage *ntm;
2249
2250   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2251               "Core service passes P2P message of type %u to client.\n",
2252               ntohs (((const struct GNUNET_MessageHeader *) m)->type));
2253   ntm = (struct NotifyTrafficMessage *) buf;
2254   ntm->header.size = htons (msize + sizeof (struct NotifyTrafficMessage));
2255   ntm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_INBOUND);
2256   ntm->reserved = htonl (0);
2257   ntm->peer = sender->peer;
2258   memcpy (&ntm[1], m, msize);
2259   send_to_client (client, &ntm->header, GNUNET_YES);
2260 }
2261
2262
2263 /**
2264  * Deliver P2P message to interested clients.
2265  *
2266  * @param sender who sent us the message?
2267  * @param m the message
2268  * @param msize size of the message (including header)
2269  */
2270 static void
2271 deliver_message (struct Neighbour *sender,
2272                  const struct GNUNET_MessageHeader *m, size_t msize)
2273 {
2274   struct Client *cpos;
2275   uint16_t type;
2276   unsigned int tpos;
2277   int deliver_full;
2278
2279   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2280               "Passing decrypted P2P message to interested clients.\n");
2281   type = ntohs (m->type);
2282   cpos = clients;
2283   while (cpos != NULL)
2284     {
2285       deliver_full = GNUNET_NO;
2286       if (cpos->options & GNUNET_CORE_OPTION_SEND_FULL_INBOUND)
2287         deliver_full = GNUNET_YES;
2288       else
2289         {
2290           for (tpos = 0; tpos < cpos->tcnt; tpos++)
2291             {
2292               if (type != cpos->types[tpos])
2293                 continue;
2294               deliver_full = GNUNET_YES;
2295               break;
2296             }
2297         }
2298       if (GNUNET_YES == deliver_full)
2299         send_p2p_message_to_client (sender, cpos, m, msize);
2300       else if (cpos->options & GNUNET_CORE_OPTION_SEND_HDR_INBOUND)
2301         send_p2p_message_to_client (sender, cpos, m,
2302                                     sizeof (struct GNUNET_MessageHeader));
2303       cpos = cpos->next;
2304     }
2305 }
2306
2307
2308 /**
2309  * Align P2P message and then deliver to interested clients.
2310  *
2311  * @param sender who sent us the message?
2312  * @param buffer unaligned (!) buffer containing message
2313  * @param msize size of the message (including header)
2314  */
2315 static void
2316 align_and_deliver (struct Neighbour *sender, const char *buffer, size_t msize)
2317 {
2318   char abuf[msize];
2319
2320   /* TODO: call to statistics? */
2321   memcpy (abuf, buffer, msize);
2322   deliver_message (sender, (const struct GNUNET_MessageHeader *) abuf, msize);
2323 }
2324
2325
2326 /**
2327  * Deliver P2P messages to interested clients.
2328  *
2329  * @param sender who sent us the message?
2330  * @param buffer buffer containing messages, can be modified
2331  * @param buffer_size size of the buffer (overall)
2332  * @param offset offset where messages in the buffer start
2333  */
2334 static void
2335 deliver_messages (struct Neighbour *sender,
2336                   const char *buffer, size_t buffer_size, size_t offset)
2337 {
2338   struct GNUNET_MessageHeader *mhp;
2339   struct GNUNET_MessageHeader mh;
2340   uint16_t msize;
2341   int need_align;
2342
2343   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2344               "Delivering %u bytes of plaintext to interested clients.\n",
2345               buffer_size);
2346   while (offset + sizeof (struct GNUNET_MessageHeader) <= buffer_size)
2347     {
2348       if (0 != offset % sizeof (uint16_t))
2349         {
2350           /* outch, need to copy to access header */
2351           memcpy (&mh, &buffer[offset], sizeof (struct GNUNET_MessageHeader));
2352           mhp = &mh;
2353         }
2354       else
2355         {
2356           /* can access header directly */
2357           mhp = (struct GNUNET_MessageHeader *) &buffer[offset];
2358         }
2359       msize = ntohs (mhp->size);
2360       if (msize + offset > buffer_size)
2361         {
2362           /* malformed message, header says it is larger than what
2363              would fit into the overall buffer */
2364           GNUNET_break_op (0);
2365           break;
2366         }
2367 #if HAVE_UNALIGNED_64_ACCESS
2368       need_align = (0 != offset % 4) ? GNUNET_YES : GNUNET_NO;
2369 #else
2370       need_align = (0 != offset % 8) ? GNUNET_YES : GNUNET_NO;
2371 #endif
2372       if (GNUNET_YES == need_align)
2373         align_and_deliver (sender, &buffer[offset], msize);
2374       else
2375         deliver_message (sender,
2376                          (const struct GNUNET_MessageHeader *)
2377                          &buffer[offset], msize);
2378       offset += msize;
2379     }
2380 }
2381
2382
2383 /**
2384  * We received an encrypted message.  Decrypt, validate and
2385  * pass on to the appropriate clients.
2386  */
2387 static void
2388 handle_encrypted_message (struct Neighbour *n,
2389                           const struct EncryptedMessage *m)
2390 {
2391   size_t size = ntohs (m->header.size);
2392   char buf[size];
2393   struct EncryptedMessage *pt;  /* plaintext */
2394   GNUNET_HashCode ph;
2395   size_t off;
2396   uint32_t snum;
2397   struct GNUNET_TIME_Absolute t;
2398
2399   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2400               "Core service receives `%s' request from `%4s'.\n",
2401               "ENCRYPTED_MESSAGE", GNUNET_i2s (&n->peer));
2402   /* decrypt */
2403   if (GNUNET_OK !=
2404       do_decrypt (n,
2405                   &m->plaintext_hash,
2406                   &m->sequence_number,
2407                   &buf[ENCRYPTED_HEADER_SIZE], size - ENCRYPTED_HEADER_SIZE))
2408     return;
2409   pt = (struct EncryptedMessage *) buf;
2410
2411   /* validate hash */
2412   GNUNET_CRYPTO_hash (&pt->sequence_number,
2413                       size - ENCRYPTED_HEADER_SIZE, &ph);
2414   if (0 != memcmp (&ph, &m->plaintext_hash, sizeof (GNUNET_HashCode)))
2415     {
2416       /* checksum failed */
2417       GNUNET_break_op (0);
2418       return;
2419     }
2420
2421   /* validate sequence number */
2422   snum = ntohl (pt->sequence_number);
2423   if (n->last_sequence_number_received == snum)
2424     {
2425       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2426                   "Received duplicate message, ignoring.\n");
2427       /* duplicate, ignore */
2428       return;
2429     }
2430   if ((n->last_sequence_number_received > snum) &&
2431       (n->last_sequence_number_received - snum > 32))
2432     {
2433       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2434                   "Received ancient out of sequence message, ignoring.\n");
2435       /* ancient out of sequence, ignore */
2436       return;
2437     }
2438   if (n->last_sequence_number_received > snum)
2439     {
2440       unsigned int rotbit =
2441         1 << (n->last_sequence_number_received - snum - 1);
2442       if ((n->last_packets_bitmap & rotbit) != 0)
2443         {
2444           GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2445                       "Received duplicate message, ignoring.\n");
2446           /* duplicate, ignore */
2447           return;
2448         }
2449       n->last_packets_bitmap |= rotbit;
2450     }
2451   if (n->last_sequence_number_received < snum)
2452     {
2453       n->last_packets_bitmap <<= (snum - n->last_sequence_number_received);
2454       n->last_sequence_number_received = snum;
2455     }
2456
2457   /* check timestamp */
2458   t = GNUNET_TIME_absolute_ntoh (pt->timestamp);
2459   if (GNUNET_TIME_absolute_get_duration (t).value > MAX_MESSAGE_AGE.value)
2460     {
2461       GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2462                   _
2463                   ("Message received far too old (%llu ms). Content ignored.\n"),
2464                   GNUNET_TIME_absolute_get_duration (t).value);
2465       return;
2466     }
2467
2468   /* process decrypted message(s) */
2469   n->bpm_out_external_limit = ntohl (pt->inbound_bpm_limit);
2470   n->bpm_out = GNUNET_MAX (n->bpm_out_external_limit,
2471                            n->bpm_out_internal_limit);
2472   n->last_activity = GNUNET_TIME_absolute_get ();
2473   off = sizeof (struct EncryptedMessage);
2474   deliver_messages (n, buf, size, off);
2475 }
2476
2477
2478 /**
2479  * Function called by the transport for each received message.
2480  *
2481  * @param cls closure
2482  * @param latency estimated latency for communicating with the
2483  *             given peer
2484  * @param peer (claimed) identity of the other peer
2485  * @param message the message
2486  */
2487 static void
2488 handle_transport_receive (void *cls,
2489                           struct GNUNET_TIME_Relative latency,
2490                           const struct GNUNET_PeerIdentity *peer,
2491                           const struct GNUNET_MessageHeader *message)
2492 {
2493   struct Neighbour *n;
2494   struct GNUNET_TIME_Absolute now;
2495   int up;
2496   uint16_t type;
2497   uint16_t size;
2498
2499   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2500               "Received message of type %u from `%4s', demultiplexing.\n",
2501               ntohs (message->type), GNUNET_i2s (peer));
2502   n = find_neighbour (peer);
2503   if (n == NULL)
2504     {
2505       GNUNET_break (0);
2506       return;
2507     }
2508   n->last_latency = latency;
2509   up = n->status == PEER_STATE_KEY_CONFIRMED;
2510   type = ntohs (message->type);
2511   size = ntohs (message->size);
2512   switch (type)
2513     {
2514     case GNUNET_MESSAGE_TYPE_CORE_SET_KEY:
2515       if (size != sizeof (struct SetKeyMessage))
2516         {
2517           GNUNET_break_op (0);
2518           return;
2519         }
2520       handle_set_key (n, (const struct SetKeyMessage *) message);
2521       break;
2522     case GNUNET_MESSAGE_TYPE_CORE_ENCRYPTED_MESSAGE:
2523       if (size < sizeof (struct EncryptedMessage) +
2524           sizeof (struct GNUNET_MessageHeader))
2525         {
2526           GNUNET_break_op (0);
2527           return;
2528         }
2529       if ((n->status != PEER_STATE_KEY_RECEIVED) &&
2530           (n->status != PEER_STATE_KEY_CONFIRMED))
2531         {
2532           GNUNET_break_op (0);
2533           return;
2534         }
2535       handle_encrypted_message (n, (const struct EncryptedMessage *) message);
2536       break;
2537     case GNUNET_MESSAGE_TYPE_CORE_PING:
2538       if (size != sizeof (struct PingMessage))
2539         {
2540           GNUNET_break_op (0);
2541           return;
2542         }
2543       if ((n->status != PEER_STATE_KEY_RECEIVED) &&
2544           (n->status != PEER_STATE_KEY_CONFIRMED))
2545         {
2546           GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2547                       "Core service receives `%s' request from `%4s' but have not processed key; marking as pending.\n",
2548                       "PING", GNUNET_i2s (&n->peer));
2549           GNUNET_free_non_null (n->pending_ping);
2550           n->pending_ping = GNUNET_malloc (sizeof (struct PingMessage));
2551           memcpy (n->pending_ping, message, sizeof (struct PingMessage));
2552           return;
2553         }
2554       handle_ping (n, (const struct PingMessage *) message);
2555       break;
2556     case GNUNET_MESSAGE_TYPE_CORE_PONG:
2557       if (size != sizeof (struct PingMessage))
2558         {
2559           GNUNET_break_op (0);
2560           return;
2561         }
2562       if ((n->status != PEER_STATE_KEY_SENT) &&
2563           (n->status != PEER_STATE_KEY_RECEIVED) &&
2564           (n->status != PEER_STATE_KEY_CONFIRMED))
2565         {
2566           /* could not decrypt pong, oops! */
2567           GNUNET_break_op (0);
2568           return;
2569         }
2570       handle_pong (n, (const struct PingMessage *) message);
2571       break;
2572     default:
2573       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2574                   _("Unsupported message of type %u received.\n"), type);
2575       return;
2576     }
2577   if (n->status == PEER_STATE_KEY_CONFIRMED)
2578     {
2579       now = GNUNET_TIME_absolute_get ();
2580       n->last_activity = now;
2581       if (!up)
2582         n->time_established = now;
2583     }
2584 }
2585
2586
2587 /**
2588  * Function called by transport to notify us that
2589  * a peer connected to us (on the network level).
2590  *
2591  * @param cls closure
2592  * @param peer the peer that connected
2593  * @param latency current latency of the connection
2594  */
2595 static void
2596 handle_transport_notify_connect (void *cls,
2597                                  const struct GNUNET_PeerIdentity *peer,
2598                                  struct GNUNET_TIME_Relative latency)
2599 {
2600   struct Neighbour *n;
2601   struct GNUNET_TIME_Absolute now;
2602   struct ConnectNotifyMessage cnm;
2603
2604   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2605               "Received connection from `%4s'.\n", GNUNET_i2s (peer));
2606   n = find_neighbour (peer);
2607   if (n != NULL)
2608     {
2609       /* duplicate connect notification!? */
2610       GNUNET_break (0);
2611       return;
2612     }
2613   now = GNUNET_TIME_absolute_get ();
2614   n = GNUNET_malloc (sizeof (struct Neighbour));
2615   n->next = neighbours;
2616   neighbours = n;
2617   n->peer = *peer;
2618   n->last_latency = latency;
2619   GNUNET_CRYPTO_aes_create_session_key (&n->encrypt_key);
2620   n->encrypt_key_created = now;
2621   n->set_key_retry_frequency = INITIAL_SET_KEY_RETRY_FREQUENCY;
2622   n->last_asw_update = now;
2623   n->last_arw_update = now;
2624   n->bpm_in = DEFAULT_BPM_IN_OUT;
2625   n->bpm_out = DEFAULT_BPM_IN_OUT;
2626   n->bpm_out_internal_limit = (uint32_t) - 1;
2627   n->bpm_out_external_limit = DEFAULT_BPM_IN_OUT;
2628   n->ping_challenge = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
2629                                                 (uint32_t) - 1);
2630   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2631               "Created entry for new neighbour `%4s'.\n",
2632               GNUNET_i2s (&n->peer));
2633   cnm.header.size = htons (sizeof (struct ConnectNotifyMessage));
2634   cnm.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT);
2635   cnm.bpm_available = htonl (DEFAULT_BPM_IN_OUT);
2636   cnm.peer = *peer;
2637   cnm.last_activity = GNUNET_TIME_absolute_hton (now);
2638   send_to_all_clients (&cnm.header, GNUNET_YES);
2639 }
2640
2641
2642 /**
2643  * Free the given entry for the neighbour (it has
2644  * already been removed from the list at this point).
2645  * @param n neighbour to free
2646  */
2647 static void
2648 free_neighbour (struct Neighbour *n)
2649 {
2650   struct MessageEntry *m;
2651
2652   while (NULL != (m = n->messages))
2653     {
2654       n->messages = m->next;
2655       GNUNET_free (m);
2656     }
2657   while (NULL != (m = n->encrypted_head))
2658     {
2659       n->encrypted_head = m->next;
2660       GNUNET_free (m);
2661     }
2662   if (NULL != n->th)
2663     GNUNET_TRANSPORT_notify_transmit_ready_cancel (n->th);
2664   if (n->retry_plaintext_task != GNUNET_SCHEDULER_NO_PREREQUISITE_TASK)
2665     GNUNET_SCHEDULER_cancel (sched, n->retry_plaintext_task);
2666   if (n->retry_set_key_task != GNUNET_SCHEDULER_NO_PREREQUISITE_TASK)
2667     GNUNET_SCHEDULER_cancel (sched, n->retry_set_key_task);
2668   GNUNET_free_non_null (n->public_key);
2669   GNUNET_free_non_null (n->pending_ping);
2670   GNUNET_free (n);
2671 }
2672
2673
2674 /**
2675  * Function called by transport telling us that a peer
2676  * disconnected.
2677  *
2678  * @param cls closure
2679  * @param peer the peer that disconnected
2680  */
2681 static void
2682 handle_transport_notify_disconnect (void *cls,
2683                                     const struct GNUNET_PeerIdentity *peer)
2684 {
2685   struct ConnectNotifyMessage cnm;
2686   struct Neighbour *n;
2687   struct Neighbour *p;
2688
2689   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2690               "Peer `%4s' disconnected from us.\n", GNUNET_i2s (peer));
2691   p = NULL;
2692   n = neighbours;
2693   while ((n != NULL) &&
2694          (0 != memcmp (&n->peer, peer, sizeof (struct GNUNET_PeerIdentity))))
2695     {
2696       p = n;
2697       n = n->next;
2698     }
2699   if (n == NULL)
2700     {
2701       GNUNET_break (0);
2702       return;
2703     }
2704   if (p == NULL)
2705     neighbours = n->next;
2706   else
2707     p->next = n->next;
2708   cnm.header.size = htons (sizeof (struct ConnectNotifyMessage));
2709   cnm.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_DISCONNECT);
2710   cnm.bpm_available = htonl (0);
2711   cnm.peer = *peer;
2712   cnm.last_activity = GNUNET_TIME_absolute_hton (n->last_activity);
2713   send_to_all_clients (&cnm.header, GNUNET_YES);
2714   free_neighbour (n);
2715 }
2716
2717
2718 /**
2719  * Last task run during shutdown.  Disconnects us from
2720  * the transport.
2721  */
2722 static void
2723 cleaning_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
2724 {
2725   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Core service shutting down.\n");
2726   GNUNET_assert (transport != NULL);
2727   GNUNET_TRANSPORT_disconnect (transport);
2728   transport = NULL;
2729 }
2730
2731
2732 /**
2733  * Initiate core service.
2734  *
2735  * @param cls closure
2736  * @param s scheduler to use
2737  * @param serv the initialized server
2738  * @param c configuration to use
2739  */
2740 static void
2741 run (void *cls,
2742      struct GNUNET_SCHEDULER_Handle *s,
2743      struct GNUNET_SERVER_Handle *serv, struct GNUNET_CONFIGURATION_Handle *c)
2744 {
2745 #if 0
2746   unsigned long long qin;
2747   unsigned long long qout;
2748   unsigned long long tneigh;
2749 #endif
2750   char *keyfile;
2751
2752   sched = s;
2753   cfg = c;
2754   /* parse configuration */
2755   if (
2756 #if 0
2757        (GNUNET_OK !=
2758         GNUNET_CONFIGURATION_get_value_number (c,
2759                                                "CORE",
2760                                                "XX",
2761                                                &qin)) ||
2762        (GNUNET_OK !=
2763         GNUNET_CONFIGURATION_get_value_number (c,
2764                                                "CORE",
2765                                                "YY",
2766                                                &qout)) ||
2767        (GNUNET_OK !=
2768         GNUNET_CONFIGURATION_get_value_number (c,
2769                                                "CORE",
2770                                                "ZZ_LIMIT", &tneigh)) ||
2771 #endif
2772        (GNUNET_OK !=
2773         GNUNET_CONFIGURATION_get_value_filename (c,
2774                                                  "GNUNETD",
2775                                                  "HOSTKEY", &keyfile)))
2776     {
2777       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2778                   _
2779                   ("Core service is lacking key configuration settings.  Exiting.\n"));
2780       GNUNET_SCHEDULER_shutdown (s);
2781       return;
2782     }
2783   my_private_key = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile);
2784   GNUNET_free (keyfile);
2785   if (my_private_key == NULL)
2786     {
2787       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2788                   _("Core service could not access hostkey.  Exiting.\n"));
2789       GNUNET_SCHEDULER_shutdown (s);
2790       return;
2791     }
2792   GNUNET_CRYPTO_rsa_key_get_public (my_private_key, &my_public_key);
2793   GNUNET_CRYPTO_hash (&my_public_key,
2794                       sizeof (my_public_key), &my_identity.hashPubKey);
2795   /* setup notification */
2796   server = serv;
2797   GNUNET_SERVER_disconnect_notify (server, &handle_client_disconnect, NULL);
2798   /* setup transport connection */
2799   transport = GNUNET_TRANSPORT_connect (sched,
2800                                         cfg,
2801                                         NULL,
2802                                         &handle_transport_receive,
2803                                         &handle_transport_notify_connect,
2804                                         &handle_transport_notify_disconnect);
2805   GNUNET_assert (NULL != transport);
2806   GNUNET_SCHEDULER_add_delayed (sched,
2807                                 GNUNET_YES,
2808                                 GNUNET_SCHEDULER_PRIORITY_IDLE,
2809                                 GNUNET_SCHEDULER_NO_PREREQUISITE_TASK,
2810                                 GNUNET_TIME_UNIT_FOREVER_REL,
2811                                 &cleaning_task, NULL);
2812   /* process client requests */
2813   GNUNET_SERVER_add_handlers (server, handlers);
2814   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2815               _("Core service of `%4s' ready.\n"), GNUNET_i2s (&my_identity));
2816 }
2817
2818
2819 /**
2820  * Function called during shutdown.  Clean up our state.
2821  */
2822 static void
2823 cleanup (void *cls, struct GNUNET_CONFIGURATION_Handle *cfg)
2824 {
2825   struct Neighbour *n;
2826
2827   if (my_private_key != NULL)
2828     GNUNET_CRYPTO_rsa_key_free (my_private_key);
2829   while (NULL != (n = neighbours))
2830     {
2831       neighbours = n->next;
2832       free_neighbour (n);
2833     }
2834   /*
2835      FIXME:
2836      - free clients
2837    */
2838 }
2839
2840
2841 /**
2842  * The main function for the transport service.
2843  *
2844  * @param argc number of arguments from the command line
2845  * @param argv command line arguments
2846  * @return 0 ok, 1 on error
2847  */
2848 int
2849 main (int argc, char *const *argv)
2850 {
2851   return (GNUNET_OK ==
2852           GNUNET_SERVICE_run (argc,
2853                               argv,
2854                               "core", &run, NULL, &cleanup, NULL)) ? 0 : 1;
2855 }
2856
2857 /* end of gnunet-service-core.c */