From c18fcd88d8897d0645900a1b6f527232d0153f88 Mon Sep 17 00:00:00 2001 From: Matthias Wachs Date: Thu, 14 Jun 2012 12:50:27 +0000 Subject: [PATCH] - adding GNUNET_ATS_address_add functionality .. no changes to scheduling API yet --- src/ats/Makefile.am | 8 + src/ats/ats_api_scheduling.c | 115 ++++++++- src/ats/gnunet-service-ats.c | 2 + src/ats/gnunet-service-ats_addresses.c | 71 +++++- src/ats/gnunet-service-ats_addresses.h | 6 + src/ats/gnunet-service-ats_scheduling.c | 58 +++++ src/ats/gnunet-service-ats_scheduling.h | 12 + src/ats/test_ats_api_scheduling_add_address.c | 226 ++++++++++++++++++ src/include/gnunet_ats_service.h | 17 ++ src/include/gnunet_protocols.h | 5 + 10 files changed, 517 insertions(+), 3 deletions(-) create mode 100644 src/ats/test_ats_api_scheduling_add_address.c diff --git a/src/ats/Makefile.am b/src/ats/Makefile.am index bf0d1c2db..5b1c6b2e4 100644 --- a/src/ats/Makefile.am +++ b/src/ats/Makefile.am @@ -56,6 +56,7 @@ gnunet_service_ats_LDADD = \ check_PROGRAMS = \ test_ats_api_scheduling \ test_ats_api_reset_backoff \ + test_ats_api_scheduling_add_address \ $(GN_MLP_TEST) \ $(GN_MLP_TEST_AVG) \ $(GN_MLP_PERF) @@ -104,6 +105,13 @@ test_ats_api_reset_backoff_LDADD = \ $(top_builddir)/src/util/libgnunetutil.la \ $(top_builddir)/src/ats/libgnunetats.la +test_ats_api_scheduling_add_address_SOURCES = \ + test_ats_api_scheduling_add_address.c +test_ats_api_scheduling_add_address_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/ats/libgnunetats.la + + #test_ats_api_scheduling_get_type_SOURCES = \ # test_ats_api_scheduling_get_type.c #test_ats_api_scheduling_get_type_LDADD = \ diff --git a/src/ats/ats_api_scheduling.c b/src/ats/ats_api_scheduling.c index 0e67a8628..cdf948291 100644 --- a/src/ats/ats_api_scheduling.c +++ b/src/ats/ats_api_scheduling.c @@ -1048,6 +1048,101 @@ GNUNET_ATS_suggest_address_cancel (struct GNUNET_ATS_SchedulingHandle *sh, } +/** + * 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 destroyed + * + * @param sh handle + * @param address the address + * @param session session handle (if available) + * @param ats performance data for the address + * @param ats_count number of performance records in 'ats' + * @return GNUNET_OK on success, GNUNET_SYSERR on error + */ +int +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 PendingMessage *p; + struct AddressUpdateMessage *m; + struct GNUNET_ATS_Information *am; + char *pm; + size_t namelen; + size_t msize; + uint32_t s = 0; + + if (address == NULL) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + if ((address == NULL) && (session == NULL)) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + + namelen = + (address->transport_name == + NULL) ? 0 : strlen (address->transport_name) + 1; + msize = + sizeof (struct AddressUpdateMessage) + address->address_length + + ats_count * sizeof (struct GNUNET_ATS_Information) + namelen; + if ((msize >= 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 (0); + return GNUNET_SYSERR; + } + + p = GNUNET_malloc (sizeof (struct PendingMessage) + msize); + p->size = msize; + p->is_init = GNUNET_NO; + m = (struct AddressUpdateMessage *) &p[1]; + m->header.type = htons (GNUNET_MESSAGE_TYPE_ATS_ADDRESS_ADD); + m->header.size = htons (msize); + m->ats_count = htonl (ats_count); + m->peer = address->peer; + m->address_length = htons (address->address_length); + m->plugin_name_length = htons (namelen); + if (NULL != session) + { + s = find_session_id (sh, session, &address->peer); + if (NOT_FOUND != s) + { + /* Already existing */ + GNUNET_break (0); + return GNUNET_SYSERR; + } + s = find_empty_session_slot (sh, session, &address->peer); + GNUNET_break (NOT_FOUND != s); + } + m->session_id = htonl (s); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Adding address for peer `%s', plugin `%s', session %p id %u\n", + GNUNET_i2s (&address->peer), + address->transport_name, session, s); + + am = (struct GNUNET_ATS_Information *) &m[1]; + memcpy (am, ats, ats_count * sizeof (struct GNUNET_ATS_Information)); + pm = (char *) &am[ats_count]; + memcpy (pm, address->address, address->address_length); + memcpy (&pm[address->address_length], address->transport_name, namelen); + GNUNET_CONTAINER_DLL_insert_tail (sh->pending_head, sh->pending_tail, p); + do_transmit (sh); + return GNUNET_OK; + +} + + /** * We have updated performance statistics for a given address. Note * that this function can be called for addresses that are currently @@ -1127,6 +1222,11 @@ GNUNET_ATS_address_update (struct GNUNET_ATS_SchedulingHandle *sh, } m->session_id = htonl (s); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Trying to update address for peer `%s', plugin `%s', session %p id %u\n", + GNUNET_i2s (&address->peer), + address->transport_name, session, s); + am = (struct GNUNET_ATS_Information *) &m[1]; memcpy (am, ats, ats_count * sizeof (struct GNUNET_ATS_Information)); pm = (char *) &am[ats_count]; @@ -1172,6 +1272,12 @@ GNUNET_ATS_address_in_use (struct GNUNET_ATS_SchedulingHandle *sh, return; } + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Trying to set address to %s for peer `%s', plugin `%s', session %p\n", + GNUNET_i2s (&address->peer), + (GNUNET_NO == in_use) ? "NO" : "YES", + address->transport_name, session); + p = GNUNET_malloc (sizeof (struct PendingMessage) + msize); p->size = msize; p->is_init = GNUNET_NO; @@ -1260,12 +1366,17 @@ GNUNET_ATS_address_destroyed (struct GNUNET_ATS_SchedulingHandle *sh, if ((NULL != session) && (NOT_FOUND == s)) { /* trying to delete unknown address */ - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Trying to delete unknown address for peer `%s', plugin `%s', session %p\n", GNUNET_i2s (&address->peer), address->transport_name, session); - GNUNET_break (0); return; } + else + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Deleting address for peer `%s', plugin `%s', session %p\n", + GNUNET_i2s (&address->peer), address->transport_name, session); + } m->session_id = htonl (s); pm = (char *) &m[1]; diff --git a/src/ats/gnunet-service-ats.c b/src/ats/gnunet-service-ats.c index aef72f171..8f2e45d5d 100644 --- a/src/ats/gnunet-service-ats.c +++ b/src/ats/gnunet-service-ats.c @@ -142,6 +142,8 @@ run (void *cls, struct GNUNET_SERVER_Handle *server, {&GAS_handle_request_address_cancel, NULL, GNUNET_MESSAGE_TYPE_ATS_REQUEST_ADDRESS_CANCEL, sizeof (struct RequestAddressMessage)}, + {&GAS_handle_address_add, NULL, + GNUNET_MESSAGE_TYPE_ATS_ADDRESS_ADD, 0}, {&GAS_handle_address_update, NULL, GNUNET_MESSAGE_TYPE_ATS_ADDRESS_UPDATE, 0}, {&GAS_handle_address_in_use, NULL, diff --git a/src/ats/gnunet-service-ats_addresses.c b/src/ats/gnunet-service-ats_addresses.c index 97475ad19..854716dc7 100644 --- a/src/ats/gnunet-service-ats_addresses.c +++ b/src/ats/gnunet-service-ats_addresses.c @@ -329,6 +329,70 @@ find_exact_address (const struct GNUNET_PeerIdentity *peer, } +void +GAS_addresses_add (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; + + if (GNUNET_NO == running) + return; + + GNUNET_assert (NULL != addresses); + + aa = create_address (peer, + plugin_name, + plugin_addr, plugin_addr_len, + session_id); + + aa->mlp_information = NULL; + aa->ats = GNUNET_malloc (atsi_count * sizeof (struct GNUNET_ATS_Information)); + aa->ats_count = atsi_count; + memcpy (aa->ats, atsi, atsi_count * sizeof (struct GNUNET_ATS_Information)); + + /* Get existing address or address with session == 0 */ + old = find_address (peer, aa); + if (old == NULL) + { + /* We have a new address */ + GNUNET_assert (GNUNET_OK == + GNUNET_CONTAINER_multihashmap_put (addresses, + &peer->hashPubKey, aa, + GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE)); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Added new address for peer `%s' %p\n", + GNUNET_i2s (peer), aa); + return; + } + + if (old->session_id == 0) + { + /* We have a base address with out an session, update this address */ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Updated existing address for peer `%s' %p with new session %u\n", + GNUNET_i2s (peer), old, session_id); + GNUNET_free_non_null (old->ats); + old->session_id = session_id; + old->ats = NULL; + old->ats_count = 0; + old->ats = aa->ats; + old->ats_count = aa->ats_count; + GNUNET_free (aa->plugin); + GNUNET_free (aa); + return; + } + + /* This address and session is already existing */ + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Added already existing address for peer `%s' `%s' %p with new session %u\n", + GNUNET_i2s (peer), plugin_name, session_id); + GNUNET_break (0); +} + + void GAS_addresses_update (const struct GNUNET_PeerIdentity *peer, const char *plugin_name, const void *plugin_addr, @@ -368,7 +432,7 @@ GAS_addresses_update (const struct GNUNET_PeerIdentity *peer, &peer->hashPubKey, aa, GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE)); #if DEBUG_ATS - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Added new address for peer `%s' %X\n", + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Added new address for peer `%s' %p\n", GNUNET_i2s (peer), aa); #endif old = aa; @@ -640,6 +704,11 @@ GAS_addresses_in_use (const struct GNUNET_PeerIdentity *peer, if (NULL == old) { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Unknown address `%s', %s %u %s \n", + GNUNET_i2s (peer), + plugin_name, session_id, + (GNUNET_NO == in_use) ? "NO" : "YES"); GNUNET_break (0); return GNUNET_SYSERR; } diff --git a/src/ats/gnunet-service-ats_addresses.h b/src/ats/gnunet-service-ats_addresses.h index fe07563ac..866d25663 100644 --- a/src/ats/gnunet-service-ats_addresses.h +++ b/src/ats/gnunet-service-ats_addresses.h @@ -156,6 +156,12 @@ GAS_addresses_change_preference (const struct GNUNET_PeerIdentity *peer, enum GNUNET_ATS_PreferenceKind kind, float score); +void +GAS_addresses_add (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); /* FIXME: add performance request API */ diff --git a/src/ats/gnunet-service-ats_scheduling.c b/src/ats/gnunet-service-ats_scheduling.c index 0b66ac566..a4c04275f 100644 --- a/src/ats/gnunet-service-ats_scheduling.c +++ b/src/ats/gnunet-service-ats_scheduling.c @@ -222,6 +222,64 @@ GAS_handle_reset_backoff (void *cls, GNUNET_SERVER_receive_done (client, GNUNET_OK); } +/** + * Handle 'address add' messages from clients. + * + * @param cls unused, NULL + * @param client client that sent the request + * @param message the request message + */ +void +GAS_handle_address_add (void *cls, struct GNUNET_SERVER_Client *client, + const struct GNUNET_MessageHeader *message) +{ + const struct AddressUpdateMessage *m; + const struct GNUNET_ATS_Information *atsi; + const char *address; + const char *plugin_name; + uint16_t address_length; + uint16_t plugin_name_length; + uint32_t ats_count; + uint16_t size; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' message\n", + "ADDRESS_ADD"); + size = ntohs (message->size); + if (size < sizeof (struct AddressUpdateMessage)) + { + GNUNET_break (0); + GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); + return; + } + m = (const struct AddressUpdateMessage *) message; + ats_count = ntohl (m->ats_count); + address_length = ntohs (m->address_length); + plugin_name_length = ntohs (m->plugin_name_length); + atsi = (const struct GNUNET_ATS_Information *) &m[1]; + address = (const char *) &atsi[ats_count]; + if (plugin_name_length != 0) + plugin_name = &address[address_length]; + else + plugin_name = ""; + + if ((address_length + plugin_name_length + + ats_count * sizeof (struct GNUNET_ATS_Information) + + sizeof (struct AddressUpdateMessage) != ntohs (message->size)) || + (ats_count > + GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_ATS_Information)) || + ((plugin_name_length > 0) && (plugin_name[plugin_name_length - 1] != '\0'))) + { + GNUNET_break (0); + GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); + return; + } + GNUNET_STATISTICS_update (GSA_stats, "# address updates received", 1, + GNUNET_NO); + GAS_addresses_add (&m->peer, plugin_name, address, address_length, + ntohl (m->session_id), atsi, ats_count); + GNUNET_SERVER_receive_done (client, GNUNET_OK); +} + /** * Handle 'address update' messages from clients. diff --git a/src/ats/gnunet-service-ats_scheduling.h b/src/ats/gnunet-service-ats_scheduling.h index 08a7f1b33..48c301d19 100644 --- a/src/ats/gnunet-service-ats_scheduling.h +++ b/src/ats/gnunet-service-ats_scheduling.h @@ -115,6 +115,18 @@ GAS_handle_request_address_cancel (void *cls, struct GNUNET_SERVER_Client *client, const struct GNUNET_MessageHeader *message); + +/** + * Handle 'address add' messages from clients. + * + * @param cls unused, NULL + * @param client client that sent the request + * @param message the request message + */ +void +GAS_handle_address_add (void *cls, struct GNUNET_SERVER_Client *client, + const struct GNUNET_MessageHeader *message); + /** * Handle 'address update' messages from clients. * diff --git a/src/ats/test_ats_api_scheduling_add_address.c b/src/ats/test_ats_api_scheduling_add_address.c new file mode 100644 index 000000000..04ece4044 --- /dev/null +++ b/src/ats/test_ats_api_scheduling_add_address.c @@ -0,0 +1,226 @@ +/* + 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/test_ats_api_scheduling.c + * @brief test automatic transport selection scheduling API + * @author Christian Grothoff + * @author Matthias Wachs + * + * TODO: + * - write test case + * - extend API to get performance data + * - implement simplistic strategy based on say 'lowest latency' or strict ordering + * - extend API to get peer preferences, implement proportional bandwidth assignment + * - re-implement API against a real ATS service (!) + */ +#include "platform.h" +#include "gnunet_ats_service.h" +#include "ats.h" + +#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10) + +static GNUNET_SCHEDULER_TaskIdentifier die_task; + +static struct GNUNET_ATS_SchedulingHandle *ats; + +struct GNUNET_OS_Process *arm_proc; + + + +static int ret; + +struct Address +{ + char *plugin; + size_t plugin_len; + + void *addr; + size_t addr_len; + + struct GNUNET_ATS_Information *ats; + int ats_count; + + void *session; +}; + +struct PeerContext +{ + struct GNUNET_PeerIdentity id; + + struct Address *addr; +}; + +struct Address addr; +struct PeerContext p; +struct GNUNET_ATS_Information atsi; + +static void +stop_arm () +{ + if (0 != GNUNET_OS_process_kill (arm_proc, SIGTERM)) + GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill"); + GNUNET_OS_process_wait (arm_proc); + GNUNET_OS_process_destroy (arm_proc); + arm_proc = NULL; +} + + +static void +end_badly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + die_task = GNUNET_SCHEDULER_NO_TASK; + if (ats != NULL) + GNUNET_ATS_scheduling_done (ats); + + ret = GNUNET_SYSERR; + + stop_arm (); +} + + +static void +end () +{ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Shutting down\n"); + if (die_task != GNUNET_SCHEDULER_NO_TASK) + { + GNUNET_SCHEDULER_cancel (die_task); + die_task = GNUNET_SCHEDULER_NO_TASK; + } + + GNUNET_ATS_scheduling_done (ats); + + ret = 0; + + stop_arm (); +} + + +static void +address_suggest_cb (void *cls, const struct GNUNET_HELLO_Address *address, + struct Session *session, + struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out, + struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in, + const struct GNUNET_ATS_Information *ats, + uint32_t ats_count) +{ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ATS suggests address `%s'\n", + GNUNET_i2s (&address->peer)); + + GNUNET_assert (0 == + memcmp (&address->peer, &p.id, + sizeof (struct GNUNET_PeerIdentity))); + GNUNET_assert (0 == strcmp (address->transport_name, addr.plugin)); + GNUNET_assert (address->address_length == addr.addr_len); + GNUNET_assert (0 == + memcmp (address->address, addr.plugin, + address->address_length)); + GNUNET_assert (addr.session == session); + + ret = 0; + + GNUNET_SCHEDULER_add_now (&end, NULL); +} + +void +start_arm (const char *cfgname) +{ + arm_proc = + GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-service-arm", + "gnunet-service-arm", + "-c", cfgname, NULL); +} + +static void +check (void *cls, char *const *args, const char *cfgfile, + const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + struct GNUNET_HELLO_Address address0; + + ret = GNUNET_SYSERR; + + die_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, NULL); + start_arm (cfgfile); + + ats = GNUNET_ATS_scheduling_init (cfg, &address_suggest_cb, NULL); + + if (ats == NULL) + { + ret = GNUNET_SYSERR; + end (); + return; + } + + /* set up peer */ + GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_WEAK, + &p.id.hashPubKey); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created peer `%s'\n", + GNUNET_i2s (&p.id)); + + addr.plugin = "test"; + addr.session = NULL; + addr.addr = GNUNET_strdup ("test"); + addr.addr_len = 4; + + /* Adding address without session */ + address0.peer = p.id; + address0.transport_name = addr.plugin; + address0.address = addr.addr; + address0.address_length = addr.addr_len; + GNUNET_ATS_address_add (ats, &address0, addr.session, NULL, 0); + + addr.session = &addr; + /* Update address with session */ + GNUNET_ATS_address_add (ats, &address0, addr.session, NULL, 0); + + /* Update address with session */ + addr.session = &address0; + GNUNET_assert (GNUNET_OK == GNUNET_ATS_address_add (ats, &address0, addr.session, NULL, 0)); + GNUNET_log_skip (2, GNUNET_NO); + GNUNET_assert (GNUNET_SYSERR == GNUNET_ATS_address_add (ats, &address0, addr.session, NULL, 0)); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Requesting peer `%s'\n", + GNUNET_i2s (&p.id)); + GNUNET_ATS_suggest_address (ats, &p.id); +} + +int +main (int argc, char *argv[]) +{ + static char *const argv2[] = { "test_ats_api_scheduling_add_address", + "-c", + "test_ats_api.conf", + "-L", "WARNING", + NULL + }; + + static struct GNUNET_GETOPT_CommandLineOption options[] = { + GNUNET_GETOPT_OPTION_END + }; + + GNUNET_PROGRAM_run ((sizeof (argv2) / sizeof (char *)) - 1, argv2, + "test_ats_api_scheduling_add_address", "nohelp", options, &check, + NULL); + + + return ret; +} + +/* end of file test_ats_api_scheduling.c */ diff --git a/src/include/gnunet_ats_service.h b/src/include/gnunet_ats_service.h index aa7a08916..e8e7abb5b 100644 --- a/src/include/gnunet_ats_service.h +++ b/src/include/gnunet_ats_service.h @@ -568,6 +568,23 @@ GNUNET_ATS_address_get_type (struct GNUNET_ATS_SchedulingHandle *sh, const struct sockaddr * addr, socklen_t addrlen); +/** + * 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 destroyed + * + * @param sh handle + * @param address the address + * @param session session handle (if available) + * @param ats performance data for the address + * @param ats_count number of performance records in 'ats' + */ +int +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); + /** * We have updated performance statistics for a given address. Note diff --git a/src/include/gnunet_protocols.h b/src/include/gnunet_protocols.h index e5f303f5d..6e7007a45 100644 --- a/src/include/gnunet_protocols.h +++ b/src/include/gnunet_protocols.h @@ -1034,6 +1034,11 @@ extern "C" */ #define GNUNET_MESSAGE_TYPE_ATS_RESET_BACKOFF 352 +/** + * Type of the 'struct AddressUpdateMessage' sent by client to ATS + * to add a new address + */ +#define GNUNET_MESSAGE_TYPE_ATS_ADDRESS_ADD 353 /******************************************************************************* * TRANSPORT message types -- 2.25.1