ng
[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_Handle *server,
838                     struct GNUNET_SERVER_Client *client,
839                     const struct GNUNET_MessageHeader *message)
840 {
841   const struct InitMessage *im;
842   struct InitReplyMessage irm;
843   struct Client *c;
844   uint16_t msize;
845   const uint16_t *types;
846   struct Neighbour *n;
847   struct ConnectNotifyMessage cnm;
848
849   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
850               "Client connecting to core service with `%s' message\n",
851               "INIT");
852   /* check that we don't have an entry already */
853   c = clients;
854   while (c != NULL)
855     {
856       if (client == c->client_handle)
857         {
858           GNUNET_break (0);
859           GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
860           return;
861         }
862       c = c->next;
863     }
864   msize = ntohs (message->size);
865   if (msize < sizeof (struct InitMessage))
866     {
867       GNUNET_break (0);
868       GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
869       return;
870     }
871   im = (const struct InitMessage *) message;
872   types = (const uint16_t *) &im[1];
873   msize -= sizeof (struct InitMessage);
874   c = GNUNET_malloc (sizeof (struct Client) + msize);
875   c->client_handle = client;
876   c->next = clients;
877   clients = c;
878   memcpy (&c[1], types, msize);
879   c->types = (uint16_t *) & c[1];
880   c->options = ntohl (im->options);
881   c->tcnt = msize / sizeof (uint16_t);
882   /* send init reply message */
883   irm.header.size = htons (sizeof (struct InitReplyMessage));
884   irm.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_INIT_REPLY);
885   irm.reserved = htonl (0);
886   memcpy (&irm.publicKey,
887           &my_public_key,
888           sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded));
889   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
890               "Sending `%s' message to client.\n", "INIT_REPLY");
891   send_to_client (c, &irm.header, GNUNET_NO);
892   /* notify new client about existing neighbours */
893   cnm.header.size = htons (sizeof (struct ConnectNotifyMessage));
894   cnm.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT);
895   n = neighbours;
896   while (n != NULL)
897     {
898       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
899                   "Sending `%s' message to client.\n", "NOTIFY_CONNECT");
900       cnm.bpm_available = htonl (n->bpm_out);
901       cnm.last_activity = GNUNET_TIME_absolute_hton (n->last_activity);
902       cnm.peer = n->peer;
903       send_to_client (c, &cnm.header, GNUNET_NO);
904       n = n->next;
905     }
906   GNUNET_SERVER_receive_done (client, GNUNET_OK);
907 }
908
909
910 /**
911  * A client disconnected, clean up.
912  *
913  * @param cls closure
914  * @param client identification of the client
915  */
916 static void
917 handle_client_disconnect (void *cls, struct GNUNET_SERVER_Client *client)
918 {
919   struct Client *pos;
920   struct Client *prev;
921
922   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
923               "Client has disconnected from core service.\n");
924   prev = NULL;
925   pos = clients;
926   while (pos != NULL)
927     {
928       if (client == pos->client_handle)
929         {
930           if (prev == NULL)
931             clients = pos->next;
932           else
933             prev->next = pos->next;
934           if (pos->th != NULL)
935             GNUNET_NETWORK_notify_transmit_ready_cancel (pos->th);
936           GNUNET_free (pos);
937           return;
938         }
939       prev = pos;
940       pos = pos->next;
941     }
942   /* client never sent INIT */
943 }
944
945
946 /**
947  * Handle REQUEST_CONFIGURE request.
948  */
949 static void
950 handle_client_request_configure (void *cls,
951                                  struct GNUNET_SERVER_Handle *server,
952                                  struct GNUNET_SERVER_Client *client,
953                                  const struct GNUNET_MessageHeader *message)
954 {
955   const struct RequestConfigureMessage *rcm;
956   struct Neighbour *n;
957   struct ConfigurationInfoMessage cim;
958   struct Client *c;
959   int reserv;
960
961   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
962               "Core service receives `%s' request.\n", "CONFIGURE");
963   rcm = (const struct RequestConfigureMessage *) message;
964   n = find_neighbour (&rcm->peer);
965   memset (&cim, 0, sizeof (cim));
966   if ((n != NULL) && (n->status == PEER_STATE_KEY_CONFIRMED))
967     {
968       n->bpm_out_internal_limit = ntohl (rcm->limit_outbound_bpm);
969       n->bpm_out = GNUNET_MAX (n->bpm_out_internal_limit,
970                                n->bpm_out_external_limit);
971       reserv = ntohl (rcm->reserve_inbound);
972       if (reserv < 0)
973         {
974           n->available_recv_window += reserv;
975         }
976       else if (reserv > 0)
977         {
978           update_window (&n->available_recv_window,
979                          &n->last_arw_update, n->bpm_in);
980           if (n->available_recv_window < reserv)
981             reserv = n->available_recv_window;
982           n->available_recv_window -= reserv;
983         }
984       n->current_preference += rcm->preference_change;
985       if (n->current_preference < 0)
986         n->current_preference = 0;
987       cim.reserved_amount = htonl (reserv);
988       cim.bpm_in = htonl (n->bpm_in);
989       cim.bpm_out = htonl (n->bpm_out);
990       cim.latency = GNUNET_TIME_relative_hton (n->last_latency);
991       cim.preference = n->current_preference;
992     }
993   cim.header.size = htons (sizeof (struct ConfigurationInfoMessage));
994   cim.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_CONFIGURATION_INFO);
995   cim.peer = rcm->peer;
996   c = find_client (client);
997   if (c == NULL)
998     {
999       GNUNET_break (0);
1000       return;
1001     }
1002   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1003               "Sending `%s' message to client.\n", "CONFIGURATION_INFO");
1004   send_to_client (c, &cim.header, GNUNET_NO);
1005 }
1006
1007
1008 /**
1009  * Check if we have encrypted messages for the specified neighbour
1010  * pending, and if so, check with the transport about sending them
1011  * out.
1012  *
1013  * @param n neighbour to check.
1014  */
1015 static void process_encrypted_neighbour_queue (struct Neighbour *n);
1016
1017
1018 /**
1019  * Function called when the transport service is ready to
1020  * receive an encrypted message for the respective peer
1021  *
1022  * @param cls neighbour to use message from
1023  * @param size number of bytes we can transmit
1024  * @param buf where to copy the message
1025  * @return number of bytes transmitted
1026  */
1027 static size_t
1028 notify_encrypted_transmit_ready (void *cls, size_t size, void *buf)
1029 {
1030   struct Neighbour *n = cls;
1031   struct MessageEntry *m;
1032   size_t ret;
1033   char *cbuf;
1034
1035   n->th = NULL;
1036   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1037               "Transport ready to receive %u bytes for `%4s'\n",
1038               size, GNUNET_i2s (&n->peer));
1039   GNUNET_assert (NULL != (m = n->encrypted_head));
1040   n->encrypted_head = m->next;
1041   if (m->next == NULL)
1042     n->encrypted_tail = NULL;
1043   ret = 0;
1044   cbuf = buf;
1045   if (buf != NULL)
1046     {
1047       GNUNET_assert (size >= m->size);
1048       memcpy (cbuf, &m[1], m->size);
1049       ret = m->size;
1050       process_encrypted_neighbour_queue (n);
1051       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1052                   "Copied message of type %u and size %u into transport buffer for `%4s'\n",
1053                   ntohs (((struct GNUNET_MessageHeader *) &m[1])->type),
1054                   ret, GNUNET_i2s (&n->peer));
1055     }
1056   else
1057     {
1058       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1059                   "Transmission for message of type %u and size %u failed\n",
1060                   ntohs (((struct GNUNET_MessageHeader *) &m[1])->type),
1061                   m->size);
1062     }
1063   GNUNET_free (m);
1064   return ret;
1065 }
1066
1067
1068 /**
1069  * Check if we have plaintext messages for the specified neighbour
1070  * pending, and if so, consider batching and encrypting them (and
1071  * then trigger processing of the encrypted queue if needed).
1072  *
1073  * @param n neighbour to check.
1074  */
1075 static void process_plaintext_neighbour_queue (struct Neighbour *n);
1076
1077
1078 /**
1079  * Check if we have encrypted messages for the specified neighbour
1080  * pending, and if so, check with the transport about sending them
1081  * out.
1082  *
1083  * @param n neighbour to check.
1084  */
1085 static void
1086 process_encrypted_neighbour_queue (struct Neighbour *n)
1087 {
1088   if (n->th != NULL)
1089     {
1090       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1091                   "Asked to process encrypted queue, but request already pending.\n");
1092       return;                   /* already pending */
1093     }
1094   if (n->encrypted_head == NULL)
1095     {
1096       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1097                   "Encrypted queue empty, trying plaintext queue instead.\n");
1098       process_plaintext_neighbour_queue (n);
1099       return;
1100     }
1101   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1102               "Asking transport for transmission of %u bytes to `%4s' in next %llu ms\n",
1103               n->encrypted_head->size,
1104               GNUNET_i2s (&n->peer),
1105               GNUNET_TIME_absolute_get_remaining (n->encrypted_head->
1106                                                   deadline).value);
1107   n->th =
1108     GNUNET_TRANSPORT_notify_transmit_ready (transport, &n->peer,
1109                                             n->encrypted_head->size,
1110                                             GNUNET_TIME_absolute_get_remaining
1111                                             (n->encrypted_head->deadline),
1112                                             &notify_encrypted_transmit_ready,
1113                                             n);
1114   if (n->th == NULL)
1115     {
1116       /* message request too large (oops) */
1117       GNUNET_break (0);
1118       /* FIXME: handle error somehow! */
1119     }
1120 }
1121
1122
1123 /**
1124  * Decrypt size bytes from in and write the result to out.  Use the
1125  * key for inbound traffic of the given neighbour.  This function does
1126  * NOT do any integrity-checks on the result.
1127  *
1128  * @param n neighbour we are receiving from
1129  * @param iv initialization vector to use
1130  * @param in ciphertext
1131  * @param out plaintext
1132  * @param size size of in/out
1133  * @return GNUNET_OK on success
1134  */
1135 static int
1136 do_decrypt (struct Neighbour *n,
1137             const GNUNET_HashCode * iv,
1138             const void *in, void *out, size_t size)
1139 {
1140   if (size != (uint16_t) size)
1141     {
1142       GNUNET_break (0);
1143       return GNUNET_NO;
1144     }
1145   if ((n->status != PEER_STATE_KEY_RECEIVED) &&
1146       (n->status != PEER_STATE_KEY_CONFIRMED))
1147     {
1148       GNUNET_break_op (0);
1149       return GNUNET_SYSERR;
1150     }
1151   if (size !=
1152       GNUNET_CRYPTO_aes_decrypt (&n->decrypt_key,
1153                                  in,
1154                                  (uint16_t) size,
1155                                  (const struct
1156                                   GNUNET_CRYPTO_AesInitializationVector *) iv,
1157                                  out))
1158     {
1159       GNUNET_break (0);
1160       return GNUNET_SYSERR;
1161     }
1162   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1163               "Decrypted %u bytes from `%4s' using key %u\n",
1164               size, GNUNET_i2s (&n->peer), n->decrypt_key.crc32);
1165   return GNUNET_OK;
1166 }
1167
1168
1169 /**
1170  * Encrypt size bytes from in and write the result to out.  Use the
1171  * key for outbound traffic of the given neighbour.
1172  *
1173  * @param n neighbour we are sending to
1174  * @param iv initialization vector to use
1175  * @param in ciphertext
1176  * @param out plaintext
1177  * @param size size of in/out
1178  * @return GNUNET_OK on success
1179  */
1180 static int
1181 do_encrypt (struct Neighbour *n,
1182             const GNUNET_HashCode * iv,
1183             const void *in, void *out, size_t size)
1184 {
1185   if (size != (uint16_t) size)
1186     {
1187       GNUNET_break (0);
1188       return GNUNET_NO;
1189     }
1190   GNUNET_assert (size ==
1191                  GNUNET_CRYPTO_aes_encrypt (in,
1192                                             (uint16_t) size,
1193                                             &n->encrypt_key,
1194                                             (const struct
1195                                              GNUNET_CRYPTO_AesInitializationVector
1196                                              *) iv, out));
1197   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1198               "Encrypted %u bytes for `%4s' using key %u\n", size,
1199               GNUNET_i2s (&n->peer), n->encrypt_key.crc32);
1200   return GNUNET_OK;
1201 }
1202
1203
1204 /**
1205  * Select messages for transmission.  This heuristic uses a combination
1206  * of earliest deadline first (EDF) scheduling (with bounded horizon)
1207  * and priority-based discard (in case no feasible schedule exist) and
1208  * speculative optimization (defer any kind of transmission until
1209  * we either create a batch of significant size, 25% of max, or until
1210  * we are close to a deadline).  Furthermore, when scheduling the
1211  * heuristic also packs as many messages into the batch as possible,
1212  * starting with those with the earliest deadline.  Yes, this is fun.
1213  *
1214  * @param n neighbour to select messages from
1215  * @param size number of bytes to select for transmission
1216  * @param retry_time set to the time when we should try again
1217  *        (only valid if this function returns zero)
1218  * @return number of bytes selected, or 0 if we decided to
1219  *         defer scheduling overall; in that case, retry_time is set.
1220  */
1221 static size_t
1222 select_messages (struct Neighbour *n,
1223                  size_t size, struct GNUNET_TIME_Relative *retry_time)
1224 {
1225   struct MessageEntry *pos;
1226   struct MessageEntry *min;
1227   struct MessageEntry *last;
1228   unsigned int min_prio;
1229   struct GNUNET_TIME_Absolute t;
1230   struct GNUNET_TIME_Absolute now;
1231   uint64_t delta;
1232   uint64_t avail;
1233   unsigned long long slack;     /* how long could we wait before missing deadlines? */
1234   size_t off;
1235   int discard_low_prio;
1236
1237   GNUNET_assert (NULL != n->messages);
1238   now = GNUNET_TIME_absolute_get ();
1239   /* last entry in linked list of messages processed */
1240   last = NULL;
1241   /* should we remove the entry with the lowest
1242      priority from consideration for scheduling at the
1243      end of the loop? */
1244   discard_low_prio = GNUNET_YES;
1245   while (GNUNET_YES == discard_low_prio)
1246     {
1247       min = NULL;
1248       min_prio = -1;
1249       discard_low_prio = GNUNET_NO;
1250       /* number of bytes available for transmission at time "t" */
1251       avail = n->available_send_window;
1252       t = n->last_asw_update;
1253       /* how many bytes have we (hyptothetically) scheduled so far */
1254       off = 0;
1255       /* maximum time we can wait before transmitting anything
1256          and still make all of our deadlines */
1257       slack = -1;
1258
1259       pos = n->messages;
1260       /* note that we use "*2" here because we want to look
1261          a bit further into the future; much more makes no
1262          sense since new message might be scheduled in the
1263          meantime... */
1264       while ((pos != NULL) && (off < size * 2))
1265         {
1266           if (pos->do_transmit == GNUNET_YES)
1267             {
1268               /* already removed from consideration */
1269               pos = pos->next;
1270               continue;
1271             }
1272           if (discard_low_prio == GNUNET_NO)
1273             {
1274               delta = pos->deadline.value;
1275               if (delta < t.value)
1276                 delta = 0;
1277               else
1278                 delta = t.value - delta;
1279               avail += delta * n->bpm_out / 1000 / 60;
1280               if (avail < pos->size)
1281                 {
1282                   discard_low_prio = GNUNET_YES;        /* we could not schedule this one! */
1283                 }
1284               else
1285                 {
1286                   avail -= pos->size;
1287                   /* update slack, considering both its absolute deadline
1288                      and relative deadlines caused by other messages
1289                      with their respective load */
1290                   slack = GNUNET_MIN (slack, avail / n->bpm_out);
1291                   if (pos->deadline.value < now.value)
1292                     slack = 0;
1293                   else
1294                     slack =
1295                       GNUNET_MIN (slack, pos->deadline.value - now.value);
1296                 }
1297             }
1298           off += pos->size;
1299           t.value = GNUNET_MAX (pos->deadline.value, t.value);
1300           if (pos->priority <= min_prio)
1301             {
1302               /* update min for discard */
1303               min_prio = pos->priority;
1304               min = pos;
1305             }
1306           pos = pos->next;
1307         }
1308       if (discard_low_prio)
1309         {
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_Handle *server,
1584                     struct GNUNET_SERVER_Client *client,
1585                     const struct GNUNET_MessageHeader *message);
1586
1587
1588 /**
1589  * Function called to notify us that we either succeeded
1590  * or failed to connect (at the transport level) to another
1591  * peer.  We should either free the message we were asked
1592  * to transmit or re-try adding it to the queue.
1593  *
1594  * @param cls closure
1595  * @param size number of bytes available in buf
1596  * @param buf where the callee should write the message
1597  * @return number of bytes written to buf
1598  */
1599 static size_t
1600 send_connect_continuation (void *cls, size_t size, void *buf)
1601 {
1602   struct SendMessage *sm = cls;
1603
1604   if (buf == NULL)
1605     {
1606       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1607                   "Asked to send message to disconnected peer `%4s' and connection failed.  Discarding message.\n",
1608                   GNUNET_i2s (&sm->peer));
1609       GNUNET_free (sm);
1610       return 0;
1611     }
1612   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1613               "Connection to peer `%4s' succeeded, retrying original send request\n",
1614               GNUNET_i2s (&sm->peer));
1615   handle_client_send (NULL, NULL, NULL, &sm->header);
1616   GNUNET_free (sm);
1617   return 0;
1618 }
1619
1620
1621 /**
1622  * Handle CORE_SEND request.
1623  */
1624 static void
1625 handle_client_send (void *cls,
1626                     struct GNUNET_SERVER_Handle *server,
1627                     struct GNUNET_SERVER_Client *client,
1628                     const struct GNUNET_MessageHeader *message)
1629 {
1630   const struct SendMessage *sm;
1631   struct SendMessage *smc;
1632   const struct GNUNET_MessageHeader *mh;
1633   struct Neighbour *n;
1634   struct MessageEntry *pred;
1635   struct MessageEntry *pos;
1636   struct MessageEntry *e;
1637   uint16_t msize;
1638
1639   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1640               "Core service receives `%s' request.\n", "SEND");
1641   msize = ntohs (message->size);
1642   if (msize <
1643       sizeof (struct SendMessage) + sizeof (struct GNUNET_MessageHeader))
1644     {
1645       GNUNET_break (0);
1646       if (client != NULL)
1647         GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1648       return;
1649     }
1650   sm = (const struct SendMessage *) message;
1651   msize -= sizeof (struct SendMessage);
1652   mh = (const struct GNUNET_MessageHeader *) &sm[1];
1653   if (msize != ntohs (mh->size))
1654     {
1655       GNUNET_break (0);
1656       if (client != NULL)
1657         GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1658       return;
1659     }
1660   n = find_neighbour (&sm->peer);
1661   if (n == NULL)
1662     {
1663       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1664                   "Not yet connected to `%4s', will try to establish connection\n",
1665                   GNUNET_i2s (&sm->peer));
1666       msize += sizeof (struct SendMessage);
1667       /* ask transport to connect to the peer */
1668       /* FIXME: this code does not handle the
1669          case where we get multiple SendMessages before
1670          transport responds to this request;
1671          => need to track pending requests! */
1672       smc = GNUNET_malloc (msize);
1673       memcpy (smc, sm, msize);
1674       GNUNET_TRANSPORT_notify_transmit_ready (transport,
1675                                               &sm->peer,
1676                                               0,
1677                                               GNUNET_TIME_absolute_get_remaining
1678                                               (GNUNET_TIME_absolute_ntoh
1679                                                (sm->deadline)),
1680                                               &send_connect_continuation,
1681                                               smc);
1682       if (client != NULL)
1683         GNUNET_SERVER_receive_done (client, GNUNET_OK);
1684       return;
1685     }
1686   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1687               "Core queues %u bytes of plaintext data for transmission to `%4s'.\n",
1688               msize, GNUNET_i2s (&sm->peer));
1689   /* FIXME: consider bounding queue size */
1690   e = GNUNET_malloc (sizeof (struct MessageEntry) + msize);
1691   e->deadline = GNUNET_TIME_absolute_ntoh (sm->deadline);
1692   e->priority = ntohl (sm->priority);
1693   e->size = msize;
1694   memcpy (&e[1], mh, msize);
1695
1696   /* insert, keep list sorted by deadline */
1697   pred = NULL;
1698   pos = n->messages;
1699   while ((pos != NULL) && (pos->deadline.value < e->deadline.value))
1700     {
1701       pred = pos;
1702       pos = pos->next;
1703     }
1704   if (pred == NULL)
1705     n->messages = e;
1706   else
1707     pred->next = e;
1708   e->next = pos;
1709
1710   /* consider scheduling now */
1711   process_plaintext_neighbour_queue (n);
1712   if (client != NULL)
1713     GNUNET_SERVER_receive_done (client, GNUNET_OK);
1714 }
1715
1716
1717 /**
1718  * List of handlers for the messages understood by this
1719  * service.
1720  */
1721 static struct GNUNET_SERVER_MessageHandler handlers[] = {
1722   {&handle_client_init, NULL,
1723    GNUNET_MESSAGE_TYPE_CORE_INIT, 0},
1724   {&handle_client_request_configure, NULL,
1725    GNUNET_MESSAGE_TYPE_CORE_REQUEST_CONFIGURE,
1726    sizeof (struct RequestConfigureMessage)},
1727   {&handle_client_send, NULL,
1728    GNUNET_MESSAGE_TYPE_CORE_SEND, 0},
1729   {NULL, NULL, 0, 0}
1730 };
1731
1732
1733 /**
1734  * PEERINFO is giving us a HELLO for a peer.  Add the
1735  * public key to the neighbour's struct and retry
1736  * send_key.  Or, if we did not get a HELLO, just do
1737  * nothing.
1738  *
1739  * @param cls NULL
1740  * @param peer the peer for which this is the HELLO
1741  * @param hello HELLO message of that peer
1742  * @param trust amount of trust we currently have in that peer
1743  */
1744 static void
1745 process_hello_retry_send_key (void *cls,
1746                               const struct GNUNET_PeerIdentity *peer,
1747                               const struct GNUNET_HELLO_Message *hello,
1748                               uint32_t trust)
1749 {
1750   struct Neighbour *n;
1751
1752   if (peer == NULL)
1753     return;
1754   n = find_neighbour (peer);
1755   if (n == NULL)
1756     return;
1757   if (n->public_key != NULL)
1758     return;
1759   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1760               "Received new HELLO for `%4s', initiating key exchange.\n",
1761               GNUNET_i2s (peer));
1762   n->public_key =
1763     GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded));
1764   if (GNUNET_OK != GNUNET_HELLO_get_key (hello, n->public_key))
1765     {
1766       GNUNET_free (n->public_key);
1767       n->public_key = NULL;
1768       return;
1769     }
1770   send_key (n);
1771 }
1772
1773
1774 /**
1775  * Task that will retry "send_key" if our previous attempt failed
1776  * to yield a PONG.
1777  */
1778 static void
1779 set_key_retry_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1780 {
1781   struct Neighbour *n = cls;
1782
1783   GNUNET_assert (n->status != PEER_STATE_KEY_CONFIRMED);
1784   n->retry_set_key_task = GNUNET_SCHEDULER_NO_PREREQUISITE_TASK;
1785   n->set_key_retry_frequency =
1786     GNUNET_TIME_relative_multiply (n->set_key_retry_frequency, 2);
1787   send_key (n);
1788 }
1789
1790
1791 /**
1792  * Send our key (and encrypted PING) to the other peer.
1793  *
1794  * @param n the other peer
1795  */
1796 static void
1797 send_key (struct Neighbour *n)
1798 {
1799   struct SetKeyMessage *sm;
1800   struct MessageEntry *me;
1801   struct PingMessage pp;
1802   struct PingMessage *pm;
1803
1804   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1805               "Asked to perform key exchange with `%4s'.\n",
1806               GNUNET_i2s (&n->peer));
1807   if (n->public_key == NULL)
1808     {
1809       /* lookup n's public key, then try again */
1810       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1811                   "Lacking public key for `%4s', trying to obtain one.\n",
1812                   GNUNET_i2s (&n->peer));
1813       GNUNET_PEERINFO_for_all (cfg,
1814                                sched,
1815                                &n->peer,
1816                                0,
1817                                GNUNET_TIME_UNIT_MINUTES,
1818                                &process_hello_retry_send_key, NULL);
1819       return;
1820     }
1821   /* first, set key message */
1822   me = GNUNET_malloc (sizeof (struct MessageEntry) +
1823                       sizeof (struct SetKeyMessage));
1824   me->deadline = GNUNET_TIME_relative_to_absolute (MAX_SET_KEY_DELAY);
1825   me->priority = SET_KEY_PRIORITY;
1826   me->size = sizeof (struct SetKeyMessage);
1827   if (n->encrypted_head == NULL)
1828     n->encrypted_head = me;
1829   else
1830     n->encrypted_tail->next = me;
1831   n->encrypted_tail = me;
1832   sm = (struct SetKeyMessage *) &me[1];
1833   sm->header.size = htons (sizeof (struct SetKeyMessage));
1834   sm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_SET_KEY);
1835   sm->sender_status = htonl ((int32_t) ((n->status == PEER_STATE_DOWN) ?
1836                                         PEER_STATE_KEY_SENT : n->status));
1837   sm->purpose.size =
1838     htonl (sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) +
1839            sizeof (struct GNUNET_TIME_AbsoluteNBO) +
1840            sizeof (struct GNUNET_CRYPTO_RsaEncryptedData) +
1841            sizeof (struct GNUNET_PeerIdentity));
1842   sm->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_SET_KEY);
1843   sm->creation_time = GNUNET_TIME_absolute_hton (n->encrypt_key_created);
1844   sm->target = n->peer;
1845   GNUNET_assert (GNUNET_OK ==
1846                  GNUNET_CRYPTO_rsa_encrypt (&n->encrypt_key,
1847                                             sizeof (struct
1848                                                     GNUNET_CRYPTO_AesSessionKey),
1849                                             n->public_key,
1850                                             &sm->encrypted_key));
1851   GNUNET_assert (GNUNET_OK ==
1852                  GNUNET_CRYPTO_rsa_sign (my_private_key, &sm->purpose,
1853                                          &sm->signature));
1854
1855   /* second, encrypted PING message */
1856   me = GNUNET_malloc (sizeof (struct MessageEntry) +
1857                       sizeof (struct PingMessage));
1858   me->deadline = GNUNET_TIME_relative_to_absolute (MAX_PING_DELAY);
1859   me->priority = PING_PRIORITY;
1860   me->size = sizeof (struct PingMessage);
1861   n->encrypted_tail->next = me;
1862   n->encrypted_tail = me;
1863   pm = (struct PingMessage *) &me[1];
1864   pm->header.size = htons (sizeof (struct PingMessage));
1865   pm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_PING);
1866   pp.challenge = htonl (n->ping_challenge);
1867   pp.target = n->peer;
1868   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1869               "Encrypting `%s' and `%s' messages for `%4s'.\n",
1870               "SET_KEY", "PING", GNUNET_i2s (&n->peer));
1871   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1872               "Sending `%s' to `%4s' with challenge %u encrypted using key %u\n",
1873               "PING",
1874               GNUNET_i2s (&n->peer), n->ping_challenge, n->encrypt_key.crc32);
1875   do_encrypt (n,
1876               &n->peer.hashPubKey,
1877               &pp.challenge,
1878               &pm->challenge,
1879               sizeof (struct PingMessage) -
1880               sizeof (struct GNUNET_MessageHeader));
1881   /* update status */
1882   switch (n->status)
1883     {
1884     case PEER_STATE_DOWN:
1885       n->status = PEER_STATE_KEY_SENT;
1886       break;
1887     case PEER_STATE_KEY_SENT:
1888       break;
1889     case PEER_STATE_KEY_RECEIVED:
1890       break;
1891     case PEER_STATE_KEY_CONFIRMED:
1892       GNUNET_break (0);
1893       break;
1894     default:
1895       GNUNET_break (0);
1896       break;
1897     }
1898   /* trigger queue processing */
1899   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1900               "Triggering processing of encrypted message queue.\n");
1901   process_encrypted_neighbour_queue (n);
1902   if (n->status != PEER_STATE_KEY_CONFIRMED)
1903     n->retry_set_key_task
1904       = GNUNET_SCHEDULER_add_delayed (sched,
1905                                       GNUNET_NO,
1906                                       GNUNET_SCHEDULER_PRIORITY_KEEP,
1907                                       GNUNET_SCHEDULER_NO_PREREQUISITE_TASK,
1908                                       n->set_key_retry_frequency,
1909                                       &set_key_retry_task, n);
1910 }
1911
1912
1913 /**
1914  * We received a SET_KEY message.  Validate and update
1915  * our key material and status.
1916  *
1917  * @param n the neighbour from which we received message m
1918  * @param m the set key message we received
1919  */
1920 static void
1921 handle_set_key (struct Neighbour *n, const struct SetKeyMessage *m);
1922
1923
1924 /**
1925  * PEERINFO is giving us a HELLO for a peer.  Add the public key to
1926  * the neighbour's struct and retry handling the set_key message.  Or,
1927  * if we did not get a HELLO, just free the set key message.
1928  *
1929  * @param cls pointer to the set key message
1930  * @param peer the peer for which this is the HELLO
1931  * @param hello HELLO message of that peer
1932  * @param trust amount of trust we currently have in that peer
1933  */
1934 static void
1935 process_hello_retry_handle_set_key (void *cls,
1936                                     const struct GNUNET_PeerIdentity *peer,
1937                                     const struct GNUNET_HELLO_Message *hello,
1938                                     uint32_t trust)
1939 {
1940   struct SetKeyMessage *sm = cls;
1941   struct Neighbour *n;
1942
1943   if (peer == NULL)
1944     {
1945       GNUNET_free (sm);
1946       return;
1947     }
1948   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1949               "Looking for peer `%4s' to handle `%s' message.\n",
1950               GNUNET_i2s (peer), "SET_KEY");
1951   n = find_neighbour (peer);
1952   if (n == NULL)
1953     {
1954       GNUNET_break (0);
1955       return;
1956     }
1957   if (n->public_key != NULL)
1958     return;                     /* multiple HELLOs match!? */
1959   n->public_key =
1960     GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded));
1961   if (GNUNET_OK != GNUNET_HELLO_get_key (hello, n->public_key))
1962     {
1963       GNUNET_free (n->public_key);
1964       n->public_key = NULL;
1965       return;
1966     }
1967   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1968               "Received `%s' for `%4s', continuing processing of `%s' message.\n",
1969               "HELLO", GNUNET_i2s (peer), "SET_KEY");
1970   handle_set_key (n, sm);
1971 }
1972
1973
1974 /**
1975  * We received a PING message.  Validate and transmit
1976  * PONG.
1977  *
1978  * @param n sender of the PING
1979  * @param m the encrypted PING message itself
1980  */
1981 static void
1982 handle_ping (struct Neighbour *n, const struct PingMessage *m)
1983 {
1984   struct PingMessage t;
1985   struct PingMessage *tp;
1986   struct MessageEntry *me;
1987
1988   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1989               "Core service receives `%s' request from `%4s'.\n",
1990               "PING", GNUNET_i2s (&n->peer));
1991   if (GNUNET_OK !=
1992       do_decrypt (n,
1993                   &my_identity.hashPubKey,
1994                   &m->challenge,
1995                   &t.challenge,
1996                   sizeof (struct PingMessage) -
1997                   sizeof (struct GNUNET_MessageHeader)))
1998     return;
1999   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2000               "Decrypted `%s' to `%4s' with challenge %u decrypted using key %u\n",
2001               "PING",
2002               GNUNET_i2s (&t.target),
2003               ntohl (t.challenge), n->decrypt_key.crc32);
2004   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2005               "Target of `%s' request is `%4s'.\n",
2006               "PING", GNUNET_i2s (&t.target));
2007   if (0 != memcmp (&t.target,
2008                    &my_identity, sizeof (struct GNUNET_PeerIdentity)))
2009     {
2010       GNUNET_break_op (0);
2011       return;
2012     }
2013   me = GNUNET_malloc (sizeof (struct MessageEntry) +
2014                       sizeof (struct PingMessage));
2015   if (n->encrypted_tail != NULL)
2016     n->encrypted_tail->next = me;
2017   else
2018     {
2019       n->encrypted_tail = me;
2020       n->encrypted_head = me;
2021     }
2022   me->deadline = GNUNET_TIME_relative_to_absolute (MAX_PONG_DELAY);
2023   me->priority = PONG_PRIORITY;
2024   me->size = sizeof (struct PingMessage);
2025   tp = (struct PingMessage *) &me[1];
2026   tp->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_PONG);
2027   tp->header.size = htons (sizeof (struct PingMessage));
2028   do_encrypt (n,
2029               &my_identity.hashPubKey,
2030               &t.challenge,
2031               &tp->challenge,
2032               sizeof (struct PingMessage) -
2033               sizeof (struct GNUNET_MessageHeader));
2034   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2035               "Encrypting `%s' with challenge %u using key %u\n", "PONG",
2036               ntohl (t.challenge), n->encrypt_key.crc32);
2037   /* trigger queue processing */
2038   process_encrypted_neighbour_queue (n);
2039 }
2040
2041
2042 /**
2043  * We received a SET_KEY message.  Validate and update
2044  * our key material and status.
2045  *
2046  * @param n the neighbour from which we received message m
2047  * @param m the set key message we received
2048  */
2049 static void
2050 handle_set_key (struct Neighbour *n, const struct SetKeyMessage *m)
2051 {
2052   struct SetKeyMessage *m_cpy;
2053   struct GNUNET_TIME_Absolute t;
2054   struct GNUNET_CRYPTO_AesSessionKey k;
2055   struct PingMessage *ping;
2056   enum PeerStateMachine sender_status;
2057
2058   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2059               "Core service receives `%s' request from `%4s'.\n",
2060               "SET_KEY", GNUNET_i2s (&n->peer));
2061   if (n->public_key == NULL)
2062     {
2063       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2064                   "Lacking public key for peer, trying to obtain one.\n");
2065       m_cpy = GNUNET_malloc (sizeof (struct SetKeyMessage));
2066       memcpy (m_cpy, m, sizeof (struct SetKeyMessage));
2067       /* lookup n's public key, then try again */
2068       GNUNET_PEERINFO_for_all (cfg,
2069                                sched,
2070                                &n->peer,
2071                                0,
2072                                GNUNET_TIME_UNIT_MINUTES,
2073                                &process_hello_retry_handle_set_key, m_cpy);
2074       return;
2075     }
2076   if ((ntohl (m->purpose.size) !=
2077        sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) +
2078        sizeof (struct GNUNET_TIME_AbsoluteNBO) +
2079        sizeof (struct GNUNET_CRYPTO_RsaEncryptedData) +
2080        sizeof (struct GNUNET_PeerIdentity)) ||
2081       (GNUNET_OK !=
2082        GNUNET_CRYPTO_rsa_verify (GNUNET_SIGNATURE_PURPOSE_SET_KEY,
2083                                  &m->purpose, &m->signature, n->public_key)))
2084     {
2085       /* invalid signature */
2086       GNUNET_break_op (0);
2087       return;
2088     }
2089   t = GNUNET_TIME_absolute_ntoh (m->creation_time);
2090   if (((n->status == PEER_STATE_KEY_RECEIVED) ||
2091        (n->status == PEER_STATE_KEY_CONFIRMED)) &&
2092       (t.value < n->decrypt_key_created.value))
2093     {
2094       /* this could rarely happen due to massive re-ordering of
2095          messages on the network level, but is most likely either
2096          a bug or some adversary messing with us.  Report. */
2097       GNUNET_break_op (0);
2098       return;
2099     }
2100   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Decrypting key material.\n");
2101   if ((GNUNET_CRYPTO_rsa_decrypt (my_private_key,
2102                                   &m->encrypted_key,
2103                                   &k,
2104                                   sizeof (struct GNUNET_CRYPTO_AesSessionKey))
2105        != sizeof (struct GNUNET_CRYPTO_AesSessionKey)) ||
2106       (GNUNET_OK != GNUNET_CRYPTO_aes_check_session_key (&k)))
2107     {
2108       /* failed to decrypt !? */
2109       GNUNET_break_op (0);
2110       return;
2111     }
2112
2113   n->decrypt_key = k;
2114   if (n->decrypt_key_created.value != t.value)
2115     {
2116       /* fresh key, reset sequence numbers */
2117       n->last_sequence_number_received = 0;
2118       n->last_packets_bitmap = 0;
2119       n->decrypt_key_created = t;
2120     }
2121   sender_status = (enum PeerStateMachine) ntohl (m->sender_status);
2122   switch (n->status)
2123     {
2124     case PEER_STATE_DOWN:
2125       n->status = PEER_STATE_KEY_RECEIVED;
2126       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2127                   "Responding to `%s' with my own key.\n", "SET_KEY");
2128       send_key (n);
2129       break;
2130     case PEER_STATE_KEY_SENT:
2131     case PEER_STATE_KEY_RECEIVED:
2132       n->status = PEER_STATE_KEY_RECEIVED;
2133       if ((sender_status != PEER_STATE_KEY_RECEIVED) &&
2134           (sender_status != PEER_STATE_KEY_CONFIRMED))
2135         {
2136           GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2137                       "Responding to `%s' with my own key (other peer has status %u).\n",
2138                       "SET_KEY", sender_status);
2139           send_key (n);
2140         }
2141       break;
2142     case PEER_STATE_KEY_CONFIRMED:
2143       if ((sender_status != PEER_STATE_KEY_RECEIVED) &&
2144           (sender_status != PEER_STATE_KEY_CONFIRMED))
2145         {
2146           GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2147                       "Responding to `%s' with my own key (other peer has status %u), I was already fully up.\n",
2148                       "SET_KEY", sender_status);
2149           send_key (n);
2150         }
2151       break;
2152     default:
2153       GNUNET_break (0);
2154       break;
2155     }
2156   if (n->pending_ping != NULL)
2157     {
2158       ping = n->pending_ping;
2159       n->pending_ping = NULL;
2160       handle_ping (n, ping);
2161       GNUNET_free (ping);
2162     }
2163 }
2164
2165
2166 /**
2167  * We received a PONG message.  Validate and update
2168  * our status.
2169  *
2170  * @param n sender of the PONG
2171  * @param m the encrypted PONG message itself
2172  */
2173 static void
2174 handle_pong (struct Neighbour *n, const struct PingMessage *m)
2175 {
2176   struct PingMessage t;
2177
2178   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2179               "Core service receives `%s' request from `%4s'.\n",
2180               "PONG", GNUNET_i2s (&n->peer));
2181   if (GNUNET_OK !=
2182       do_decrypt (n,
2183                   &n->peer.hashPubKey,
2184                   &m->challenge,
2185                   &t.challenge,
2186                   sizeof (struct PingMessage) -
2187                   sizeof (struct GNUNET_MessageHeader)))
2188     return;
2189   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2190               "Decrypted `%s' from `%4s' with challenge %u using key %u\n",
2191               "PONG",
2192               GNUNET_i2s (&t.target),
2193               ntohl (t.challenge), n->decrypt_key.crc32);
2194   if ((0 != memcmp (&t.target,
2195                     &n->peer,
2196                     sizeof (struct GNUNET_PeerIdentity))) ||
2197       (n->ping_challenge != ntohl (t.challenge)))
2198     {
2199       /* PONG malformed */
2200       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2201                   "Received malfromed `%s' wanted sender `%4s' with challenge %u\n",
2202                   "PONG", GNUNET_i2s (&n->peer), n->ping_challenge);
2203       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2204                   "Received malfromed `%s' received from `%4s' with challenge %u\n",
2205                   "PONG", GNUNET_i2s (&t.target), ntohl (t.challenge));
2206       GNUNET_break_op (0);
2207       return;
2208     }
2209   switch (n->status)
2210     {
2211     case PEER_STATE_DOWN:
2212       GNUNET_break (0);         /* should be impossible */
2213       return;
2214     case PEER_STATE_KEY_SENT:
2215       GNUNET_break (0);         /* should be impossible, how did we decrypt? */
2216       return;
2217     case PEER_STATE_KEY_RECEIVED:
2218       n->status = PEER_STATE_KEY_CONFIRMED;
2219       if (n->retry_set_key_task != GNUNET_SCHEDULER_NO_PREREQUISITE_TASK)
2220         {
2221           GNUNET_SCHEDULER_cancel (sched, n->retry_set_key_task);
2222           n->retry_set_key_task = GNUNET_SCHEDULER_NO_PREREQUISITE_TASK;
2223         }
2224       process_encrypted_neighbour_queue (n);
2225       break;
2226     case PEER_STATE_KEY_CONFIRMED:
2227       /* duplicate PONG? */
2228       break;
2229     default:
2230       GNUNET_break (0);
2231       break;
2232     }
2233 }
2234
2235
2236 /**
2237  * Send a P2P message to a client.
2238  *
2239  * @param sender who sent us the message?
2240  * @param client who should we give the message to?
2241  * @param m contains the message to transmit
2242  * @param msize number of bytes in buf to transmit
2243  */
2244 static void
2245 send_p2p_message_to_client (struct Neighbour *sender,
2246                             struct Client *client,
2247                             const void *m, size_t msize)
2248 {
2249   char buf[msize + sizeof (struct NotifyTrafficMessage)];
2250   struct NotifyTrafficMessage *ntm;
2251
2252   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2253               "Core service passes P2P message of type %u to client.\n",
2254               ntohs (((const struct GNUNET_MessageHeader *) m)->type));
2255   ntm = (struct NotifyTrafficMessage *) buf;
2256   ntm->header.size = htons (msize + sizeof (struct NotifyTrafficMessage));
2257   ntm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_INBOUND);
2258   ntm->reserved = htonl (0);
2259   ntm->peer = sender->peer;
2260   memcpy (&ntm[1], m, msize);
2261   send_to_client (client, &ntm->header, GNUNET_YES);
2262 }
2263
2264
2265 /**
2266  * Deliver P2P message to interested clients.
2267  *
2268  * @param sender who sent us the message?
2269  * @param m the message
2270  * @param msize size of the message (including header)
2271  */
2272 static void
2273 deliver_message (struct Neighbour *sender,
2274                  const struct GNUNET_MessageHeader *m, size_t msize)
2275 {
2276   struct Client *cpos;
2277   uint16_t type;
2278   unsigned int tpos;
2279   int deliver_full;
2280
2281   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2282               "Passing decrypted P2P message to interested clients.\n");
2283   type = ntohs (m->type);
2284   cpos = clients;
2285   while (cpos != NULL)
2286     {
2287       deliver_full = GNUNET_NO;
2288       if (cpos->options & GNUNET_CORE_OPTION_SEND_FULL_INBOUND)
2289         deliver_full = GNUNET_YES;
2290       else
2291         {
2292           for (tpos = 0; tpos < cpos->tcnt; tpos++)
2293             {
2294               if (type != cpos->types[tpos])
2295                 continue;
2296               deliver_full = GNUNET_YES;
2297               break;
2298             }
2299         }
2300       if (GNUNET_YES == deliver_full)
2301         send_p2p_message_to_client (sender, cpos, m, msize);
2302       else if (cpos->options & GNUNET_CORE_OPTION_SEND_HDR_INBOUND)
2303         send_p2p_message_to_client (sender, cpos, m,
2304                                     sizeof (struct GNUNET_MessageHeader));
2305       cpos = cpos->next;
2306     }
2307 }
2308
2309
2310 /**
2311  * Align P2P message and then deliver to interested clients.
2312  *
2313  * @param sender who sent us the message?
2314  * @param buffer unaligned (!) buffer containing message
2315  * @param msize size of the message (including header)
2316  */
2317 static void
2318 align_and_deliver (struct Neighbour *sender, const char *buffer, size_t msize)
2319 {
2320   char abuf[msize];
2321
2322   /* TODO: call to statistics? */
2323   memcpy (abuf, buffer, msize);
2324   deliver_message (sender, (const struct GNUNET_MessageHeader *) abuf, msize);
2325 }
2326
2327
2328 /**
2329  * Deliver P2P messages to interested clients.
2330  *
2331  * @param sender who sent us the message?
2332  * @param buffer buffer containing messages, can be modified
2333  * @param buffer_size size of the buffer (overall)
2334  * @param offset offset where messages in the buffer start
2335  */
2336 static void
2337 deliver_messages (struct Neighbour *sender,
2338                   const char *buffer, size_t buffer_size, size_t offset)
2339 {
2340   struct GNUNET_MessageHeader *mhp;
2341   struct GNUNET_MessageHeader mh;
2342   uint16_t msize;
2343   int need_align;
2344
2345   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2346               "Delivering %u bytes of plaintext to interested clients.\n",
2347               buffer_size);
2348   while (offset + sizeof (struct GNUNET_MessageHeader) <= buffer_size)
2349     {
2350       if (0 != offset % sizeof (uint16_t))
2351         {
2352           /* outch, need to copy to access header */
2353           memcpy (&mh, &buffer[offset], sizeof (struct GNUNET_MessageHeader));
2354           mhp = &mh;
2355         }
2356       else
2357         {
2358           /* can access header directly */
2359           mhp = (struct GNUNET_MessageHeader *) &buffer[offset];
2360         }
2361       msize = ntohs (mhp->size);
2362       if (msize + offset > buffer_size)
2363         {
2364           /* malformed message, header says it is larger than what
2365              would fit into the overall buffer */
2366           GNUNET_break_op (0);
2367           break;
2368         }
2369 #if HAVE_UNALIGNED_64_ACCESS
2370       need_align = (0 != offset % 4) ? GNUNET_YES : GNUNET_NO;
2371 #else
2372       need_align = (0 != offset % 8) ? GNUNET_YES : GNUNET_NO;
2373 #endif
2374       if (GNUNET_YES == need_align)
2375         align_and_deliver (sender, &buffer[offset], msize);
2376       else
2377         deliver_message (sender,
2378                          (const struct GNUNET_MessageHeader *)
2379                          &buffer[offset], msize);
2380       offset += msize;
2381     }
2382 }
2383
2384
2385 /**
2386  * We received an encrypted message.  Decrypt, validate and
2387  * pass on to the appropriate clients.
2388  */
2389 static void
2390 handle_encrypted_message (struct Neighbour *n,
2391                           const struct EncryptedMessage *m)
2392 {
2393   size_t size = ntohs (m->header.size);
2394   char buf[size];
2395   struct EncryptedMessage *pt;  /* plaintext */
2396   GNUNET_HashCode ph;
2397   size_t off;
2398   uint32_t snum;
2399   struct GNUNET_TIME_Absolute t;
2400
2401   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2402               "Core service receives `%s' request from `%4s'.\n",
2403               "ENCRYPTED_MESSAGE", GNUNET_i2s (&n->peer));
2404   /* decrypt */
2405   if (GNUNET_OK !=
2406       do_decrypt (n,
2407                   &m->plaintext_hash,
2408                   &m->sequence_number,
2409                   &buf[ENCRYPTED_HEADER_SIZE], size - ENCRYPTED_HEADER_SIZE))
2410     return;
2411   pt = (struct EncryptedMessage *) buf;
2412
2413   /* validate hash */
2414   GNUNET_CRYPTO_hash (&pt->sequence_number,
2415                       size - ENCRYPTED_HEADER_SIZE, &ph);
2416   if (0 != memcmp (&ph, &m->plaintext_hash, sizeof (GNUNET_HashCode)))
2417     {
2418       /* checksum failed */
2419       GNUNET_break_op (0);
2420       return;
2421     }
2422
2423   /* validate sequence number */
2424   snum = ntohl (pt->sequence_number);
2425   if (n->last_sequence_number_received == snum)
2426     {
2427       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2428                   "Received duplicate message, ignoring.\n");
2429       /* duplicate, ignore */
2430       return;
2431     }
2432   if ((n->last_sequence_number_received > snum) &&
2433       (n->last_sequence_number_received - snum > 32))
2434     {
2435       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2436                   "Received ancient out of sequence message, ignoring.\n");
2437       /* ancient out of sequence, ignore */
2438       return;
2439     }
2440   if (n->last_sequence_number_received > snum)
2441     {
2442       unsigned int rotbit =
2443         1 << (n->last_sequence_number_received - snum - 1);
2444       if ((n->last_packets_bitmap & rotbit) != 0)
2445         {
2446           GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2447                       "Received duplicate message, ignoring.\n");
2448           /* duplicate, ignore */
2449           return;
2450         }
2451       n->last_packets_bitmap |= rotbit;
2452     }
2453   if (n->last_sequence_number_received < snum)
2454     {
2455       n->last_packets_bitmap <<= (snum - n->last_sequence_number_received);
2456       n->last_sequence_number_received = snum;
2457     }
2458
2459   /* check timestamp */
2460   t = GNUNET_TIME_absolute_ntoh (pt->timestamp);
2461   if (GNUNET_TIME_absolute_get_duration (t).value > MAX_MESSAGE_AGE.value)
2462     {
2463       GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2464                   _
2465                   ("Message received far too old (%llu ms). Content ignored.\n"),
2466                   GNUNET_TIME_absolute_get_duration (t).value);
2467       return;
2468     }
2469
2470   /* process decrypted message(s) */
2471   n->bpm_out_external_limit = ntohl (pt->inbound_bpm_limit);
2472   n->bpm_out = GNUNET_MAX (n->bpm_out_external_limit,
2473                            n->bpm_out_internal_limit);
2474   n->last_activity = GNUNET_TIME_absolute_get ();
2475   off = sizeof (struct EncryptedMessage);
2476   deliver_messages (n, buf, size, off);
2477 }
2478
2479
2480 /**
2481  * Function called by the transport for each received message.
2482  *
2483  * @param cls closure
2484  * @param latency estimated latency for communicating with the
2485  *             given peer
2486  * @param peer (claimed) identity of the other peer
2487  * @param message the message
2488  */
2489 static void
2490 handle_transport_receive (void *cls,
2491                           struct GNUNET_TIME_Relative latency,
2492                           const struct GNUNET_PeerIdentity *peer,
2493                           const struct GNUNET_MessageHeader *message)
2494 {
2495   struct Neighbour *n;
2496   struct GNUNET_TIME_Absolute now;
2497   int up;
2498   uint16_t type;
2499   uint16_t size;
2500
2501   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2502               "Received message of type %u from `%4s', demultiplexing.\n",
2503               ntohs (message->type), GNUNET_i2s (peer));
2504   n = find_neighbour (peer);
2505   if (n == NULL)
2506     {
2507       GNUNET_break (0);
2508       return;
2509     }
2510   n->last_latency = latency;
2511   up = n->status == PEER_STATE_KEY_CONFIRMED;
2512   type = ntohs (message->type);
2513   size = ntohs (message->size);
2514   switch (type)
2515     {
2516     case GNUNET_MESSAGE_TYPE_CORE_SET_KEY:
2517       if (size != sizeof (struct SetKeyMessage))
2518         {
2519           GNUNET_break_op (0);
2520           return;
2521         }
2522       handle_set_key (n, (const struct SetKeyMessage *) message);
2523       break;
2524     case GNUNET_MESSAGE_TYPE_CORE_ENCRYPTED_MESSAGE:
2525       if (size < sizeof (struct EncryptedMessage) +
2526           sizeof (struct GNUNET_MessageHeader))
2527         {
2528           GNUNET_break_op (0);
2529           return;
2530         }
2531       if ((n->status != PEER_STATE_KEY_RECEIVED) &&
2532           (n->status != PEER_STATE_KEY_CONFIRMED))
2533         {
2534           GNUNET_break_op (0);
2535           return;
2536         }
2537       handle_encrypted_message (n, (const struct EncryptedMessage *) message);
2538       break;
2539     case GNUNET_MESSAGE_TYPE_CORE_PING:
2540       if (size != sizeof (struct PingMessage))
2541         {
2542           GNUNET_break_op (0);
2543           return;
2544         }
2545       if ((n->status != PEER_STATE_KEY_RECEIVED) &&
2546           (n->status != PEER_STATE_KEY_CONFIRMED))
2547         {
2548           GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2549                       "Core service receives `%s' request from `%4s' but have not processed key; marking as pending.\n",
2550                       "PING", GNUNET_i2s (&n->peer));
2551           GNUNET_free_non_null (n->pending_ping);
2552           n->pending_ping = GNUNET_malloc (sizeof (struct PingMessage));
2553           memcpy (n->pending_ping, message, sizeof (struct PingMessage));
2554           return;
2555         }
2556       handle_ping (n, (const struct PingMessage *) message);
2557       break;
2558     case GNUNET_MESSAGE_TYPE_CORE_PONG:
2559       if (size != sizeof (struct PingMessage))
2560         {
2561           GNUNET_break_op (0);
2562           return;
2563         }
2564       if ((n->status != PEER_STATE_KEY_SENT) &&
2565           (n->status != PEER_STATE_KEY_RECEIVED) &&
2566           (n->status != PEER_STATE_KEY_CONFIRMED))
2567         {
2568           /* could not decrypt pong, oops! */
2569           GNUNET_break_op (0);
2570           return;
2571         }
2572       handle_pong (n, (const struct PingMessage *) message);
2573       break;
2574     default:
2575       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2576                   _("Unsupported message of type %u received.\n"), type);
2577       return;
2578     }
2579   if (n->status == PEER_STATE_KEY_CONFIRMED)
2580     {
2581       now = GNUNET_TIME_absolute_get ();
2582       n->last_activity = now;
2583       if (!up)
2584         n->time_established = now;
2585     }
2586 }
2587
2588
2589 /**
2590  * Function called by transport to notify us that
2591  * a peer connected to us (on the network level).
2592  *
2593  * @param cls closure
2594  * @param peer the peer that connected
2595  * @param latency current latency of the connection
2596  */
2597 static void
2598 handle_transport_notify_connect (void *cls,
2599                                  const struct GNUNET_PeerIdentity *peer,
2600                                  struct GNUNET_TIME_Relative latency)
2601 {
2602   struct Neighbour *n;
2603   struct GNUNET_TIME_Absolute now;
2604   struct ConnectNotifyMessage cnm;
2605
2606   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2607               "Received connection from `%4s'.\n", GNUNET_i2s (peer));
2608   n = find_neighbour (peer);
2609   if (n != NULL)
2610     {
2611       /* duplicate connect notification!? */
2612       GNUNET_break (0);
2613       return;
2614     }
2615   now = GNUNET_TIME_absolute_get ();
2616   n = GNUNET_malloc (sizeof (struct Neighbour));
2617   n->next = neighbours;
2618   neighbours = n;
2619   n->peer = *peer;
2620   n->last_latency = latency;
2621   GNUNET_CRYPTO_aes_create_session_key (&n->encrypt_key);
2622   n->encrypt_key_created = now;
2623   n->set_key_retry_frequency = INITIAL_SET_KEY_RETRY_FREQUENCY;
2624   n->last_asw_update = now;
2625   n->last_arw_update = now;
2626   n->bpm_in = DEFAULT_BPM_IN_OUT;
2627   n->bpm_out = DEFAULT_BPM_IN_OUT;
2628   n->bpm_out_internal_limit = (uint32_t) - 1;
2629   n->bpm_out_external_limit = DEFAULT_BPM_IN_OUT;
2630   n->ping_challenge = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
2631                                                 (uint32_t) - 1);
2632   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2633               "Created entry for new neighbour `%4s'.\n",
2634               GNUNET_i2s (&n->peer));
2635   cnm.header.size = htons (sizeof (struct ConnectNotifyMessage));
2636   cnm.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT);
2637   cnm.bpm_available = htonl (DEFAULT_BPM_IN_OUT);
2638   cnm.peer = *peer;
2639   cnm.last_activity = GNUNET_TIME_absolute_hton (now);
2640   send_to_all_clients (&cnm.header, GNUNET_YES);
2641 }
2642
2643
2644 /**
2645  * Free the given entry for the neighbour (it has
2646  * already been removed from the list at this point).
2647  * @param n neighbour to free
2648  */
2649 static void
2650 free_neighbour (struct Neighbour *n)
2651 {
2652   struct MessageEntry *m;
2653
2654   while (NULL != (m = n->messages))
2655     {
2656       n->messages = m->next;
2657       GNUNET_free (m);
2658     }
2659   while (NULL != (m = n->encrypted_head))
2660     {
2661       n->encrypted_head = m->next;
2662       GNUNET_free (m);
2663     }
2664   if (NULL != n->th)
2665     GNUNET_TRANSPORT_notify_transmit_ready_cancel (n->th);
2666   if (n->retry_plaintext_task != GNUNET_SCHEDULER_NO_PREREQUISITE_TASK)
2667     GNUNET_SCHEDULER_cancel (sched, n->retry_plaintext_task);
2668   if (n->retry_set_key_task != GNUNET_SCHEDULER_NO_PREREQUISITE_TASK)
2669     GNUNET_SCHEDULER_cancel (sched, n->retry_set_key_task);
2670   GNUNET_free_non_null (n->public_key);
2671   GNUNET_free_non_null (n->pending_ping);
2672   GNUNET_free (n);
2673 }
2674
2675
2676 /**
2677  * Function called by transport telling us that a peer
2678  * disconnected.
2679  *
2680  * @param cls closure
2681  * @param peer the peer that disconnected
2682  */
2683 static void
2684 handle_transport_notify_disconnect (void *cls,
2685                                     const struct GNUNET_PeerIdentity *peer)
2686 {
2687   struct ConnectNotifyMessage cnm;
2688   struct Neighbour *n;
2689   struct Neighbour *p;
2690
2691   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2692               "Peer `%4s' disconnected from us.\n", GNUNET_i2s (peer));
2693   p = NULL;
2694   n = neighbours;
2695   while ((n != NULL) &&
2696          (0 != memcmp (&n->peer, peer, sizeof (struct GNUNET_PeerIdentity))))
2697     {
2698       p = n;
2699       n = n->next;
2700     }
2701   if (n == NULL)
2702     {
2703       GNUNET_break (0);
2704       return;
2705     }
2706   if (p == NULL)
2707     neighbours = n->next;
2708   else
2709     p->next = n->next;
2710   cnm.header.size = htons (sizeof (struct ConnectNotifyMessage));
2711   cnm.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_DISCONNECT);
2712   cnm.bpm_available = htonl (0);
2713   cnm.peer = *peer;
2714   cnm.last_activity = GNUNET_TIME_absolute_hton (n->last_activity);
2715   send_to_all_clients (&cnm.header, GNUNET_YES);
2716   free_neighbour (n);
2717 }
2718
2719
2720 /**
2721  * Last task run during shutdown.  Disconnects us from
2722  * the transport.
2723  */
2724 static void
2725 cleaning_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
2726 {
2727   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Core service shutting down.\n");
2728   GNUNET_assert (transport != NULL);
2729   GNUNET_TRANSPORT_disconnect (transport);
2730   transport = NULL;
2731 }
2732
2733
2734 /**
2735  * Initiate core service.
2736  *
2737  * @param cls closure
2738  * @param s scheduler to use
2739  * @param serv the initialized server
2740  * @param c configuration to use
2741  */
2742 static void
2743 run (void *cls,
2744      struct GNUNET_SCHEDULER_Handle *s,
2745      struct GNUNET_SERVER_Handle *serv, struct GNUNET_CONFIGURATION_Handle *c)
2746 {
2747 #if 0
2748   unsigned long long qin;
2749   unsigned long long qout;
2750   unsigned long long tneigh;
2751 #endif
2752   char *keyfile;
2753
2754   sched = s;
2755   cfg = c;
2756   /* parse configuration */
2757   if (
2758 #if 0
2759        (GNUNET_OK !=
2760         GNUNET_CONFIGURATION_get_value_number (c,
2761                                                "CORE",
2762                                                "XX",
2763                                                &qin)) ||
2764        (GNUNET_OK !=
2765         GNUNET_CONFIGURATION_get_value_number (c,
2766                                                "CORE",
2767                                                "YY",
2768                                                &qout)) ||
2769        (GNUNET_OK !=
2770         GNUNET_CONFIGURATION_get_value_number (c,
2771                                                "CORE",
2772                                                "ZZ_LIMIT", &tneigh)) ||
2773 #endif
2774        (GNUNET_OK !=
2775         GNUNET_CONFIGURATION_get_value_filename (c,
2776                                                  "GNUNETD",
2777                                                  "HOSTKEY", &keyfile)))
2778     {
2779       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2780                   _
2781                   ("Core service is lacking key configuration settings.  Exiting.\n"));
2782       GNUNET_SCHEDULER_shutdown (s);
2783       return;
2784     }
2785   my_private_key = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile);
2786   GNUNET_free (keyfile);
2787   if (my_private_key == NULL)
2788     {
2789       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2790                   _("Core service could not access hostkey.  Exiting.\n"));
2791       GNUNET_SCHEDULER_shutdown (s);
2792       return;
2793     }
2794   GNUNET_CRYPTO_rsa_key_get_public (my_private_key, &my_public_key);
2795   GNUNET_CRYPTO_hash (&my_public_key,
2796                       sizeof (my_public_key), &my_identity.hashPubKey);
2797   /* setup notification */
2798   server = serv;
2799   GNUNET_SERVER_disconnect_notify (server, &handle_client_disconnect, NULL);
2800   /* setup transport connection */
2801   transport = GNUNET_TRANSPORT_connect (sched,
2802                                         cfg,
2803                                         NULL,
2804                                         &handle_transport_receive,
2805                                         &handle_transport_notify_connect,
2806                                         &handle_transport_notify_disconnect);
2807   GNUNET_assert (NULL != transport);
2808   GNUNET_SCHEDULER_add_delayed (sched,
2809                                 GNUNET_YES,
2810                                 GNUNET_SCHEDULER_PRIORITY_IDLE,
2811                                 GNUNET_SCHEDULER_NO_PREREQUISITE_TASK,
2812                                 GNUNET_TIME_UNIT_FOREVER_REL,
2813                                 &cleaning_task, NULL);
2814   /* process client requests */
2815   GNUNET_SERVER_add_handlers (server, handlers);
2816   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2817               _("Core service of `%4s' ready.\n"), GNUNET_i2s (&my_identity));
2818 }
2819
2820
2821 /**
2822  * Function called during shutdown.  Clean up our state.
2823  */
2824 static void
2825 cleanup (void *cls, struct GNUNET_CONFIGURATION_Handle *cfg)
2826 {
2827   struct Neighbour *n;
2828
2829   if (my_private_key != NULL)
2830     GNUNET_CRYPTO_rsa_key_free (my_private_key);
2831   while (NULL != (n = neighbours))
2832     {
2833       neighbours = n->next;
2834       free_neighbour (n);
2835     }
2836   /*
2837      FIXME:
2838      - free clients
2839    */
2840 }
2841
2842
2843 /**
2844  * The main function for the transport service.
2845  *
2846  * @param argc number of arguments from the command line
2847  * @param argv command line arguments
2848  * @return 0 ok, 1 on error
2849  */
2850 int
2851 main (int argc, char *const *argv)
2852 {
2853   return (GNUNET_OK ==
2854           GNUNET_SERVICE_run (argc,
2855                               argv,
2856                               "core", &run, NULL, &cleanup, NULL)) ? 0 : 1;
2857 }
2858
2859 /* end of gnunet-service-core.c */