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