Skip to content

Commit

Permalink
fixes #844 WebSocket wildcard host errors
Browse files Browse the repository at this point in the history
fixes #1224 wss fails on IPV6 address

This fixes bugs and inconsistencies in the way addresses are
handled for HTTP (and consequently websocket).  The Host:
address line needs to look at numeric IPs and treat wildcards
as if they are not specified, and needs to understand the IPv6
address format using brackets (e.g. [::1]:80).
  • Loading branch information
gdamore committed Jul 28, 2020
1 parent 1669812 commit 09d667c
Show file tree
Hide file tree
Showing 5 changed files with 305 additions and 28 deletions.
6 changes: 6 additions & 0 deletions src/core/platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,12 @@ extern void nni_tcp_resolv(const char *, const char *, int, int, nni_aio *);
// service names using UDP.
extern void nni_udp_resolv(const char *, const char *, int, int, nni_aio *);

// nni_parse_ip parses an IP address, without a port.
extern int nni_parse_ip(const char *, nng_sockaddr *);

// nni_parse_ip_port parses an IP address with an optional port appended.
extern int nni_parse_ip_port(const char *, nng_sockaddr *);

//
// IPC (UNIX Domain Sockets & Named Pipes) Support.
//
Expand Down
111 changes: 108 additions & 3 deletions src/platform/posix/posix_resolv_gai.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Copyright 2019 Staysail Systems, Inc. <[email protected]>
// Copyright 2020 Staysail Systems, Inc. <[email protected]>
// Copyright 2018 Capitar IT Group BV <[email protected]>
//
// This software is supplied under the terms of the MIT License, a
Expand Down Expand Up @@ -257,8 +257,9 @@ resolv_ip(const char *host, const char *serv, int passive, int family,
// NB: must remain valid until this is completed. So we have to
// keep our own copy.

if (host != NULL && nni_strnlen(host, sizeof(item->name_buf)) >=
sizeof(item->name_buf)) {
if (host != NULL &&
nni_strnlen(host, sizeof(item->name_buf)) >=
sizeof(item->name_buf)) {
NNI_FREE_STRUCT(item);
nni_aio_finish_error(aio, NNG_EADDRINVAL);
return;
Expand Down Expand Up @@ -353,6 +354,110 @@ resolv_worker(void *unused)
nni_mtx_unlock(&resolv_mtx);
}

int
parse_ip(const char *addr, nng_sockaddr *sa, bool want_port)
{
struct addrinfo hints;
struct addrinfo *results;
int rv;
bool v6 = false;
bool wrapped = false;
char * port;
char * host;
char * buf;
size_t buf_len;

if (addr == NULL) {
addr = "";
}

buf_len = strlen(addr) + 1;
if ((buf = nni_alloc(buf_len)) == NULL) {
return (NNG_ENOMEM);
}
memcpy(buf, addr, buf_len);
host = buf;
if (*host == '[') {
v6 = true;
wrapped = true;
host++;
} else {
char *s;
for (s = host; *s != '\0'; s++) {
if (*s == '.') {
break;
}
if (*s == ':') {
v6 = true;
break;
}
}
}
for (port = host; *port != '\0'; port++) {
if (wrapped) {
if (*port == ']') {
*port++ = '\0';
wrapped = false;
break;
}
} else if (!v6) {
if (*port == ':') {
break;
}
}
}

if (wrapped) {
// Never got the closing bracket.
rv = NNG_EADDRINVAL;
goto done;
}

if ((!want_port) && (*port != '\0')) {
rv = NNG_EADDRINVAL;
goto done;
} else if (*port == ':') {
*port++ = '\0';
}

if (*port == '\0') {
port = "0";
}

memset(&hints, 0, sizeof(hints));
hints.ai_flags = AI_NUMERICSERV | AI_NUMERICHOST | AI_PASSIVE;
if (v6) {
hints.ai_family = AF_INET6;
}
#ifdef AI_ADDRCONFIG
hints.ai_flags |= AI_ADDRCONFIG;
#endif

rv = getaddrinfo(host, port, &hints, &results);
if ((rv != 0) || (results == NULL)) {
rv = nni_plat_errno(rv);
goto done;
}
nni_posix_sockaddr2nn(sa, (void *) results->ai_addr);
freeaddrinfo(results);

done:
nni_free(buf, buf_len);
return (rv);
}

int
nni_parse_ip(const char *addr, nni_sockaddr *sa)
{
return (parse_ip(addr, sa, false));
}

int
nni_parse_ip_port(const char *addr, nni_sockaddr *sa)
{
return (parse_ip(addr, sa, true));
}

int
nni_posix_resolv_sysinit(void)
{
Expand Down
104 changes: 103 additions & 1 deletion src/platform/windows/win_resolv.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Copyright 2019 Staysail Systems, Inc. <[email protected]>
// Copyright 2020 Staysail Systems, Inc. <[email protected]>
// Copyright 2018 Capitar IT Group BV <[email protected]>
//
// This software is supplied under the terms of the MIT License, a
Expand Down Expand Up @@ -316,6 +316,108 @@ resolv_worker(void *notused)
nni_mtx_unlock(&resolv_mtx);
}

int
parse_ip(const char *addr, nng_sockaddr *sa, bool want_port)
{
struct addrinfo hints;
struct addrinfo *results;
int rv;
bool v6 = false;
bool wrapped = false;
char * port;
char * host;
char * buf;
size_t buf_len;

if (addr == NULL) {
addr = "";
}

buf_len = strlen(addr) + 1;
if ((buf = nni_alloc(buf_len)) == NULL) {
return (NNG_ENOMEM);
}
memcpy(buf, addr, buf_len);
host = buf;
if (*host == '[') {
v6 = true;
wrapped = true;
host++;
} else {
char *s;
for (s = host; *s != '\0'; s++) {
if (*s == '.') {
break;
}
if (*s == ':') {
v6 = true;
break;
}
}
}
for (port = host; *port != '\0'; port++) {
if (wrapped) {
if (*port == ']') {
*port++ = '\0';
wrapped = false;
break;
}
} else if (!v6) {
if (*port == ':') {
break;
}
}
}

if (wrapped) {
// Never got the closing bracket.
rv = NNG_EADDRINVAL;
goto done;
}

if ((!want_port) && (*port != '\0')) {
rv = NNG_EADDRINVAL;
goto done;
} else if (*port == ':') {
*port++ = '\0';
}

if (*port == '\0') {
port = "0";
}

memset(&hints, 0, sizeof(hints));
hints.ai_flags =
AI_ADDRCONFIG | AI_NUMERICSERV | AI_NUMERICHOST | AI_PASSIVE;
if (v6) {
hints.ai_family = AF_INET6;
}

rv = getaddrinfo(host, port, &hints, &results);
if ((rv != 0) || (results == NULL)) {
rv = nni_win_error(rv);
goto done;
}
nni_win_sockaddr2nn(sa, (void *) results->ai_addr);
freeaddrinfo(results);

done:
nni_free(buf, buf_len);
return (rv);
}

int
nni_parse_ip(const char *addr, nni_sockaddr *sa)
{
return (parse_ip(addr, sa, false));
}

int
nni_parse_ip_port(const char *addr, nni_sockaddr *sa)
{
return (parse_ip(addr, sa, true));
}

int
nni_win_resolv_sysinit(void)
{
Expand Down
Loading

0 comments on commit 09d667c

Please sign in to comment.