X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Fats%2Fats_api_performance.c;h=90e061c1d2873e62716ff1cb183716dcac7fcb1b;hb=f1ca38573f22205e28ac482efebe463696c9c2c7;hp=5cb199266d286867f7b569e2ab7b315df8e47d1a;hpb=b2c95277e4ebc0da4a580c93c3467ea4d7847fab;p=oweals%2Fgnunet.git diff --git a/src/ats/ats_api_performance.c b/src/ats/ats_api_performance.c index 5cb199266..90e061c1d 100644 --- a/src/ats/ats_api_performance.c +++ b/src/ats/ats_api_performance.c @@ -1,33 +1,32 @@ /* - This file is part of GNUnet. - (C) 2010,2011 Christian Grothoff (and other contributing authors) - - 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 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. -*/ + This file is part of GNUnet. + (C) 2010,2011 Christian Grothoff (and other contributing authors) + + 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 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. + */ /** * @file ats/ats_api_performance.c * @brief automatic transport selection and outbound bandwidth determination * @author Christian Grothoff * @author Matthias Wachs - */ + */ #include "platform.h" #include "gnunet_ats_service.h" #include "ats.h" - /** * Message in linked list we should send to the ATS service. The * actual binary message follows this struct. @@ -56,7 +55,6 @@ struct PendingMessage int is_init; }; - /** * Linked list of pending reservations. */ @@ -104,7 +102,6 @@ struct GNUNET_ATS_ReservationContext int undo; }; - /** * Linked list of pending reservations. */ @@ -129,7 +126,7 @@ struct GNUNET_ATS_AddressListHandle /** * Callback */ - GNUNET_ATS_PeerInformationCallback cb; + GNUNET_ATS_AddressInformationCallback cb; /** * Callback closure @@ -169,14 +166,14 @@ struct GNUNET_ATS_PerformanceHandle const struct GNUNET_CONFIGURATION_Handle *cfg; /** - * Callback to invoke on performance changes. + * Callback to invoke when an address has performance changes. */ - GNUNET_ATS_PeerInformationCallback infocb; + GNUNET_ATS_AddressInformationCallback addr_info_cb; /** - * Closure for 'infocb'. + * Closure for 'addr_info_cb'. */ - void *infocb_cls; + void *addr_info_cb_cls; /** * Connection to ATS service. @@ -223,13 +220,17 @@ struct GNUNET_ATS_PerformanceHandle */ GNUNET_SCHEDULER_TaskIdentifier task; + /** + * Monitor request multiplexing + */ + uint32_t monitor_id; + /** * Request multiplexing */ uint32_t id; }; - /** * Re-establish the connection to the ATS service. * @@ -238,7 +239,6 @@ struct GNUNET_ATS_PerformanceHandle static void reconnect (struct GNUNET_ATS_PerformanceHandle *ph); - /** * Re-establish the connection to the ATS service. * @@ -254,7 +254,6 @@ reconnect_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) reconnect (ph); } - /** * Transmit messages from the message queue to the service * (if there are any, and if we are not already trying). @@ -264,6 +263,15 @@ reconnect_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) static void do_transmit (struct GNUNET_ATS_PerformanceHandle *ph); +/** + * Type of a function to call when we receive a message + * from the service. + * + * @param cls the 'struct GNUNET_ATS_SchedulingHandle' + * @param msg message received, NULL on timeout or fatal error + */ +static void +process_ats_message (void *cls, const struct GNUNET_MessageHeader *msg); /** * We can now transmit a message to ATS. Do it. @@ -289,14 +297,13 @@ transmit_message_to_ats (void *cls, size_t size, void *buf) memcpy (&cbuf[ret], &p[1], p->size); ret += p->size; size -= p->size; - GNUNET_CONTAINER_DLL_remove (ph->pending_head, ph->pending_tail, p); - GNUNET_free (p); + GNUNET_CONTAINER_DLL_remove(ph->pending_head, ph->pending_tail, p); + GNUNET_free(p); } do_transmit (ph); return ret; } - /** * Transmit messages from the message queue to the service * (if there are any, and if we are not already trying). @@ -313,15 +320,11 @@ do_transmit (struct GNUNET_ATS_PerformanceHandle *ph) if (NULL == (p = ph->pending_head)) return; if (NULL == ph->client) - return; /* currently reconnecting */ - ph->th = - GNUNET_CLIENT_notify_transmit_ready (ph->client, p->size, - GNUNET_TIME_UNIT_FOREVER_REL, - GNUNET_YES, &transmit_message_to_ats, - ph); + return; /* currently reconnecting */ + ph->th = GNUNET_CLIENT_notify_transmit_ready (ph->client, p->size, + GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_YES, &transmit_message_to_ats, ph); } - /** * We received a peer information message. Validate and process it. * @@ -331,7 +334,7 @@ do_transmit (struct GNUNET_ATS_PerformanceHandle *ph) */ static int process_pi_message (struct GNUNET_ATS_PerformanceHandle *ph, - const struct GNUNET_MessageHeader *msg) + const struct GNUNET_MessageHeader *msg) { const struct PeerInformationMessage *pi; const struct GNUNET_ATS_Information *atsi; @@ -341,10 +344,11 @@ process_pi_message (struct GNUNET_ATS_PerformanceHandle *ph, uint16_t plugin_address_length; uint16_t plugin_name_length; uint32_t ats_count; + int addr_active; - if (ntohs (msg->size) < sizeof (struct PeerInformationMessage)) + if (ntohs (msg->size) < sizeof(struct PeerInformationMessage)) { - GNUNET_break (0); + GNUNET_break(0); return GNUNET_SYSERR; } @@ -352,34 +356,35 @@ process_pi_message (struct GNUNET_ATS_PerformanceHandle *ph, ats_count = ntohl (pi->ats_count); plugin_address_length = ntohs (pi->address_length); plugin_name_length = ntohs (pi->plugin_name_length); + addr_active = ntohl (pi->address_active); atsi = (const struct GNUNET_ATS_Information *) &pi[1]; plugin_address = (const char *) &atsi[ats_count]; plugin_name = &plugin_address[plugin_address_length]; - if ((plugin_address_length + plugin_name_length + - ats_count * sizeof (struct GNUNET_ATS_Information) + - sizeof (struct PeerInformationMessage) != ntohs (msg->size)) || - (ats_count > - GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_ATS_Information)) + if ((plugin_address_length + plugin_name_length + + ats_count * sizeof(struct GNUNET_ATS_Information) + + sizeof(struct PeerInformationMessage) != ntohs (msg->size)) + || (ats_count + > GNUNET_SERVER_MAX_MESSAGE_SIZE + / sizeof(struct GNUNET_ATS_Information)) || (plugin_name[plugin_name_length - 1] != '\0')) { - GNUNET_break (0); + GNUNET_break(0); return GNUNET_SYSERR; } - if (ph->infocb == NULL) + + if (NULL != ph->addr_info_cb) { - return GNUNET_OK; - } + address.peer = pi->peer; + address.address = plugin_address; + address.address_length = plugin_address_length; + address.transport_name = plugin_name; - address.peer = pi->peer; - address.address = plugin_address; - address.address_length = plugin_address_length; - address.transport_name = plugin_name; - ph->infocb (ph->infocb_cls, &address, pi->bandwidth_out, pi->bandwidth_in, - atsi, ats_count); + ph->addr_info_cb (ph->addr_info_cb_cls, &address, addr_active, + pi->bandwidth_out, pi->bandwidth_in, atsi, ats_count); + } return GNUNET_OK; } - /** * We received a reservation result message. Validate and process it. * @@ -389,47 +394,46 @@ process_pi_message (struct GNUNET_ATS_PerformanceHandle *ph, */ static int process_rr_message (struct GNUNET_ATS_PerformanceHandle *ph, - const struct GNUNET_MessageHeader *msg) + const struct GNUNET_MessageHeader *msg) { const struct ReservationResultMessage *rr; struct GNUNET_ATS_ReservationContext *rc; int32_t amount; - if (ntohs (msg->size) < sizeof (struct ReservationResultMessage)) + if (ntohs (msg->size) < sizeof(struct ReservationResultMessage)) { - GNUNET_break (0); + GNUNET_break(0); return GNUNET_SYSERR; } rr = (const struct ReservationResultMessage *) msg; amount = ntohl (rr->amount); rc = ph->reservation_head; - if (0 != memcmp (&rr->peer, &rc->peer, sizeof (struct GNUNET_PeerIdentity))) + if (0 != memcmp (&rr->peer, &rc->peer, sizeof(struct GNUNET_PeerIdentity))) { - GNUNET_break (0); + GNUNET_break(0); return GNUNET_SYSERR; } - GNUNET_CONTAINER_DLL_remove (ph->reservation_head, ph->reservation_tail, rc); - if ((amount == 0) || (rc->rcb != NULL)) + GNUNET_CONTAINER_DLL_remove(ph->reservation_head, ph->reservation_tail, rc); + if ((amount == 0) || (rc->rcb != NULL )) { /* tell client if not cancelled */ - if (rc->rcb != NULL) + if (rc->rcb != NULL ) rc->rcb (rc->rcb_cls, &rr->peer, amount, - GNUNET_TIME_relative_ntoh (rr->res_delay)); - GNUNET_free (rc); + GNUNET_TIME_relative_ntoh (rr->res_delay)); + GNUNET_free(rc); return GNUNET_OK; } /* amount non-zero, but client cancelled, consider undo! */ if (GNUNET_YES != rc->undo) { - GNUNET_free (rc); - return GNUNET_OK; /* do not try to undo failed undos or negative amounts */ + GNUNET_free(rc); + return GNUNET_OK; /* do not try to undo failed undos or negative amounts */ } - GNUNET_free (rc); - (void) GNUNET_ATS_reserve_bandwidth (ph, &rr->peer, -amount, NULL, NULL); + GNUNET_free(rc); + (void) GNUNET_ATS_reserve_bandwidth (ph, &rr->peer, -amount, NULL, NULL ); return GNUNET_OK; } - /** * We received a reservation result message. Validate and process it. * @@ -439,7 +443,7 @@ process_rr_message (struct GNUNET_ATS_PerformanceHandle *ph, */ static int process_ar_message (struct GNUNET_ATS_PerformanceHandle *ph, - const struct GNUNET_MessageHeader *msg) + const struct GNUNET_MessageHeader *msg) { const struct PeerInformationMessage *pi; struct GNUNET_ATS_AddressListHandle *alh; @@ -456,13 +460,13 @@ process_ar_message (struct GNUNET_ATS_PerformanceHandle *ph, uint32_t active; uint32_t id; - if (ntohs (msg->size) < sizeof (struct PeerInformationMessage)) + if (ntohs (msg->size) < sizeof(struct PeerInformationMessage)) { - GNUNET_break (0); + GNUNET_break(0); return GNUNET_SYSERR; } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - _("Received %s message\n"), "ATS_ADDRESSLIST_RESPONSE"); + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, _("Received %s message\n"), + "ATS_ADDRESSLIST_RESPONSE"); pi = (const struct PeerInformationMessage *) msg; id = ntohl (pi->id); @@ -473,48 +477,47 @@ process_ar_message (struct GNUNET_ATS_PerformanceHandle *ph, atsi = (const struct GNUNET_ATS_Information *) &pi[1]; plugin_address = (const char *) &atsi[ats_count]; plugin_name = &plugin_address[plugin_address_length]; - if ((plugin_address_length + plugin_name_length + - ats_count * sizeof (struct GNUNET_ATS_Information) + - sizeof (struct PeerInformationMessage) != ntohs (msg->size)) || - (ats_count > - GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_ATS_Information)) + if ((plugin_address_length + plugin_name_length + + ats_count * sizeof(struct GNUNET_ATS_Information) + + sizeof(struct PeerInformationMessage) != ntohs (msg->size)) + || (ats_count + > GNUNET_SERVER_MAX_MESSAGE_SIZE + / sizeof(struct GNUNET_ATS_Information)) || (plugin_name[plugin_name_length - 1] != '\0')) { - GNUNET_break (0); + GNUNET_break(0); return GNUNET_SYSERR; } next = ph->addresslist_head; while (NULL != (alh = next)) { - next = alh->next; - if (alh->id == id) - break; + next = alh->next; + if (alh->id == id) + break; } if (NULL == alh) { - /* was canceled */ - return GNUNET_SYSERR; + /* was canceled */ + return GNUNET_SYSERR; } - memset (&allzeros, '\0', sizeof (allzeros)); - if ((0 == memcmp (&allzeros, &pi->peer, sizeof (allzeros))) && - (0 == plugin_name_length) && - (0 == plugin_address_length) && - (0 == ats_count)) + memset (&allzeros, '\0', sizeof(allzeros)); + if ((0 == memcmp (&allzeros, &pi->peer, sizeof(allzeros))) + && (0 == plugin_name_length) && (0 == plugin_address_length) + && (0 == ats_count)) { - /* Done */ - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - _("Received last message for %s \n"), "ATS_ADDRESSLIST_RESPONSE"); - bandwidth_zero.value__ = htonl (0); - if (NULL != alh->cb) - alh->cb (ph->infocb_cls, - NULL, - bandwidth_zero, bandwidth_zero, - NULL, 0); - GNUNET_CONTAINER_DLL_remove (ph->addresslist_head, ph->addresslist_tail, alh); - GNUNET_free (alh); - return GNUNET_OK; + /* Done */ + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, _("Received last message for %s \n"), + "ATS_ADDRESSLIST_RESPONSE"); + bandwidth_zero.value__ = htonl (0); + if (NULL != alh->cb) + alh->cb (ph->addr_info_cb_cls, NULL, GNUNET_NO, bandwidth_zero, + bandwidth_zero, NULL, 0); + GNUNET_CONTAINER_DLL_remove(ph->addresslist_head, ph->addresslist_tail, + alh); + GNUNET_free(alh); + return GNUNET_OK; } address.peer = pi->peer; @@ -525,15 +528,12 @@ process_ar_message (struct GNUNET_ATS_PerformanceHandle *ph, if ((GNUNET_YES == alh->all_addresses) || (GNUNET_YES == active)) { if (NULL != alh->cb) - alh->cb (ph->infocb_cls, - &address, - pi->bandwidth_out, pi->bandwidth_in, - atsi, ats_count); + alh->cb (ph->addr_info_cb_cls, &address, active, pi->bandwidth_out, + pi->bandwidth_in, atsi, ats_count); } return GNUNET_OK; } - /** * Type of a function to call when we receive a message * from the service. @@ -563,26 +563,23 @@ process_ats_message (void *cls, const struct GNUNET_MessageHeader *msg) goto reconnect; break; default: - GNUNET_break (0); + GNUNET_break(0); goto reconnect; } GNUNET_CLIENT_receive (ph->client, &process_ats_message, ph, - GNUNET_TIME_UNIT_FOREVER_REL); + GNUNET_TIME_UNIT_FOREVER_REL); return; -reconnect: - if (NULL != ph->th) + reconnect: if (NULL != ph->th) { GNUNET_CLIENT_notify_transmit_ready_cancel (ph->th); ph->th = NULL; } GNUNET_CLIENT_disconnect (ph->client); ph->client = NULL; - ph->task = - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, &reconnect_task, - ph); + ph->task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, + &reconnect_task, ph); } - /** * Re-establish the connection to the ATS service. * @@ -594,56 +591,52 @@ reconnect (struct GNUNET_ATS_PerformanceHandle *ph) struct PendingMessage *p; struct ClientStartMessage *init; - GNUNET_assert (NULL == ph->client); + GNUNET_assert(NULL == ph->client); ph->client = GNUNET_CLIENT_connect ("ats", ph->cfg); - GNUNET_assert (NULL != ph->client); + GNUNET_assert(NULL != ph->client); GNUNET_CLIENT_receive (ph->client, &process_ats_message, ph, - GNUNET_TIME_UNIT_FOREVER_REL); + GNUNET_TIME_UNIT_FOREVER_REL); if ((NULL == (p = ph->pending_head)) || (GNUNET_YES != p->is_init)) { p = GNUNET_malloc (sizeof (struct PendingMessage) + - sizeof (struct ClientStartMessage)); - p->size = sizeof (struct ClientStartMessage); + sizeof (struct ClientStartMessage)); + p->size = sizeof(struct ClientStartMessage); p->is_init = GNUNET_YES; init = (struct ClientStartMessage *) &p[1]; init->header.type = htons (GNUNET_MESSAGE_TYPE_ATS_START); - init->header.size = htons (sizeof (struct ClientStartMessage)); - init->start_flag = - htonl ((ph->infocb == - NULL) ? START_FLAG_PERFORMANCE_NO_PIC : - START_FLAG_PERFORMANCE_WITH_PIC); - GNUNET_CONTAINER_DLL_insert (ph->pending_head, ph->pending_tail, p); + init->header.size = htons (sizeof(struct ClientStartMessage)); + init->start_flag = htonl ( + (NULL == ph->addr_info_cb) ? + START_FLAG_PERFORMANCE_NO_PIC : START_FLAG_PERFORMANCE_WITH_PIC); + GNUNET_CONTAINER_DLL_insert(ph->pending_head, ph->pending_tail, p); } do_transmit (ph); } - - /** * Get handle to access performance API of the ATS subsystem. * * @param cfg configuration to use - * @param infocb function to call on allocation changes, can be NULL - * @param infocb_cls closure for infocb + * @param addr_info_cb callback called when performance characteristics for + * an address change + * @param addr_info_cb_cls closure for infocb * @return ats performance context */ struct GNUNET_ATS_PerformanceHandle * GNUNET_ATS_performance_init (const struct GNUNET_CONFIGURATION_Handle *cfg, - GNUNET_ATS_PeerInformationCallback infocb, - void *infocb_cls) + GNUNET_ATS_AddressInformationCallback addr_info_cb, void *addr_info_cb_cls) { struct GNUNET_ATS_PerformanceHandle *ph; - ph = GNUNET_malloc (sizeof (struct GNUNET_ATS_PerformanceHandle)); + ph = GNUNET_new (struct GNUNET_ATS_PerformanceHandle); ph->cfg = cfg; - ph->infocb = infocb; - ph->infocb_cls = infocb_cls; - ph->id = 0; + ph->addr_info_cb = addr_info_cb; + ph->addr_info_cb_cls = addr_info_cb_cls; + ph->id = 0; reconnect (ph); return ph; } - /** * Client is done using the ATS performance subsystem, release resources. * @@ -658,22 +651,22 @@ GNUNET_ATS_performance_done (struct GNUNET_ATS_PerformanceHandle *ph) while (NULL != (p = ph->pending_head)) { - GNUNET_CONTAINER_DLL_remove (ph->pending_head, ph->pending_tail, p); - GNUNET_free (p); + GNUNET_CONTAINER_DLL_remove(ph->pending_head, ph->pending_tail, p); + GNUNET_free(p); } while (NULL != (alh = ph->addresslist_head)) { - GNUNET_CONTAINER_DLL_remove (ph->addresslist_head, ph->addresslist_tail, - alh); - GNUNET_free (alh); + GNUNET_CONTAINER_DLL_remove(ph->addresslist_head, ph->addresslist_tail, + alh); + GNUNET_free(alh); } while (NULL != (rc = ph->reservation_head)) { - GNUNET_CONTAINER_DLL_remove (ph->reservation_head, ph->reservation_tail, - rc); - GNUNET_break (NULL == rc->rcb); - GNUNET_free (rc); + GNUNET_CONTAINER_DLL_remove(ph->reservation_head, ph->reservation_tail, rc); + GNUNET_break(NULL == rc->rcb); + GNUNET_free(rc); } + if (GNUNET_SCHEDULER_NO_TASK != ph->task) { GNUNET_SCHEDULER_cancel (ph->task); @@ -684,10 +677,9 @@ GNUNET_ATS_performance_done (struct GNUNET_ATS_PerformanceHandle *ph) GNUNET_CLIENT_disconnect (ph->client); ph->client = NULL; } - GNUNET_free (ph); + GNUNET_free(ph); } - /** * Reserve inbound bandwidth from the given peer. ATS will look at * the current amount of traffic we receive from the peer and ensure @@ -704,39 +696,36 @@ GNUNET_ATS_performance_done (struct GNUNET_ATS_PerformanceHandle *ph) */ struct GNUNET_ATS_ReservationContext * GNUNET_ATS_reserve_bandwidth (struct GNUNET_ATS_PerformanceHandle *ph, - const struct GNUNET_PeerIdentity *peer, - int32_t amount, - GNUNET_ATS_ReservationCallback rcb, void *rcb_cls) + const struct GNUNET_PeerIdentity *peer, int32_t amount, + GNUNET_ATS_ReservationCallback rcb, void *rcb_cls) { struct GNUNET_ATS_ReservationContext *rc; struct PendingMessage *p; struct ReservationRequestMessage *m; - rc = GNUNET_malloc (sizeof (struct GNUNET_ATS_ReservationContext)); + rc = GNUNET_new (struct GNUNET_ATS_ReservationContext); rc->size = amount; rc->peer = *peer; rc->rcb = rcb; rc->rcb_cls = rcb_cls; - if ((rcb != NULL) && (amount > 0)) - rc->undo = GNUNET_YES; - GNUNET_CONTAINER_DLL_insert_tail (ph->reservation_head, ph->reservation_tail, - rc); + if ((rcb != NULL )&& (amount > 0))rc->undo = GNUNET_YES; + GNUNET_CONTAINER_DLL_insert_tail(ph->reservation_head, ph->reservation_tail, + rc); p = GNUNET_malloc (sizeof (struct PendingMessage) + - sizeof (struct ReservationRequestMessage)); - p->size = sizeof (struct ReservationRequestMessage); + sizeof (struct ReservationRequestMessage)); + p->size = sizeof(struct ReservationRequestMessage); p->is_init = GNUNET_NO; m = (struct ReservationRequestMessage *) &p[1]; m->header.type = htons (GNUNET_MESSAGE_TYPE_ATS_RESERVATION_REQUEST); - m->header.size = htons (sizeof (struct ReservationRequestMessage)); + m->header.size = htons (sizeof(struct ReservationRequestMessage)); m->amount = htonl (amount); m->peer = *peer; - GNUNET_CONTAINER_DLL_insert_tail (ph->pending_head, ph->pending_tail, p); + GNUNET_CONTAINER_DLL_insert_tail(ph->pending_head, ph->pending_tail, p); do_transmit (ph); return rc; } - /** * Cancel request for reserving bandwidth. * @@ -761,23 +750,22 @@ GNUNET_ATS_reserve_bandwidth_cancel (struct GNUNET_ATS_ReservationContext *rc) * @return ats performance context */ struct GNUNET_ATS_AddressListHandle* -GNUNET_ATS_performance_list_addresses (struct GNUNET_ATS_PerformanceHandle *handle, - const struct GNUNET_PeerIdentity *peer, - int all, - GNUNET_ATS_PeerInformationCallback infocb, - void *infocb_cls) +GNUNET_ATS_performance_list_addresses ( + struct GNUNET_ATS_PerformanceHandle *handle, + const struct GNUNET_PeerIdentity *peer, int all, + GNUNET_ATS_AddressInformationCallback infocb, void *infocb_cls) { struct GNUNET_ATS_AddressListHandle *alh; struct PendingMessage *p; struct AddressListRequestMessage *m; - GNUNET_assert (NULL != handle); + GNUNET_assert(NULL != handle); if (NULL == infocb) - return NULL; + return NULL ; - alh = GNUNET_malloc (sizeof (struct GNUNET_ATS_AddressListHandle)); + alh = GNUNET_new (struct GNUNET_ATS_AddressListHandle); alh->id = handle->id; - handle->id ++; + handle->id++; alh->cb = infocb; alh->cb_cls = infocb_cls; alh->ph = handle; @@ -786,48 +774,65 @@ GNUNET_ATS_performance_list_addresses (struct GNUNET_ATS_PerformanceHandle *hand alh->all_peers = GNUNET_YES; else { - alh->all_peers = GNUNET_NO; - alh->peer = (*peer); + alh->all_peers = GNUNET_NO; + alh->peer = (*peer); } - GNUNET_CONTAINER_DLL_insert (handle->addresslist_head, handle->addresslist_tail, alh); + GNUNET_CONTAINER_DLL_insert(handle->addresslist_head, + handle->addresslist_tail, alh); p = GNUNET_malloc (sizeof (struct PendingMessage) + - sizeof (struct AddressListRequestMessage)); - p->size = sizeof (struct AddressListRequestMessage); + sizeof (struct AddressListRequestMessage)); + p->size = sizeof(struct AddressListRequestMessage); m = (struct AddressListRequestMessage *) &p[1]; m->header.type = htons (GNUNET_MESSAGE_TYPE_ATS_ADDRESSLIST_REQUEST); - m->header.size = htons (sizeof (struct AddressListRequestMessage)); + m->header.size = htons (sizeof(struct AddressListRequestMessage)); m->all = htonl (all); m->id = htonl (alh->id); if (NULL != peer) m->peer = *peer; else { - memset (&m->peer, '\0', sizeof (struct GNUNET_PeerIdentity)); + memset (&m->peer, '\0', sizeof(struct GNUNET_PeerIdentity)); } - GNUNET_CONTAINER_DLL_insert_tail (handle->pending_head, handle->pending_tail, p); + GNUNET_CONTAINER_DLL_insert_tail(handle->pending_head, handle->pending_tail, + p); do_transmit (handle); return alh; } - /** * Cancel a pending address listing operation * * @param handle the GNUNET_ATS_AddressListHandle handle to cancel */ void -GNUNET_ATS_performance_list_addresses_cancel (struct GNUNET_ATS_AddressListHandle *handle) +GNUNET_ATS_performance_list_addresses_cancel ( + struct GNUNET_ATS_AddressListHandle *handle) { - GNUNET_assert (NULL != handle); + GNUNET_assert(NULL != handle); - GNUNET_CONTAINER_DLL_remove (handle->ph->addresslist_head, handle->ph->addresslist_tail, handle); - GNUNET_free (handle); + GNUNET_CONTAINER_DLL_remove(handle->ph->addresslist_head, + handle->ph->addresslist_tail, handle); + GNUNET_free(handle); } +/** + * Convert a GNUNET_ATS_PreferenceType to a string + * + * @param type the preference type + * @return a string or NULL if invalid + */ +const char * +GNUNET_ATS_print_preference_type (uint32_t type) +{ + char *prefs[GNUNET_ATS_PreferenceCount] = GNUNET_ATS_PreferenceTypeString; + if (type < GNUNET_ATS_PreferenceCount) + return prefs[type]; + return NULL ; +} /** * Change preferences for the given peer. Preference changes are forgotten if peers @@ -838,8 +843,9 @@ GNUNET_ATS_performance_list_addresses_cancel (struct GNUNET_ATS_AddressListHandl * @param ... 0-terminated specification of the desired changes */ void -GNUNET_ATS_change_preference (struct GNUNET_ATS_PerformanceHandle *ph, - const struct GNUNET_PeerIdentity *peer, ...) +GNUNET_ATS_performance_change_preference ( + struct GNUNET_ATS_PerformanceHandle *ph, + const struct GNUNET_PeerIdentity *peer, ...) { struct PendingMessage *p; struct ChangePreferenceMessage *m; @@ -850,9 +856,9 @@ GNUNET_ATS_change_preference (struct GNUNET_ATS_PerformanceHandle *ph, enum GNUNET_ATS_PreferenceKind kind; count = 0; - va_start (ap, peer); - while (GNUNET_ATS_PREFERENCE_END != - (kind = va_arg (ap, enum GNUNET_ATS_PreferenceKind))) + va_start(ap, peer); + while (GNUNET_ATS_PREFERENCE_END != (kind = + va_arg (ap, enum GNUNET_ATS_PreferenceKind) )) { switch (kind) { @@ -867,13 +873,12 @@ GNUNET_ATS_change_preference (struct GNUNET_ATS_PerformanceHandle *ph, break; default: - GNUNET_assert (0); + GNUNET_assert(0); } } - va_end (ap); - msize = - count * sizeof (struct PreferenceInformation) + - sizeof (struct ChangePreferenceMessage); + va_end(ap); + msize = count * sizeof(struct PreferenceInformation) + + sizeof(struct ChangePreferenceMessage); p = GNUNET_malloc (sizeof (struct PendingMessage) + msize); p->size = msize; p->is_init = GNUNET_NO; @@ -884,9 +889,92 @@ GNUNET_ATS_change_preference (struct GNUNET_ATS_PerformanceHandle *ph, m->peer = *peer; pi = (struct PreferenceInformation *) &m[1]; count = 0; - va_start (ap, peer); - while (GNUNET_ATS_PREFERENCE_END != - (kind = va_arg (ap, enum GNUNET_ATS_PreferenceKind))) + va_start(ap, peer); + while (GNUNET_ATS_PREFERENCE_END != (kind = + va_arg (ap, enum GNUNET_ATS_PreferenceKind) )) + { + pi[count].preference_kind = htonl (kind); + switch (kind) + { + case GNUNET_ATS_PREFERENCE_BANDWIDTH: + pi[count].preference_value = (float) va_arg (ap, double); + + count++; + break; + case GNUNET_ATS_PREFERENCE_LATENCY: + pi[count].preference_value = (float) va_arg (ap, double); + + count++; + break; + default: + GNUNET_assert(0); + } + } + va_end(ap); + GNUNET_CONTAINER_DLL_insert_tail(ph->pending_head, ph->pending_tail, p); + do_transmit (ph); +} + +/** + * Send feedback to ATS on how good a the requirements for a peer and a + * preference is satisfied by ATS + * + * @param ph performance handle + * @param scope the time interval this valid for: [now - scope .. now] + * @param peer identifies the peer + * @param ... 0-terminated specification of the desired changes + */ +void +GNUNET_ATS_performance_give_feedback (struct GNUNET_ATS_PerformanceHandle *ph, + const struct GNUNET_PeerIdentity *peer, + const struct GNUNET_TIME_Relative scope, ...) +{ + struct PendingMessage *p; + struct FeedbackPreferenceMessage *m; + size_t msize; + uint32_t count; + struct PreferenceInformation *pi; + va_list ap; + enum GNUNET_ATS_PreferenceKind kind; + + count = 0; + va_start(ap, scope); + while (GNUNET_ATS_PREFERENCE_END != (kind = + va_arg (ap, enum GNUNET_ATS_PreferenceKind) )) + { + switch (kind) + { + case GNUNET_ATS_PREFERENCE_BANDWIDTH: + count++; + (void) va_arg (ap, double); + + break; + case GNUNET_ATS_PREFERENCE_LATENCY: + count++; + (void) va_arg (ap, double); + + break; + default: + GNUNET_assert(0); + } + } + va_end(ap); + msize = count * sizeof(struct PreferenceInformation) + + sizeof(struct FeedbackPreferenceMessage); + p = GNUNET_malloc (sizeof (struct PendingMessage) + msize); + p->size = msize; + p->is_init = GNUNET_NO; + m = (struct FeedbackPreferenceMessage *) &p[1]; + m->header.type = htons (GNUNET_MESSAGE_TYPE_ATS_PREFERENCE_FEEDBACK); + m->header.size = htons (msize); + m->scope = GNUNET_TIME_relative_hton (scope); + m->num_feedback = htonl (count); + m->peer = *peer; + pi = (struct PreferenceInformation *) &m[1]; + count = 0; + va_start(ap, scope); + while (GNUNET_ATS_PREFERENCE_END != (kind = + va_arg (ap, enum GNUNET_ATS_PreferenceKind) )) { pi[count].preference_kind = htonl (kind); switch (kind) @@ -902,11 +990,11 @@ GNUNET_ATS_change_preference (struct GNUNET_ATS_PerformanceHandle *ph, count++; break; default: - GNUNET_assert (0); + GNUNET_assert(0); } } - va_end (ap); - GNUNET_CONTAINER_DLL_insert_tail (ph->pending_head, ph->pending_tail, p); + va_end(ap); + GNUNET_CONTAINER_DLL_insert_tail(ph->pending_head, ph->pending_tail, p); do_transmit (ph); }