From e5bd8fb4aa72717b8707a4652f14c0735acb52c4 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Wed, 7 Oct 2015 14:15:38 +0000 Subject: determine network scope for ATS even if we do not yet have a session and only have an address --- src/transport/gnunet-service-transport_ats.c | 1 + .../gnunet-service-transport_neighbours.c | 9 +-- .../gnunet-service-transport_validation.c | 21 ++++++- src/transport/plugin_transport_http_client.c | 19 ++++++ src/transport/plugin_transport_http_common.c | 51 +++++++++++++++- src/transport/plugin_transport_http_common.h | 13 +++++ src/transport/plugin_transport_http_server.c | 21 ++++++- src/transport/plugin_transport_tcp.c | 61 ++++++++++++++++++++ src/transport/plugin_transport_udp.c | 67 +++++++++++++++++++++- src/transport/plugin_transport_unix.c | 17 ++++++ src/transport/plugin_transport_wlan.c | 20 +++++++ 11 files changed, 288 insertions(+), 12 deletions(-) (limited to 'src/transport') diff --git a/src/transport/gnunet-service-transport_ats.c b/src/transport/gnunet-service-transport_ats.c index 74658822e..5124cd578 100644 --- a/src/transport/gnunet-service-transport_ats.c +++ b/src/transport/gnunet-service-transport_ats.c @@ -478,6 +478,7 @@ GST_ats_add_address (const struct GNUNET_HELLO_Address *address, GNUNET_HELLO_ADDRESS_INFO_INBOUND)); ai = find_ai_no_session (address); GNUNET_assert (NULL == ai); + GNUNET_break (GNUNET_ATS_NET_UNSPECIFIED != prop->scope); LOG (GNUNET_ERROR_TYPE_INFO, "Notifying ATS about peer `%s''s new address `%s'\n", GNUNET_i2s (&address->peer), diff --git a/src/transport/gnunet-service-transport_neighbours.c b/src/transport/gnunet-service-transport_neighbours.c index 01546ded4..461d2669a 100644 --- a/src/transport/gnunet-service-transport_neighbours.c +++ b/src/transport/gnunet-service-transport_neighbours.c @@ -3530,7 +3530,7 @@ GST_neighbours_handle_session_ack (const struct GNUNET_MessageHeader *message, if ( ( (GNUNET_TRANSPORT_PS_SYN_RECV_ACK != n->state) && (ACK_SEND_ACK != n->ack_state) ) || - (NULL == n->primary_address.address) ) + (NULL == n->primary_address.address) ) { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Received unexpected ACK message from peer `%s' in state %s/%s\n", @@ -3850,10 +3850,11 @@ neighbours_iterate (void *cls, * Iterate over all connected neighbours. * * @param cb function to call - * @param cb_cls closure for cb + * @param cb_cls closure for @a cb */ void -GST_neighbours_iterate (GST_NeighbourIterator cb, void *cb_cls) +GST_neighbours_iterate (GST_NeighbourIterator cb, + void *cb_cls) { struct IteratorContext ic; @@ -3930,7 +3931,7 @@ GST_neighbours_start (unsigned int max_fds) * * @param cls unused * @param key hash of neighbour's public key (not used) - * @param value the 'struct NeighbourMapEntry' of the neighbour + * @param value the `struct NeighbourMapEntry` of the neighbour * @return #GNUNET_OK (continue to iterate) */ static int diff --git a/src/transport/gnunet-service-transport_validation.c b/src/transport/gnunet-service-transport_validation.c index 66f9f5409..c7d760199 100644 --- a/src/transport/gnunet-service-transport_validation.c +++ b/src/transport/gnunet-service-transport_validation.c @@ -789,7 +789,9 @@ find_validation_entry (const struct GNUNET_HELLO_Address *address) ve->in_use = GNUNET_SYSERR; /* not defined */ ve->address = GNUNET_HELLO_address_copy (address); ve->pong_sig_valid_until = GNUNET_TIME_UNIT_ZERO_ABS; - memset (&ve->pong_sig_cache, '\0', sizeof (struct GNUNET_CRYPTO_EddsaSignature)); + memset (&ve->pong_sig_cache, + '\0', + sizeof (struct GNUNET_CRYPTO_EddsaSignature)); ve->latency = GNUNET_TIME_UNIT_FOREVER_REL; ve->challenge = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, UINT32_MAX); @@ -828,6 +830,7 @@ add_valid_address (void *cls, struct ValidationEntry *ve; struct GNUNET_PeerIdentity pid; struct GNUNET_ATS_Properties prop; + struct GNUNET_TRANSPORT_PluginFunctions *papi; if (0 == GNUNET_TIME_absolute_get_remaining (expiration).rel_value_us) return GNUNET_OK; /* expired */ @@ -836,14 +839,26 @@ add_valid_address (void *cls, GNUNET_break (0); return GNUNET_OK; /* invalid HELLO !? */ } - if (NULL == GST_plugins_find (address->transport_name)) + if (NULL == (papi = GST_plugins_find (address->transport_name))) { /* might have been valid in the past, but we don't have that plugin loaded right now */ return GNUNET_OK; } + if (NULL == + papi->address_to_string (papi->cls, + address->address, + address->address_length)) + { + /* Why do we try to add an ill-formed address? */ + GNUNET_break (0); + return GNUNET_OK; + } ve = find_validation_entry (address); + ve->network = papi->get_network_for_address (papi->cls, + address); + GNUNET_break (GNUNET_ATS_NET_UNSPECIFIED != ve->network); ve->valid_until = GNUNET_TIME_absolute_max (ve->valid_until, expiration); if (NULL == ve->revalidation_task) @@ -857,6 +872,7 @@ add_valid_address (void *cls, validation_entry_changed (ve, GNUNET_TRANSPORT_VS_UPDATE); memset (&prop, 0, sizeof (prop)); + GNUNET_break (GNUNET_ATS_NET_UNSPECIFIED != ve->network); prop.scope = ve->network; prop.delay = GNUNET_TIME_relative_divide (ve->latency, 2); if (GNUNET_YES != ve->known_to_ats) @@ -1506,6 +1522,7 @@ GST_validation_handle_pong (const struct GNUNET_PeerIdentity *sender, struct GNUNET_ATS_Properties prop; memset (&prop, 0, sizeof (prop)); + GNUNET_break (GNUNET_ATS_NET_UNSPECIFIED != ve->network); prop.scope = ve->network; prop.delay = GNUNET_TIME_relative_divide (ve->latency, 2); GNUNET_assert (GNUNET_NO == diff --git a/src/transport/plugin_transport_http_client.c b/src/transport/plugin_transport_http_client.c index de9ad541b..8066fb384 100644 --- a/src/transport/plugin_transport_http_client.c +++ b/src/transport/plugin_transport_http_client.c @@ -1941,6 +1941,24 @@ http_client_plugin_get_network (void *cls, } +/** + * Function obtain the network type for an address. + * + * @param cls closure (`struct Plugin *`) + * @param address the address + * @return the network type + */ +static enum GNUNET_ATS_Network_Type +http_client_plugin_get_network_for_address (void *cls, + const struct GNUNET_HELLO_Address *address) +{ + struct HTTP_Client_Plugin *plugin = cls; + + return http_common_get_network_for_address (plugin->env, + address); +} + + /** * Session was idle, so disconnect it * @@ -2469,6 +2487,7 @@ LIBGNUNET_PLUGIN_TRANSPORT_INIT (void *cls) api->string_to_address = &http_common_plugin_string_to_address; api->address_pretty_printer = &http_common_plugin_address_pretty_printer; api->get_network = &http_client_plugin_get_network; + api->get_network_for_address = &http_client_plugin_get_network_for_address; api->update_session_timeout = &http_client_plugin_update_session_timeout; api->update_inbound_delay = &http_client_plugin_update_inbound_delay; api->setup_monitor = &http_client_plugin_setup_monitor; diff --git a/src/transport/plugin_transport_http_common.c b/src/transport/plugin_transport_http_common.c index 77558a49b..13f01f713 100644 --- a/src/transport/plugin_transport_http_common.c +++ b/src/transport/plugin_transport_http_common.c @@ -854,8 +854,10 @@ http_common_address_get_size (const struct HttpAddress * addr) * @return #GNUNET_YES if equal, #GNUNET_NO if not, #GNUNET_SYSERR on error */ size_t -http_common_cmp_addresses (const void *addr1, size_t addrlen1, - const void *addr2, size_t addrlen2) +http_common_cmp_addresses (const void *addr1, + size_t addrlen1, + const void *addr2, + size_t addrlen2) { const char *a1 = addr1; const char *a2 = addr2; @@ -888,4 +890,49 @@ http_common_cmp_addresses (const void *addr1, size_t addrlen1, return GNUNET_NO; } + +/** + * Function obtain the network type for an address. + * + * @param env the environment + * @param address the address + * @return the network type + */ +enum GNUNET_ATS_Network_Type +http_common_get_network_for_address (struct GNUNET_TRANSPORT_PluginEnvironment *env, + const struct GNUNET_HELLO_Address *address) +{ + + struct sockaddr *sa; + enum GNUNET_ATS_Network_Type net_type; + size_t salen = 0; + int res; + + net_type = GNUNET_ATS_NET_UNSPECIFIED; + sa = http_common_socket_from_address (address->address, + address->address_length, + &res); + if (GNUNET_SYSERR == res) + return net_type; + if (GNUNET_YES == res) + { + GNUNET_assert (NULL != sa); + if (AF_INET == sa->sa_family) + { + salen = sizeof (struct sockaddr_in); + } + else if (AF_INET6 == sa->sa_family) + { + salen = sizeof (struct sockaddr_in6); + } + net_type = env->get_address_type (env->cls, + sa, + salen); + GNUNET_free (sa); + } + return net_type; +} + + + /* end of plugin_transport_http_common.c */ diff --git a/src/transport/plugin_transport_http_common.h b/src/transport/plugin_transport_http_common.h index 15466cc9e..51438d6e6 100644 --- a/src/transport/plugin_transport_http_common.h +++ b/src/transport/plugin_transport_http_common.h @@ -247,4 +247,17 @@ http_common_cmp_addresses (const void *addr1, const void *addr2, size_t addrlen2); + +/** + * Function obtain the network type for an address. + * + * @param env the environment + * @param address the address + * @return the network type + */ +enum GNUNET_ATS_Network_Type +http_common_get_network_for_address (struct GNUNET_TRANSPORT_PluginEnvironment *env, + const struct GNUNET_HELLO_Address *address); + + /* end of plugin_transport_http_common.h */ diff --git a/src/transport/plugin_transport_http_server.c b/src/transport/plugin_transport_http_server.c index 0000a604d..db483098a 100644 --- a/src/transport/plugin_transport_http_server.c +++ b/src/transport/plugin_transport_http_server.c @@ -3251,7 +3251,7 @@ http_server_plugin_address_to_string (void *cls, /** * Function obtain the network type for a session * - * @param cls closure ('struct HTTP_Server_Plugin*') + * @param cls closure (`struct HTTP_Server_Plugin *`) * @param session the session * @return the network type in HBO or #GNUNET_SYSERR */ @@ -3263,6 +3263,24 @@ http_server_plugin_get_network (void *cls, } +/** + * Function obtain the network type for an address. + * + * @param cls closure (`struct Plugin *`) + * @param address the address + * @return the network type + */ +static enum GNUNET_ATS_Network_Type +http_server_plugin_get_network_for_address (void *cls, + const struct GNUNET_HELLO_Address *address) +{ + struct HTTP_Server_Plugin *plugin = cls; + + return http_common_get_network_for_address (plugin->env, + address); +} + + /** * Function that will be called whenever the transport service wants to * notify the plugin that the inbound quota changed and that the plugin @@ -3393,6 +3411,7 @@ LIBGNUNET_PLUGIN_TRANSPORT_INIT (void *cls) api->string_to_address = &http_common_plugin_string_to_address; api->address_pretty_printer = &http_common_plugin_address_pretty_printer; api->get_network = &http_server_plugin_get_network; + api->get_network_for_address = &http_server_plugin_get_network_for_address; api->update_session_timeout = &http_server_plugin_update_session_timeout; api->update_inbound_delay = &http_server_plugin_update_inbound_delay; api->setup_monitor = &http_server_plugin_setup_monitor; diff --git a/src/transport/plugin_transport_tcp.c b/src/transport/plugin_transport_tcp.c index 330b24f61..453a0095f 100644 --- a/src/transport/plugin_transport_tcp.c +++ b/src/transport/plugin_transport_tcp.c @@ -2733,6 +2733,66 @@ tcp_plugin_get_network (void *cls, } +/** + * Function obtain the network type for an address. + * + * @param cls closure (`struct Plugin *`) + * @param address the address + * @return the network type + */ +static enum GNUNET_ATS_Network_Type +tcp_plugin_get_network_for_address (void *cls, + const struct GNUNET_HELLO_Address *address) +{ + struct Plugin *plugin = cls; + size_t addrlen; + struct sockaddr_in a4; + struct sockaddr_in6 a6; + const struct IPv4TcpAddress *t4; + const struct IPv6TcpAddress *t6; + const void *sb; + size_t sbs; + + addrlen = address->address_length; + if (addrlen == sizeof(struct IPv6TcpAddress)) + { + GNUNET_assert (NULL != address->address); /* make static analysis happy */ + t6 = address->address; + memset (&a6, 0, sizeof(a6)); +#if HAVE_SOCKADDR_IN_SIN_LEN + a6.sin6_len = sizeof (a6); +#endif + a6.sin6_family = AF_INET6; + a6.sin6_port = t6->t6_port; + memcpy (&a6.sin6_addr, &t6->ipv6_addr, sizeof(struct in6_addr)); + sb = &a6; + sbs = sizeof(a6); + } + else if (addrlen == sizeof(struct IPv4TcpAddress)) + { + GNUNET_assert (NULL != address->address); /* make static analysis happy */ + t4 = address->address; + memset (&a4, 0, sizeof(a4)); +#if HAVE_SOCKADDR_IN_SIN_LEN + a4.sin_len = sizeof (a4); +#endif + a4.sin_family = AF_INET; + a4.sin_port = t4->t4_port; + a4.sin_addr.s_addr = t4->ipv4_addr; + sb = &a4; + sbs = sizeof(a4); + } + else + { + GNUNET_break (0); + return GNUNET_ATS_NET_UNSPECIFIED; + } + return plugin->env->get_address_type (plugin->env->cls, + sb, + sbs); +} + + /** * Return information about the given session to the * monitor callback. @@ -2991,6 +3051,7 @@ libgnunet_plugin_transport_tcp_init (void *cls) api->address_to_string = &tcp_plugin_address_to_string; api->string_to_address = &tcp_plugin_string_to_address; api->get_network = &tcp_plugin_get_network; + api->get_network_for_address = &tcp_plugin_get_network_for_address; api->update_session_timeout = &tcp_plugin_update_session_timeout; api->update_inbound_delay = &tcp_plugin_update_inbound_delay; api->setup_monitor = &tcp_plugin_setup_monitor; diff --git a/src/transport/plugin_transport_udp.c b/src/transport/plugin_transport_udp.c index 7c36e172c..ca5166600 100644 --- a/src/transport/plugin_transport_udp.c +++ b/src/transport/plugin_transport_udp.c @@ -614,13 +614,73 @@ udp_query_keepalive_factor (void *cls) * @return the network type */ static enum GNUNET_ATS_Network_Type -udp_get_network (void *cls, - struct Session *session) +udp_plugin_get_network (void *cls, + struct Session *session) { return session->scope; } +/** + * Function obtain the network type for an address. + * + * @param cls closure (`struct Plugin *`) + * @param address the address + * @return the network type + */ +static enum GNUNET_ATS_Network_Type +udp_plugin_get_network_for_address (void *cls, + const struct GNUNET_HELLO_Address *address) +{ + struct Plugin *plugin = cls; + size_t addrlen; + struct sockaddr_in a4; + struct sockaddr_in6 a6; + const struct IPv4UdpAddress *u4; + const struct IPv6UdpAddress *u6; + const void *sb; + size_t sbs; + + addrlen = address->address_length; + if (addrlen == sizeof(struct IPv6UdpAddress)) + { + GNUNET_assert (NULL != address->address); /* make static analysis happy */ + u6 = address->address; + memset (&a6, 0, sizeof(a6)); +#if HAVE_SOCKADDR_IN_SIN_LEN + a6.sin6_len = sizeof (a6); +#endif + a6.sin6_family = AF_INET6; + a6.sin6_port = u6->u6_port; + memcpy (&a6.sin6_addr, &u6->ipv6_addr, sizeof(struct in6_addr)); + sb = &a6; + sbs = sizeof(a6); + } + else if (addrlen == sizeof(struct IPv4UdpAddress)) + { + GNUNET_assert (NULL != address->address); /* make static analysis happy */ + u4 = address->address; + memset (&a4, 0, sizeof(a4)); +#if HAVE_SOCKADDR_IN_SIN_LEN + a4.sin_len = sizeof (a4); +#endif + a4.sin_family = AF_INET; + a4.sin_port = u4->u4_port; + a4.sin_addr.s_addr = u4->ipv4_addr; + sb = &a4; + sbs = sizeof(a4); + } + else + { + GNUNET_break (0); + return GNUNET_ATS_NET_UNSPECIFIED; + } + return plugin->env->get_address_type (plugin->env->cls, + sb, + sbs); +} + + /* ******************* Event loop ******************** */ /** @@ -3766,7 +3826,8 @@ libgnunet_plugin_transport_udp_init (void *cls) api->check_address = &udp_plugin_check_address; api->get_session = &udp_plugin_get_session; api->send = &udp_plugin_send; - api->get_network = &udp_get_network; + api->get_network = &udp_plugin_get_network; + api->get_network_for_address = &udp_plugin_get_network_for_address; api->update_session_timeout = &udp_plugin_update_session_timeout; api->setup_monitor = &udp_plugin_setup_monitor; return api; diff --git a/src/transport/plugin_transport_unix.c b/src/transport/plugin_transport_unix.c index a664941e0..c6ac0e508 100644 --- a/src/transport/plugin_transport_unix.c +++ b/src/transport/plugin_transport_unix.c @@ -804,6 +804,22 @@ unix_plugin_get_network (void *cls, } +/** + * Function obtain the network type for a session + * + * @param cls closure (`struct Plugin *`) + * @param address the address + * @return the network type + */ +static enum GNUNET_ATS_Network_Type +unix_plugin_get_network_for_address (void *cls, + const struct GNUNET_HELLO_Address *address) + +{ + return GNUNET_ATS_NET_LOOPBACK; +} + + /** * Creates a new outbound session the transport service will use to send data to the * peer @@ -1798,6 +1814,7 @@ libgnunet_plugin_transport_unix_init (void *cls) api->check_address = &unix_plugin_check_address; api->string_to_address = &unix_plugin_string_to_address; api->get_network = &unix_plugin_get_network; + api->get_network_for_address = &unix_plugin_get_network_for_address; api->update_session_timeout = &unix_plugin_update_session_timeout; api->setup_monitor = &unix_plugin_setup_monitor; sockets_created = unix_transport_server_start (plugin); diff --git a/src/transport/plugin_transport_wlan.c b/src/transport/plugin_transport_wlan.c index 52f454560..d5932bb30 100644 --- a/src/transport/plugin_transport_wlan.c +++ b/src/transport/plugin_transport_wlan.c @@ -1291,6 +1291,25 @@ wlan_plugin_get_network (void *cls, } +/** + * Function obtain the network type for an address. + * + * @param cls closure (`struct Plugin *`) + * @param address the address + * @return the network type + */ +static enum GNUNET_ATS_Network_Type +wlan_plugin_get_network_for_address (void *cls, + const struct GNUNET_HELLO_Address *address) +{ +#if BUILD_WLAN + return GNUNET_ATS_NET_WLAN; +#else + return GNUNET_ATS_NET_BT; +#endif +} + + /** * Creates a new outbound session the transport service will use to * send data to the peer @@ -2332,6 +2351,7 @@ LIBGNUNET_PLUGIN_TRANSPORT_INIT (void *cls) api->address_to_string = &wlan_plugin_address_to_string; api->string_to_address = &wlan_plugin_string_to_address; api->get_network = &wlan_plugin_get_network; + api->get_network_for_address = &wlan_plugin_get_network_for_address; api->update_session_timeout = &wlan_plugin_update_session_timeout; api->update_inbound_delay = &wlan_plugin_update_inbound_delay; api->setup_monitor = &wlan_plugin_setup_monitor; -- cgit v1.2.3