mirror of
https://github.com/cesanta/mongoose.git
synced 2026-10-30 12:50:58 +00:00
Add IPv6 client test
This commit is contained in:
1 parent
fbab767b9f
commit
2e87783246
13 files changed
+515
-244
No files matched your search
@@ -20,9 +20,18 @@ int mg_printf(struct mg_connection *c, const char *fmt, ...) {
|
||||
}
|
||||
|
||||
char *mg_straddr(struct mg_connection *c, char *buf, size_t len) {
|
||||
unsigned char *p = (unsigned char *) &c->peer.ip;
|
||||
snprintf(buf, len, "%d.%d.%d.%d:%hu", p[0], p[1], p[2], p[3],
|
||||
mg_ntohs(c->peer.port));
|
||||
if (c->peer.is_ip6) {
|
||||
uint16_t *p = (uint16_t *) c->peer.ip6;
|
||||
snprintf(buf, len, "[%x:%x:%x:%x:%x:%x:%x:%x]:%hu", mg_htons(p[0]),
|
||||
mg_htons(p[1]), mg_htons(p[2]), mg_htons(p[3]), mg_htons(p[4]),
|
||||
mg_htons(p[5]), mg_htons(p[6]), mg_htons(p[7]),
|
||||
mg_ntohs(c->peer.port));
|
||||
|
||||
} else {
|
||||
unsigned char *p = (unsigned char *) &c->peer.ip;
|
||||
snprintf(buf, len, "%d.%d.%d.%d:%hu", p[0], p[1], p[2], p[3],
|
||||
mg_ntohs(c->peer.port));
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
@@ -33,35 +42,73 @@ char *mg_ntoa(const struct mg_addr *addr, char *buf, size_t len) {
|
||||
return buf;
|
||||
}
|
||||
|
||||
static bool mg_atonl(struct mg_str str, struct mg_addr *addr) {
|
||||
if (mg_casecmp(str.ptr, "localhost") != 0) return false;
|
||||
addr->ip = mg_htonl(0x7f000001);
|
||||
addr->is_ip6 = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool mg_aton4(struct mg_str str, struct mg_addr *addr) {
|
||||
uint8_t data[4] = {0, 0, 0, 0};
|
||||
size_t i, num_dots = 0;
|
||||
for (i = 0; i < str.len; i++) {
|
||||
if (str.ptr[i] >= '0' && str.ptr[i] <= '9') {
|
||||
int octet = data[num_dots] * 10 + (str.ptr[i] - '0');
|
||||
if (octet > 255) return false;
|
||||
data[num_dots] = octet;
|
||||
} else if (str.ptr[i] == '.') {
|
||||
if (num_dots >= 3 || i == 0 || str.ptr[i - 1] == '.') return false;
|
||||
num_dots++;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (num_dots != 3 || str.ptr[i - 1] == '.') return false;
|
||||
memcpy(&addr->ip, data, sizeof(data));
|
||||
addr->is_ip6 = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool mg_aton6(struct mg_str str, struct mg_addr *addr) {
|
||||
size_t i, j = 0, n = 0, dc = 42;
|
||||
for (i = 0; i < str.len; i++) {
|
||||
if ((str.ptr[i] >= '0' && str.ptr[i] <= '9') ||
|
||||
(str.ptr[i] >= 'a' && str.ptr[i] <= 'f') ||
|
||||
(str.ptr[i] >= 'A' && str.ptr[i] <= 'F')) {
|
||||
unsigned long val;
|
||||
if (i > j + 3) return false;
|
||||
// LOG(LL_DEBUG, ("%zu %zu [%.*s]", i, j, (int) (i - j + 1),
|
||||
// &str.ptr[j]));
|
||||
val = mg_unhexn(&str.ptr[j], i - j + 1);
|
||||
addr->ip6[n] = (uint8_t)((val >> 8) & 255);
|
||||
addr->ip6[n + 1] = (uint8_t)(val & 255);
|
||||
} else if (str.ptr[i] == ':') {
|
||||
j = i + 1;
|
||||
if (i > 0 && str.ptr[i - 1] == ':') {
|
||||
dc = n; // Double colon
|
||||
if (i > 1 && str.ptr[i - 2] == ':') return false;
|
||||
} else if (i > 0) {
|
||||
n += 2;
|
||||
}
|
||||
if (n > 14) return false;
|
||||
addr->ip6[n] = addr->ip6[n + 1] = 0; // For trailing ::
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (n < 14 && dc == 42) return false;
|
||||
if (n < 14) {
|
||||
memmove(&addr->ip6[dc + (14 - n)], &addr->ip6[dc], n - dc + 2);
|
||||
memset(&addr->ip6[dc], 0, 14 - n);
|
||||
}
|
||||
addr->is_ip6 = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool mg_aton(struct mg_str str, struct mg_addr *addr) {
|
||||
// LOG(LL_INFO, ("[%.*s]", (int) str.len, str.ptr));
|
||||
if (!mg_casecmp(str.ptr, "localhost")) {
|
||||
addr->ip = mg_htonl(0x7f000001);
|
||||
return true;
|
||||
} else if (addr->is_ip6) {
|
||||
return false;
|
||||
} else {
|
||||
uint8_t data[4] = {0, 0, 0, 0};
|
||||
size_t i, num_octets = 0;
|
||||
// LOG(LL_DEBUG, ("[%.*s]", (int) str.len, str.ptr));
|
||||
for (i = 0; i < str.len; i++) {
|
||||
// LOG(LL_DEBUG,
|
||||
//(" %c %zu %hhu %zu", str.ptr[i], i, data[num_octets], num_octets));
|
||||
if (str.ptr[i] >= '0' && str.ptr[i] <= '9') {
|
||||
int octet = data[num_octets] * 10 + (str.ptr[i] - '0');
|
||||
if (octet > 255) return false;
|
||||
data[num_octets] = octet;
|
||||
} else if (str.ptr[i] == '.') {
|
||||
if (num_octets >= 3 || i == 0 || str.ptr[i - 1] == '.') return false;
|
||||
num_octets++;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (num_octets != 3 || str.ptr[i - 1] == '.') return false;
|
||||
memcpy(&addr->ip, data, sizeof(data));
|
||||
return true;
|
||||
}
|
||||
return mg_atonl(str, addr) || mg_aton4(str, addr) || mg_aton6(str, addr);
|
||||
}
|
||||
|
||||
void mg_mgr_free(struct mg_mgr *mgr) {
|
||||
@@ -87,4 +134,6 @@ void mg_mgr_init(struct mg_mgr *mgr) {
|
||||
#endif
|
||||
memset(mgr, 0, sizeof(*mgr));
|
||||
mgr->dnstimeout = 3000;
|
||||
mgr->dns4.url = "udp://8.8.8.8:53";
|
||||
mgr->dns6.url = "udp://[2001:4860:4860::8888]:53";
|
||||
}
|
||||
Reference in new issue
Block a user