2 This file is part of GNUnet.
3 (C) 2009 Christian Grothoff (and other contributing authors)
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.
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.
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.
22 * @file core/gnunet-service-core.c
23 * @brief high-level P2P messaging
24 * @author Christian Grothoff
27 * - revisit API (which arguments are used, needed)?
28 * - add code to re-transmit key if first attempt failed
29 * + timeout on connect / key exchange, etc.
30 * + timeout for automatic re-try, etc.
31 * - add code to give up re-transmission of key if many attempts fail
32 * - add code to send PINGs if we are about to time-out otherwise
33 * ? add heuristic to do another send_key in "handle_set_key"
34 * in case previous attempt failed / didn't work / persist
35 * (but don't do it always to avoid storm of SET_KEY's going
36 * back and forth!) --- alternatively, add "status" field
37 * of the other peer to the set key message, that way we'd
39 * - check that hostkey used by transport (for HELLOs) is the
40 * same as the hostkey that we are using!
41 * - topology management:
42 * + bootstrapping (transport offer hello, plugins)
43 * + internal neighbour selection
44 * + update bandwidth usage statistics
45 * + bandwidth allocation (transport set quota)
46 * - optimize lookup (many O(n) list traversals
47 * could ideally be changed to O(1) hash map lookups)
50 #include "gnunet_util_lib.h"
51 #include "gnunet_hello_lib.h"
52 #include "gnunet_peerinfo_service.h"
53 #include "gnunet_protocols.h"
54 #include "gnunet_signatures.h"
55 #include "gnunet_transport_service.h"
60 * Receive and send buffer windows grow over time. For
61 * how long can 'unused' bandwidth accumulate before we
62 * need to cap it? (specified in ms).
64 #define MAX_WINDOW_TIME (5 * 60 * 1000)
68 * Amount of bytes per minute (in/out) to assume initially
69 * (before either peer has communicated any particular
70 * preference). Should be rather low.
72 #define DEFAULT_BPM_IN_OUT 2048
76 * After how much time past the "official" expiration time do
77 * we discard messages? Should not be zero since we may
78 * intentionally defer transmission until close to the deadline
79 * and then may be slightly past the deadline due to inaccuracy
80 * in sleep and our own CPU consumption.
82 #define PAST_EXPIRATION_DISCARD_TIME GNUNET_TIME_UNIT_SECONDS
86 * What is the maximum delay for a SET_KEY message?
88 #define MAX_SET_KEY_DELAY GNUNET_TIME_UNIT_SECONDS
92 * What how long do we wait for SET_KEY confirmation initially?
94 #define INITIAL_SET_KEY_RETRY_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 3)
98 * What is the maximum delay for a PING message?
100 #define MAX_PING_DELAY GNUNET_TIME_UNIT_SECONDS
104 * What is the maximum delay for a PONG message?
106 #define MAX_PONG_DELAY GNUNET_TIME_UNIT_SECONDS
110 * What is the priority for a SET_KEY message?
112 #define SET_KEY_PRIORITY 0xFFFFFF
116 * What is the priority for a PING message?
118 #define PING_PRIORITY 0xFFFFFF
122 * What is the priority for a PONG message?
124 #define PONG_PRIORITY 0xFFFFFF
128 * How many messages do we queue per peer at most?
130 #define MAX_PEER_QUEUE_SIZE 16
134 * How many non-mandatory messages do we queue per client at most?
136 #define MAX_CLIENT_QUEUE_SIZE 32
140 * What is the maximum age of a message for us to consider
141 * processing it? Note that this looks at the timestamp used
142 * by the other peer, so clock skew between machines does
143 * come into play here. So this should be picked high enough
144 * so that a little bit of clock skew does not prevent peers
145 * from connecting to us.
147 #define MAX_MESSAGE_AGE GNUNET_TIME_UNIT_DAYS
151 * What is the maximum size for encrypted messages? Note that this
152 * number imposes a clear limit on the maximum size of any message.
153 * Set to a value close to 64k but not so close that transports will
154 * have trouble with their headers.
156 #define MAX_ENCRYPTED_MESSAGE_SIZE (63 * 1024)
160 * State machine for our P2P encryption handshake. Everyone starts in
161 * "DOWN", if we receive the other peer's key (other peer initiated)
162 * we start in state RECEIVED (since we will immediately send our
163 * own); otherwise we start in SENT. If we get back a PONG from
164 * within either state, we move up to CONFIRMED (the PONG will always
165 * be sent back encrypted with the key we sent to the other peer).
167 enum PeerStateMachine
171 PEER_STATE_KEY_RECEIVED,
172 PEER_STATE_KEY_CONFIRMED
177 * Number of bytes (at the beginning) of "struct EncryptedMessage"
178 * that are NOT encrypted.
180 #define ENCRYPTED_HEADER_SIZE (sizeof(struct GNUNET_MessageHeader) + sizeof(uint32_t) + sizeof(GNUNET_HashCode))
183 * Encapsulation for encrypted messages exchanged between
184 * peers. Followed by the actual encrypted data.
186 struct EncryptedMessage
189 * Message type is either CORE_ENCRYPTED_MESSAGE.
191 struct GNUNET_MessageHeader header;
196 uint32_t reserved GNUNET_PACKED;
199 * Hash of the plaintext, used to verify message integrity;
200 * ALSO used as the IV for the symmetric cipher! Everything
201 * after this hash will be encrypted. ENCRYPTED_HEADER_SIZE
202 * must be set to the offset of the next field.
204 GNUNET_HashCode plaintext_hash;
207 * Sequence number, in network byte order. This field
208 * must be the first encrypted/decrypted field and the
209 * first byte that is hashed for the plaintext hash.
211 uint32_t sequence_number GNUNET_PACKED;
214 * Desired bandwidth (how much we should send to this
215 * peer / how much is the sender willing to receive),
216 * in bytes per minute.
218 uint32_t inbound_bpm_limit GNUNET_PACKED;
221 * Timestamp. Used to prevent reply of ancient messages
222 * (recent messages are caught with the sequence number).
224 struct GNUNET_TIME_AbsoluteNBO timestamp;
229 * We're sending an (encrypted) PING to the other peer to check if he
230 * can decrypt. The other peer should respond with a PONG with the
231 * same content, except this time encrypted with the receiver's key.
236 * Message type is either CORE_PING or CORE_PONG.
238 struct GNUNET_MessageHeader header;
241 * Random number chosen to make reply harder.
243 uint32_t challenge GNUNET_PACKED;
246 * Intended target of the PING, used primarily to check
247 * that decryption actually worked.
249 struct GNUNET_PeerIdentity target;
254 * Message transmitted to set (or update) a session key.
260 * Message type is either CORE_SET_KEY.
262 struct GNUNET_MessageHeader header;
265 * Status of the sender (should be in "enum PeerStateMachine"), nbo.
267 int32_t sender_status GNUNET_PACKED;
270 * Purpose of the signature, will be
271 * GNUNET_SIGNATURE_PURPOSE_SET_KEY.
273 struct GNUNET_CRYPTO_RsaSignaturePurpose purpose;
276 * At what time was this key created?
278 struct GNUNET_TIME_AbsoluteNBO creation_time;
281 * The encrypted session key.
283 struct GNUNET_CRYPTO_RsaEncryptedData encrypted_key;
286 * Who is the intended recipient?
288 struct GNUNET_PeerIdentity target;
291 * Signature of the stuff above (starting at purpose).
293 struct GNUNET_CRYPTO_RsaSignature signature;
299 * Message waiting for transmission. This struct
300 * is followed by the actual content of the message.
306 * We keep messages in a linked list (for now).
308 struct MessageEntry *next;
311 * By when are we supposed to transmit this message?
313 struct GNUNET_TIME_Absolute deadline;
316 * How important is this message to us?
318 unsigned int priority;
321 * How long is the message? (number of bytes following
322 * the "struct MessageEntry", but not including the
323 * size of "struct MessageEntry" itself!)
328 * Was this message selected for transmission in the
329 * current round? GNUNET_YES or GNUNET_NO.
339 * We keep neighbours in a linked list (for now).
341 struct Neighbour *next;
344 * Unencrypted messages destined for this peer.
346 struct MessageEntry *messages;
349 * Head of the batched, encrypted message queue (already ordered,
350 * transmit starting with the head).
352 struct MessageEntry *encrypted_head;
355 * Tail of the batched, encrypted message queue (already ordered,
356 * append new messages to tail)
358 struct MessageEntry *encrypted_tail;
361 * Handle for pending requests for transmission to this peer
362 * with the transport service. NULL if no request is pending.
364 struct GNUNET_TRANSPORT_TransmitHandle *th;
367 * Public key of the neighbour, NULL if we don't have it yet.
369 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *public_key;
372 * We received a PING message before we got the "public_key"
373 * (or the SET_KEY). We keep it here until we have a key
374 * to decrypt it. NULL if no PING is pending.
376 struct PingMessage *pending_ping;
379 * Identity of the neighbour.
381 struct GNUNET_PeerIdentity peer;
384 * Key we use to encrypt our messages for the other peer
385 * (initialized by us when we do the handshake).
387 struct GNUNET_CRYPTO_AesSessionKey encrypt_key;
390 * Key we use to decrypt messages from the other peer
391 * (given to us by the other peer during the handshake).
393 struct GNUNET_CRYPTO_AesSessionKey decrypt_key;
396 * ID of task used for re-trying plaintext scheduling.
398 GNUNET_SCHEDULER_TaskIdentifier retry_plaintext_task;
401 * ID of task used for re-trying SET_KEY and PING message.
403 GNUNET_SCHEDULER_TaskIdentifier retry_set_key_task;
406 * At what time did we generate our encryption key?
408 struct GNUNET_TIME_Absolute encrypt_key_created;
411 * At what time did the other peer generate the decryption key?
413 struct GNUNET_TIME_Absolute decrypt_key_created;
416 * At what time did we initially establish (as in, complete session
417 * key handshake) this connection? Should be zero if status != KEY_CONFIRMED.
419 struct GNUNET_TIME_Absolute time_established;
422 * At what time did we last receive an encrypted message from the
423 * other peer? Should be zero if status != KEY_CONFIRMED.
425 struct GNUNET_TIME_Absolute last_activity;
428 * Last latency observed from this peer.
430 struct GNUNET_TIME_Relative last_latency;
433 * At what frequency are we currently re-trying SET KEY messages?
435 struct GNUNET_TIME_Relative set_key_retry_frequency;
438 * Time of our last update to the "available_send_window".
440 struct GNUNET_TIME_Absolute last_asw_update;
443 * Time of our last update to the "available_recv_window".
445 struct GNUNET_TIME_Absolute last_arw_update;
448 * Number of bytes that we are eligible to transmit to this
449 * peer at this point. Incremented every minute by max_out_bpm,
450 * bounded by max_bpm (no back-log larger than MAX_BUF_FACT minutes,
451 * bandwidth-hogs are sampled at a frequency of about 78s!);
452 * may get negative if we have VERY high priority content.
454 long long available_send_window;
457 * How much downstream capacity of this peer has been reserved for
458 * our traffic? (Our clients can request that a certain amount of
459 * bandwidth is available for replies to them; this value is used to
460 * make sure that this reserved amount of bandwidth is actually
463 long long available_recv_window;
466 * How valueable were the messages of this peer recently?
468 double current_preference;
471 * Bit map indicating which of the 32 sequence numbers before the last
472 * were received (good for accepting out-of-order packets and
473 * estimating reliability of the connection)
475 unsigned int last_packets_bitmap;
478 * Number of messages in the message queue for this peer.
480 unsigned int message_queue_size;
483 * last sequence number received on this connection (highest)
485 uint32_t last_sequence_number_received;
488 * last sequence number transmitted
490 uint32_t last_sequence_number_sent;
493 * Available bandwidth in for this peer (current target).
498 * Available bandwidth out for this peer (current target).
503 * Internal bandwidth limit set for this peer (initially
504 * typcially set to "-1"). "bpm_out" is MAX of
505 * "bpm_out_internal_limit" and "bpm_out_external_limit".
507 uint32_t bpm_out_internal_limit;
510 * External bandwidth limit set for this peer by the
511 * peer that we are communicating with. "bpm_out" is MAX of
512 * "bpm_out_internal_limit" and "bpm_out_external_limit".
514 uint32_t bpm_out_external_limit;
517 * What was our PING challenge number?
519 uint32_t ping_challenge;
522 * What is our connection status?
524 enum PeerStateMachine status;
530 * Events are messages for clients. The struct
531 * itself is followed by the actual message.
536 * This is a linked list.
541 * Size of the message.
546 * Could this event be dropped if this queue
547 * is getting too large? (NOT YET USED!)
555 * Data structure for each client connected to the core service.
560 * Clients are kept in a linked list.
565 * Handle for the client with the server API.
567 struct GNUNET_SERVER_Client *client_handle;
570 * Linked list of messages we still need to deliver to
573 struct Event *event_head;
576 * Tail of the linked list of events.
578 struct Event *event_tail;
581 * Current transmit handle, NULL if no transmission request
584 struct GNUNET_NETWORK_TransmitHandle *th;
587 * Array of the types of messages this peer cares
588 * about (with "tcnt" entries). Allocated as part
589 * of this client struct, do not free!
594 * Options for messages this client cares about,
595 * see GNUNET_CORE_OPTION_ values.
600 * Number of types of incoming messages this client
601 * specifically cares about. Size of the "types" array.
611 static struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded my_public_key;
616 static struct GNUNET_PeerIdentity my_identity;
621 static struct GNUNET_CRYPTO_RsaPrivateKey *my_private_key;
626 struct GNUNET_SCHEDULER_Handle *sched;
631 struct GNUNET_CONFIGURATION_Handle *cfg;
636 static struct GNUNET_SERVER_Handle *server;
641 static struct GNUNET_TRANSPORT_Handle *transport;
644 * We keep neighbours in a linked list (for now).
646 static struct Neighbour *neighbours;
649 * Linked list of our clients.
651 static struct Client *clients;
655 * Recalculate the number of bytes we expect to
656 * receive or transmit in a given window.
658 * @param window pointer to the byte counter (updated)
659 * @param ts pointer to the timestamp (updated)
660 * @param bpm number of bytes per minute that should
661 * be added to the window.
664 update_window (long long *window,
665 struct GNUNET_TIME_Absolute *ts, unsigned int bpm)
667 struct GNUNET_TIME_Relative since;
669 since = GNUNET_TIME_absolute_get_duration (*ts);
670 if (since.value < 60 * 1000)
671 return; /* not even a minute has passed */
672 *ts = GNUNET_TIME_absolute_get ();
673 *window += (bpm * since.value) / 60 / 1000;
674 if (*window > MAX_WINDOW_TIME * bpm)
675 *window = MAX_WINDOW_TIME * bpm;
680 * Find the entry for the given neighbour.
682 * @param peer identity of the neighbour
683 * @return NULL if we are not connected, otherwise the
686 static struct Neighbour *
687 find_neighbour (const struct GNUNET_PeerIdentity *peer)
689 struct Neighbour *ret;
692 while ((ret != NULL) &&
693 (0 != memcmp (&ret->peer,
694 peer, sizeof (struct GNUNET_PeerIdentity))))
701 * Find the entry for the given client.
703 * @param client handle for the client
704 * @return NULL if we are not connected, otherwise the
707 static struct Client *
708 find_client (const struct GNUNET_SERVER_Client *client)
713 while ((ret != NULL) && (client != ret->client_handle))
720 * If necessary, initiate a request with the server to
721 * transmit messages from the queue of the given client.
722 * @param client who to transfer messages to
724 static void request_transmit (struct Client *client);
728 * Client is ready to receive data, provide it.
731 * @param size number of bytes available in buf
732 * @param buf where the callee should write the message
733 * @return number of bytes written to buf
736 do_client_transmit (void *cls, size_t size, void *buf)
738 struct Client *client = cls;
744 #if DEBUG_CORE_CLIENT
745 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
746 "Client ready to receive %u bytes.\n", size);
751 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
752 "Failed to transmit data to client (disconnect)?\n");
754 return 0; /* we'll surely get a disconnect soon... */
758 while ((NULL != (e = client->event_head)) && (e->size <= size))
760 memcpy (&tgt[ret], &e[1], e->size);
763 client->event_head = e->next;
766 GNUNET_assert (ret > 0);
767 if (client->event_head == NULL)
768 client->event_tail = NULL;
769 #if DEBUG_CORE_CLIENT
770 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
771 "Transmitting %u bytes to client\n", ret);
773 request_transmit (client);
779 * If necessary, initiate a request with the server to
780 * transmit messages from the queue of the given client.
781 * @param client who to transfer messages to
784 request_transmit (struct Client *client)
787 if (NULL != client->th)
788 return; /* already pending */
789 if (NULL == client->event_head)
790 return; /* no more events pending */
791 #if DEBUG_CORE_CLIENT
792 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
793 "Asking server to transmit %u bytes to client\n",
794 client->event_head->size);
797 = GNUNET_SERVER_notify_transmit_ready (client->client_handle,
798 client->event_head->size,
799 GNUNET_TIME_UNIT_FOREVER_REL,
800 &do_client_transmit, client);
805 * Send a message to one of our clients.
806 * @param client target for the message
807 * @param msg message to transmit
808 * @param can_drop could this message be dropped if the
809 * client's queue is getting too large?
812 send_to_client (struct Client *client,
813 const struct GNUNET_MessageHeader *msg, int can_drop)
816 unsigned int queue_size;
819 #if DEBUG_CORE_CLIENT
820 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
821 "Preparing to send message of type %u to client.\n",
825 e = client->event_head;
831 if ( (queue_size >= MAX_CLIENT_QUEUE_SIZE) &&
832 (can_drop == GNUNET_YES) )
835 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
836 "Too many messages in queue for the client, dropping the new message.\n");
841 msize = ntohs (msg->size);
842 e = GNUNET_malloc (sizeof (struct Event) + msize);
844 if (client->event_tail != NULL)
845 client->event_tail->next = e;
847 client->event_head = e;
848 client->event_tail = e;
849 e->can_drop = can_drop;
851 memcpy (&e[1], msg, msize);
852 request_transmit (client);
857 * Send a message to all of our current clients.
860 send_to_all_clients (const struct GNUNET_MessageHeader *msg, int can_drop)
867 send_to_client (c, msg, can_drop);
874 * Handle CORE_INIT request.
877 handle_client_init (void *cls,
878 struct GNUNET_SERVER_Client *client,
879 const struct GNUNET_MessageHeader *message)
881 const struct InitMessage *im;
882 struct InitReplyMessage irm;
885 const uint16_t *types;
887 struct ConnectNotifyMessage cnm;
889 #if DEBUG_CORE_CLIENT
890 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
891 "Client connecting to core service with `%s' message\n",
894 /* check that we don't have an entry already */
898 if (client == c->client_handle)
901 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
906 msize = ntohs (message->size);
907 if (msize < sizeof (struct InitMessage))
910 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
913 im = (const struct InitMessage *) message;
914 types = (const uint16_t *) &im[1];
915 msize -= sizeof (struct InitMessage);
916 c = GNUNET_malloc (sizeof (struct Client) + msize);
917 c->client_handle = client;
920 memcpy (&c[1], types, msize);
921 c->types = (uint16_t *) & c[1];
922 c->options = ntohl (im->options);
923 c->tcnt = msize / sizeof (uint16_t);
924 /* send init reply message */
925 irm.header.size = htons (sizeof (struct InitReplyMessage));
926 irm.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_INIT_REPLY);
927 irm.reserved = htonl (0);
928 memcpy (&irm.publicKey,
930 sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded));
931 #if DEBUG_CORE_CLIENT
932 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
933 "Sending `%s' message to client.\n", "INIT_REPLY");
935 send_to_client (c, &irm.header, GNUNET_NO);
936 /* notify new client about existing neighbours */
937 cnm.header.size = htons (sizeof (struct ConnectNotifyMessage));
938 cnm.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT);
942 #if DEBUG_CORE_CLIENT
943 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
944 "Sending `%s' message to client.\n", "NOTIFY_CONNECT");
946 cnm.bpm_available = htonl (n->bpm_out);
947 cnm.last_activity = GNUNET_TIME_absolute_hton (n->last_activity);
949 send_to_client (c, &cnm.header, GNUNET_NO);
952 GNUNET_SERVER_receive_done (client, GNUNET_OK);
957 * A client disconnected, clean up.
960 * @param client identification of the client
963 handle_client_disconnect (void *cls, struct GNUNET_SERVER_Client *client)
969 #if DEBUG_CORE_CLIENT
970 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
971 "Client has disconnected from core service.\n");
977 if (client == pos->client_handle)
982 prev->next = pos->next;
984 GNUNET_NETWORK_notify_transmit_ready_cancel (pos->th);
985 while (NULL != (e = pos->event_head))
987 pos->event_head = e->next;
996 /* client never sent INIT */
1001 * Handle REQUEST_CONFIGURE request.
1004 handle_client_request_configure (void *cls,
1005 struct GNUNET_SERVER_Client *client,
1006 const struct GNUNET_MessageHeader *message)
1008 const struct RequestConfigureMessage *rcm;
1009 struct Neighbour *n;
1010 struct ConfigurationInfoMessage cim;
1014 #if DEBUG_CORE_CLIENT
1015 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1016 "Core service receives `%s' request.\n", "CONFIGURE");
1018 rcm = (const struct RequestConfigureMessage *) message;
1019 n = find_neighbour (&rcm->peer);
1020 memset (&cim, 0, sizeof (cim));
1021 if ((n != NULL) && (n->status == PEER_STATE_KEY_CONFIRMED))
1023 n->bpm_out_internal_limit = ntohl (rcm->limit_outbound_bpm);
1024 n->bpm_out = GNUNET_MAX (n->bpm_out_internal_limit,
1025 n->bpm_out_external_limit);
1026 reserv = ntohl (rcm->reserve_inbound);
1029 n->available_recv_window += reserv;
1031 else if (reserv > 0)
1033 update_window (&n->available_recv_window,
1034 &n->last_arw_update, n->bpm_in);
1035 if (n->available_recv_window < reserv)
1036 reserv = n->available_recv_window;
1037 n->available_recv_window -= reserv;
1039 n->current_preference += rcm->preference_change;
1040 if (n->current_preference < 0)
1041 n->current_preference = 0;
1042 cim.reserved_amount = htonl (reserv);
1043 cim.bpm_in = htonl (n->bpm_in);
1044 cim.bpm_out = htonl (n->bpm_out);
1045 cim.latency = GNUNET_TIME_relative_hton (n->last_latency);
1046 cim.preference = n->current_preference;
1048 cim.header.size = htons (sizeof (struct ConfigurationInfoMessage));
1049 cim.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_CONFIGURATION_INFO);
1050 cim.peer = rcm->peer;
1051 c = find_client (client);
1057 #if DEBUG_CORE_CLIENT
1058 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1059 "Sending `%s' message to client.\n", "CONFIGURATION_INFO");
1061 send_to_client (c, &cim.header, GNUNET_NO);
1066 * Check if we have encrypted messages for the specified neighbour
1067 * pending, and if so, check with the transport about sending them
1070 * @param n neighbour to check.
1072 static void process_encrypted_neighbour_queue (struct Neighbour *n);
1076 * Function called when the transport service is ready to
1077 * receive an encrypted message for the respective peer
1079 * @param cls neighbour to use message from
1080 * @param size number of bytes we can transmit
1081 * @param buf where to copy the message
1082 * @return number of bytes transmitted
1085 notify_encrypted_transmit_ready (void *cls, size_t size, void *buf)
1087 struct Neighbour *n = cls;
1088 struct MessageEntry *m;
1093 GNUNET_assert (NULL != (m = n->encrypted_head));
1094 n->encrypted_head = m->next;
1095 if (m->next == NULL)
1096 n->encrypted_tail = NULL;
1101 GNUNET_assert (size >= m->size);
1102 memcpy (cbuf, &m[1], m->size);
1104 process_encrypted_neighbour_queue (n);
1106 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1107 "Copied message of type %u and size %u into transport buffer for `%4s'\n",
1108 ntohs (((struct GNUNET_MessageHeader *) &m[1])->type),
1109 ret, GNUNET_i2s (&n->peer));
1114 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1115 "Transmission for message of type %u and size %u failed\n",
1116 ntohs (((struct GNUNET_MessageHeader *) &m[1])->type),
1125 * Check if we have plaintext messages for the specified neighbour
1126 * pending, and if so, consider batching and encrypting them (and
1127 * then trigger processing of the encrypted queue if needed).
1129 * @param n neighbour to check.
1131 static void process_plaintext_neighbour_queue (struct Neighbour *n);
1135 * Check if we have encrypted messages for the specified neighbour
1136 * pending, and if so, check with the transport about sending them
1139 * @param n neighbour to check.
1142 process_encrypted_neighbour_queue (struct Neighbour *n)
1144 struct MessageEntry *m;
1147 return; /* request already pending */
1148 if (n->encrypted_head == NULL)
1150 /* encrypted queue empty, try plaintext instead */
1151 process_plaintext_neighbour_queue (n);
1155 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1156 "Asking transport for transmission of %u bytes to `%4s' in next %llu ms\n",
1157 n->encrypted_head->size,
1158 GNUNET_i2s (&n->peer),
1159 GNUNET_TIME_absolute_get_remaining (n->
1160 encrypted_head->deadline).
1164 GNUNET_TRANSPORT_notify_transmit_ready (transport, &n->peer,
1165 n->encrypted_head->size,
1166 GNUNET_TIME_absolute_get_remaining
1167 (n->encrypted_head->deadline),
1168 ¬ify_encrypted_transmit_ready,
1172 /* message request too large (oops) */
1174 /* discard encrypted message */
1175 GNUNET_assert (NULL != (m = n->encrypted_head));
1176 n->encrypted_head = m->next;
1177 if (m->next == NULL)
1178 n->encrypted_tail = NULL;
1180 process_encrypted_neighbour_queue (n);
1186 * Decrypt size bytes from in and write the result to out. Use the
1187 * key for inbound traffic of the given neighbour. This function does
1188 * NOT do any integrity-checks on the result.
1190 * @param n neighbour we are receiving from
1191 * @param iv initialization vector to use
1192 * @param in ciphertext
1193 * @param out plaintext
1194 * @param size size of in/out
1195 * @return GNUNET_OK on success
1198 do_decrypt (struct Neighbour *n,
1199 const GNUNET_HashCode * iv,
1200 const void *in, void *out, size_t size)
1202 if (size != (uint16_t) size)
1207 if ((n->status != PEER_STATE_KEY_RECEIVED) &&
1208 (n->status != PEER_STATE_KEY_CONFIRMED))
1210 GNUNET_break_op (0);
1211 return GNUNET_SYSERR;
1214 GNUNET_CRYPTO_aes_decrypt (&n->decrypt_key,
1218 GNUNET_CRYPTO_AesInitializationVector *) iv,
1222 return GNUNET_SYSERR;
1225 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1226 "Decrypted %u bytes from `%4s' using key %u\n",
1227 size, GNUNET_i2s (&n->peer), n->decrypt_key.crc32);
1234 * Encrypt size bytes from in and write the result to out. Use the
1235 * key for outbound traffic of the given neighbour.
1237 * @param n neighbour we are sending to
1238 * @param iv initialization vector to use
1239 * @param in ciphertext
1240 * @param out plaintext
1241 * @param size size of in/out
1242 * @return GNUNET_OK on success
1245 do_encrypt (struct Neighbour *n,
1246 const GNUNET_HashCode * iv,
1247 const void *in, void *out, size_t size)
1249 if (size != (uint16_t) size)
1254 GNUNET_assert (size ==
1255 GNUNET_CRYPTO_aes_encrypt (in,
1259 GNUNET_CRYPTO_AesInitializationVector
1262 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1263 "Encrypted %u bytes for `%4s' using key %u\n", size,
1264 GNUNET_i2s (&n->peer), n->encrypt_key.crc32);
1271 * Select messages for transmission. This heuristic uses a combination
1272 * of earliest deadline first (EDF) scheduling (with bounded horizon)
1273 * and priority-based discard (in case no feasible schedule exist) and
1274 * speculative optimization (defer any kind of transmission until
1275 * we either create a batch of significant size, 25% of max, or until
1276 * we are close to a deadline). Furthermore, when scheduling the
1277 * heuristic also packs as many messages into the batch as possible,
1278 * starting with those with the earliest deadline. Yes, this is fun.
1280 * @param n neighbour to select messages from
1281 * @param size number of bytes to select for transmission
1282 * @param retry_time set to the time when we should try again
1283 * (only valid if this function returns zero)
1284 * @return number of bytes selected, or 0 if we decided to
1285 * defer scheduling overall; in that case, retry_time is set.
1288 select_messages (struct Neighbour *n,
1289 size_t size, struct GNUNET_TIME_Relative *retry_time)
1291 struct MessageEntry *pos;
1292 struct MessageEntry *min;
1293 struct MessageEntry *last;
1294 unsigned int min_prio;
1295 struct GNUNET_TIME_Absolute t;
1296 struct GNUNET_TIME_Absolute now;
1299 unsigned long long slack; /* how long could we wait before missing deadlines? */
1301 int discard_low_prio;
1303 GNUNET_assert (NULL != n->messages);
1304 now = GNUNET_TIME_absolute_get ();
1305 /* last entry in linked list of messages processed */
1307 /* should we remove the entry with the lowest
1308 priority from consideration for scheduling at the
1310 discard_low_prio = GNUNET_YES;
1311 while (GNUNET_YES == discard_low_prio)
1315 discard_low_prio = GNUNET_NO;
1316 /* number of bytes available for transmission at time "t" */
1317 avail = n->available_send_window;
1318 t = n->last_asw_update;
1319 /* how many bytes have we (hyptothetically) scheduled so far */
1321 /* maximum time we can wait before transmitting anything
1322 and still make all of our deadlines */
1326 /* note that we use "*2" here because we want to look
1327 a bit further into the future; much more makes no
1328 sense since new message might be scheduled in the
1330 while ((pos != NULL) && (off < size * 2))
1332 if (pos->do_transmit == GNUNET_YES)
1334 /* already removed from consideration */
1338 if (discard_low_prio == GNUNET_NO)
1340 delta = pos->deadline.value;
1341 if (delta < t.value)
1344 delta = t.value - delta;
1345 avail += delta * n->bpm_out / 1000 / 60;
1346 if (avail < pos->size)
1348 discard_low_prio = GNUNET_YES; /* we could not schedule this one! */
1353 /* update slack, considering both its absolute deadline
1354 and relative deadlines caused by other messages
1355 with their respective load */
1356 slack = GNUNET_MIN (slack, avail / n->bpm_out);
1357 if (pos->deadline.value < now.value)
1361 GNUNET_MIN (slack, pos->deadline.value - now.value);
1365 t.value = GNUNET_MAX (pos->deadline.value, t.value);
1366 if (pos->priority <= min_prio)
1368 /* update min for discard */
1369 min_prio = pos->priority;
1374 if (discard_low_prio)
1376 GNUNET_assert (min != NULL);
1377 /* remove lowest-priority entry from consideration */
1378 min->do_transmit = GNUNET_YES; /* means: discard (for now) */
1382 /* guard against sending "tiny" messages with large headers without
1384 if ((slack > 1000) && (size > 4 * off))
1386 /* less than 25% of message would be filled with
1387 deadlines still being met if we delay by one
1388 second or more; so just wait for more data */
1389 retry_time->value = slack / 2;
1390 /* reset do_transmit values for next time */
1393 pos->do_transmit = GNUNET_NO;
1398 /* select marked messages (up to size) for transmission */
1403 if ((pos->size <= size) && (pos->do_transmit == GNUNET_NO))
1405 pos->do_transmit = GNUNET_YES; /* mark for transmission */
1410 pos->do_transmit = GNUNET_NO; /* mark for not transmitting! */
1414 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1415 "Selected %u bytes of plaintext messages for transmission to `%4s'.\n",
1416 off, GNUNET_i2s (&n->peer));
1423 * Batch multiple messages into a larger buffer.
1425 * @param n neighbour to take messages from
1426 * @param buf target buffer
1427 * @param size size of buf
1428 * @param deadline set to transmission deadline for the result
1429 * @param retry_time set to the time when we should try again
1430 * (only valid if this function returns zero)
1431 * @param priority set to the priority of the batch
1432 * @return number of bytes written to buf (can be zero)
1435 batch_message (struct Neighbour *n,
1438 struct GNUNET_TIME_Absolute *deadline,
1439 struct GNUNET_TIME_Relative *retry_time,
1440 unsigned int *priority)
1442 struct MessageEntry *pos;
1443 struct MessageEntry *prev;
1444 struct MessageEntry *next;
1449 *deadline = GNUNET_TIME_UNIT_FOREVER_ABS;
1450 *retry_time = GNUNET_TIME_UNIT_FOREVER_REL;
1451 if (0 == select_messages (n, size, retry_time))
1453 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1454 "No messages selected, will try again in %llu ms\n",
1460 while ((pos != NULL) && (size >= sizeof (struct GNUNET_MessageHeader)))
1463 if (GNUNET_YES == pos->do_transmit)
1465 GNUNET_assert (pos->size <= size);
1466 memcpy (&buf[ret], &pos[1], pos->size);
1469 *priority += pos->priority;
1470 deadline->value = GNUNET_MIN (deadline->value, pos->deadline.value);
1488 * Remove messages with deadlines that have long expired from
1491 * @param n neighbour to inspect
1494 discard_expired_messages (struct Neighbour *n)
1496 struct MessageEntry *prev;
1497 struct MessageEntry *next;
1498 struct MessageEntry *pos;
1499 struct GNUNET_TIME_Absolute cutoff;
1501 cutoff = GNUNET_TIME_relative_to_absolute(PAST_EXPIRATION_DISCARD_TIME);
1507 if (pos->deadline.value < cutoff.value)
1509 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1510 "Message is %llu ms past due, discarding.\n",
1511 cutoff.value - pos->deadline.value);
1526 * Signature of the main function of a task.
1528 * @param cls closure
1529 * @param tc context information (why was this task triggered now)
1532 retry_plaintext_processing (void *cls,
1533 const struct GNUNET_SCHEDULER_TaskContext *tc)
1535 struct Neighbour *n = cls;
1537 n->retry_plaintext_task = GNUNET_SCHEDULER_NO_PREREQUISITE_TASK;
1538 process_plaintext_neighbour_queue (n);
1543 * Send our key (and encrypted PING) to the other peer.
1545 * @param n the other peer
1547 static void send_key (struct Neighbour *n);
1551 * Check if we have plaintext messages for the specified neighbour
1552 * pending, and if so, consider batching and encrypting them (and
1553 * then trigger processing of the encrypted queue if needed).
1555 * @param n neighbour to check.
1558 process_plaintext_neighbour_queue (struct Neighbour *n)
1560 char pbuf[MAX_ENCRYPTED_MESSAGE_SIZE]; /* plaintext */
1563 struct EncryptedMessage *em; /* encrypted message */
1564 struct EncryptedMessage *ph; /* plaintext header */
1565 struct MessageEntry *me;
1566 unsigned int priority;
1567 struct GNUNET_TIME_Absolute deadline;
1568 struct GNUNET_TIME_Relative retry_time;
1570 if (n->retry_plaintext_task != GNUNET_SCHEDULER_NO_PREREQUISITE_TASK)
1572 GNUNET_SCHEDULER_cancel (sched, n->retry_plaintext_task);
1573 n->retry_plaintext_task = GNUNET_SCHEDULER_NO_PREREQUISITE_TASK;
1577 case PEER_STATE_DOWN:
1580 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1581 "Not yet connected to `%4s', deferring processing of plaintext messages.\n",
1582 GNUNET_i2s(&n->peer));
1585 case PEER_STATE_KEY_SENT:
1586 GNUNET_assert (n->retry_set_key_task !=
1587 GNUNET_SCHEDULER_NO_PREREQUISITE_TASK);
1589 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1590 "Not yet connected to `%4s', deferring processing of plaintext messages.\n",
1591 GNUNET_i2s(&n->peer));
1594 case PEER_STATE_KEY_RECEIVED:
1595 GNUNET_assert (n->retry_set_key_task !=
1596 GNUNET_SCHEDULER_NO_PREREQUISITE_TASK);
1598 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1599 "Not yet connected to `%4s', deferring processing of plaintext messages.\n",
1600 GNUNET_i2s(&n->peer));
1603 case PEER_STATE_KEY_CONFIRMED:
1604 /* ready to continue */
1607 discard_expired_messages (n);
1608 if (n->messages == NULL)
1611 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1612 "Plaintext message queue for `%4s' is empty.\n",
1613 GNUNET_i2s(&n->peer));
1615 return; /* no pending messages */
1617 if (n->encrypted_head != NULL)
1620 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1621 "Encrypted message queue for `%4s' is still full, delaying plaintext processing.\n",
1622 GNUNET_i2s(&n->peer));
1624 return; /* wait for messages already encrypted to be
1627 ph = (struct EncryptedMessage *) pbuf;
1628 deadline = GNUNET_TIME_UNIT_FOREVER_ABS;
1630 used = sizeof (struct EncryptedMessage);
1631 used += batch_message (n,
1633 MAX_ENCRYPTED_MESSAGE_SIZE - used,
1634 &deadline, &retry_time, &priority);
1635 if (used == sizeof (struct EncryptedMessage))
1638 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1639 "No messages selected for transmission to `%4s' at this time, will try again later.\n",
1640 GNUNET_i2s(&n->peer));
1642 /* no messages selected for sending, try again later... */
1643 n->retry_plaintext_task =
1644 GNUNET_SCHEDULER_add_delayed (sched,
1646 GNUNET_SCHEDULER_PRIORITY_IDLE,
1647 GNUNET_SCHEDULER_NO_PREREQUISITE_TASK,
1649 &retry_plaintext_processing, n);
1653 ph->sequence_number = htonl (++n->last_sequence_number_sent);
1654 ph->inbound_bpm_limit = htonl (n->bpm_in);
1655 ph->timestamp = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get ());
1657 /* setup encryption message header */
1658 me = GNUNET_malloc (sizeof (struct MessageEntry) + used);
1659 me->deadline = deadline;
1660 me->priority = priority;
1662 em = (struct EncryptedMessage *) &me[1];
1663 em->header.size = htons (used);
1664 em->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_ENCRYPTED_MESSAGE);
1665 em->reserved = htonl (0);
1666 esize = used - ENCRYPTED_HEADER_SIZE;
1667 GNUNET_CRYPTO_hash (&ph->sequence_number, esize, &em->plaintext_hash);
1670 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1671 "Encrypting %u bytes of plaintext messages for `%4s' for transmission.\n",
1673 GNUNET_i2s(&n->peer));
1675 GNUNET_assert (GNUNET_OK ==
1677 &em->plaintext_hash,
1678 &ph->sequence_number,
1679 &em->sequence_number, esize));
1680 /* append to transmission list */
1681 if (n->encrypted_tail == NULL)
1682 n->encrypted_head = me;
1684 n->encrypted_tail->next = me;
1685 n->encrypted_tail = me;
1686 process_encrypted_neighbour_queue (n);
1691 * Handle CORE_SEND request.
1694 handle_client_send (void *cls,
1695 struct GNUNET_SERVER_Client *client,
1696 const struct GNUNET_MessageHeader *message);
1700 * Function called to notify us that we either succeeded
1701 * or failed to connect (at the transport level) to another
1702 * peer. We should either free the message we were asked
1703 * to transmit or re-try adding it to the queue.
1705 * @param cls closure
1706 * @param size number of bytes available in buf
1707 * @param buf where the callee should write the message
1708 * @return number of bytes written to buf
1711 send_connect_continuation (void *cls, size_t size, void *buf)
1713 struct SendMessage *sm = cls;
1718 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1719 "Asked to send message to disconnected peer `%4s' and connection failed. Discarding message.\n",
1720 GNUNET_i2s (&sm->peer));
1726 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1727 "Connection to peer `%4s' succeeded, retrying original transmission request\n",
1728 GNUNET_i2s (&sm->peer));
1730 handle_client_send (NULL, NULL, &sm->header);
1737 * Handle CORE_SEND request.
1740 handle_client_send (void *cls,
1741 struct GNUNET_SERVER_Client *client,
1742 const struct GNUNET_MessageHeader *message)
1744 const struct SendMessage *sm;
1745 struct SendMessage *smc;
1746 const struct GNUNET_MessageHeader *mh;
1747 struct Neighbour *n;
1748 struct MessageEntry *prev;
1749 struct MessageEntry *pos;
1750 struct MessageEntry *e;
1751 struct MessageEntry *min_prio_entry;
1752 struct MessageEntry *min_prio_prev;
1753 unsigned int min_prio;
1754 unsigned int queue_size;
1757 msize = ntohs (message->size);
1759 sizeof (struct SendMessage) + sizeof (struct GNUNET_MessageHeader))
1763 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1766 sm = (const struct SendMessage *) message;
1767 msize -= sizeof (struct SendMessage);
1768 mh = (const struct GNUNET_MessageHeader *) &sm[1];
1769 if (msize != ntohs (mh->size))
1773 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
1776 n = find_neighbour (&sm->peer);
1780 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1781 "Core received `%s' request for `%4s', will try to establish connection within %llu ms\n",
1783 GNUNET_i2s (&sm->peer),
1784 sm->deadline.value);
1786 msize += sizeof (struct SendMessage);
1787 /* ask transport to connect to the peer */
1788 smc = GNUNET_malloc (msize);
1789 memcpy (smc, sm, msize);
1791 GNUNET_TRANSPORT_notify_transmit_ready (transport,
1794 GNUNET_TIME_absolute_get_remaining
1795 (GNUNET_TIME_absolute_ntoh
1797 &send_connect_continuation,
1800 /* transport has already a request pending for this peer! */
1802 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1803 "Dropped second message destined for `%4s' since connection is still down.\n",
1804 GNUNET_i2s(&sm->peer));
1809 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1813 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1814 "Core received `%s' request, queueing %u bytes of plaintext data for transmission to `%4s'.\n",
1817 GNUNET_i2s (&sm->peer));
1819 /* bound queue size */
1820 discard_expired_messages (n);
1821 min_prio = (unsigned int) -1;
1827 if (pos->priority < min_prio)
1829 min_prio_entry = pos;
1830 min_prio_prev = prev;
1831 min_prio = pos->priority;
1837 if (queue_size >= MAX_PEER_QUEUE_SIZE)
1840 if (ntohl(sm->priority) <= min_prio)
1842 /* discard new entry */
1844 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1845 "Queue full, discarding new request\n");
1848 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1851 /* discard "min_prio_entry" */
1853 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1854 "Queue full, discarding existing older request\n");
1856 if (min_prio_prev == NULL)
1857 n->messages = min_prio_entry->next;
1859 min_prio_prev->next = min_prio_entry->next;
1860 GNUNET_free (min_prio_entry);
1863 e = GNUNET_malloc (sizeof (struct MessageEntry) + msize);
1864 e->deadline = GNUNET_TIME_absolute_ntoh (sm->deadline);
1865 e->priority = ntohl (sm->priority);
1867 memcpy (&e[1], mh, msize);
1869 /* insert, keep list sorted by deadline */
1872 while ((pos != NULL) && (pos->deadline.value < e->deadline.value))
1883 /* consider scheduling now */
1884 process_plaintext_neighbour_queue (n);
1886 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1891 * List of handlers for the messages understood by this
1894 static struct GNUNET_SERVER_MessageHandler handlers[] = {
1895 {&handle_client_init, NULL,
1896 GNUNET_MESSAGE_TYPE_CORE_INIT, 0},
1897 {&handle_client_request_configure, NULL,
1898 GNUNET_MESSAGE_TYPE_CORE_REQUEST_CONFIGURE,
1899 sizeof (struct RequestConfigureMessage)},
1900 {&handle_client_send, NULL,
1901 GNUNET_MESSAGE_TYPE_CORE_SEND, 0},
1907 * PEERINFO is giving us a HELLO for a peer. Add the
1908 * public key to the neighbour's struct and retry
1909 * send_key. Or, if we did not get a HELLO, just do
1913 * @param peer the peer for which this is the HELLO
1914 * @param hello HELLO message of that peer
1915 * @param trust amount of trust we currently have in that peer
1918 process_hello_retry_send_key (void *cls,
1919 const struct GNUNET_PeerIdentity *peer,
1920 const struct GNUNET_HELLO_Message *hello,
1923 struct Neighbour *n;
1927 n = find_neighbour (peer);
1930 if (n->public_key != NULL)
1933 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1934 "Received new `%s' message for `%4s', initiating key exchange.\n",
1939 GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded));
1940 if (GNUNET_OK != GNUNET_HELLO_get_key (hello, n->public_key))
1942 GNUNET_free (n->public_key);
1943 n->public_key = NULL;
1951 * Task that will retry "send_key" if our previous attempt failed
1955 set_key_retry_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1957 struct Neighbour *n = cls;
1959 GNUNET_assert (n->status != PEER_STATE_KEY_CONFIRMED);
1960 n->retry_set_key_task = GNUNET_SCHEDULER_NO_PREREQUISITE_TASK;
1961 n->set_key_retry_frequency =
1962 GNUNET_TIME_relative_multiply (n->set_key_retry_frequency, 2);
1968 * Send our key (and encrypted PING) to the other peer.
1970 * @param n the other peer
1973 send_key (struct Neighbour *n)
1975 struct SetKeyMessage *sm;
1976 struct MessageEntry *me;
1977 struct PingMessage pp;
1978 struct PingMessage *pm;
1981 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1982 "Asked to perform key exchange with `%4s'.\n",
1983 GNUNET_i2s (&n->peer));
1985 if (n->public_key == NULL)
1987 /* lookup n's public key, then try again */
1989 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1990 "Lacking public key for `%4s', trying to obtain one.\n",
1991 GNUNET_i2s (&n->peer));
1993 GNUNET_PEERINFO_for_all (cfg,
1997 GNUNET_TIME_UNIT_MINUTES,
1998 &process_hello_retry_send_key, NULL);
2001 /* first, set key message */
2002 me = GNUNET_malloc (sizeof (struct MessageEntry) +
2003 sizeof (struct SetKeyMessage));
2004 me->deadline = GNUNET_TIME_relative_to_absolute (MAX_SET_KEY_DELAY);
2005 me->priority = SET_KEY_PRIORITY;
2006 me->size = sizeof (struct SetKeyMessage);
2007 if (n->encrypted_head == NULL)
2008 n->encrypted_head = me;
2010 n->encrypted_tail->next = me;
2011 n->encrypted_tail = me;
2012 sm = (struct SetKeyMessage *) &me[1];
2013 sm->header.size = htons (sizeof (struct SetKeyMessage));
2014 sm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_SET_KEY);
2015 sm->sender_status = htonl ((int32_t) ((n->status == PEER_STATE_DOWN) ?
2016 PEER_STATE_KEY_SENT : n->status));
2018 htonl (sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) +
2019 sizeof (struct GNUNET_TIME_AbsoluteNBO) +
2020 sizeof (struct GNUNET_CRYPTO_RsaEncryptedData) +
2021 sizeof (struct GNUNET_PeerIdentity));
2022 sm->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_SET_KEY);
2023 sm->creation_time = GNUNET_TIME_absolute_hton (n->encrypt_key_created);
2024 sm->target = n->peer;
2025 GNUNET_assert (GNUNET_OK ==
2026 GNUNET_CRYPTO_rsa_encrypt (&n->encrypt_key,
2028 GNUNET_CRYPTO_AesSessionKey),
2030 &sm->encrypted_key));
2031 GNUNET_assert (GNUNET_OK ==
2032 GNUNET_CRYPTO_rsa_sign (my_private_key, &sm->purpose,
2035 /* second, encrypted PING message */
2036 me = GNUNET_malloc (sizeof (struct MessageEntry) +
2037 sizeof (struct PingMessage));
2038 me->deadline = GNUNET_TIME_relative_to_absolute (MAX_PING_DELAY);
2039 me->priority = PING_PRIORITY;
2040 me->size = sizeof (struct PingMessage);
2041 n->encrypted_tail->next = me;
2042 n->encrypted_tail = me;
2043 pm = (struct PingMessage *) &me[1];
2044 pm->header.size = htons (sizeof (struct PingMessage));
2045 pm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_PING);
2046 pp.challenge = htonl (n->ping_challenge);
2047 pp.target = n->peer;
2049 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2050 "Encrypting `%s' and `%s' messages for `%4s'.\n",
2051 "SET_KEY", "PING", GNUNET_i2s (&n->peer));
2052 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2053 "Sending `%s' to `%4s' with challenge %u encrypted using key %u\n",
2055 GNUNET_i2s (&n->peer), n->ping_challenge, n->encrypt_key.crc32);
2058 &n->peer.hashPubKey,
2061 sizeof (struct PingMessage) -
2062 sizeof (struct GNUNET_MessageHeader));
2066 case PEER_STATE_DOWN:
2067 n->status = PEER_STATE_KEY_SENT;
2069 case PEER_STATE_KEY_SENT:
2071 case PEER_STATE_KEY_RECEIVED:
2073 case PEER_STATE_KEY_CONFIRMED:
2080 /* trigger queue processing */
2081 process_encrypted_neighbour_queue (n);
2082 if (n->status != PEER_STATE_KEY_CONFIRMED)
2083 n->retry_set_key_task
2084 = GNUNET_SCHEDULER_add_delayed (sched,
2086 GNUNET_SCHEDULER_PRIORITY_KEEP,
2087 GNUNET_SCHEDULER_NO_PREREQUISITE_TASK,
2088 n->set_key_retry_frequency,
2089 &set_key_retry_task, n);
2094 * We received a SET_KEY message. Validate and update
2095 * our key material and status.
2097 * @param n the neighbour from which we received message m
2098 * @param m the set key message we received
2101 handle_set_key (struct Neighbour *n, const struct SetKeyMessage *m);
2105 * PEERINFO is giving us a HELLO for a peer. Add the public key to
2106 * the neighbour's struct and retry handling the set_key message. Or,
2107 * if we did not get a HELLO, just free the set key message.
2109 * @param cls pointer to the set key message
2110 * @param peer the peer for which this is the HELLO
2111 * @param hello HELLO message of that peer
2112 * @param trust amount of trust we currently have in that peer
2115 process_hello_retry_handle_set_key (void *cls,
2116 const struct GNUNET_PeerIdentity *peer,
2117 const struct GNUNET_HELLO_Message *hello,
2120 struct SetKeyMessage *sm = cls;
2121 struct Neighbour *n;
2128 n = find_neighbour (peer);
2134 if (n->public_key != NULL)
2135 return; /* multiple HELLOs match!? */
2137 GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded));
2138 if (GNUNET_OK != GNUNET_HELLO_get_key (hello, n->public_key))
2140 GNUNET_break_op (0);
2141 GNUNET_free (n->public_key);
2142 n->public_key = NULL;
2146 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2147 "Received `%s' for `%4s', continuing processing of `%s' message.\n",
2148 "HELLO", GNUNET_i2s (peer), "SET_KEY");
2150 handle_set_key (n, sm);
2155 * We received a PING message. Validate and transmit
2158 * @param n sender of the PING
2159 * @param m the encrypted PING message itself
2162 handle_ping (struct Neighbour *n, const struct PingMessage *m)
2164 struct PingMessage t;
2165 struct PingMessage *tp;
2166 struct MessageEntry *me;
2169 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2170 "Core service receives `%s' request from `%4s'.\n",
2171 "PING", GNUNET_i2s (&n->peer));
2175 &my_identity.hashPubKey,
2178 sizeof (struct PingMessage) -
2179 sizeof (struct GNUNET_MessageHeader)))
2182 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2183 "Decrypted `%s' to `%4s' with challenge %u decrypted using key %u\n",
2185 GNUNET_i2s (&t.target),
2186 ntohl (t.challenge), n->decrypt_key.crc32);
2187 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2188 "Target of `%s' request is `%4s'.\n",
2189 "PING", GNUNET_i2s (&t.target));
2191 if (0 != memcmp (&t.target,
2192 &my_identity, sizeof (struct GNUNET_PeerIdentity)))
2194 GNUNET_break_op (0);
2197 me = GNUNET_malloc (sizeof (struct MessageEntry) +
2198 sizeof (struct PingMessage));
2199 if (n->encrypted_tail != NULL)
2200 n->encrypted_tail->next = me;
2203 n->encrypted_tail = me;
2204 n->encrypted_head = me;
2206 me->deadline = GNUNET_TIME_relative_to_absolute (MAX_PONG_DELAY);
2207 me->priority = PONG_PRIORITY;
2208 me->size = sizeof (struct PingMessage);
2209 tp = (struct PingMessage *) &me[1];
2210 tp->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_PONG);
2211 tp->header.size = htons (sizeof (struct PingMessage));
2213 &my_identity.hashPubKey,
2216 sizeof (struct PingMessage) -
2217 sizeof (struct GNUNET_MessageHeader));
2219 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2220 "Encrypting `%s' with challenge %u using key %u\n", "PONG",
2221 ntohl (t.challenge), n->encrypt_key.crc32);
2223 /* trigger queue processing */
2224 process_encrypted_neighbour_queue (n);
2229 * We received a SET_KEY message. Validate and update
2230 * our key material and status.
2232 * @param n the neighbour from which we received message m
2233 * @param m the set key message we received
2236 handle_set_key (struct Neighbour *n, const struct SetKeyMessage *m)
2238 struct SetKeyMessage *m_cpy;
2239 struct GNUNET_TIME_Absolute t;
2240 struct GNUNET_CRYPTO_AesSessionKey k;
2241 struct PingMessage *ping;
2242 enum PeerStateMachine sender_status;
2245 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2246 "Core service receives `%s' request from `%4s'.\n",
2247 "SET_KEY", GNUNET_i2s (&n->peer));
2249 if (n->public_key == NULL)
2251 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2252 "Lacking public key for peer, trying to obtain one.\n");
2253 m_cpy = GNUNET_malloc (sizeof (struct SetKeyMessage));
2254 memcpy (m_cpy, m, sizeof (struct SetKeyMessage));
2255 /* lookup n's public key, then try again */
2256 GNUNET_PEERINFO_for_all (cfg,
2260 GNUNET_TIME_UNIT_MINUTES,
2261 &process_hello_retry_handle_set_key, m_cpy);
2264 if ((ntohl (m->purpose.size) !=
2265 sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) +
2266 sizeof (struct GNUNET_TIME_AbsoluteNBO) +
2267 sizeof (struct GNUNET_CRYPTO_RsaEncryptedData) +
2268 sizeof (struct GNUNET_PeerIdentity)) ||
2270 GNUNET_CRYPTO_rsa_verify (GNUNET_SIGNATURE_PURPOSE_SET_KEY,
2271 &m->purpose, &m->signature, n->public_key)))
2273 /* invalid signature */
2274 GNUNET_break_op (0);
2277 t = GNUNET_TIME_absolute_ntoh (m->creation_time);
2278 if (((n->status == PEER_STATE_KEY_RECEIVED) ||
2279 (n->status == PEER_STATE_KEY_CONFIRMED)) &&
2280 (t.value < n->decrypt_key_created.value))
2282 /* this could rarely happen due to massive re-ordering of
2283 messages on the network level, but is most likely either
2284 a bug or some adversary messing with us. Report. */
2285 GNUNET_break_op (0);
2289 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Decrypting key material.\n");
2291 if ((GNUNET_CRYPTO_rsa_decrypt (my_private_key,
2294 sizeof (struct GNUNET_CRYPTO_AesSessionKey))
2295 != sizeof (struct GNUNET_CRYPTO_AesSessionKey)) ||
2296 (GNUNET_OK != GNUNET_CRYPTO_aes_check_session_key (&k)))
2298 /* failed to decrypt !? */
2299 GNUNET_break_op (0);
2304 if (n->decrypt_key_created.value != t.value)
2306 /* fresh key, reset sequence numbers */
2307 n->last_sequence_number_received = 0;
2308 n->last_packets_bitmap = 0;
2309 n->decrypt_key_created = t;
2311 sender_status = (enum PeerStateMachine) ntohl (m->sender_status);
2314 case PEER_STATE_DOWN:
2315 n->status = PEER_STATE_KEY_RECEIVED;
2317 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2318 "Responding to `%s' with my own key.\n", "SET_KEY");
2322 case PEER_STATE_KEY_SENT:
2323 case PEER_STATE_KEY_RECEIVED:
2324 n->status = PEER_STATE_KEY_RECEIVED;
2325 if ((sender_status != PEER_STATE_KEY_RECEIVED) &&
2326 (sender_status != PEER_STATE_KEY_CONFIRMED))
2329 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2330 "Responding to `%s' with my own key (other peer has status %u).\n",
2331 "SET_KEY", sender_status);
2336 case PEER_STATE_KEY_CONFIRMED:
2337 if ((sender_status != PEER_STATE_KEY_RECEIVED) &&
2338 (sender_status != PEER_STATE_KEY_CONFIRMED))
2341 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2342 "Responding to `%s' with my own key (other peer has status %u), I was already fully up.\n",
2343 "SET_KEY", sender_status);
2352 if (n->pending_ping != NULL)
2354 ping = n->pending_ping;
2355 n->pending_ping = NULL;
2356 handle_ping (n, ping);
2363 * We received a PONG message. Validate and update
2366 * @param n sender of the PONG
2367 * @param m the encrypted PONG message itself
2370 handle_pong (struct Neighbour *n, const struct PingMessage *m)
2372 struct PingMessage t;
2375 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2376 "Core service receives `%s' request from `%4s'.\n",
2377 "PONG", GNUNET_i2s (&n->peer));
2381 &n->peer.hashPubKey,
2384 sizeof (struct PingMessage) -
2385 sizeof (struct GNUNET_MessageHeader)))
2388 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2389 "Decrypted `%s' from `%4s' with challenge %u using key %u\n",
2391 GNUNET_i2s (&t.target),
2392 ntohl (t.challenge), n->decrypt_key.crc32);
2394 if ((0 != memcmp (&t.target,
2396 sizeof (struct GNUNET_PeerIdentity))) ||
2397 (n->ping_challenge != ntohl (t.challenge)))
2399 /* PONG malformed */
2401 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2402 "Received malfromed `%s' wanted sender `%4s' with challenge %u\n",
2403 "PONG", GNUNET_i2s (&n->peer), n->ping_challenge);
2404 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2405 "Received malfromed `%s' received from `%4s' with challenge %u\n",
2406 "PONG", GNUNET_i2s (&t.target), ntohl (t.challenge));
2408 GNUNET_break_op (0);
2413 case PEER_STATE_DOWN:
2414 GNUNET_break (0); /* should be impossible */
2416 case PEER_STATE_KEY_SENT:
2417 GNUNET_break (0); /* should be impossible, how did we decrypt? */
2419 case PEER_STATE_KEY_RECEIVED:
2420 n->status = PEER_STATE_KEY_CONFIRMED;
2421 if (n->retry_set_key_task != GNUNET_SCHEDULER_NO_PREREQUISITE_TASK)
2423 GNUNET_SCHEDULER_cancel (sched, n->retry_set_key_task);
2424 n->retry_set_key_task = GNUNET_SCHEDULER_NO_PREREQUISITE_TASK;
2426 process_encrypted_neighbour_queue (n);
2428 case PEER_STATE_KEY_CONFIRMED:
2429 /* duplicate PONG? */
2439 * Send a P2P message to a client.
2441 * @param sender who sent us the message?
2442 * @param client who should we give the message to?
2443 * @param m contains the message to transmit
2444 * @param msize number of bytes in buf to transmit
2447 send_p2p_message_to_client (struct Neighbour *sender,
2448 struct Client *client,
2449 const void *m, size_t msize)
2451 char buf[msize + sizeof (struct NotifyTrafficMessage)];
2452 struct NotifyTrafficMessage *ntm;
2455 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2456 "Core service passes message from `%4s' of type %u to client.\n",
2457 GNUNET_i2s(&sender->peer),
2458 ntohs (((const struct GNUNET_MessageHeader *) m)->type));
2460 ntm = (struct NotifyTrafficMessage *) buf;
2461 ntm->header.size = htons (msize + sizeof (struct NotifyTrafficMessage));
2462 ntm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_INBOUND);
2463 ntm->reserved = htonl (0);
2464 ntm->peer = sender->peer;
2465 memcpy (&ntm[1], m, msize);
2466 send_to_client (client, &ntm->header, GNUNET_YES);
2471 * Deliver P2P message to interested clients.
2473 * @param sender who sent us the message?
2474 * @param m the message
2475 * @param msize size of the message (including header)
2478 deliver_message (struct Neighbour *sender,
2479 const struct GNUNET_MessageHeader *m, size_t msize)
2481 struct Client *cpos;
2486 type = ntohs (m->type);
2488 while (cpos != NULL)
2490 deliver_full = GNUNET_NO;
2491 if (cpos->options & GNUNET_CORE_OPTION_SEND_FULL_INBOUND)
2492 deliver_full = GNUNET_YES;
2495 for (tpos = 0; tpos < cpos->tcnt; tpos++)
2497 if (type != cpos->types[tpos])
2499 deliver_full = GNUNET_YES;
2503 if (GNUNET_YES == deliver_full)
2504 send_p2p_message_to_client (sender, cpos, m, msize);
2505 else if (cpos->options & GNUNET_CORE_OPTION_SEND_HDR_INBOUND)
2506 send_p2p_message_to_client (sender, cpos, m,
2507 sizeof (struct GNUNET_MessageHeader));
2514 * Align P2P message and then deliver to interested clients.
2516 * @param sender who sent us the message?
2517 * @param buffer unaligned (!) buffer containing message
2518 * @param msize size of the message (including header)
2521 align_and_deliver (struct Neighbour *sender, const char *buffer, size_t msize)
2525 /* TODO: call to statistics? */
2526 memcpy (abuf, buffer, msize);
2527 deliver_message (sender, (const struct GNUNET_MessageHeader *) abuf, msize);
2532 * Deliver P2P messages to interested clients.
2534 * @param sender who sent us the message?
2535 * @param buffer buffer containing messages, can be modified
2536 * @param buffer_size size of the buffer (overall)
2537 * @param offset offset where messages in the buffer start
2540 deliver_messages (struct Neighbour *sender,
2541 const char *buffer, size_t buffer_size, size_t offset)
2543 struct GNUNET_MessageHeader *mhp;
2544 struct GNUNET_MessageHeader mh;
2548 while (offset + sizeof (struct GNUNET_MessageHeader) <= buffer_size)
2550 if (0 != offset % sizeof (uint16_t))
2552 /* outch, need to copy to access header */
2553 memcpy (&mh, &buffer[offset], sizeof (struct GNUNET_MessageHeader));
2558 /* can access header directly */
2559 mhp = (struct GNUNET_MessageHeader *) &buffer[offset];
2561 msize = ntohs (mhp->size);
2562 if (msize + offset > buffer_size)
2564 /* malformed message, header says it is larger than what
2565 would fit into the overall buffer */
2566 GNUNET_break_op (0);
2569 #if HAVE_UNALIGNED_64_ACCESS
2570 need_align = (0 != offset % 4) ? GNUNET_YES : GNUNET_NO;
2572 need_align = (0 != offset % 8) ? GNUNET_YES : GNUNET_NO;
2574 if (GNUNET_YES == need_align)
2575 align_and_deliver (sender, &buffer[offset], msize);
2577 deliver_message (sender,
2578 (const struct GNUNET_MessageHeader *)
2579 &buffer[offset], msize);
2586 * We received an encrypted message. Decrypt, validate and
2587 * pass on to the appropriate clients.
2590 handle_encrypted_message (struct Neighbour *n,
2591 const struct EncryptedMessage *m)
2593 size_t size = ntohs (m->header.size);
2595 struct EncryptedMessage *pt; /* plaintext */
2599 struct GNUNET_TIME_Absolute t;
2602 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2603 "Core service receives `%s' request from `%4s'.\n",
2604 "ENCRYPTED_MESSAGE", GNUNET_i2s (&n->peer));
2610 &m->sequence_number,
2611 &buf[ENCRYPTED_HEADER_SIZE], size - ENCRYPTED_HEADER_SIZE))
2613 pt = (struct EncryptedMessage *) buf;
2616 GNUNET_CRYPTO_hash (&pt->sequence_number,
2617 size - ENCRYPTED_HEADER_SIZE, &ph);
2618 if (0 != memcmp (&ph, &m->plaintext_hash, sizeof (GNUNET_HashCode)))
2620 /* checksum failed */
2621 GNUNET_break_op (0);
2625 /* validate sequence number */
2626 snum = ntohl (pt->sequence_number);
2627 if (n->last_sequence_number_received == snum)
2629 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2630 "Received duplicate message, ignoring.\n");
2631 /* duplicate, ignore */
2634 if ((n->last_sequence_number_received > snum) &&
2635 (n->last_sequence_number_received - snum > 32))
2637 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2638 "Received ancient out of sequence message, ignoring.\n");
2639 /* ancient out of sequence, ignore */
2642 if (n->last_sequence_number_received > snum)
2644 unsigned int rotbit =
2645 1 << (n->last_sequence_number_received - snum - 1);
2646 if ((n->last_packets_bitmap & rotbit) != 0)
2648 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2649 "Received duplicate message, ignoring.\n");
2650 /* duplicate, ignore */
2653 n->last_packets_bitmap |= rotbit;
2655 if (n->last_sequence_number_received < snum)
2657 n->last_packets_bitmap <<= (snum - n->last_sequence_number_received);
2658 n->last_sequence_number_received = snum;
2661 /* check timestamp */
2662 t = GNUNET_TIME_absolute_ntoh (pt->timestamp);
2663 if (GNUNET_TIME_absolute_get_duration (t).value > MAX_MESSAGE_AGE.value)
2665 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2667 ("Message received far too old (%llu ms). Content ignored.\n"),
2668 GNUNET_TIME_absolute_get_duration (t).value);
2672 /* process decrypted message(s) */
2673 n->bpm_out_external_limit = ntohl (pt->inbound_bpm_limit);
2674 n->bpm_out = GNUNET_MAX (n->bpm_out_external_limit,
2675 n->bpm_out_internal_limit);
2676 n->last_activity = GNUNET_TIME_absolute_get ();
2677 off = sizeof (struct EncryptedMessage);
2678 deliver_messages (n, buf, size, off);
2683 * Function called by the transport for each received message.
2685 * @param cls closure
2686 * @param latency estimated latency for communicating with the
2688 * @param peer (claimed) identity of the other peer
2689 * @param message the message
2692 handle_transport_receive (void *cls,
2693 struct GNUNET_TIME_Relative latency,
2694 const struct GNUNET_PeerIdentity *peer,
2695 const struct GNUNET_MessageHeader *message)
2697 struct Neighbour *n;
2698 struct GNUNET_TIME_Absolute now;
2704 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2705 "Received message of type %u from `%4s', demultiplexing.\n",
2706 ntohs (message->type), GNUNET_i2s (peer));
2708 n = find_neighbour (peer);
2714 n->last_latency = latency;
2715 up = n->status == PEER_STATE_KEY_CONFIRMED;
2716 type = ntohs (message->type);
2717 size = ntohs (message->size);
2720 case GNUNET_MESSAGE_TYPE_CORE_SET_KEY:
2721 if (size != sizeof (struct SetKeyMessage))
2723 GNUNET_break_op (0);
2726 handle_set_key (n, (const struct SetKeyMessage *) message);
2728 case GNUNET_MESSAGE_TYPE_CORE_ENCRYPTED_MESSAGE:
2729 if (size < sizeof (struct EncryptedMessage) +
2730 sizeof (struct GNUNET_MessageHeader))
2732 GNUNET_break_op (0);
2735 if ((n->status != PEER_STATE_KEY_RECEIVED) &&
2736 (n->status != PEER_STATE_KEY_CONFIRMED))
2738 GNUNET_break_op (0);
2741 handle_encrypted_message (n, (const struct EncryptedMessage *) message);
2743 case GNUNET_MESSAGE_TYPE_CORE_PING:
2744 if (size != sizeof (struct PingMessage))
2746 GNUNET_break_op (0);
2749 if ((n->status != PEER_STATE_KEY_RECEIVED) &&
2750 (n->status != PEER_STATE_KEY_CONFIRMED))
2753 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2754 "Core service receives `%s' request from `%4s' but have not processed key; marking as pending.\n",
2755 "PING", GNUNET_i2s (&n->peer));
2757 GNUNET_free_non_null (n->pending_ping);
2758 n->pending_ping = GNUNET_malloc (sizeof (struct PingMessage));
2759 memcpy (n->pending_ping, message, sizeof (struct PingMessage));
2762 handle_ping (n, (const struct PingMessage *) message);
2764 case GNUNET_MESSAGE_TYPE_CORE_PONG:
2765 if (size != sizeof (struct PingMessage))
2767 GNUNET_break_op (0);
2770 if ((n->status != PEER_STATE_KEY_SENT) &&
2771 (n->status != PEER_STATE_KEY_RECEIVED) &&
2772 (n->status != PEER_STATE_KEY_CONFIRMED))
2774 /* could not decrypt pong, oops! */
2775 GNUNET_break_op (0);
2778 handle_pong (n, (const struct PingMessage *) message);
2781 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2782 _("Unsupported message of type %u received.\n"), type);
2785 if (n->status == PEER_STATE_KEY_CONFIRMED)
2787 now = GNUNET_TIME_absolute_get ();
2788 n->last_activity = now;
2790 n->time_established = now;
2796 * Function called by transport to notify us that
2797 * a peer connected to us (on the network level).
2799 * @param cls closure
2800 * @param peer the peer that connected
2801 * @param latency current latency of the connection
2804 handle_transport_notify_connect (void *cls,
2805 const struct GNUNET_PeerIdentity *peer,
2806 struct GNUNET_TIME_Relative latency)
2808 struct Neighbour *n;
2809 struct GNUNET_TIME_Absolute now;
2810 struct ConnectNotifyMessage cnm;
2812 n = find_neighbour (peer);
2815 /* duplicate connect notification!? */
2819 now = GNUNET_TIME_absolute_get ();
2820 n = GNUNET_malloc (sizeof (struct Neighbour));
2821 n->next = neighbours;
2824 n->last_latency = latency;
2825 GNUNET_CRYPTO_aes_create_session_key (&n->encrypt_key);
2826 n->encrypt_key_created = now;
2827 n->set_key_retry_frequency = INITIAL_SET_KEY_RETRY_FREQUENCY;
2828 n->last_asw_update = now;
2829 n->last_arw_update = now;
2830 n->bpm_in = DEFAULT_BPM_IN_OUT;
2831 n->bpm_out = DEFAULT_BPM_IN_OUT;
2832 n->bpm_out_internal_limit = (uint32_t) - 1;
2833 n->bpm_out_external_limit = DEFAULT_BPM_IN_OUT;
2834 n->ping_challenge = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
2837 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2838 "Received connection from `%4s'.\n",
2839 GNUNET_i2s (&n->peer));
2841 cnm.header.size = htons (sizeof (struct ConnectNotifyMessage));
2842 cnm.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT);
2843 cnm.bpm_available = htonl (DEFAULT_BPM_IN_OUT);
2845 cnm.last_activity = GNUNET_TIME_absolute_hton (now);
2846 send_to_all_clients (&cnm.header, GNUNET_YES);
2851 * Free the given entry for the neighbour (it has
2852 * already been removed from the list at this point).
2853 * @param n neighbour to free
2856 free_neighbour (struct Neighbour *n)
2858 struct MessageEntry *m;
2860 while (NULL != (m = n->messages))
2862 n->messages = m->next;
2865 while (NULL != (m = n->encrypted_head))
2867 n->encrypted_head = m->next;
2871 GNUNET_TRANSPORT_notify_transmit_ready_cancel (n->th);
2872 if (n->retry_plaintext_task != GNUNET_SCHEDULER_NO_PREREQUISITE_TASK)
2873 GNUNET_SCHEDULER_cancel (sched, n->retry_plaintext_task);
2874 if (n->retry_set_key_task != GNUNET_SCHEDULER_NO_PREREQUISITE_TASK)
2875 GNUNET_SCHEDULER_cancel (sched, n->retry_set_key_task);
2876 GNUNET_free_non_null (n->public_key);
2877 GNUNET_free_non_null (n->pending_ping);
2883 * Function called by transport telling us that a peer
2886 * @param cls closure
2887 * @param peer the peer that disconnected
2890 handle_transport_notify_disconnect (void *cls,
2891 const struct GNUNET_PeerIdentity *peer)
2893 struct ConnectNotifyMessage cnm;
2894 struct Neighbour *n;
2895 struct Neighbour *p;
2898 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2899 "Peer `%4s' disconnected from us.\n", GNUNET_i2s (peer));
2903 while ((n != NULL) &&
2904 (0 != memcmp (&n->peer, peer, sizeof (struct GNUNET_PeerIdentity))))
2915 neighbours = n->next;
2918 cnm.header.size = htons (sizeof (struct ConnectNotifyMessage));
2919 cnm.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_DISCONNECT);
2920 cnm.bpm_available = htonl (0);
2922 cnm.last_activity = GNUNET_TIME_absolute_hton (n->last_activity);
2923 send_to_all_clients (&cnm.header, GNUNET_YES);
2929 * Last task run during shutdown. Disconnects us from
2933 cleaning_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
2935 struct Neighbour *n;
2939 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2940 "Core service shutting down.\n");
2942 GNUNET_assert (transport != NULL);
2943 GNUNET_TRANSPORT_disconnect (transport);
2945 while (NULL != (n = neighbours))
2947 neighbours = n->next;
2950 while (NULL != (c = clients))
2951 handle_client_disconnect (NULL, c->client_handle);
2956 * Initiate core service.
2958 * @param cls closure
2959 * @param s scheduler to use
2960 * @param serv the initialized server
2961 * @param c configuration to use
2965 struct GNUNET_SCHEDULER_Handle *s,
2966 struct GNUNET_SERVER_Handle *serv, struct GNUNET_CONFIGURATION_Handle *c)
2969 unsigned long long qin;
2970 unsigned long long qout;
2971 unsigned long long tneigh;
2977 /* parse configuration */
2981 GNUNET_CONFIGURATION_get_value_number (c,
2986 GNUNET_CONFIGURATION_get_value_number (c,
2991 GNUNET_CONFIGURATION_get_value_number (c,
2993 "ZZ_LIMIT", &tneigh)) ||
2996 GNUNET_CONFIGURATION_get_value_filename (c,
2998 "HOSTKEY", &keyfile)))
3000 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3002 ("Core service is lacking key configuration settings. Exiting.\n"));
3003 GNUNET_SCHEDULER_shutdown (s);
3006 my_private_key = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile);
3007 GNUNET_free (keyfile);
3008 if (my_private_key == NULL)
3010 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3011 _("Core service could not access hostkey. Exiting.\n"));
3012 GNUNET_SCHEDULER_shutdown (s);
3015 GNUNET_CRYPTO_rsa_key_get_public (my_private_key, &my_public_key);
3016 GNUNET_CRYPTO_hash (&my_public_key,
3017 sizeof (my_public_key), &my_identity.hashPubKey);
3018 /* setup notification */
3020 GNUNET_SERVER_disconnect_notify (server, &handle_client_disconnect, NULL);
3021 /* setup transport connection */
3022 transport = GNUNET_TRANSPORT_connect (sched,
3025 &handle_transport_receive,
3026 &handle_transport_notify_connect,
3027 &handle_transport_notify_disconnect);
3028 GNUNET_assert (NULL != transport);
3029 GNUNET_SCHEDULER_add_delayed (sched,
3031 GNUNET_SCHEDULER_PRIORITY_IDLE,
3032 GNUNET_SCHEDULER_NO_PREREQUISITE_TASK,
3033 GNUNET_TIME_UNIT_FOREVER_REL,
3034 &cleaning_task, NULL);
3035 /* process client requests */
3036 GNUNET_SERVER_add_handlers (server, handlers);
3037 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
3038 _("Core service of `%4s' ready.\n"), GNUNET_i2s (&my_identity));
3043 * Function called during shutdown. Clean up our state.
3046 cleanup (void *cls, struct GNUNET_CONFIGURATION_Handle *cfg)
3050 if (my_private_key != NULL)
3051 GNUNET_CRYPTO_rsa_key_free (my_private_key);
3056 * The main function for the transport service.
3058 * @param argc number of arguments from the command line
3059 * @param argv command line arguments
3060 * @return 0 ok, 1 on error
3063 main (int argc, char *const *argv)
3065 return (GNUNET_OK ==
3066 GNUNET_SERVICE_run (argc,
3068 "core", &run, NULL, &cleanup, NULL)) ? 0 : 1;
3071 /* end of gnunet-service-core.c */