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