X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Fcore%2Fgnunet-service-core_sessions.c;h=1f697cf160d2d04e2cc2a1d5839808db0c21c67f;hb=b0c7119fa2f43fe1b5978651152974359de5a5d2;hp=6e1494373a8004a984657d5837b1d557f006ceef;hpb=013cf64f56c0a529f0c11597e912b39e4a0a896c;p=oweals%2Fgnunet.git diff --git a/src/core/gnunet-service-core_sessions.c b/src/core/gnunet-service-core_sessions.c index 6e1494373..1f697cf16 100644 --- a/src/core/gnunet-service-core_sessions.c +++ b/src/core/gnunet-service-core_sessions.c @@ -20,7 +20,7 @@ /** * @file core/gnunet-service-core_sessions.c - * @brief code for managing of 'encrypted' sessions (key exchange done) + * @brief code for managing of 'encrypted' sessions (key exchange done) * @author Christian Grothoff */ #include "platform.h" @@ -32,6 +32,11 @@ #include "gnunet-service-core_clients.h" #include "gnunet_constants.h" +/** + * How often do we transmit our typemap? + */ +#define TYPEMAP_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5) + /** * Message ready for encryption. This struct is followed by the @@ -121,9 +126,14 @@ struct Session */ GNUNET_SCHEDULER_TaskIdentifier cork_task; + /** + * Task to transmit our type map. + */ + GNUNET_SCHEDULER_TaskIdentifier typemap_task; + /** * Is the neighbour queue empty and thus ready for us - * to transmit an encrypted message? + * to transmit an encrypted message? */ int ready_to_transmit; @@ -152,7 +162,7 @@ find_session (const struct GNUNET_PeerIdentity *peer) /** * End the session with the given peer (we are no longer - * connected). + * connected). * * @param pid identity of peer to kill session with */ @@ -161,13 +171,13 @@ GSC_SESSIONS_end (const struct GNUNET_PeerIdentity *pid) { struct Session *session; struct GSC_ClientActiveRequest *car; + struct SessionMessageEntry *sme; session = find_session (pid); if (NULL == session) return; #if DEBUG_CORE - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Destroying session for peer `%4s'\n", + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Destroying session for peer `%4s'\n", GNUNET_i2s (&session->peer)); #endif if (GNUNET_SCHEDULER_NO_TASK != session->cork_task) @@ -175,24 +185,64 @@ GSC_SESSIONS_end (const struct GNUNET_PeerIdentity *pid) GNUNET_SCHEDULER_cancel (session->cork_task); session->cork_task = GNUNET_SCHEDULER_NO_TASK; } - GNUNET_assert (GNUNET_YES == - GNUNET_CONTAINER_multihashmap_remove (sessions, - &session->peer.hashPubKey, session)); while (NULL != (car = session->active_client_request_head)) { GNUNET_CONTAINER_DLL_remove (session->active_client_request_head, - session->active_client_request_tail, - car); + session->active_client_request_tail, car); GSC_CLIENTS_reject_request (car); } - GNUNET_STATISTICS_set (GSC_stats, - gettext_noop ("# established sessions"), - GNUNET_CONTAINER_multihashmap_size (sessions), - GNUNET_NO); + while (NULL != (sme = session->sme_head)) + { + GNUNET_CONTAINER_DLL_remove (session->sme_head, session->sme_tail, sme); + GNUNET_free (sme); + } + GNUNET_SCHEDULER_cancel (session->typemap_task); + GSC_CLIENTS_notify_clients_about_neighbour (&session->peer, NULL, + 0 /* FIXME: ATSI */ , + session->tmap, NULL); + GNUNET_assert (GNUNET_YES == + GNUNET_CONTAINER_multihashmap_remove (sessions, + &session-> + peer.hashPubKey, + session)); + GNUNET_STATISTICS_set (GSC_stats, gettext_noop ("# entries in session map"), + GNUNET_CONTAINER_multihashmap_size (sessions), + GNUNET_NO); + GSC_TYPEMAP_destroy (session->tmap); + session->tmap = NULL; GNUNET_free (session); } +/** + * Transmit our current typemap message to the other peer. + * (Done periodically in case an update got lost). + * + * @param cls the 'struct Session*' + * @param tc unused + */ +static void +transmit_typemap_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct Session *session = cls; + struct GNUNET_MessageHeader *hdr; + struct GNUNET_TIME_Relative delay; + + delay = TYPEMAP_FREQUENCY; + /* randomize a bit to avoid spont. sync */ + delay.rel_value += + GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 1000); + session->typemap_task = + GNUNET_SCHEDULER_add_delayed (delay, &transmit_typemap_task, session); + GNUNET_STATISTICS_update (GSC_stats, + gettext_noop ("# type map refreshes sent"), 1, + GNUNET_NO); + hdr = GSC_TYPEMAP_compute_type_map_message (); + GSC_KX_encrypt_and_transmit (session->kxinfo, hdr, ntohs (hdr->size)); + GNUNET_free (hdr); +} + + /** * Create a session, a key exchange was just completed. * @@ -201,43 +251,30 @@ GSC_SESSIONS_end (const struct GNUNET_PeerIdentity *pid) */ void GSC_SESSIONS_create (const struct GNUNET_PeerIdentity *peer, - struct GSC_KeyExchangeInfo *kx) + struct GSC_KeyExchangeInfo *kx) { - struct GNUNET_MessageHeader *hdr; struct Session *session; #if DEBUG_CORE - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Creating session for peer `%4s'\n", GNUNET_i2s (pid)); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating session for peer `%4s'\n", + GNUNET_i2s (peer)); #endif session = GNUNET_malloc (sizeof (struct Session)); + session->tmap = GSC_TYPEMAP_create (); session->peer = *peer; session->kxinfo = kx; session->time_established = GNUNET_TIME_absolute_get (); + session->typemap_task = + GNUNET_SCHEDULER_add_now (&transmit_typemap_task, session); GNUNET_assert (GNUNET_OK == - GNUNET_CONTAINER_multihashmap_put (sessions, - &peer->hashPubKey, session, + GNUNET_CONTAINER_multihashmap_put (sessions, &peer->hashPubKey, + session, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); - GNUNET_STATISTICS_update (GSC_stats, - gettext_noop ("# established sessions"), - GNUNET_CONTAINER_multihashmap_size (sessions), - GNUNET_NO); -#if 0 - /* FIXME: integration with ATS for quota calculations... */ - /* FIXME: who should do this? Neighbours!? */ - GNUNET_TRANSPORT_set_quota (transport, - peer, - GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT, - GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT); -#endif - /* FIXME: we should probably do this periodically (in case - type map message is lost...) */ - hdr = GSC_TYPEMAP_compute_type_map_message (); - GSC_KX_encrypt_and_transmit (kx, - GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT, - hdr, - ntohs (hdr->size)); - GNUNET_free (hdr); + GNUNET_STATISTICS_set (GSC_stats, gettext_noop ("# entries in session map"), + GNUNET_CONTAINER_multihashmap_size (sessions), + GNUNET_NO); + GSC_CLIENTS_notify_clients_about_neighbour (peer, NULL, 0 /* FIXME: ATSI */ , + NULL, session->tmap); } @@ -245,23 +282,20 @@ GSC_SESSIONS_create (const struct GNUNET_PeerIdentity *peer, * Notify the given client about the session (client is new). * * @param cls the 'struct GSC_Client' - * @param key peer identity + * @param key peer identity * @param value the 'struct Session' * @return GNUNET_OK (continue to iterate) */ static int -notify_client_about_session (void *cls, - const GNUNET_HashCode *key, - void *value) +notify_client_about_session (void *cls, const GNUNET_HashCode * key, + void *value) { struct GSC_Client *client = cls; struct Session *session = value; - GDS_CLIENTS_notify_client_about_neighbour (client, - &session->peer, - NULL, 0, /* FIXME: ATS!? */ - NULL, /* old TMAP: none */ - session->tmap); + GSC_CLIENTS_notify_client_about_neighbour (client, &session->peer, NULL, 0, /* FIXME: ATS!? */ + NULL, /* old TMAP: none */ + session->tmap); return GNUNET_OK; } @@ -275,8 +309,8 @@ void GSC_SESSIONS_notify_client_about_sessions (struct GSC_Client *client) { /* notify new client about existing sessions */ - GNUNET_CONTAINER_multihashmap_iterate (sessions, - ¬ify_client_about_session, client); + GNUNET_CONTAINER_multihashmap_iterate (sessions, ¬ify_client_about_session, + client); } @@ -307,17 +341,11 @@ GSC_SESSIONS_queue_request (struct GSC_ClientActiveRequest *car) session = find_session (&car->target); if (session == NULL) { - /* neighbour must have disconnected since request was issued, - * ignore (client will realize it once it processes the - * disconnect notification) */ -#if DEBUG_CORE_CLIENT +#if DEBUG_CORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Dropped client request for transmission (am disconnected)\n"); #endif - GNUNET_STATISTICS_update (GSC_stats, - gettext_noop - ("# send requests dropped (disconnected)"), 1, - GNUNET_NO); + GNUNET_break (0); /* should have been rejected earlier */ GSC_CLIENTS_reject_request (car); return; } @@ -327,12 +355,12 @@ GSC_SESSIONS_queue_request (struct GSC_ClientActiveRequest *car) GSC_CLIENTS_reject_request (car); return; } -#if DEBUG_CORE_CLIENT +#if DEBUG_CORE GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received client transmission request. queueing\n"); #endif GNUNET_CONTAINER_DLL_insert (session->active_client_request_head, - session->active_client_request_tail, car); + session->active_client_request_tail, car); try_transmission (session); } @@ -348,7 +376,12 @@ GSC_SESSIONS_dequeue_request (struct GSC_ClientActiveRequest *car) { struct Session *s; + if (0 == + memcmp (&car->target, &GSC_my_identity, + sizeof (struct GNUNET_PeerIdentity))) + return; s = find_session (&car->target); + GNUNET_assert (NULL != s); GNUNET_CONTAINER_DLL_remove (s->active_client_request_head, s->active_client_request_tail, car); } @@ -365,7 +398,7 @@ discard_expired_requests (struct Session *session) struct GSC_ClientActiveRequest *pos; struct GSC_ClientActiveRequest *nxt; struct GNUNET_TIME_Absolute now; - + now = GNUNET_TIME_absolute_get (); pos = NULL; nxt = session->active_client_request_head; @@ -373,16 +406,15 @@ discard_expired_requests (struct Session *session) { pos = nxt; nxt = pos->next; - if ( (pos->deadline.abs_value < now.abs_value) && - (GNUNET_YES != pos->was_solicited) ) + if ((pos->deadline.abs_value < now.abs_value) && + (GNUNET_YES != pos->was_solicited)) { GNUNET_STATISTICS_update (GSC_stats, gettext_noop ("# messages discarded (expired prior to transmission)"), 1, GNUNET_NO); GNUNET_CONTAINER_DLL_remove (session->active_client_request_head, - session->active_client_request_tail, - pos); + session->active_client_request_tail, pos); GSC_CLIENTS_reject_request (pos); } } @@ -398,12 +430,15 @@ static void solicit_messages (struct Session *session) { struct GSC_ClientActiveRequest *car; + struct GSC_ClientActiveRequest *nxt; size_t so_size; - discard_expired_requests (session); + discard_expired_requests (session); so_size = 0; - for (car = session->active_client_request_head; NULL != car; car = car->next) + nxt = session->active_client_request_head; + while (NULL != (car = nxt)) { + nxt = car->next; if (so_size + car->msize > GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE) break; so_size += car->msize; @@ -416,17 +451,16 @@ solicit_messages (struct Session *session) /** - * Some messages were delayed (corked), but the timeout has now expired. + * Some messages were delayed (corked), but the timeout has now expired. * Send them now. * * @param cls 'struct Session' with the messages to transmit now * @param tc scheduler context (unused) */ static void -pop_cork_task (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc) +pop_cork_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { - struct Session *session = session; + struct Session *session = cls; session->cork_task = GNUNET_SCHEDULER_NO_TASK; try_transmission (session); @@ -453,31 +487,31 @@ try_transmission (struct Session *session) min_deadline = GNUNET_TIME_UNIT_FOREVER_ABS; /* check 'ready' messages */ pos = session->sme_head; - GNUNET_assert (pos->size < GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE); - while ( (NULL != pos) && - (msize + pos->size <= GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE) ) + while ((NULL != pos) && + (msize + pos->size <= GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE)) { + GNUNET_assert (pos->size < GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE); msize += pos->size; - min_deadline = GNUNET_TIME_absolute_min (min_deadline, - pos->deadline); + min_deadline = GNUNET_TIME_absolute_min (min_deadline, pos->deadline); pos = pos->next; } now = GNUNET_TIME_absolute_get (); - if ( (msize == 0) || - ( (msize < GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE / 2) && - (min_deadline.abs_value > now.abs_value) ) ) + if ((msize == 0) || + ((msize < GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE / 2) && + (min_deadline.abs_value > now.abs_value))) { /* not enough ready yet, try to solicit more */ solicit_messages (session); if (msize > 0) { /* if there is data to send, just not yet, make sure we do transmit - it once the deadline is reached */ + * it once the deadline is reached */ if (session->cork_task != GNUNET_SCHEDULER_NO_TASK) - GNUNET_SCHEDULER_cancel (session->cork_task); - session->cork_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_absolute_get_remaining (min_deadline), - &pop_cork_task, - session); + GNUNET_SCHEDULER_cancel (session->cork_task); + session->cork_task = + GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_absolute_get_remaining + (min_deadline), &pop_cork_task, + session); } return; } @@ -485,16 +519,16 @@ try_transmission (struct Session *session) { static unsigned long long total_bytes; static unsigned int total_msgs; - char pbuf[msize]; /* plaintext */ + char pbuf[msize]; /* plaintext */ size_t used; used = 0; - pos = session->sme_head; - while ( (NULL != pos) && - (used + pos->size <= msize) ) + while ((NULL != (pos = session->sme_head)) && (used + pos->size <= msize)) { memcpy (&pbuf[used], &pos[1], pos->size); used += pos->size; + GNUNET_CONTAINER_DLL_remove (session->sme_head, session->sme_tail, pos); + GNUNET_free (pos); } /* compute average payload size */ total_bytes += used; @@ -505,16 +539,11 @@ try_transmission (struct Session *session) total_msgs = 1; total_bytes = used; } - GNUNET_STATISTICS_set (GSC_stats, - "# avg payload per encrypted message", - total_bytes / total_msgs, - GNUNET_NO); + GNUNET_STATISTICS_set (GSC_stats, "# avg payload per encrypted message", + total_bytes / total_msgs, GNUNET_NO); /* now actually transmit... */ session->ready_to_transmit = GNUNET_NO; - GSC_KX_encrypt_and_transmit (session->kxinfo, - GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT /* FIXME! */, - pbuf, - used); + GSC_KX_encrypt_and_transmit (session->kxinfo, pbuf, used); } } @@ -539,9 +568,7 @@ do_send_message (void *cls, const GNUNET_HashCode * key, void *value) m = GNUNET_malloc (sizeof (struct SessionMessageEntry) + size); memcpy (&m[1], hdr, size); m->size = size; - GNUNET_CONTAINER_DLL_insert (session->sme_head, - session->sme_tail, - m); + GNUNET_CONTAINER_DLL_insert (session->sme_head, session->sme_tail, m); try_transmission (session); return GNUNET_OK; } @@ -557,8 +584,8 @@ GSC_SESSIONS_broadcast (const struct GNUNET_MessageHeader *msg) { if (NULL == sessions) return; - GNUNET_CONTAINER_multihashmap_iterate (sessions, - &do_send_message, (void*) msg); + GNUNET_CONTAINER_multihashmap_iterate (sessions, &do_send_message, + (void *) msg); } @@ -575,6 +602,8 @@ GSC_SESSIONS_solicit (const struct GNUNET_PeerIdentity *pid) struct Session *session; session = find_session (pid); + if (NULL == session) + return; session->ready_to_transmit = GNUNET_YES; try_transmission (session); } @@ -590,23 +619,23 @@ GSC_SESSIONS_solicit (const struct GNUNET_PeerIdentity *pid) */ void GSC_SESSIONS_transmit (struct GSC_ClientActiveRequest *car, - const struct GNUNET_MessageHeader *msg, - int cork) + const struct GNUNET_MessageHeader *msg, int cork) { struct Session *session; struct SessionMessageEntry *sme; size_t msize; session = find_session (&car->target); + if (NULL == session) + return; msize = ntohs (msg->size); sme = GNUNET_malloc (sizeof (struct SessionMessageEntry) + msize); memcpy (&sme[1], msg, msize); sme->size = msize; if (GNUNET_YES == cork) - sme->deadline = GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_MAX_CORK_DELAY); - GNUNET_CONTAINER_DLL_insert_tail (session->sme_head, - session->sme_tail, - sme); + sme->deadline = + GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_MAX_CORK_DELAY); + GNUNET_CONTAINER_DLL_insert_tail (session->sme_head, session->sme_tail, sme); try_transmission (session); } @@ -626,17 +655,13 @@ queue_connect_message (void *cls, const GNUNET_HashCode * key, void *value) struct GNUNET_SERVER_TransmitContext *tc = cls; struct Session *session = value; struct ConnectNotifyMessage cnm; - struct GNUNET_TRANSPORT_ATS_Information *a; - + /* FIXME: code duplication with clients... */ cnm.header.size = htons (sizeof (struct ConnectNotifyMessage)); cnm.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT); + // FIXME: full ats... cnm.ats_count = htonl (0); cnm.peer = session->peer; - a = &cnm.ats; - // FIXME: full ats... - a[0].type = htonl (GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR); - a[0].value = htonl (0); GNUNET_SERVER_transmit_context_append_message (tc, &cnm.header); return GNUNET_OK; } @@ -645,23 +670,23 @@ queue_connect_message (void *cls, const GNUNET_HashCode * key, void *value) /** * Handle CORE_ITERATE_PEERS request. For this request type, the client * does not have to have transmitted an INIT request. All current peers - * are returned, regardless of which message types they accept. + * are returned, regardless of which message types they accept. * * @param cls unused * @param client client sending the iteration request * @param message iteration request message */ void -GSC_SESSIONS_handle_client_iterate_peers (void *cls, struct GNUNET_SERVER_Client *client, - const struct GNUNET_MessageHeader *message) +GSC_SESSIONS_handle_client_iterate_peers (void *cls, + struct GNUNET_SERVER_Client *client, + const struct GNUNET_MessageHeader + *message) { struct GNUNET_MessageHeader done_msg; struct GNUNET_SERVER_TransmitContext *tc; tc = GNUNET_SERVER_transmit_context_create (client); - GNUNET_CONTAINER_multihashmap_iterate (sessions, - &queue_connect_message, - tc); + GNUNET_CONTAINER_multihashmap_iterate (sessions, &queue_connect_message, tc); done_msg.size = htons (sizeof (struct GNUNET_MessageHeader)); done_msg.type = htons (GNUNET_MESSAGE_TYPE_CORE_ITERATE_PEERS_END); GNUNET_SERVER_transmit_context_append_message (tc, &done_msg); @@ -680,14 +705,16 @@ GSC_SESSIONS_handle_client_iterate_peers (void *cls, struct GNUNET_SERVER_Client * @param message iteration request message */ void -GSC_SESSIONS_handle_client_have_peer (void *cls, struct GNUNET_SERVER_Client *client, - const struct GNUNET_MessageHeader *message) +GSC_SESSIONS_handle_client_have_peer (void *cls, + struct GNUNET_SERVER_Client *client, + const struct GNUNET_MessageHeader + *message) { struct GNUNET_MessageHeader done_msg; struct GNUNET_SERVER_TransmitContext *tc; const struct GNUNET_PeerIdentity *peer; - peer = (const struct GNUNET_PeerIdentity *) &message[1]; // YUCK! + peer = (const struct GNUNET_PeerIdentity *) &message[1]; // YUCK! tc = GNUNET_SERVER_transmit_context_create (client); GNUNET_CONTAINER_multihashmap_get_multiple (sessions, &peer->hashPubKey, &queue_connect_message, tc); @@ -699,115 +726,61 @@ GSC_SESSIONS_handle_client_have_peer (void *cls, struct GNUNET_SERVER_Client *cl /** - * Handle REQUEST_INFO request. For this request type, the client must - * have transmitted an INIT first. + * We've received a typemap message from a peer, update ours. + * Notifies clients about the session. * - * @param cls unused - * @param client client sending the request - * @param message iteration request message + * @param peer peer this is about + * @param msg typemap update message */ void -GSC_SESSIONS_handle_client_request_info (void *cls, struct GNUNET_SERVER_Client *client, - const struct GNUNET_MessageHeader *message) +GSC_SESSIONS_set_typemap (const struct GNUNET_PeerIdentity *peer, + const struct GNUNET_MessageHeader *msg) { - const struct RequestInfoMessage *rcm; struct Session *session; - struct ConfigurationInfoMessage cim; - int32_t want_reserv; - int32_t got_reserv; - struct GNUNET_TIME_Relative rdelay; + struct GSC_TypeMap *nmap; - rdelay = GNUNET_TIME_UNIT_ZERO; -#if DEBUG_CORE_CLIENT - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Core service receives `%s' request.\n", - "REQUEST_INFO"); -#endif - rcm = (const struct RequestInfoMessage *) message; - session = find_session (&rcm->peer); + nmap = GSC_TYPEMAP_get_from_message (msg); + if (NULL == nmap) + return; /* malformed */ + session = find_session (peer); if (NULL == session) { - /* Technically, this COULD happen (due to asynchronous behavior), - * but it should be rare, so we should generate an info event - * to help diagnosis of serious errors that might be masked by this */ - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - _("Client asked for preference change with peer `%s', which is not connected!\n"), - GNUNET_i2s (&rcm->peer)); - GNUNET_SERVER_receive_done (client, GNUNET_OK); + GNUNET_break (0); return; } - - want_reserv = ntohl (rcm->reserve_inbound); - if (session->bw_out_internal_limit.value__ != rcm->limit_outbound.value__) - { - session->bw_out_internal_limit = rcm->limit_outbound; - if (session->bw_out.value__ != - GNUNET_BANDWIDTH_value_min (session->bw_out_internal_limit, - session->bw_out_external_limit).value__) - { - session->bw_out = - GNUNET_BANDWIDTH_value_min (session->bw_out_internal_limit, - session->bw_out_external_limit); - GNUNET_BANDWIDTH_tracker_update_quota (&session->available_recv_window, - session->bw_out); -#if 0 - // FIXME: who does this? - GNUNET_TRANSPORT_set_quota (transport, &session->peer, - session->bw_in, - session->bw_out); -#endif - } - } - if (want_reserv < 0) - { - got_reserv = want_reserv; - } - else if (want_reserv > 0) - { - rdelay = - GNUNET_BANDWIDTH_tracker_get_delay (&session->available_recv_window, - want_reserv); - if (rdelay.rel_value == 0) - got_reserv = want_reserv; - else - got_reserv = 0; /* all or nothing */ - } - else - got_reserv = 0; - GNUNET_BANDWIDTH_tracker_consume (&session->available_recv_window, got_reserv); -#if DEBUG_CORE_QUOTA - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Received reservation request for %d bytes for peer `%4s', reserved %d bytes, suggesting delay of %llu ms\n", - (int) want_reserv, GNUNET_i2s (&rcm->peer), (int) got_reserv, - (unsigned long long) rdelay.rel_value); -#endif - cim.header.size = htons (sizeof (struct ConfigurationInfoMessage)); - cim.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_CONFIGURATION_INFO); - cim.reserved_amount = htonl (got_reserv); - cim.reserve_delay = GNUNET_TIME_relative_hton (rdelay); - cim.rim_id = rcm->rim_id; - cim.bw_out = session->bw_out; - cim.preference = 0; /* FIXME: remove */ - cim.peer = rcm->peer; - GSC_CLIENTS_send_to_client (client, &cim.header, GNUNET_NO); - GNUNET_SERVER_receive_done (client, GNUNET_OK); + GSC_CLIENTS_notify_clients_about_neighbour (peer, NULL, 0, /* FIXME: ATS */ + session->tmap, nmap); + GSC_TYPEMAP_destroy (session->tmap); + session->tmap = nmap; } /** - * Update information about a session. + * The given peer send a message of the specified type. Make sure the + * respective bit is set in its type-map and that clients are notified + * about the session. * - * @param peer peer who's session should be updated - * @param bw_out new outbound bandwidth limit for the peer - * @param atsi performance information - * @param atsi_count number of performance records supplied + * @param peer peer this is about + * @param type type of the message */ void -GSC_SESSIONS_update (const struct GNUNET_PeerIdentity *peer, - struct GNUNET_BANDWIDTH_Value32NBO bw_out) +GSC_SESSIONS_add_to_typemap (const struct GNUNET_PeerIdentity *peer, + uint16_t type) { - // FIXME - /* not implemented */ + struct Session *session; + struct GSC_TypeMap *nmap; + + if (0 == memcmp (peer, &GSC_my_identity, sizeof (struct GNUNET_PeerIdentity))) + return; + session = find_session (peer); + GNUNET_assert (NULL != session); + if (GNUNET_YES == GSC_TYPEMAP_test_match (session->tmap, &type, 1)) + return; /* already in it */ + nmap = GSC_TYPEMAP_extend (session->tmap, &type, 1); + GSC_CLIENTS_notify_clients_about_neighbour (peer, NULL, 0, /* FIXME: ATS */ + session->tmap, nmap); + GSC_TYPEMAP_destroy (session->tmap); + session->tmap = nmap; } @@ -845,15 +818,9 @@ free_session_helper (void *cls, const GNUNET_HashCode * key, void *value) void GSC_SESSIONS_done () { - GNUNET_CONTAINER_multihashmap_iterate (sessions, - &free_session_helper, - NULL); + GNUNET_CONTAINER_multihashmap_iterate (sessions, &free_session_helper, NULL); GNUNET_CONTAINER_multihashmap_destroy (sessions); sessions = NULL; - GNUNET_STATISTICS_set (GSC_stats, - gettext_noop ("# established sessions"), - 0, GNUNET_NO); } /* end of gnunet-service-core_sessions.c */ -