From 70f9bcf894b28799df078330d204860e7ea7bae8 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Fri, 14 Oct 2011 08:03:02 +0000 Subject: [PATCH] more ATS implementation: message parsing and generation: --- src/ats/gnunet-service-ats.c | 18 +- src/ats/gnunet-service-ats_addresses.c | 18 +- src/ats/gnunet-service-ats_addresses.h | 18 +- src/ats/gnunet-service-ats_performance.c | 5 +- src/ats/gnunet-service-ats_performance.h | 5 +- src/ats/gnunet-service-ats_scheduling.c | 212 ++++++++++++++++++++++- src/ats/gnunet-service-ats_scheduling.h | 82 ++++++++- 7 files changed, 333 insertions(+), 25 deletions(-) diff --git a/src/ats/gnunet-service-ats.c b/src/ats/gnunet-service-ats.c index 19a5d4380..91ffd9c9d 100644 --- a/src/ats/gnunet-service-ats.c +++ b/src/ats/gnunet-service-ats.c @@ -22,6 +22,7 @@ * @file ats/gnunet-service-ats.c * @brief ats service * @author Matthias Wachs + * @author Christian Grothoff */ #include "platform.h" #include "gnunet_util_lib.h" @@ -32,6 +33,13 @@ #include "ats.h" +/** + * We have received a 'ClientStartMessage' from a client. Find out which + * type of client it is and notify the respective subsystem. + * + * @param client handle to the client + * @param message the start message + */ static void handle_ats_start (void *cls, struct GNUNET_SERVER_Client *client, const struct GNUNET_MessageHeader *message) @@ -44,10 +52,10 @@ handle_ats_start (void *cls, struct GNUNET_SERVER_Client *client, switch (ntohl (msg->start_flag)) { case START_FLAG_SCHEDULING: - GAS_add_scheduling_client (client); + GAS_scheduling_add_client (client); break; case START_FLAG_PERFORMANCE_WITH_PIC: - GAS_add_performance_client (client); + GAS_performance_add_client (client); break; case START_FLAG_PERFORMANCE_NO_PIC: break; @@ -70,8 +78,8 @@ handle_ats_start (void *cls, struct GNUNET_SERVER_Client *client, static void client_disconnect_handler (void *cls, struct GNUNET_SERVER_Client *client) { - GAS_remove_scheduling_client (client); - GAS_remove_performance_client (client); + GAS_scheduling_remove_client (client); + GAS_performance_remove_client (client); } @@ -85,6 +93,7 @@ static void cleanup_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { GAS_addresses_done (); + GAS_scheduling_done (); } @@ -114,6 +123,7 @@ run (void *cls, struct GNUNET_SERVER_Handle *server, GNUNET_MESSAGE_TYPE_ATS_PREFERENCE_CHANGE, 0}, {NULL, NULL, 0, 0} }; + GAS_scheduling_init (server); GAS_addresses_init (); GNUNET_SERVER_disconnect_notify (server, &client_disconnect_handler, diff --git a/src/ats/gnunet-service-ats_addresses.c b/src/ats/gnunet-service-ats_addresses.c index 4f9f877a5..48a1b305d 100644 --- a/src/ats/gnunet-service-ats_addresses.c +++ b/src/ats/gnunet-service-ats_addresses.c @@ -22,6 +22,7 @@ * @file ats/gnunet-service-ats_addresses.c * @brief ats service address management * @author Matthias Wachs + * @author Christian Grothoff */ #include "platform.h" #include "gnunet-service-ats_addresses.h" @@ -82,10 +83,10 @@ free_address_it (void *cls, void -GAS_address_update (struct GNUNET_SERVER_Client *client, - const struct GNUNET_PeerIdentity *peer, +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_TRANSPORT_ATS_Information *atsi, uint32_t atsi_count) @@ -113,8 +114,11 @@ GAS_address_update (struct GNUNET_SERVER_Client *client, void -GAS_address_destroyed (struct GNUNET_SERVER_Client *client, - ...) +GAS_address_destroyed (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) { #if 0 // struct AddressDestroyedMessage * msg = (struct AddressDestroyedMessage *) message; @@ -127,6 +131,12 @@ GAS_address_destroyed (struct GNUNET_SERVER_Client *client, } +void +GAS_addresses_request_address (const struct GNUNET_PeerIdentity *peer) +{ +} + + /** */ void diff --git a/src/ats/gnunet-service-ats_addresses.h b/src/ats/gnunet-service-ats_addresses.h index 299619c6f..4e27b96d2 100644 --- a/src/ats/gnunet-service-ats_addresses.h +++ b/src/ats/gnunet-service-ats_addresses.h @@ -22,6 +22,7 @@ * @file ats/gnunet-service-ats_addresses.c * @brief ats service address management * @author Matthias Wachs + * @author Christian Grothoff */ #ifndef GNUNET_SERVICE_ATS_ADDRESSES_H #define GNUNET_SERVICE_ATS_ADDRESSES_H @@ -42,12 +43,25 @@ GAS_addresses_done (void); void -GAS_address_update (struct GNUNET_SERVER_Client *client, - const struct GNUNET_PeerIdentity *peer, +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_TRANSPORT_ATS_Information *atsi, uint32_t atsi_count); + +void +GAS_address_destroyed (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_addresses_request_address (const struct GNUNET_PeerIdentity *peer); + + #endif diff --git a/src/ats/gnunet-service-ats_performance.c b/src/ats/gnunet-service-ats_performance.c index edad22512..a0062ab7a 100644 --- a/src/ats/gnunet-service-ats_performance.c +++ b/src/ats/gnunet-service-ats_performance.c @@ -22,6 +22,7 @@ * @file ats/gnunet-service-ats_performance.c * @brief ats service, interaction with 'performance' API * @author Matthias Wachs + * @author Christian Grothoff */ #include "platform.h" #include "gnunet-service-ats_performance.h" @@ -63,7 +64,7 @@ find_client (struct GNUNET_SERVER_Client *client) void -GAS_add_performance_client (struct GNUNET_SERVER_Client *client) +GAS_performance_add_client (struct GNUNET_SERVER_Client *client) { struct PerformanceClient * pc; @@ -75,7 +76,7 @@ GAS_add_performance_client (struct GNUNET_SERVER_Client *client) void -GAS_remove_performance_client (struct GNUNET_SERVER_Client *client) +GAS_performance_remove_client (struct GNUNET_SERVER_Client *client) { struct PerformanceClient * pc; diff --git a/src/ats/gnunet-service-ats_performance.h b/src/ats/gnunet-service-ats_performance.h index 45bc39c35..cb6677f5b 100644 --- a/src/ats/gnunet-service-ats_performance.h +++ b/src/ats/gnunet-service-ats_performance.h @@ -22,6 +22,7 @@ * @file ats/gnunet-service-ats_performance.h * @brief ats service, interaction with 'performance' API * @author Matthias Wachs + * @author Christian Grothoff */ #ifndef GNUNET_SERVICE_ATS_PERFORMANCE_H #define GNUNET_SERVICE_ATS_PERFORMANCE_H @@ -29,11 +30,11 @@ #include "gnunet_util_lib.h" void -GAS_add_performance_client (struct GNUNET_SERVER_Client *client); +GAS_performance_add_client (struct GNUNET_SERVER_Client *client); void -GAS_remove_performance_client (struct GNUNET_SERVER_Client *client); +GAS_performance_remove_client (struct GNUNET_SERVER_Client *client); void diff --git a/src/ats/gnunet-service-ats_scheduling.c b/src/ats/gnunet-service-ats_scheduling.c index 60305bac9..9a16269d9 100644 --- a/src/ats/gnunet-service-ats_scheduling.c +++ b/src/ats/gnunet-service-ats_scheduling.c @@ -22,6 +22,7 @@ * @file ats/gnunet-service-ats_scheduling.c * @brief ats service, interaction with 'scheduling' API * @author Matthias Wachs + * @author Christian Grothoff */ #include "platform.h" #include "gnunet-service-ats_addresses.h" @@ -29,12 +30,29 @@ #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; }; @@ -50,7 +68,19 @@ static struct SchedulingClient *sc_head; */ 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 + */ static struct SchedulingClient * find_client (struct GNUNET_SERVER_Client *client) { @@ -63,21 +93,33 @@ find_client (struct GNUNET_SERVER_Client *client) } +/** + * Register a new scheduling client. + * + * @param client handle of the new client + */ void -GAS_add_scheduling_client (struct GNUNET_SERVER_Client *client) +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; + GNUNET_SERVER_notification_context_add (nc, client); GNUNET_SERVER_client_keep (client); GNUNET_CONTAINER_DLL_insert(sc_head, sc_tail, sc); } +/** + * Unregister a client (which may have been a scheduling client, + * but this is not assured). + * + * @param client handle of the (now dead) client + */ void -GAS_remove_scheduling_client (struct GNUNET_SERVER_Client *client) +GAS_scheduling_remove_client (struct GNUNET_SERVER_Client *client) { struct SchedulingClient * sc; @@ -90,17 +132,100 @@ GAS_remove_scheduling_client (struct GNUNET_SERVER_Client *client) } +/** + * Transmit the given address suggestion and bandwidth update to all scheduling + * clients. + * + * @param peer peer for which this is an address suggestion + * @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' + * @param bandwidth_out assigned outbound bandwidth + * @param bandwidth_in assigned inbound bandwidth + */ +void +GAS_scheduling_transmit_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_TRANSPORT_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_TRANSPORT_ATS_Information) + + plugin_addr_len + plugin_name_length; + char buf[msize]; + struct GNUNET_TRANSPORT_ATS_Information *atsp; + char *addrp; + + GNUNET_assert (msize < GNUNET_SERVER_MAX_MESSAGE_SIZE); + GNUNET_assert (atsi_count < GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_TRANSPORT_ATS_Information)); + msg = (struct AddressSuggestionMessage*) buf; + msg->header.size = htons (msize); + msg->header.type = htons (GNUNET_MESSAGE_TYPE_ATS_ADDRESS_SUGGESTION); + msg->ats_count = htonl (atsi_count); + 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->bandwidth_out = bandwidth_out; + msg->bandwidth_in = bandwidth_in; + atsp = (struct GNUNET_TRANSPORT_ATS_Information* ) &msg[1]; + memcpy (atsp, atsi, sizeof (struct GNUNET_TRANSPORT_ATS_Information) * atsi_count); + 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); + } +} + + +/** + * Handle 'request address' messages from clients. + * + * @param cls unused, NULL + * @param client client that sent the request + * @param message the request message + */ void GAS_handle_request_address (void *cls, struct GNUNET_SERVER_Client *client, - const struct GNUNET_MessageHeader *message) + const struct GNUNET_MessageHeader *message) { - // struct RequestAddressMessage * msg = (struct RequestAddressMessage *) message; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' message\n", "REQUEST_ADDRESS"); + const struct RequestAddressMessage * msg = (const struct RequestAddressMessage *) message; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' message\n", "REQUEST_ADDRESS"); + GNUNET_break (0 == ntohl (msg->reserved)); + GAS_addresses_request_address (&msg->peer); + GNUNET_SERVER_receive_done (client, GNUNET_OK); } +/** + * Handle 'address update' messages from clients. + * + * @param cls unused, NULL + * @param client client that sent the request + * @param message the request message + */ void GAS_handle_address_update (void *cls, struct GNUNET_SERVER_Client *client, const struct GNUNET_MessageHeader *message) @@ -143,11 +268,11 @@ GAS_handle_address_update (void *cls, struct GNUNET_SERVER_Client *client, GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); return; } - GAS_address_update (client, - &m->peer, + GAS_address_update (&m->peer, plugin_name, address, address_length, + client, ntohl (m->session_id), atsi, ats_count); @@ -155,12 +280,81 @@ GAS_handle_address_update (void *cls, struct GNUNET_SERVER_Client *client, } +/** + * Handle 'address destroyed' messages from clients. + * + * @param cls unused, NULL + * @param client client that sent the request + * @param message the request message + */ void GAS_handle_address_destroyed (void *cls, struct GNUNET_SERVER_Client *client, - const struct GNUNET_MessageHeader *message) + const struct GNUNET_MessageHeader *message) + +{ + const struct AddressDestroyedMessage * m; + const char *address; + const char *plugin_name; + uint16_t address_length; + uint16_t plugin_name_length; + uint16_t size; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Received `%s' message\n", + "ADDRESS_DESTROYED"); + size = ntohs (message->size); + if (size <= sizeof (struct AddressDestroyedMessage)) + { + GNUNET_break (0); + GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); + return; + } + m = (const struct AddressDestroyedMessage*) message; + GNUNET_break (0 == ntohl (m->reserved)); + address_length = ntohs (m->address_length); + plugin_name_length = ntohs (m->plugin_name_length); + address = (const char*) &m[1]; + plugin_name = &address[address_length]; + if ( (address_length + + plugin_name_length + + sizeof (struct AddressSuggestionMessage) != ntohs (message->size)) || + (plugin_name[plugin_name_length - 1] != '\0') ) + { + GNUNET_break (0); + GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); + return; + } + GAS_address_destroyed (&m->peer, + plugin_name, + address, + address_length, + client, + ntohl (m->session_id)); + GNUNET_SERVER_receive_done (client, GNUNET_OK); +} + + +/** + * Initialize scheduling subsystem. + * + * @param server handle to our server + */ +void +GAS_scheduling_init (struct GNUNET_SERVER_Handle *server) +{ + nc = GNUNET_SERVER_notification_context_create (server, 128); +} + +/** + * Shutdown scheduling subsystem. + */ +void +GAS_scheduling_done () { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' message\n", "ADDRESS_DESTROYED"); + GNUNET_SERVER_notification_context_destroy (nc); + nc = NULL; } + /* end of gnunet-service-ats_scheduling.c */ diff --git a/src/ats/gnunet-service-ats_scheduling.h b/src/ats/gnunet-service-ats_scheduling.h index 5c8f77ed8..d2506de6a 100644 --- a/src/ats/gnunet-service-ats_scheduling.h +++ b/src/ats/gnunet-service-ats_scheduling.h @@ -22,34 +22,112 @@ * @file ats/gnunet-service-ats_scheduling.h * @brief ats service, interaction with 'scheduling' API * @author Matthias Wachs + * @author Christian Grothoff */ #ifndef GNUNET_SERVICE_ATS_SCHEDULING_H #define GNUNET_SERVICE_ATS_SCHEDULING_H #include "gnunet_util_lib.h" + +/** + * Register a new scheduling client. + * + * @param client handle of the new client + */ +void +GAS_scheduling_add_client (struct GNUNET_SERVER_Client *client); + + +/** + * Unregister a client (which may have been a scheduling client, + * but this is not assured). + * + * @param client handle of the (now dead) client + */ void -GAS_add_scheduling_client (struct GNUNET_SERVER_Client *client); +GAS_scheduling_remove_client (struct GNUNET_SERVER_Client *client); +/** + * Transmit the given address suggestion and bandwidth update to all scheduling + * clients. + * + * @param peer peer for which this is an address suggestion + * @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' + * @param bandwidth_out assigned outbound bandwidth + * @param bandwidth_in assigned inbound bandwidth + */ void -GAS_remove_scheduling_client (struct GNUNET_SERVER_Client *client); +GAS_scheduling_transmit_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_TRANSPORT_ATS_Information *atsi, + uint32_t atsi_count, + struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out, + struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in); +/** + * Handle 'request address' messages from clients. + * + * @param cls unused, NULL + * @param client client that sent the request + * @param message the request message + */ void GAS_handle_request_address (void *cls, struct GNUNET_SERVER_Client *client, const struct GNUNET_MessageHeader *message); + +/** + * Handle 'address update' messages from clients. + * + * @param cls unused, NULL + * @param client client that sent the request + * @param message the request message + */ void GAS_handle_address_update (void *cls, struct GNUNET_SERVER_Client *client, const struct GNUNET_MessageHeader *message); +/** + * Handle 'address destroyed' messages from clients. + * + * @param cls unused, NULL + * @param client client that sent the request + * @param message the request message + */ void GAS_handle_address_destroyed (void *cls, struct GNUNET_SERVER_Client *client, const struct GNUNET_MessageHeader *message); +/** + * Initialize scheduling subsystem. + * + * @param server handle to our server + */ +void +GAS_scheduling_init (struct GNUNET_SERVER_Handle *server); + + +/** + * Shutdown scheduling subsystem. + */ +void +GAS_scheduling_done (void); + + #endif /* end of gnunet-service-ats_scheduling.h */ -- 2.25.1