Skip to content

Commit 370afe5

Browse files
committed
nsapi - Folded IP parsing logic into SocketAddress
Merged duplicated logic into the SocketAddress class. Based on parallel work by @mkaleppanen and @kjbracey-arm. Also added small ipv6 parsing fix by @mikaleppanen
1 parent d237ee8 commit 370afe5

File tree

3 files changed

+21
-116
lines changed

3 files changed

+21
-116
lines changed

features/net/network-socket/SocketAddress.cpp

Lines changed: 10 additions & 2 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

features/net/network-socket/SocketAddress.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,10 @@ class SocketAddress {
8585
/** Set the IP address
8686
*
8787
* @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
8890
*/
89-
void set_ip_address(const char *addr);
91+
bool set_ip_address(const char *addr);
9092

9193
/** Set the raw IP bytes and IP version
9294
*

features/net/network-socket/nsapi_dns.cpp

Lines changed: 8 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222

2323

2424
// DNS options
25-
#define DNS_BUFFER_SIZE 256
25+
#define DNS_BUFFER_SIZE 256
2626
#define DNS_TIMEOUT 5000
2727
#define DNS_SERVERS_SIZE 5
2828

@@ -45,111 +45,6 @@ extern "C" int nsapi_dns_add_server(nsapi_addr_t addr)
4545
return 0;
4646
}
4747

48-
// IP parsing
49-
static bool dns_parse_ipv4(const char *host, nsapi_addr_t *addr)
50-
{
51-
int i = 0;
52-
53-
// Check each digit for [0-9.]
54-
for (; host[i]; i++) {
55-
if (!(host[i] >= '0' && host[i] <= '9') && host[i] != '.') {
56-
return false;
57-
}
58-
}
59-
60-
// Ending with '.' garuntees host
61-
if (i > 0 && host[i-1] == '.') {
62-
return false;
63-
}
64-
65-
// Build up the ip address
66-
addr->version = NSAPI_IPv4;
67-
i = 0;
68-
69-
for (int count = 0; count < NSAPI_IPv4_BYTES; count++) {
70-
int scanned = sscanf(&host[i], "%hhu", &addr->bytes[count]);
71-
if (scanned < 1) {
72-
return true;
73-
}
74-
75-
for (; host[i] != '.'; i++) {
76-
if (!host[i]) {
77-
return true;
78-
}
79-
}
80-
81-
i++;
82-
}
83-
84-
return true;
85-
}
86-
87-
static int dns_parse_ipv6_chunk(const char *chunk, uint16_t *shorts) {
88-
int count = 0;
89-
int i = 0;
90-
91-
for (; count < NSAPI_IPv6_BYTES/2; count++) {
92-
int scanned = sscanf(&chunk[i], "%hx", &shorts[count]);
93-
if (scanned < 1) {
94-
return count;
95-
}
96-
97-
for (; chunk[i] != ':'; i++) {
98-
if (!chunk[i]) {
99-
return count+1;
100-
}
101-
}
102-
103-
i++;
104-
}
105-
106-
return count;
107-
}
108-
109-
static bool dns_parse_ipv6(const char *host, nsapi_addr_t *addr)
110-
{
111-
// Check each digit for [0-9a-fA-F:]
112-
for (int i = 0; host[i]; i++) {
113-
if (!(host[i] >= '0' && host[i] <= '9') &&
114-
!(host[i] >= 'a' && host[i] <= 'f') &&
115-
!(host[i] >= 'A' && host[i] <= 'F') &&
116-
host[i] != ':') {
117-
return false;
118-
}
119-
}
120-
121-
// Build up address
122-
addr->version = NSAPI_IPv6;
123-
124-
// Start with zeroed address
125-
uint16_t shorts[NSAPI_IPv6_BYTES/2];
126-
memset(shorts, 0, sizeof shorts);
127-
128-
int suffix = 0;
129-
130-
// Find double colons and scan suffix
131-
for (int i = 0; host[i]; i++) {
132-
if (host[i] == ':' && host[i+1] == ':') {
133-
suffix = dns_parse_ipv6_chunk(&host[i+2], shorts);
134-
break;
135-
}
136-
}
137-
138-
// Move suffix to end
139-
memmove(&shorts[NSAPI_IPv6_BYTES/2-suffix], &shorts[0],
140-
suffix*sizeof(uint16_t));
141-
142-
// Scan prefix
143-
dns_parse_ipv6_chunk(&host[0], shorts);
144-
145-
// Flip bytes
146-
for (int i = 0; i < NSAPI_IPv6_BYTES/2; i++) {
147-
addr->bytes[2*i+0] = (uint8_t)(shorts[i] >> 8);
148-
addr->bytes[2*i+1] = (uint8_t)(shorts[i] >> 0);
149-
}
150-
151-
return true;
152-
}
15348

15449
// DNS packet parsing
15550
static void dns_append_byte(uint8_t **p, uint8_t byte)
@@ -305,14 +200,14 @@ static int nsapi_dns_query_multiple(NetworkStack *stack, const char *host,
305200
}
306201

307202
// check for simple ip addresses
308-
if (version == NSAPI_IPv4) {
309-
if (dns_parse_ipv4(host, addr)) {
310-
return 0;
311-
}
312-
} else if (version == NSAPI_IPv6) {
313-
if (dns_parse_ipv6(host, addr)) {
314-
return 0;
203+
SocketAddress address;
204+
if (address.set_ip_address(host)) {
205+
if (address.get_ip_version() != version) {
206+
return NSAPI_ERROR_DNS_FAILURE;
315207
}
208+
209+
*addr = address.get_addr();
210+
return 0;
316211
}
317212

318213
// create a udp socket

0 commit comments

Comments
 (0)