Skip to content

Commit f93f484

Browse files
authored
Merge pull request #2652 from geky/nsapi-gethostbyname
nsapi - Add explicit DNS interface to the network socket API
2 parents 196584d + 4f7b10f commit f93f484

File tree

12 files changed

+203
-70
lines changed

12 files changed

+203
-70
lines changed

features/net/FEATURE_IPV4/lwip-interface/lwip_stack.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ static int lwip_err_remap(err_t err) {
273273

274274

275275
/* LWIP network stack implementation */
276-
static int lwip_gethostbyname(nsapi_stack_t *stack, nsapi_addr_t *addr, const char *host)
276+
static int lwip_gethostbyname(nsapi_stack_t *stack, const char *host, nsapi_addr_t *addr)
277277
{
278278
err_t err = netconn_gethostbyname(host, (ip_addr_t *)addr->bytes);
279279
if (err != ERR_OK) {

features/net/network-socket/NetworkInterface.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,11 @@
1515
*/
1616

1717
#include "network-socket/NetworkInterface.h"
18+
#include "network-socket/NetworkStack.h"
1819
#include <string.h>
1920

2021

22+
// Default network-interface state
2123
const char *NetworkInterface::get_mac_address()
2224
{
2325
return 0;
@@ -52,3 +54,19 @@ int NetworkInterface::set_dhcp(bool dhcp)
5254
}
5355
}
5456

57+
// DNS operations go through the underlying stack by default
58+
int NetworkInterface::gethostbyname(const char *name, SocketAddress *address)
59+
{
60+
return get_stack()->gethostbyname(name, address);
61+
}
62+
63+
int NetworkInterface::gethostbyname(const char *name, SocketAddress *address, nsapi_version_t version)
64+
{
65+
return get_stack()->gethostbyname(name, address, version);
66+
}
67+
68+
int NetworkInterface::add_dns_server(const SocketAddress &address)
69+
{
70+
return get_stack()->add_dns_server(address);
71+
}
72+

features/net/network-socket/NetworkInterface.h

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#define NETWORK_INTERFACE_H
1919

2020
#include "network-socket/nsapi_types.h"
21+
#include "network-socket/SocketAddress.h"
2122

2223
// Predeclared class
2324
class NetworkStack;
@@ -99,6 +100,42 @@ class NetworkInterface {
99100
*/
100101
virtual int disconnect() = 0;
101102

103+
/** Translates a hostname to an IP address
104+
*
105+
* The hostname may be either a domain name or an IP address. If the
106+
* hostname is an IP address, no network transactions will be performed.
107+
*
108+
* If no stack-specific DNS resolution is provided, the hostname
109+
* will be resolve using a UDP socket on the stack.
110+
*
111+
* @param address Destination for the host SocketAddress
112+
* @param host Hostname to resolve
113+
* @return 0 on success, negative error code on failure
114+
*/
115+
virtual int gethostbyname(const char *host, SocketAddress *address);
116+
117+
/** Translates a hostname to an IP address with specific version
118+
*
119+
* The hostname may be either a domain name or an IP address. If the
120+
* hostname is an IP address, no network transactions will be performed.
121+
*
122+
* If no stack-specific DNS resolution is provided, the hostname
123+
* will be resolve using a UDP socket on the stack.
124+
*
125+
* @param address Destination for the host SocketAddress
126+
* @param host Hostname to resolve
127+
* @param version IP version of address to resolve
128+
* @return 0 on success, negative error code on failure
129+
*/
130+
virtual int gethostbyname(const char *host, SocketAddress *address, nsapi_version_t version);
131+
132+
/** Add a domain name server to list of servers to query
133+
*
134+
* @param addr Destination for the host address
135+
* @return 0 on success, negative error code on failure
136+
*/
137+
virtual int add_dns_server(const SocketAddress &address);
138+
102139
protected:
103140
friend class Socket;
104141
friend class UDPSocket;

features/net/network-socket/NetworkStack.cpp

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,33 @@
2222

2323

2424
// Default NetworkStack operations
25-
int NetworkStack::gethostbyname(SocketAddress *address, const char *name)
25+
int NetworkStack::gethostbyname(const char *name, SocketAddress *address)
2626
{
27-
return nsapi_dns_query(this, address, name);
27+
// check for simple ip addresses
28+
if (address->set_ip_address(name)) {
29+
return 0;
30+
}
31+
32+
return nsapi_dns_query(this, name, address);
33+
}
34+
35+
int NetworkStack::gethostbyname(const char *name, SocketAddress *address, nsapi_version_t version)
36+
{
37+
// check for simple ip addresses
38+
if (address->set_ip_address(name)) {
39+
if (address->get_ip_version() != version) {
40+
return NSAPI_ERROR_DNS_FAILURE;
41+
}
42+
43+
return 0;
44+
}
45+
46+
return nsapi_dns_query(this, name, address, version);
47+
}
48+
49+
int NetworkStack::add_dns_server(const SocketAddress &address)
50+
{
51+
return nsapi_dns_add_server(address);
2852
}
2953

3054
int NetworkStack::setstackopt(int level, int optname, const void *optval, unsigned optlen)
@@ -76,18 +100,27 @@ class NetworkStackWrapper : public NetworkStack
76100
return address->get_ip_address();
77101
}
78102

79-
virtual int gethostbyname(SocketAddress *address, const char *name)
103+
virtual int gethostbyname(const char *name, SocketAddress *address)
80104
{
81105
if (!_stack_api()->gethostbyname) {
82-
return NetworkStack::gethostbyname(address, name);
106+
return NetworkStack::gethostbyname(name, address);
83107
}
84108

85109
nsapi_addr_t addr = {NSAPI_IPv4, 0};
86-
int err = _stack_api()->gethostbyname(_stack(), &addr, name);
110+
int err = _stack_api()->gethostbyname(_stack(), name, &addr);
87111
address->set_addr(addr);
88112
return err;
89113
}
90114

115+
virtual int add_dns_server(const SocketAddress &address)
116+
{
117+
if (!_stack_api()->add_dns_server) {
118+
return NetworkStack::add_dns_server(address);
119+
}
120+
121+
return _stack_api()->add_dns_server(_stack(), address.get_addr());
122+
}
123+
91124
virtual int setstackopt(int level, int optname, const void *optval, unsigned optlen)
92125
{
93126
if (!_stack_api()->setstackopt) {

features/net/network-socket/NetworkStack.h

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -45,15 +45,37 @@ class NetworkStack
4545
*
4646
* The hostname may be either a domain name or an IP address. If the
4747
* hostname is an IP address, no network transactions will be performed.
48-
*
48+
*
4949
* If no stack-specific DNS resolution is provided, the hostname
50-
* will be resolve using a UDP socket on the stack.
50+
* will be resolve using a UDP socket on the stack.
5151
*
52+
* @param host Hostname to resolve
5253
* @param address Destination for the host SocketAddress
54+
* @return 0 on success, negative error code on failure
55+
*/
56+
virtual int gethostbyname(const char *host, SocketAddress *address);
57+
58+
/** Translates a hostname to an IP address with specific version
59+
*
60+
* The hostname may be either a domain name or an IP address. If the
61+
* hostname is an IP address, no network transactions will be performed.
62+
*
63+
* If no stack-specific DNS resolution is provided, the hostname
64+
* will be resolve using a UDP socket on the stack.
65+
*
5366
* @param host Hostname to resolve
67+
* @param address Destination for the host SocketAddress
68+
* @param version IP version of address to resolve
69+
* @return 0 on success, negative error code on failure
70+
*/
71+
virtual int gethostbyname(const char *host, SocketAddress *address, nsapi_version_t version);
72+
73+
/** Add a domain name server to list of servers to query
74+
*
75+
* @param addr Destination for the host address
5476
* @return 0 on success, negative error code on failure
5577
*/
56-
virtual int gethostbyname(SocketAddress *address, const char *host);
78+
virtual int add_dns_server(const SocketAddress &address);
5779

5880
/* Set stack-specific stack options
5981
*
@@ -66,7 +88,7 @@ class NetworkStack
6688
* @param optval Option value
6789
* @param optlen Length of the option value
6890
* @return 0 on success, negative error code on failure
69-
*/
91+
*/
7092
virtual int setstackopt(int level, int optname, const void *optval, unsigned optlen);
7193

7294
/* Get stack-specific stack options
@@ -80,7 +102,7 @@ class NetworkStack
80102
* @param optval Destination for option value
81103
* @param optlen Length of the option value
82104
* @return 0 on success, negative error code on failure
83-
*/
105+
*/
84106
virtual int getstackopt(int level, int optname, void *optval, unsigned *optlen);
85107

86108
protected:
@@ -260,7 +282,7 @@ class NetworkStack
260282
* @param optval Option value
261283
* @param optlen Length of the option value
262284
* @return 0 on success, negative error code on failure
263-
*/
285+
*/
264286
virtual int setsockopt(nsapi_socket_t handle, int level, int optname, const void *optval, unsigned optlen);
265287

266288
/* Get stack-specific socket options
@@ -275,7 +297,7 @@ class NetworkStack
275297
* @param optval Destination for option value
276298
* @param optlen Length of the option value
277299
* @return 0 on success, negative error code on failure
278-
*/
300+
*/
279301
virtual int getsockopt(nsapi_socket_t handle, int level, int optname, void *optval, unsigned *optlen);
280302
};
281303

features/net/network-socket/SocketAddress.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,16 +43,21 @@ static bool ipv4_is_valid(const char *addr)
4343
static bool ipv6_is_valid(const char *addr)
4444
{
4545
// Check each digit for [0-9a-fA-F:]
46+
// Must also have at least 2 colons
47+
int colons = 0;
4648
for (int i = 0; addr[i]; i++) {
4749
if (!(addr[i] >= '0' && addr[i] <= '9') &&
4850
!(addr[i] >= 'a' && addr[i] <= 'f') &&
4951
!(addr[i] >= 'A' && addr[i] <= 'F') &&
5052
addr[i] != ':') {
5153
return false;
5254
}
55+
if (addr[i] == ':') {
56+
colons++;
57+
}
5358
}
5459

55-
return true;
60+
return colons >= 2;
5661
}
5762

5863
static void ipv4_from_address(uint8_t *bytes, const char *addr)
@@ -171,18 +176,21 @@ SocketAddress::SocketAddress(const SocketAddress &addr)
171176
set_port(addr.get_port());
172177
}
173178

174-
void SocketAddress::set_ip_address(const char *addr)
179+
bool SocketAddress::set_ip_address(const char *addr)
175180
{
176181
_ip_address[0] = '\0';
177182

178183
if (addr && ipv4_is_valid(addr)) {
179184
_addr.version = NSAPI_IPv4;
180185
ipv4_from_address(_addr.bytes, addr);
186+
return true;
181187
} else if (addr && ipv6_is_valid(addr)) {
182188
_addr.version = NSAPI_IPv6;
183189
ipv6_from_address(_addr.bytes, addr);
190+
return true;
184191
} else {
185192
_addr = nsapi_addr_t();
193+
return false;
186194
}
187195
}
188196

@@ -292,7 +300,7 @@ void SocketAddress::_SocketAddress(NetworkStack *iface, const char *host, uint16
292300
_port = port;
293301
} else {
294302
// DNS lookup
295-
int err = iface->gethostbyname(this, host);
303+
int err = iface->gethostbyname(host, this);
296304
_port = port;
297305
if (err) {
298306
_addr = nsapi_addr_t();

features/net/network-socket/SocketAddress.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,14 @@ class SocketAddress {
4141
* @param stack Network stack to use for DNS resolution
4242
* @param host Hostname to resolve
4343
* @param port Optional 16-bit port
44+
* @deprecated
45+
* Constructors hide possible errors. Replaced by
46+
* NetworkInterface::gethostbyname.
4447
*/
4548
template <typename S>
49+
MBED_DEPRECATED_SINCE("mbed-os-5.1.3",
50+
"Constructors hide possible errors. Replaced by "
51+
"NetworkInterface::gethostbyname.")
4652
SocketAddress(S *stack, const char *host, uint16_t port = 0)
4753
{
4854
_SocketAddress(nsapi_create_stack(stack), host, port);
@@ -79,8 +85,10 @@ class SocketAddress {
7985
/** Set the IP address
8086
*
8187
* @param addr Null-terminated represention of the IP address
88+
* @return True if address is a valid representation of an IP address,
89+
* otherwise False and SocketAddress is set to null
8290
*/
83-
void set_ip_address(const char *addr);
91+
bool set_ip_address(const char *addr);
8492

8593
/** Set the raw IP bytes and IP version
8694
*

features/net/network-socket/TCPSocket.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,14 @@ int TCPSocket::connect(const SocketAddress &address)
5151

5252
int TCPSocket::connect(const char *host, uint16_t port)
5353
{
54-
SocketAddress address(_stack, host, port);
55-
if (!address) {
54+
SocketAddress address;
55+
int err = _stack->gethostbyname(host, &address);
56+
if (err) {
5657
return NSAPI_ERROR_DNS_FAILURE;
5758
}
5859

60+
address.set_port(port);
61+
5962
// connect is thread safe
6063
return connect(address);
6164
}

features/net/network-socket/UDPSocket.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,14 @@ nsapi_protocol_t UDPSocket::get_proto()
3636

3737
int UDPSocket::sendto(const char *host, uint16_t port, const void *data, unsigned size)
3838
{
39-
SocketAddress address(_stack, host, port);
40-
if (!address) {
39+
SocketAddress address;
40+
int err = _stack->gethostbyname(host, &address);
41+
if (err) {
4142
return NSAPI_ERROR_DNS_FAILURE;
4243
}
4344

45+
address.set_port(port);
46+
4447
// sendto is thread safe
4548
return sendto(address, data, size);
4649
}

0 commit comments

Comments
 (0)