From: Christian Grothoff Date: Mon, 17 Oct 2011 08:13:49 +0000 (+0000) Subject: restrict to 1 scheduling client X-Git-Tag: initial-import-from-subversion-38251~16490 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=c0d32e08cddf59b933cecd744c6cd582ec566694;p=oweals%2Fgnunet.git restrict to 1 scheduling client --- diff --git a/src/ats/gnunet-service-ats.c b/src/ats/gnunet-service-ats.c index a2c0e8c73..3babc0988 100644 --- a/src/ats/gnunet-service-ats.c +++ b/src/ats/gnunet-service-ats.c @@ -55,7 +55,11 @@ handle_ats_start (void *cls, struct GNUNET_SERVER_Client *client, switch (flag) { case START_FLAG_SCHEDULING: - GAS_scheduling_add_client (client); + if (GNUNET_OK != GAS_scheduling_add_client (client)) + { + GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); + return; + } break; case START_FLAG_PERFORMANCE_WITH_PIC: GAS_performance_add_client (client, flag); diff --git a/src/ats/gnunet-service-ats_addresses.c b/src/ats/gnunet-service-ats_addresses.c index 2bcb9913a..68d4b03de 100644 --- a/src/ats/gnunet-service-ats_addresses.c +++ b/src/ats/gnunet-service-ats_addresses.c @@ -36,8 +36,6 @@ struct ATS_Address size_t addr_len; - struct GNUNET_SERVER_Client *session_client; - uint32_t session_id; uint32_t ats_count; @@ -48,6 +46,24 @@ struct ATS_Address struct GNUNET_ATS_Information * ats; + struct GNUNET_BANDWIDTH_Value32NBO atsp_utilization_in; + + struct GNUNET_BANDWIDTH_Value32NBO atsp_utilization_out; + + struct GNUNET_TIME_Relative atsp_latency; + + uint32_t atsp_distance; + + uint32_t atsp_cost_wan; + + uint32_t atsp_cost_lan; + + uint32_t atsp_cost_wlan; + + struct GNUNET_BANDWIDTH_Value32NBO assigned_bw_in; + + struct GNUNET_BANDWIDTH_Value32NBO assigned_bw_out; + struct GNUNET_BANDWIDTH_Value32NBO bw_in; struct GNUNET_BANDWIDTH_Value32NBO bw_out; @@ -98,8 +114,7 @@ compare_address_it (void *cls, struct ATS_Address * aa = (struct ATS_Address *) value; /* compare sessions */ - if ((aa->session_client != cac->search->session_client) || - (aa->session_id != cac->search->session_id)) + if (aa->session_id != cac->search->session_id) return GNUNET_YES; if (aa->addr_len != cac->search->addr_len) @@ -139,13 +154,12 @@ find_address (const struct GNUNET_PeerIdentity *peer, void -GAS_address_update (const struct GNUNET_PeerIdentity *peer, - const char *plugin_name, - const void *plugin_addr, size_t plugin_addr_len, - struct GNUNET_SERVER_Client *session_client, - uint32_t session_id, - const struct GNUNET_ATS_Information *atsi, - uint32_t atsi_count) +GAS_addresses_update (const struct GNUNET_PeerIdentity *peer, + const char *plugin_name, + const void *plugin_addr, size_t plugin_addr_len, + uint32_t session_id, + const struct GNUNET_ATS_Information *atsi, + uint32_t atsi_count) { struct ATS_Address * aa; struct ATS_Address * old; @@ -159,7 +173,6 @@ GAS_address_update (const struct GNUNET_PeerIdentity *peer, aa->addr = &aa[1]; memcpy (&aa[1], plugin_addr, plugin_addr_len); aa->plugin = GNUNET_strdup (plugin_name); - aa->session_client = session_client; aa->session_id = session_id; old = find_address (peer, aa); if (old == NULL) @@ -187,34 +200,10 @@ GAS_address_update (const struct GNUNET_PeerIdentity *peer, } -static int -remove_address_by_client (void *cls, - const GNUNET_HashCode * key, - void *value) -{ - struct GNUNET_SERVER_Client *client = cls; - struct ATS_Address * aa = value; - - if (aa->session_client == client) - destroy_address (aa); - return GNUNET_OK; -} - - -void -GAS_address_client_disconnected (struct GNUNET_SERVER_Client *client) -{ - if (addresses != NULL) - GNUNET_CONTAINER_multihashmap_iterate(addresses, - &remove_address_by_client, client); -} - - void -GAS_address_destroyed (const struct GNUNET_PeerIdentity *peer, +GAS_addresses_destroy (const struct GNUNET_PeerIdentity *peer, const char *plugin_name, const void *plugin_addr, size_t plugin_addr_len, - struct GNUNET_SERVER_Client *session_client, uint32_t session_id) { @@ -225,7 +214,6 @@ GAS_address_destroyed (const struct GNUNET_PeerIdentity *peer, aa.addr_len = plugin_addr_len; aa.addr = plugin_addr; aa.plugin = (char*) plugin_name; - aa.session_client = session_client; aa.session_id = session_id; res = find_address (peer, &aa); @@ -269,7 +257,7 @@ GAS_addresses_request_address (const struct GNUNET_PeerIdentity *peer) aa->bw_in); GAS_scheduling_transmit_address_suggestion (peer, aa->plugin, aa->addr, aa->addr_len, - aa->session_client, aa->session_id, + aa->session_id, aa->ats, aa->ats_count, aa->bw_out, aa->bw_in); GAS_performance_notify_clients (peer, aa->plugin, @@ -332,13 +320,22 @@ free_address_it (void *cls, } +void +GAS_addresses_destroy_all () +{ + if (addresses != NULL) + GNUNET_CONTAINER_multihashmap_iterate(addresses, + &free_address_it, NULL); +} + + /** * Shutdown address subsystem. */ void GAS_addresses_done () { - GNUNET_CONTAINER_multihashmap_iterate (addresses, &free_address_it, NULL); + GAS_addresses_destroy_all (); GNUNET_CONTAINER_multihashmap_destroy (addresses); addresses = NULL; } diff --git a/src/ats/gnunet-service-ats_addresses.h b/src/ats/gnunet-service-ats_addresses.h index 335876720..1d218ba57 100644 --- a/src/ats/gnunet-service-ats_addresses.h +++ b/src/ats/gnunet-service-ats_addresses.h @@ -47,24 +47,24 @@ GAS_addresses_done (void); void -GAS_address_update (const struct GNUNET_PeerIdentity *peer, - const char *plugin_name, - const void *plugin_addr, size_t plugin_addr_len, - struct GNUNET_SERVER_Client *session_client, - uint32_t session_id, - const struct GNUNET_ATS_Information *atsi, - uint32_t atsi_count); +GAS_addresses_update (const struct GNUNET_PeerIdentity *peer, + const char *plugin_name, + const void *plugin_addr, size_t plugin_addr_len, + uint32_t session_id, + const struct GNUNET_ATS_Information *atsi, + uint32_t atsi_count); void -GAS_address_destroyed (const struct GNUNET_PeerIdentity *peer, +GAS_addresses_destroy (const struct GNUNET_PeerIdentity *peer, const char *plugin_name, const void *plugin_addr, size_t plugin_addr_len, - struct GNUNET_SERVER_Client *session_client, uint32_t session_id); + void -GAS_address_client_disconnected (struct GNUNET_SERVER_Client *session_client); +GAS_addresses_destroy_all (void); + // FIXME: this function should likely end up in the LP-subsystem and // not with 'addresses' in the future... diff --git a/src/ats/gnunet-service-ats_scheduling.c b/src/ats/gnunet-service-ats_scheduling.c index 825f00085..3d53c1e42 100644 --- a/src/ats/gnunet-service-ats_scheduling.c +++ b/src/ats/gnunet-service-ats_scheduling.c @@ -30,89 +30,39 @@ #include "ats.h" -/** - * We keep clients that are interested in scheduling in a linked list. - * This list typically has only one entry (for the - * gnunet-service-transport process); however, it is possible that - * there is more than one (at least briefly) because after a crash a - * new one may connect before we've been notified to clean up the old - * process. - */ -struct SchedulingClient -{ - /** - * Next in doubly-linked list. - */ - struct SchedulingClient * next; - - /** - * Previous in doubly-linked list. - */ - struct SchedulingClient * prev; - - /** - * Actual handle to the client. - */ - struct GNUNET_SERVER_Client *client; - -}; - - -/** - * Head of linked list of all clients to this service. - */ -static struct SchedulingClient *sc_head; - -/** - * Tail of linked list of all clients to this service. - */ -static struct SchedulingClient *sc_tail; - /** * Context for sending messages to clients. */ static struct GNUNET_SERVER_NotificationContext *nc; - /** - * Find the scheduling client associated with the given - * handle. - * - * @param client server handle - * @return internal handle + * Actual handle to the client. */ -static struct SchedulingClient * -find_client (struct GNUNET_SERVER_Client *client) -{ - struct SchedulingClient * sc; - - for (sc = sc_head; sc != NULL; sc = sc->next) - if (sc->client == client) - return sc; - return NULL; -} +static struct GNUNET_SERVER_Client *my_client; /** * Register a new scheduling client. * * @param client handle of the new client + * @return GNUNET_OK on success, GNUNET_SYSERR on error */ -void +int GAS_scheduling_add_client (struct GNUNET_SERVER_Client *client) { - struct SchedulingClient *sc; - - GNUNET_break (NULL == find_client (client)); - sc = GNUNET_malloc (sizeof (struct SchedulingClient)); - sc->client = client; + if (my_client != NULL) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "This ATS already has a scheduling client, refusing new scheduling client for now.\n"); + return GNUNET_SYSERR; + } + my_client = client; GNUNET_SERVER_notification_context_add (nc, client); GNUNET_SERVER_client_keep (client); - GNUNET_CONTAINER_DLL_insert(sc_head, sc_tail, sc); + return GNUNET_OK; } - /** * Unregister a client (which may have been a scheduling client, * but this is not assured). @@ -122,15 +72,11 @@ GAS_scheduling_add_client (struct GNUNET_SERVER_Client *client) void GAS_scheduling_remove_client (struct GNUNET_SERVER_Client *client) { - struct SchedulingClient * sc; - - sc = find_client (client); - if (NULL == sc) + if (my_client != client) return; - GNUNET_CONTAINER_DLL_remove (sc_head, sc_tail, sc); - GAS_address_client_disconnected (client); + GAS_addresses_destroy_all (); GNUNET_SERVER_client_drop (client); - GNUNET_free (sc); + my_client = NULL; } @@ -142,7 +88,6 @@ GAS_scheduling_remove_client (struct GNUNET_SERVER_Client *client) * @param plugin_name 0-termintated string specifying the transport plugin * @param plugin_addr binary address for the plugin to use * @param plugin_addr_len number of bytes in plugin_addr - * @param session_client which client gave us this session_id? * @param session_id session ID to use for the given client (other clients will see 0) * @param atsi performance data for the address * @param atsi_count number of performance records in 'ats' @@ -153,14 +98,12 @@ void GAS_scheduling_transmit_address_suggestion (const struct GNUNET_PeerIdentity *peer, const char *plugin_name, const void *plugin_addr, size_t plugin_addr_len, - struct GNUNET_SERVER_Client *session_client, uint32_t session_id, const struct GNUNET_ATS_Information *atsi, uint32_t atsi_count, struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out, struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in) { - struct SchedulingClient *sc; struct AddressSuggestionMessage *msg; size_t plugin_name_length = strlen (plugin_name) + 1; size_t msize = sizeof (struct AddressSuggestionMessage) + atsi_count * sizeof (struct GNUNET_ATS_Information) @@ -169,6 +112,8 @@ GAS_scheduling_transmit_address_suggestion (const struct GNUNET_PeerIdentity *pe struct GNUNET_ATS_Information *atsp; char *addrp; + if (my_client == NULL) + return; GNUNET_assert (msize < GNUNET_SERVER_MAX_MESSAGE_SIZE); GNUNET_assert (atsi_count < GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_ATS_Information)); msg = (struct AddressSuggestionMessage*) buf; @@ -178,7 +123,7 @@ GAS_scheduling_transmit_address_suggestion (const struct GNUNET_PeerIdentity *pe msg->peer = *peer; msg->address_length = htons (plugin_addr_len); msg->plugin_name_length = htons (plugin_name_length); - /* session ID is set only if 'client' is the same... */ + msg->session_id = htonl (session_id); msg->bandwidth_out = bandwidth_out; msg->bandwidth_in = bandwidth_in; atsp = (struct GNUNET_ATS_Information* ) &msg[1]; @@ -186,17 +131,10 @@ GAS_scheduling_transmit_address_suggestion (const struct GNUNET_PeerIdentity *pe addrp = (char*) &atsp[atsi_count]; memcpy (addrp, plugin_addr, plugin_addr_len); strcpy (&addrp[plugin_addr_len], plugin_name); - for (sc = sc_head; sc != NULL; sc = sc->next) - { - if (sc->client == session_client) - msg->session_id = htonl (session_id); - else - msg->session_id = htonl (0); - GNUNET_SERVER_notification_context_unicast (nc, - sc->client, - &msg->header, - GNUNET_YES); - } + GNUNET_SERVER_notification_context_unicast (nc, + my_client, + &msg->header, + GNUNET_YES); } @@ -230,8 +168,7 @@ GAS_handle_request_address (void *cls, struct GNUNET_SERVER_Client *client, */ void GAS_handle_address_update (void *cls, struct GNUNET_SERVER_Client *client, - const struct GNUNET_MessageHeader *message) - + const struct GNUNET_MessageHeader *message) { const struct AddressUpdateMessage * m; const struct GNUNET_ATS_Information *atsi; @@ -273,14 +210,13 @@ GAS_handle_address_update (void *cls, struct GNUNET_SERVER_Client *client, GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); return; } - GAS_address_update (&m->peer, - plugin_name, - address, - address_length, - client, - ntohl (m->session_id), - atsi, - ats_count); + GAS_addresses_update (&m->peer, + plugin_name, + address, + address_length, + ntohl (m->session_id), + atsi, + ats_count); GNUNET_SERVER_receive_done (client, GNUNET_OK); } @@ -308,7 +244,8 @@ GAS_handle_address_destroyed (void *cls, struct GNUNET_SERVER_Client *client, "Received `%s' message of size %u %u\n", "ADDRESS_DESTROYED", ntohs (message->size), sizeof (struct AddressDestroyedMessage)); size = ntohs (message->size); - if (size < sizeof (struct AddressDestroyedMessage)) + if ( (size < sizeof (struct AddressDestroyedMessage)) || + (client != my_client) ) { GNUNET_break (0); GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); @@ -323,7 +260,6 @@ GAS_handle_address_destroyed (void *cls, struct GNUNET_SERVER_Client *client, plugin_name = &address[address_length]; else plugin_name = ""; - if ( (address_length + plugin_name_length + sizeof (struct AddressDestroyedMessage) != ntohs (message->size))) @@ -331,21 +267,18 @@ GAS_handle_address_destroyed (void *cls, struct GNUNET_SERVER_Client *client, GNUNET_break (0); GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); return; + } + if ( (plugin_name_length != 0) && + (plugin_name[plugin_name_length - 1] != '\0') ) + { + GNUNET_break (0); + GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); + return; } - - if (plugin_name_length != 0) - if (plugin_name[plugin_name_length - 1] != '\0') - { - GNUNET_break (0); - GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); - return; - } - - GAS_address_destroyed (&m->peer, + GAS_addresses_destroy (&m->peer, plugin_name, address, address_length, - client, ntohl (m->session_id)); GNUNET_SERVER_receive_done (client, GNUNET_OK); } diff --git a/src/ats/gnunet-service-ats_scheduling.h b/src/ats/gnunet-service-ats_scheduling.h index 15eed7f85..9e188fe8f 100644 --- a/src/ats/gnunet-service-ats_scheduling.h +++ b/src/ats/gnunet-service-ats_scheduling.h @@ -34,8 +34,9 @@ * Register a new scheduling client. * * @param client handle of the new client + * @return GNUNET_OK on success, GNUNET_SYSERR on error */ -void +int GAS_scheduling_add_client (struct GNUNET_SERVER_Client *client); @@ -57,8 +58,7 @@ GAS_scheduling_remove_client (struct GNUNET_SERVER_Client *client); * @param plugin_name 0-termintated string specifying the transport plugin * @param plugin_addr binary address for the plugin to use * @param plugin_addr_len number of bytes in plugin_addr - * @param session_client which client gave us this session_id? - * @param session_id session ID to use for the given client (other clients will see 0) + * @param session_id session ID to use * @param atsi performance data for the address * @param atsi_count number of performance records in 'ats' * @param bandwidth_out assigned outbound bandwidth @@ -68,7 +68,6 @@ void GAS_scheduling_transmit_address_suggestion (const struct GNUNET_PeerIdentity *peer, const char *plugin_name, const void *plugin_addr, size_t plugin_addr_len, - struct GNUNET_SERVER_Client *session_client, uint32_t session_id, const struct GNUNET_ATS_Information *atsi, uint32_t atsi_count,