X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Fats%2Fats_api_scheduling.c;h=783b9f59617c8fcaa6c55f1ba5a55e176ad07844;hb=7a5a724a6f96baf80d2226326124aa01c58ad3fe;hp=ed82dd2ada8bb97d4cbc7a0dc860af58eb27e494;hpb=b861288c1689fe2274fb7d08e207e8db5af3c716;p=oweals%2Fgnunet.git diff --git a/src/ats/ats_api_scheduling.c b/src/ats/ats_api_scheduling.c index ed82dd2ad..783b9f596 100644 --- a/src/ats/ats_api_scheduling.c +++ b/src/ats/ats_api_scheduling.c @@ -1,21 +1,19 @@ /* This file is part of GNUnet. - Copyright (C) 2010-2015 Christian Grothoff (and other contributing authors) + Copyright (C) 2010-2015 GNUnet e.V. - GNUnet is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3, or (at your - option) any later version. + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. GNUnet is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GNUnet; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ /** * @file ats/ats_api_scheduling.c @@ -70,21 +68,16 @@ struct GNUNET_ATS_AddressRecord * Session handle. NULL if we have an address but no * active session for this address. */ - struct Session *session; + struct GNUNET_ATS_Session *session; /** - * Array with performance data about the address. + * Performance data about the address. */ - struct GNUNET_ATS_Information *ats; - - /** - * Number of entries in @e ats. - */ - uint32_t ats_count; + struct GNUNET_ATS_PropertiesNBO properties; /** * Which slot (index) in the session array does - * this record correspond to? FIXME: + * this record correspond to? * FIXME: a linear search on this is really crappy! * Maybe switch to a 64-bit global counter and be * done with it? Or does that then cause too much @@ -122,11 +115,6 @@ struct GNUNET_ATS_SchedulingHandle */ void *suggest_cb_cls; - /** - * Connection to ATS service. - */ - struct GNUNET_CLIENT_Connection *client; - /** * Message queue for sending requests to the ATS service. */ @@ -171,11 +159,9 @@ reconnect (struct GNUNET_ATS_SchedulingHandle *sh); * Re-establish the connection to the ATS service. * * @param cls handle to use to re-connect. - * @param tc scheduler context */ static void -reconnect_task (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc) +reconnect_task (void *cls) { struct GNUNET_ATS_SchedulingHandle *sh = cls; @@ -197,11 +183,6 @@ force_reconnect (struct GNUNET_ATS_SchedulingHandle *sh) GNUNET_MQ_destroy (sh->mq); sh->mq = NULL; } - if (NULL != sh->client) - { - GNUNET_CLIENT_disconnect (sh->client); - sh->client = NULL; - } sh->suggest_cb (sh->suggest_cb_cls, NULL, NULL, NULL, GNUNET_BANDWIDTH_ZERO, @@ -252,7 +233,6 @@ find_session (struct GNUNET_ATS_SchedulingHandle *sh, sizeof (struct GNUNET_PeerIdentity))) { GNUNET_break (0); - force_reconnect (sh); return NULL; } return ar; @@ -271,6 +251,7 @@ find_empty_session_slot (struct GNUNET_ATS_SchedulingHandle *sh) static uint32_t off; uint32_t i; + GNUNET_assert (0 != sh->session_array_size); i = 0; while ( ( (NOT_FOUND == off) || (NULL != sh->session_array[off % sh->session_array_size]) ) && @@ -300,7 +281,7 @@ find_empty_session_slot (struct GNUNET_ATS_SchedulingHandle *sh) */ static uint32_t find_session_id (struct GNUNET_ATS_SchedulingHandle *sh, - struct Session *session, + struct GNUNET_ATS_Session *session, const struct GNUNET_HELLO_Address *address) { uint32_t i; @@ -312,8 +293,12 @@ find_session_id (struct GNUNET_ATS_SchedulingHandle *sh, } for (i = 1; i < sh->session_array_size; i++) if ( (NULL != sh->session_array[i]) && + (GNUNET_NO == sh->session_array[i]->in_destroy) && ( (session == sh->session_array[i]->session) || (NULL == sh->session_array[i]->session) ) && + (0 == memcmp (&address->peer, + &sh->session_array[i]->address->peer, + sizeof (struct GNUNET_PeerIdentity))) && (0 == GNUNET_HELLO_address_cmp (address, sh->session_array[i]->address)) ) return i; @@ -361,16 +346,14 @@ release_session (struct GNUNET_ATS_SchedulingHandle *sh, * message from the service. * * @param cls the `struct GNUNET_ATS_SchedulingHandle` - * @param msg message received, NULL on timeout or fatal error + * @param srm message received */ static void -process_ats_session_release_message (void *cls, - const struct GNUNET_MessageHeader *msg) +handle_ats_session_release (void *cls, + const struct GNUNET_ATS_SessionReleaseMessage *srm) { struct GNUNET_ATS_SchedulingHandle *sh = cls; - const struct SessionReleaseMessage *srm; - srm = (const struct SessionReleaseMessage *) msg; /* Note: peer field in srm not necessary right now, but might be good to have in the future */ release_session (sh, @@ -383,18 +366,16 @@ process_ats_session_release_message (void *cls, * message from the service. * * @param cls the `struct GNUNET_ATS_SchedulingHandle` - * @param msg message received, NULL on timeout or fatal error + * @param m message received */ static void -process_ats_address_suggestion_message (void *cls, - const struct GNUNET_MessageHeader *msg) +handle_ats_address_suggestion (void *cls, + const struct AddressSuggestionMessage *m) { struct GNUNET_ATS_SchedulingHandle *sh = cls; - const struct AddressSuggestionMessage *m; struct GNUNET_ATS_AddressRecord *ar; uint32_t session_id; - m = (const struct AddressSuggestionMessage *) msg; session_id = ntohl (m->session_id); if (0 == session_id) { @@ -402,7 +383,9 @@ process_ats_address_suggestion_message (void *cls, force_reconnect (sh); return; } - ar = find_session (sh, session_id, &m->peer); + ar = find_session (sh, + session_id, + &m->peer); if (NULL == ar) { GNUNET_break (0); @@ -467,7 +450,7 @@ error_handler (void *cls, { struct GNUNET_ATS_SchedulingHandle *sh = cls; - LOG (GNUNET_ERROR_TYPE_WARNING, + LOG (GNUNET_ERROR_TYPE_DEBUG, "ATS connection died (code %d), reconnecting\n", (int) error); force_reconnect (sh); @@ -487,26 +470,22 @@ send_add_address_message (struct GNUNET_ATS_SchedulingHandle *sh, { struct GNUNET_MQ_Envelope *ev; struct AddressAddMessage *m; - struct GNUNET_ATS_Information *am; char *pm; size_t namelen; size_t msize; if (NULL == sh->mq) return; /* disconnected, skip for now */ - namelen = (NULL == ar->address->transport_name) - ? 0 - : strlen (ar->address->transport_name) + 1; - msize = ar->address->address_length + - ar->ats_count * sizeof (struct GNUNET_ATS_Information) + namelen; - + GNUNET_break (GNUNET_ATS_NET_UNSPECIFIED != ar->properties.scope); + namelen = strlen (ar->address->transport_name) + 1; + msize = ar->address->address_length + namelen; ev = GNUNET_MQ_msg_extra (m, msize, GNUNET_MESSAGE_TYPE_ATS_ADDRESS_ADD); - m->ats_count = htonl (ar->ats_count); m->peer = ar->address->peer; m->address_length = htons (ar->address->address_length); m->address_local_info = htonl ((uint32_t) ar->address->local_info); m->plugin_name_length = htons (namelen); m->session_id = htonl (ar->slot); + m->properties = ar->properties; LOG (GNUNET_ERROR_TYPE_DEBUG, "Adding address for peer `%s', plugin `%s', session %p slot %u\n", @@ -514,16 +493,12 @@ send_add_address_message (struct GNUNET_ATS_SchedulingHandle *sh, ar->address->transport_name, ar->session, ar->slot); - am = (struct GNUNET_ATS_Information *) &m[1]; - memcpy (am, - ar->ats, - ar->ats_count * sizeof (struct GNUNET_ATS_Information)); - pm = (char *) &am[ar->ats_count]; - memcpy (pm, + pm = (char *) &m[1]; + GNUNET_memcpy (pm, ar->address->address, ar->address->address_length); if (NULL != ar->address->transport_name) - memcpy (&pm[ar->address->address_length], + GNUNET_memcpy (&pm[ar->address->address_length], ar->address->transport_name, namelen); GNUNET_MQ_send (sh->mq, ev); @@ -538,30 +513,34 @@ send_add_address_message (struct GNUNET_ATS_SchedulingHandle *sh, static void reconnect (struct GNUNET_ATS_SchedulingHandle *sh) { - static const struct GNUNET_MQ_MessageHandler handlers[] = - { { &process_ats_session_release_message, - GNUNET_MESSAGE_TYPE_ATS_SESSION_RELEASE, - sizeof (struct SessionReleaseMessage) }, - { &process_ats_address_suggestion_message, - GNUNET_MESSAGE_TYPE_ATS_ADDRESS_SUGGESTION, - sizeof (struct AddressSuggestionMessage) }, - { NULL, 0, 0 } }; + struct GNUNET_MQ_MessageHandler handlers[] = { + GNUNET_MQ_hd_fixed_size (ats_session_release, + GNUNET_MESSAGE_TYPE_ATS_SESSION_RELEASE, + struct GNUNET_ATS_SessionReleaseMessage, + sh), + GNUNET_MQ_hd_fixed_size (ats_address_suggestion, + GNUNET_MESSAGE_TYPE_ATS_ADDRESS_SUGGESTION, + struct AddressSuggestionMessage, + sh), + GNUNET_MQ_handler_end () + }; struct GNUNET_MQ_Envelope *ev; struct ClientStartMessage *init; unsigned int i; struct GNUNET_ATS_AddressRecord *ar; - GNUNET_assert (NULL == sh->client); - sh->client = GNUNET_CLIENT_connect ("ats", sh->cfg); - if (NULL == sh->client) + GNUNET_assert (NULL == sh->mq); + sh->mq = GNUNET_CLIENT_connect (sh->cfg, + "ats", + handlers, + &error_handler, + sh); + if (NULL == sh->mq) { + GNUNET_break (0); force_reconnect (sh); return; } - sh->mq = GNUNET_MQ_queue_for_connection_client (sh->client, - handlers, - &error_handler, - sh); ev = GNUNET_MQ_msg (init, GNUNET_MESSAGE_TYPE_ATS_START); init->start_flag = htonl (START_FLAG_SCHEDULING); @@ -615,6 +594,7 @@ GNUNET_ATS_scheduling_init (const struct GNUNET_CONFIGURATION_Handle *cfg, void GNUNET_ATS_scheduling_done (struct GNUNET_ATS_SchedulingHandle *sh) { + struct GNUNET_ATS_AddressRecord *ar; unsigned int i; if (NULL != sh->mq) @@ -622,11 +602,6 @@ GNUNET_ATS_scheduling_done (struct GNUNET_ATS_SchedulingHandle *sh) GNUNET_MQ_destroy (sh->mq); sh->mq = NULL; } - if (NULL != sh->client) - { - GNUNET_CLIENT_disconnect (sh->client); - sh->client = NULL; - } if (NULL != sh->task) { GNUNET_SCHEDULER_cancel (sh->task); @@ -634,8 +609,12 @@ GNUNET_ATS_scheduling_done (struct GNUNET_ATS_SchedulingHandle *sh) } for (i=0;isession_array_size;i++) { - GNUNET_free_non_null (sh->session_array[i]); - sh->session_array[i] = NULL; + if (NULL != (ar = sh->session_array[i])) + { + GNUNET_HELLO_address_free (ar->address); + GNUNET_free (ar); + sh->session_array[i] = NULL; + } } GNUNET_array_grow (sh->session_array, sh->session_array_size, @@ -644,29 +623,6 @@ GNUNET_ATS_scheduling_done (struct GNUNET_ATS_SchedulingHandle *sh) } -/** - * Test if a address and a session is known to ATS - * - * @param sh the scheduling handle - * @param address the address - * @param session the session - * @return #GNUNET_YES or #GNUNET_NO - */ -int -GNUNET_ATS_session_known (struct GNUNET_ATS_SchedulingHandle *sh, - const struct GNUNET_HELLO_Address *address, - struct Session *session) -{ - if (NULL == session) - return GNUNET_NO; - if (NOT_FOUND != find_session_id (sh, - session, - address)) - return GNUNET_YES; /* Exists */ - return GNUNET_NO; -} - - /** * We have a new address ATS should know. Addresses have to be added * with this function before they can be: updated, set in use and @@ -675,17 +631,15 @@ GNUNET_ATS_session_known (struct GNUNET_ATS_SchedulingHandle *sh, * @param sh handle * @param address the address * @param session session handle, can be NULL - * @param ats performance data for the address - * @param ats_count number of performance records in @a ats + * @param prop performance data for the address * @return handle to the address representation inside ATS, NULL * on error (i.e. ATS knows this exact address already) */ struct GNUNET_ATS_AddressRecord * GNUNET_ATS_address_add (struct GNUNET_ATS_SchedulingHandle *sh, const struct GNUNET_HELLO_Address *address, - struct Session *session, - const struct GNUNET_ATS_Information *ats, - uint32_t ats_count) + struct GNUNET_ATS_Session *session, + const struct GNUNET_ATS_Properties *prop) { struct GNUNET_ATS_AddressRecord *ar; size_t namelen; @@ -698,16 +652,12 @@ GNUNET_ATS_address_add (struct GNUNET_ATS_SchedulingHandle *sh, GNUNET_break (0); return NULL; } - namelen = (NULL == address->transport_name) - ? 0 - : strlen (address->transport_name) + 1; - msize = address->address_length + - ats_count * sizeof (struct GNUNET_ATS_Information) + namelen; - if ((msize + sizeof (struct AddressUpdateMessage) >= GNUNET_SERVER_MAX_MESSAGE_SIZE) || - (address->address_length >= GNUNET_SERVER_MAX_MESSAGE_SIZE) || - (namelen >= GNUNET_SERVER_MAX_MESSAGE_SIZE) || - (ats_count >= - GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_ATS_Information))) + GNUNET_break (GNUNET_ATS_NET_UNSPECIFIED != prop->scope); + namelen = strlen (address->transport_name) + 1; + msize = address->address_length + namelen; + if ((msize + sizeof (struct AddressUpdateMessage) >= GNUNET_MAX_MESSAGE_SIZE) || + (address->address_length >= GNUNET_MAX_MESSAGE_SIZE) || + (namelen >= GNUNET_MAX_MESSAGE_SIZE) ) { /* address too large for us, this should not happen */ GNUNET_break (0); @@ -729,12 +679,8 @@ GNUNET_ATS_address_add (struct GNUNET_ATS_SchedulingHandle *sh, ar->slot = s; ar->session = session; ar->address = GNUNET_HELLO_address_copy (address); - GNUNET_array_grow (ar->ats, - ar->ats_count, - ats_count); - memcpy (ar->ats, - ats, - ats_count * sizeof (struct GNUNET_ATS_Information)); + GNUNET_ATS_properties_hton (&ar->properties, + prop); sh->session_array[s] = ar; send_add_address_message (sh, ar); return ar; @@ -749,7 +695,7 @@ GNUNET_ATS_address_add (struct GNUNET_ATS_SchedulingHandle *sh, */ void GNUNET_ATS_address_add_session (struct GNUNET_ATS_AddressRecord *ar, - struct Session *session) + struct GNUNET_ATS_Session *session) { GNUNET_break (NULL == ar->session); ar->session = session; @@ -770,9 +716,9 @@ GNUNET_ATS_address_add_session (struct GNUNET_ATS_AddressRecord *ar, */ int GNUNET_ATS_address_del_session (struct GNUNET_ATS_AddressRecord *ar, - struct Session *session) + struct GNUNET_ATS_Session *session) { - GNUNET_break (session == ar->session); + GNUNET_assert (session == ar->session); ar->session = NULL; if (GNUNET_HELLO_address_check_option (ar->address, GNUNET_HELLO_ADDRESS_INFO_INBOUND)) @@ -793,19 +739,15 @@ GNUNET_ATS_address_del_session (struct GNUNET_ATS_AddressRecord *ar, * for later use). Update bandwidth assignments. * * @param ar address record to update information for - * @param ats performance data for the address - * @param ats_count number of performance records in @a ats + * @param prop performance data for the address */ void GNUNET_ATS_address_update (struct GNUNET_ATS_AddressRecord *ar, - const struct GNUNET_ATS_Information *ats, - uint32_t ats_count) + const struct GNUNET_ATS_Properties *prop) { struct GNUNET_ATS_SchedulingHandle *sh = ar->sh; struct GNUNET_MQ_Envelope *ev; struct AddressUpdateMessage *m; - struct GNUNET_ATS_Information *am; - size_t msize; LOG (GNUNET_ERROR_TYPE_DEBUG, "Updating address for peer `%s', plugin `%s', session %p slot %u\n", @@ -813,29 +755,20 @@ GNUNET_ATS_address_update (struct GNUNET_ATS_AddressRecord *ar, ar->address->transport_name, ar->session, ar->slot); - GNUNET_array_grow (ar->ats, - ar->ats_count, - ats_count); - memcpy (ar->ats, - ats, - ats_count * sizeof (struct GNUNET_ATS_Information)); - + GNUNET_break (GNUNET_ATS_NET_UNSPECIFIED != prop->scope); + GNUNET_ATS_properties_hton (&ar->properties, + prop); if (NULL == sh->mq) return; /* disconnected, skip for now */ - msize = ar->ats_count * sizeof (struct GNUNET_ATS_Information); - ev = GNUNET_MQ_msg_extra (m, msize, GNUNET_MESSAGE_TYPE_ATS_ADDRESS_UPDATE); - m->ats_count = htonl (ar->ats_count); - m->peer = ar->address->peer; + ev = GNUNET_MQ_msg (m, GNUNET_MESSAGE_TYPE_ATS_ADDRESS_UPDATE); m->session_id = htonl (ar->slot); - am = (struct GNUNET_ATS_Information *) &m[1]; - memcpy (am, - ar->ats, - ar->ats_count * sizeof (struct GNUNET_ATS_Information)); - GNUNET_MQ_send (sh->mq, ev); + m->peer = ar->address->peer; + m->properties = ar->properties; + GNUNET_MQ_send (sh->mq, + ev); } - /** * An address got destroyed, stop using it as a valid address. * @@ -857,9 +790,6 @@ GNUNET_ATS_address_destroy (struct GNUNET_ATS_AddressRecord *ar) GNUNET_break (NULL == ar->session); ar->session = NULL; ar->in_destroy = GNUNET_YES; - GNUNET_array_grow (ar->ats, - ar->ats_count, - 0); if (NULL == sh->mq) return; ev = GNUNET_MQ_msg (m, GNUNET_MESSAGE_TYPE_ATS_ADDRESS_DESTROYED);