X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Fcore%2Fgnunet-service-core_neighbours.c;h=65b4ba41a218e1e6efe8b2c04d59e4c7c3bdffbe;hb=6c471eeb15e27f8226492b4860a3c2acb94c5f25;hp=12d002da805382c0e2a931b6872db1848c71a352;hpb=0f29195adbd56ae10dea70c2951333c13e765f88;p=oweals%2Fgnunet.git diff --git a/src/core/gnunet-service-core_neighbours.c b/src/core/gnunet-service-core_neighbours.c index 12d002da8..65b4ba41a 100644 --- a/src/core/gnunet-service-core_neighbours.c +++ b/src/core/gnunet-service-core_neighbours.c @@ -25,28 +25,31 @@ */ #include "platform.h" #include "gnunet_util_lib.h" +#include "gnunet_statistics_service.h" #include "gnunet_transport_service.h" -#include "gnunet_service_core.h" -#include "gnunet_service_core-neighbours.h" -#include "gnunet_service_core-kx.h" +#include "gnunet-service-core.h" +#include "gnunet-service-core_neighbours.h" +#include "gnunet-service-core_kx.h" +#include "gnunet-service-core_sessions.h" +#include "gnunet_constants.h" /** * Message ready for transmission via transport service. This struct * is followed by the actual content of the message. */ -struct MessageEntry +struct NeighbourMessageEntry { /** * We keep messages in a doubly linked list. */ - struct MessageEntry *next; + struct NeighbourMessageEntry *next; /** * We keep messages in a doubly linked list. */ - struct MessageEntry *prev; + struct NeighbourMessageEntry *prev; /** * By when are we supposed to transmit this message? @@ -73,13 +76,13 @@ struct Neighbour * Head of the batched message queue (already ordered, transmit * starting with the head). */ - struct MessageEntry *message_head; + struct NeighbourMessageEntry *message_head; /** * Tail of the batched message queue (already ordered, append new * messages to tail). */ - struct MessageEntry *message_tail; + struct NeighbourMessageEntry *message_tail; /** * Handle for pending requests for transmission to this peer @@ -102,17 +105,6 @@ struct Neighbour */ GNUNET_SCHEDULER_TaskIdentifier retry_plaintext_task; - /** - * Tracking bandwidth for sending to this peer. - */ - struct GNUNET_BANDWIDTH_Tracker available_send_window; - - /** - * Tracking bandwidth for sending to this peer. - */ - struct GNUNET_BANDWIDTH_Tracker available_recv_window; - - }; @@ -127,7 +119,6 @@ static struct GNUNET_CONTAINER_MultiHashMap *neighbours; static struct GNUNET_TRANSPORT_Handle *transport; - /** * Find the entry for the given neighbour. * @@ -138,6 +129,8 @@ static struct GNUNET_TRANSPORT_Handle *transport; static struct Neighbour * find_neighbour (const struct GNUNET_PeerIdentity *peer) { + if (NULL == neighbours) + return NULL; return GNUNET_CONTAINER_multihashmap_get (neighbours, &peer->hashPubKey); } @@ -150,13 +143,11 @@ find_neighbour (const struct GNUNET_PeerIdentity *peer) static void free_neighbour (struct Neighbour *n) { - struct MessageEntry *m; + struct NeighbourMessageEntry *m; -#if DEBUG_CORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Destroying neighbour entry for peer `%4s'\n", GNUNET_i2s (&n->peer)); -#endif while (NULL != (m = n->message_head)) { GNUNET_CONTAINER_DLL_remove (n->message_head, n->message_tail, m); @@ -167,10 +158,15 @@ free_neighbour (struct Neighbour *n) GNUNET_TRANSPORT_notify_transmit_ready_cancel (n->th); n->th = NULL; } - if (NULL != n->kx) + GNUNET_STATISTICS_update (GSC_stats, + gettext_noop + ("# sessions terminated by transport disconnect"), + 1, GNUNET_NO); + GSC_SESSIONS_end (&n->peer); + if (NULL != n->kxinfo) { - GSC_KX_stop (n->kx); - n->kx = NULL; + GSC_KX_stop (n->kxinfo); + n->kxinfo = NULL; } if (n->retry_plaintext_task != GNUNET_SCHEDULER_NO_TASK) { @@ -179,8 +175,9 @@ free_neighbour (struct Neighbour *n) } GNUNET_assert (GNUNET_OK == GNUNET_CONTAINER_multihashmap_remove (neighbours, - &n->peer.hashPubKey, n)); - GNUNET_STATISTICS_set (stats, gettext_noop ("# neighbour entries allocated"), + &n->peer.hashPubKey, n)); + GNUNET_STATISTICS_set (GSC_stats, + gettext_noop ("# neighbour entries allocated"), GNUNET_CONTAINER_multihashmap_size (neighbours), GNUNET_NO); GNUNET_free (n); @@ -211,7 +208,7 @@ static size_t transmit_ready (void *cls, size_t size, void *buf) { struct Neighbour *n = cls; - struct MessageEntry *m; + struct NeighbourMessageEntry *m; size_t ret; char *cbuf; @@ -219,40 +216,30 @@ transmit_ready (void *cls, size_t size, void *buf) m = n->message_head; if (m == NULL) { -#if DEBUG_CORE - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Encrypted message queue empty, no messages added to buffer for `%4s'\n", - GNUNET_i2s (&n->peer)); -#endif + GNUNET_break (0); return 0; } - GNUNET_CONTAINER_DLL_remove (n->encrypted_head, n->encrypted_tail, m); + GNUNET_CONTAINER_DLL_remove (n->message_head, n->message_tail, m); if (buf == NULL) { -#if DEBUG_CORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Transmission of message of type %u and size %u failed\n", (unsigned int) ntohs (((struct GNUNET_MessageHeader *) &m[1])->type), (unsigned int) m->size); -#endif GNUNET_free (m); process_queue (n); return 0; } - ret = 0; cbuf = buf; GNUNET_assert (size >= m->size); memcpy (cbuf, &m[1], m->size); ret = m->size; - GNUNET_BANDWIDTH_tracker_consume (&n->available_send_window, m->size); -#if DEBUG_CORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Copied message of type %u and size %u into transport buffer for `%4s'\n", - (unsigned int) - ntohs (((struct GNUNET_MessageHeader *) &m[1])->type), - (unsigned int) ret, GNUNET_i2s (&n->peer)); -#endif + "Copied message of type %u and size %u into transport buffer for `%4s'\n", + (unsigned int) + ntohs (((struct GNUNET_MessageHeader *) &m[1])->type), + (unsigned int) ret, GNUNET_i2s (&n->peer)); GNUNET_free (m); process_queue (n); GNUNET_STATISTICS_update (GSC_stats, @@ -272,33 +259,34 @@ transmit_ready (void *cls, size_t size, void *buf) static void process_queue (struct Neighbour *n) { - struct MessageEntry *m; + struct NeighbourMessageEntry *m; if (n->th != NULL) return; /* request already pending */ m = n->message_head; if (m == NULL) + { + /* notify sessions that the queue is empty and more messages + * could thus be queued now */ + GSC_SESSIONS_solicit (&n->peer); return; -#if DEBUG_CORE > 1 + } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Asking transport for transmission of %u bytes to `%4s' in next %llu ms\n", (unsigned int) m->size, GNUNET_i2s (&n->peer), (unsigned long long) GNUNET_TIME_absolute_get_remaining (m->deadline).rel_value); -#endif n->th = - GNUNET_TRANSPORT_notify_transmit_ready (transport, &n->peer, m->size, - m->priority, - GNUNET_TIME_absolute_get_remaining - (m->deadline), - &transmit_ready, - n); + GNUNET_TRANSPORT_notify_transmit_ready (transport, &n->peer, m->size, 0, + GNUNET_TIME_absolute_get_remaining + (m->deadline), &transmit_ready, + n); if (n->th != NULL) return; /* message request too large or duplicate request */ GNUNET_break (0); /* discard encrypted message */ - GNUNET_CONTAINER_DLL_remove (n->encrypted_head, n->encrypted_tail, m); + GNUNET_CONTAINER_DLL_remove (n->message_head, n->message_tail, m); GNUNET_free (m); process_queue (n); } @@ -311,18 +299,18 @@ process_queue (struct Neighbour *n) * * @param cls closure * @param peer the peer that connected - * @param ats performance data - * @param ats_count number of entries in ats (excluding 0-termination) + * @param atsi performance data + * @param atsi_count number of entries in ats (excluding 0-termination) */ static void handle_transport_notify_connect (void *cls, const struct GNUNET_PeerIdentity *peer, - const struct GNUNET_TRANSPORT_ATS_Information - *ats, uint32_t ats_count) + const struct GNUNET_ATS_Information *atsi, + uint32_t atsi_count) { struct Neighbour *n; - if (0 == memcmp (peer, &my_identity, sizeof (struct GNUNET_PeerIdentity))) + if (0 == memcmp (peer, &GSC_my_identity, sizeof (struct GNUNET_PeerIdentity))) { GNUNET_break (0); return; @@ -334,29 +322,19 @@ handle_transport_notify_connect (void *cls, GNUNET_break (0); return; } -#if DEBUG_CORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received connection from `%4s'.\n", GNUNET_i2s (peer)); -#endif n = GNUNET_malloc (sizeof (struct Neighbour)); - n->peer = *pid; - GNUNET_BANDWIDTH_tracker_init (&n->available_send_window, - GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT, - MAX_WINDOW_TIME_S); - GNUNET_BANDWIDTH_tracker_init (&n->available_recv_window, - GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT, - MAX_WINDOW_TIME_S); + n->peer = *peer; GNUNET_assert (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put (neighbours, &n->peer.hashPubKey, n, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); - GNUNET_STATISTICS_set (stats, gettext_noop ("# neighbour entries allocated"), + GNUNET_STATISTICS_set (GSC_stats, + gettext_noop ("# neighbour entries allocated"), GNUNET_CONTAINER_multihashmap_size (neighbours), GNUNET_NO); - GNUNET_TRANSPORT_set_quota (transport, peer, - GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT, - GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT); - n->kx = GSC_KX_start (pid); + n->kxinfo = GSC_KX_start (peer); } @@ -373,11 +351,9 @@ handle_transport_notify_disconnect (void *cls, { struct Neighbour *n; -#if DEBUG_CORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer `%4s' disconnected from us; received notification from transport.\n", GNUNET_i2s (peer)); -#endif n = find_neighbour (peer); if (n == NULL) { @@ -394,28 +370,22 @@ handle_transport_notify_disconnect (void *cls, * @param cls closure * @param peer (claimed) identity of the other peer * @param message the message - * @param ats performance data - * @param ats_count number of entries in ats (excluding 0-termination) + * @param atsi performance data + * @param atsi_count number of entries in ats (excluding 0-termination) */ static void handle_transport_receive (void *cls, const struct GNUNET_PeerIdentity *peer, const struct GNUNET_MessageHeader *message, - const struct GNUNET_TRANSPORT_ATS_Information *ats, - uint32_t ats_count) + const struct GNUNET_ATS_Information *atsi, + uint32_t atsi_count) { struct Neighbour *n; - struct GNUNET_TIME_Absolute now; - int up; uint16_t type; - uint16_t size; - int changed; -#if DEBUG_CORE > 1 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received message of type %u from `%4s', demultiplexing.\n", (unsigned int) ntohs (message->type), GNUNET_i2s (peer)); -#endif - if (0 == memcmp (peer, &my_identity, sizeof (struct GNUNET_PeerIdentity))) + if (0 == memcmp (peer, &GSC_my_identity, sizeof (struct GNUNET_PeerIdentity))) { GNUNET_break (0); return; @@ -427,132 +397,61 @@ handle_transport_receive (void *cls, const struct GNUNET_PeerIdentity *peer, GNUNET_break (0); return; } - - - changed = GNUNET_NO; - up = (n->status == PEER_STATE_KEY_CONFIRMED); type = ntohs (message->type); - size = ntohs (message->size); switch (type) { case GNUNET_MESSAGE_TYPE_CORE_SET_KEY: - if (size != sizeof (struct SetKeyMessage)) - { - GNUNET_break_op (0); - return; - } - GNUNET_STATISTICS_update (stats, gettext_noop ("# session keys received"), - 1, GNUNET_NO); - handle_set_key (n, (const struct SetKeyMessage *) message, ats, ats_count); - break; - case GNUNET_MESSAGE_TYPE_CORE_ENCRYPTED_MESSAGE: - if (size < - sizeof (struct EncryptedMessage) + sizeof (struct GNUNET_MessageHeader)) - { - GNUNET_break_op (0); - return; - } - if ((n->status != PEER_STATE_KEY_RECEIVED) && - (n->status != PEER_STATE_KEY_CONFIRMED)) - { - GNUNET_STATISTICS_update (stats, - gettext_noop - ("# failed to decrypt message (no session key)"), - 1, GNUNET_NO); - send_key (n); - return; - } - handle_encrypted_message (n, (const struct EncryptedMessage *) message, ats, - ats_count); + GSC_KX_handle_set_key (n->kxinfo, message); break; case GNUNET_MESSAGE_TYPE_CORE_PING: - if (size != sizeof (struct PingMessage)) - { - GNUNET_break_op (0); - return; - } - GNUNET_STATISTICS_update (stats, gettext_noop ("# PING messages received"), - 1, GNUNET_NO); - if ((n->status != PEER_STATE_KEY_RECEIVED) && - (n->status != PEER_STATE_KEY_CONFIRMED)) - { -#if DEBUG_CORE > 1 - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Core service receives `%s' request from `%4s' but have not processed key; marking as pending.\n", - "PING", GNUNET_i2s (&n->peer)); -#endif - GNUNET_free_non_null (n->pending_ping); - n->pending_ping = GNUNET_malloc (sizeof (struct PingMessage)); - memcpy (n->pending_ping, message, sizeof (struct PingMessage)); - return; - } - handle_ping (n, (const struct PingMessage *) message, ats, ats_count); + GSC_KX_handle_ping (n->kxinfo, message); break; case GNUNET_MESSAGE_TYPE_CORE_PONG: - if (size != sizeof (struct PongMessage)) - { - GNUNET_break_op (0); - return; - } - GNUNET_STATISTICS_update (stats, gettext_noop ("# PONG messages received"), - 1, GNUNET_NO); - if ((n->status != PEER_STATE_KEY_RECEIVED) && - (n->status != PEER_STATE_KEY_CONFIRMED)) - { -#if DEBUG_CORE > 1 - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Core service receives `%s' request from `%4s' but have not processed key; marking as pending.\n", - "PONG", GNUNET_i2s (&n->peer)); -#endif - GNUNET_free_non_null (n->pending_pong); - n->pending_pong = GNUNET_malloc (sizeof (struct PongMessage)); - memcpy (n->pending_pong, message, sizeof (struct PongMessage)); - return; - } - handle_pong (n, (const struct PongMessage *) message, ats, ats_count); + GSC_KX_handle_pong (n->kxinfo, message); + break; + case GNUNET_MESSAGE_TYPE_CORE_ENCRYPTED_MESSAGE: + GSC_KX_handle_encrypted_message (n->kxinfo, message, atsi, atsi_count); break; default: GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - _("Unsupported message of type %u received.\n"), - (unsigned int) type); + _ + ("Unsupported message of type %u (%u bytes) received from peer `%s'\n"), + (unsigned int) type, (unsigned int) ntohs (message->size), + GNUNET_i2s (peer)); return; } - if (n->status == PEER_STATE_KEY_CONFIRMED) - { - now = GNUNET_TIME_absolute_get (); - n->last_activity = now; - changed = GNUNET_YES; - if (!up) - { - GNUNET_STATISTICS_update (stats, gettext_noop ("# established sessions"), - 1, GNUNET_NO); - n->time_established = now; - } - if (n->keep_alive_task != GNUNET_SCHEDULER_NO_TASK) - GNUNET_SCHEDULER_cancel (n->keep_alive_task); - n->keep_alive_task = - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_divide - (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, - 2), &send_keep_alive, n); - } - if (changed) - handle_peer_status_change (n); } /** * Transmit the given message to the given target. - * + * * @param target peer that should receive the message (must be connected) * @param msg message to transmit * @param timeout by when should the transmission be done? */ void -GDS_NEIGHBOURS_transmit (const struct GNUNET_PeerIdentity *target, - const struct GNUNET_MessageHeader *msg, - struct GNUNET_TIME_Relative timeout) +GSC_NEIGHBOURS_transmit (const struct GNUNET_PeerIdentity *target, + const struct GNUNET_MessageHeader *msg, + struct GNUNET_TIME_Relative timeout) { - + struct NeighbourMessageEntry *me; + struct Neighbour *n; + size_t msize; + + n = find_neighbour (target); + if (NULL == n) + { + GNUNET_break (0); + return; + } + msize = ntohs (msg->size); + me = GNUNET_malloc (sizeof (struct NeighbourMessageEntry) + msize); + me->deadline = GNUNET_TIME_relative_to_absolute (timeout); + me->size = msize; + memcpy (&me[1], msg, msize); + GNUNET_CONTAINER_DLL_insert_tail (n->message_head, n->message_tail, me); + process_queue (n); } @@ -564,8 +463,7 @@ GSC_NEIGHBOURS_init () { neighbours = GNUNET_CONTAINER_multihashmap_create (128); transport = - GNUNET_TRANSPORT_connect (GSC_cfg, - &GSC_my_identity, NULL, + GNUNET_TRANSPORT_connect (GSC_cfg, &GSC_my_identity, NULL, &handle_transport_receive, &handle_transport_notify_connect, &handle_transport_notify_disconnect); @@ -588,10 +486,12 @@ GSC_NEIGHBOURS_init () * @return GNUNET_OK (continue to iterate) */ static int -free_neighbour_helper (void *cls, const GNUNET_HashCode * key, void *value) +free_neighbour_helper (void *cls, const struct GNUNET_HashCode * key, void *value) { struct Neighbour *n = value; + /* transport should have 'disconnected' all neighbours... */ + GNUNET_break (0); free_neighbour (n); return GNUNET_OK; } @@ -605,13 +505,12 @@ GSC_NEIGHBOURS_done () { if (NULL == transport) return; - GNUNET_CONTAINER_multihashmap_iterate (neighbours, &free_neighbour_helper, - NULL); GNUNET_TRANSPORT_disconnect (transport); transport = NULL; + GNUNET_CONTAINER_multihashmap_iterate (neighbours, &free_neighbour_helper, + NULL); GNUNET_CONTAINER_multihashmap_destroy (neighbours); neighbours = NULL; } /* end of gnunet-service-core_neighbours.c */ -