diff --git a/features/FEATURE_LWIP/lwip-interface/lwip_stack.c b/features/FEATURE_LWIP/lwip-interface/lwip_stack.c index 67ad1f77a5..f8099386f4 100644 --- a/features/FEATURE_LWIP/lwip-interface/lwip_stack.c +++ b/features/FEATURE_LWIP/lwip-interface/lwip_stack.c @@ -130,7 +130,8 @@ static bool convert_mbed_addr_to_lwip(ip_addr_t *out, const nsapi_addr_t *in) #if !LWIP_IPV4 /* For bind() and other purposes, need to accept "null" of other type */ /* (People use IPv4 0.0.0.0 as a general null) */ - if (in->version == NSAPI_IPv4 && all_zeros(in->bytes, 4)) { + if (in->version == NSAPI_UNSPEC || + (in->version == NSAPI_IPv4 && all_zeros(in->bytes, 4))) { ip_addr_set_zero_ip6(out); return true; } @@ -145,13 +146,25 @@ static bool convert_mbed_addr_to_lwip(ip_addr_t *out, const nsapi_addr_t *in) } #if !LWIP_IPV6 /* For symmetry with above, accept IPv6 :: as a general null */ - if (in->version == NSAPI_IPv6 && all_zeros(in->bytes, 16)) { + if (in->version == NSAPI_UNSPEC || + (in->version == NSAPI_IPv6 && all_zeros(in->bytes, 16))) { ip_addr_set_zero_ip4(out); return true; } #endif #endif +#if LWIP_IPV4 && LWIP_IPV6 + if (in->version == NSAPI_UNSPEC) { +#if IP_VERSION_PREF == PREF_IPV4 + ip_addr_set_zero_ip4(out); +#else + ip_addr_set_zero_ip6(out); +#endif + return true; + } +#endif + return false; } diff --git a/features/netsocket/NetworkInterface.cpp b/features/netsocket/NetworkInterface.cpp index bd6f49831b..c5b68d4a5b 100644 --- a/features/netsocket/NetworkInterface.cpp +++ b/features/netsocket/NetworkInterface.cpp @@ -55,11 +55,6 @@ int NetworkInterface::set_dhcp(bool dhcp) } // DNS operations go through the underlying stack by default -int NetworkInterface::gethostbyname(const char *name, SocketAddress *address) -{ - return get_stack()->gethostbyname(name, address); -} - int NetworkInterface::gethostbyname(const char *name, SocketAddress *address, nsapi_version_t version) { return get_stack()->gethostbyname(name, address, version); diff --git a/features/netsocket/NetworkInterface.h b/features/netsocket/NetworkInterface.h index 948b1fb37f..dbebd6fc9d 100644 --- a/features/netsocket/NetworkInterface.h +++ b/features/netsocket/NetworkInterface.h @@ -103,20 +103,6 @@ public: */ virtual int disconnect() = 0; - /** Translates a hostname to an IP address - * - * The hostname may be either a domain name or an IP address. If the - * hostname is an IP address, no network transactions will be performed. - * - * If no stack-specific DNS resolution is provided, the hostname - * will be resolve using a UDP socket on the stack. - * - * @param address Destination for the host SocketAddress - * @param host Hostname to resolve - * @return 0 on success, negative error code on failure - */ - virtual int gethostbyname(const char *host, SocketAddress *address); - /** Translates a hostname to an IP address with specific version * * The hostname may be either a domain name or an IP address. If the @@ -127,10 +113,11 @@ public: * * @param address Destination for the host SocketAddress * @param host Hostname to resolve - * @param version IP version of address to resolve + * @param version IP version of address to resolve, NSAPI_UNSPEC indicates + * version is chosen by the stack (defaults to NSAPI_UNSPEC) * @return 0 on success, negative error code on failure */ - virtual int gethostbyname(const char *host, SocketAddress *address, nsapi_version_t version); + virtual int gethostbyname(const char *host, SocketAddress *address, nsapi_version_t version = NSAPI_UNSPEC); /** Add a domain name server to list of servers to query * diff --git a/features/netsocket/NetworkStack.cpp b/features/netsocket/NetworkStack.cpp index 908cdd38d5..44419905f4 100644 --- a/features/netsocket/NetworkStack.cpp +++ b/features/netsocket/NetworkStack.cpp @@ -22,16 +22,6 @@ // Default NetworkStack operations -int NetworkStack::gethostbyname(const char *name, SocketAddress *address) -{ - // check for simple ip addresses - if (address->set_ip_address(name)) { - return 0; - } - - return nsapi_dns_query(this, name, address); -} - int NetworkStack::gethostbyname(const char *name, SocketAddress *address, nsapi_version_t version) { // check for simple ip addresses @@ -100,25 +90,13 @@ public: return address->get_ip_address(); } - virtual int gethostbyname(const char *name, SocketAddress *address) - { - if (!_stack_api()->gethostbyname) { - return NetworkStack::gethostbyname(name, address); - } - - nsapi_addr_t addr = {NSAPI_IPv4, 0}; - int err = _stack_api()->gethostbyname(_stack(), name, &addr, NSAPI_UNSPEC); - address->set_addr(addr); - return err; - } - virtual int gethostbyname(const char *name, SocketAddress *address, nsapi_version_t version) { if (!_stack_api()->gethostbyname) { return NetworkStack::gethostbyname(name, address, version); } - nsapi_addr_t addr = {NSAPI_IPv4, 0}; + nsapi_addr_t addr = {NSAPI_UNSPEC, 0}; int err = _stack_api()->gethostbyname(_stack(), name, &addr, version); address->set_addr(addr); return err; diff --git a/features/netsocket/NetworkStack.h b/features/netsocket/NetworkStack.h index bb89e583ce..cad473a4ec 100644 --- a/features/netsocket/NetworkStack.h +++ b/features/netsocket/NetworkStack.h @@ -44,20 +44,6 @@ public: */ virtual const char *get_ip_address() = 0; - /** Translates a hostname to an IP address - * - * The hostname may be either a domain name or an IP address. If the - * hostname is an IP address, no network transactions will be performed. - * - * If no stack-specific DNS resolution is provided, the hostname - * will be resolve using a UDP socket on the stack. - * - * @param host Hostname to resolve - * @param address Destination for the host SocketAddress - * @return 0 on success, negative error code on failure - */ - virtual int gethostbyname(const char *host, SocketAddress *address); - /** Translates a hostname to an IP address with specific version * * The hostname may be either a domain name or an IP address. If the @@ -68,10 +54,11 @@ public: * * @param host Hostname to resolve * @param address Destination for the host SocketAddress - * @param version IP version of address to resolve + * @param version IP version of address to resolve, NSAPI_UNSPEC indicates + * version is chosen by the stack (defaults to NSAPI_UNSPEC) * @return 0 on success, negative error code on failure */ - virtual int gethostbyname(const char *host, SocketAddress *address, nsapi_version_t version); + virtual int gethostbyname(const char *host, SocketAddress *address, nsapi_version_t version = NSAPI_UNSPEC); /** Add a domain name server to list of servers to query * diff --git a/features/netsocket/SocketAddress.cpp b/features/netsocket/SocketAddress.cpp index 2a8a8d7a44..7e45700740 100644 --- a/features/netsocket/SocketAddress.cpp +++ b/features/netsocket/SocketAddress.cpp @@ -221,17 +221,19 @@ void SocketAddress::set_port(uint16_t port) const char *SocketAddress::get_ip_address() const { - char *ip_address = (char *)_ip_address; + if (_addr.version == NSAPI_UNSPEC) { + return NULL; + } - if (!ip_address[0]) { + if (!_ip_address[0]) { if (_addr.version == NSAPI_IPv4) { - ipv4_to_address(ip_address, _addr.bytes); + ipv4_to_address(_ip_address, _addr.bytes); } else if (_addr.version == NSAPI_IPv6) { - ipv6_to_address(ip_address, _addr.bytes); + ipv6_to_address(_ip_address, _addr.bytes); } } - return ip_address; + return _ip_address; } const void *SocketAddress::get_ip_bytes() const @@ -256,34 +258,38 @@ uint16_t SocketAddress::get_port() const SocketAddress::operator bool() const { - int count = 0; if (_addr.version == NSAPI_IPv4) { - count = NSAPI_IPv4_BYTES; - } else if (_addr.version == NSAPI_IPv6) { - count = NSAPI_IPv6_BYTES; - } - - for (int i = 0; i < count; i++) { - if (_addr.bytes[i]) { - return true; + for (int i = 0; i < NSAPI_IPv4_BYTES; i++) { + if (_addr.bytes[i]) { + return true; + } } - } - return false; + return false; + } else if (_addr.version == NSAPI_IPv6) { + for (int i = 0; i < NSAPI_IPv6_BYTES; i++) { + if (_addr.bytes[i]) { + return true; + } + } + + return false; + } else { + return false; + } } bool operator==(const SocketAddress &a, const SocketAddress &b) { - int count = 0; - if (a._addr.version == NSAPI_IPv4 && b._addr.version == NSAPI_IPv4) { - count = NSAPI_IPv4_BYTES; - } else if (a._addr.version == NSAPI_IPv6 && b._addr.version == NSAPI_IPv6) { - count = NSAPI_IPv6_BYTES; - } else { + if (!a && !b) { + return true; + } else if (a._addr.version != b._addr.version) { return false; + } else if (a._addr.version == NSAPI_IPv4) { + return memcmp(a._addr.bytes, b._addr.bytes, NSAPI_IPv4_BYTES) == 0; + } else if (a._addr.version == NSAPI_IPv6) { + return memcmp(a._addr.bytes, b._addr.bytes, NSAPI_IPv6_BYTES) == 0; } - - return (memcmp(a._addr.bytes, b._addr.bytes, count) == 0); } bool operator!=(const SocketAddress &a, const SocketAddress &b) diff --git a/features/netsocket/SocketAddress.h b/features/netsocket/SocketAddress.h index bad1392931..4aa7f30ecc 100644 --- a/features/netsocket/SocketAddress.h +++ b/features/netsocket/SocketAddress.h @@ -163,7 +163,7 @@ public: private: void _SocketAddress(NetworkStack *iface, const char *host, uint16_t port); - char _ip_address[NSAPI_IP_SIZE]; + mutable char _ip_address[NSAPI_IP_SIZE]; nsapi_addr_t _addr; uint16_t _port; }; diff --git a/features/netsocket/nsapi_dns.cpp b/features/netsocket/nsapi_dns.cpp index efeb84f033..118a71ae8f 100644 --- a/features/netsocket/nsapi_dns.cpp +++ b/features/netsocket/nsapi_dns.cpp @@ -102,7 +102,7 @@ static void dns_append_question(uint8_t **p, const char *host, nsapi_version_t v dns_append_byte(p, 0); // fill out question footer - if (version == NSAPI_IPv4) { + if (version != NSAPI_IPv6) { dns_append_word(p, RR_A); // qtype = ipv4 } else { dns_append_word(p, RR_AAAA); // qtype = ipv6 diff --git a/features/netsocket/nsapi_types.h b/features/netsocket/nsapi_types.h index 758daa3809..04df2c21c1 100644 --- a/features/netsocket/nsapi_types.h +++ b/features/netsocket/nsapi_types.h @@ -103,16 +103,18 @@ typedef enum nsapi_security { * @enum nsapi_version_t */ typedef enum nsapi_version { - NSAPI_IPv4, /*!< Address is IPv4 */ - NSAPI_IPv6, /*!< Address is IPv6 */ - NSAPI_UNSPEC /*!< Address is unspecified */ + NSAPI_UNSPEC, /*!< Address is unspecified */ + NSAPI_IPv4, /*!< Address is IPv4 */ + NSAPI_IPv6, /*!< Address is IPv6 */ } nsapi_version_t; /** IP address structure for passing IP addresses by value */ typedef struct nsapi_addr { /** IP version - * NSAPI_IPv4 or NSAPI_IPv6 (NSAPI_UNSPEC not currently supported) + * - NSAPI_IPv4 + * - NSAPI_IPv6 + * - NSAPI_UNSPEC */ nsapi_version_t version;