aboutsummaryrefslogtreecommitdiff
path: root/src/platform/windows
diff options
context:
space:
mode:
Diffstat (limited to 'src/platform/windows')
-rw-r--r--src/platform/windows/win_ipc.c10
-rw-r--r--src/platform/windows/win_net.c85
-rw-r--r--src/platform/windows/win_resolv.c154
3 files changed, 89 insertions, 160 deletions
diff --git a/src/platform/windows/win_ipc.c b/src/platform/windows/win_ipc.c
index 20ae81b5..bca579cf 100644
--- a/src/platform/windows/win_ipc.c
+++ b/src/platform/windows/win_ipc.c
@@ -22,6 +22,7 @@ struct nni_plat_ipc_pipe {
struct nni_plat_ipc_ep {
char path[256];
+ nni_sockaddr addr;
int mode;
int started;
HANDLE p; // accept side only
@@ -205,15 +206,13 @@ nni_plat_ipc_pipe_fini(nni_plat_ipc_pipe *pipe)
}
int
-nni_plat_ipc_ep_init(nni_plat_ipc_ep **epp, const char *url, int mode)
+nni_plat_ipc_ep_init(nni_plat_ipc_ep **epp, const nni_sockaddr *sa, int mode)
{
const char * path;
nni_plat_ipc_ep *ep;
- if (strncmp(url, "ipc://", strlen("ipc://")) != 0) {
- return (NNG_EADDRINVAL);
- }
- path = url + strlen("ipc://");
+ path = sa->s_un.s_path.sa_path;
+
if ((ep = NNI_ALLOC_STRUCT(ep)) == NULL) {
return (NNG_ENOMEM);
}
@@ -222,6 +221,7 @@ nni_plat_ipc_ep_init(nni_plat_ipc_ep **epp, const char *url, int mode)
ep->mode = mode;
NNI_LIST_NODE_INIT(&ep->node);
+ ep->addr = *sa;
(void) snprintf(ep->path, sizeof(ep->path), "\\\\.\\pipe\\%s", path);
*epp = ep;
diff --git a/src/platform/windows/win_net.c b/src/platform/windows/win_net.c
index dee9b745..07c30e11 100644
--- a/src/platform/windows/win_net.c
+++ b/src/platform/windows/win_net.c
@@ -25,7 +25,6 @@ struct nni_plat_tcp_ep {
SOCKET acc_s;
nni_win_event con_ev;
nni_win_event acc_ev;
- int mode;
int started;
int bound;
@@ -285,19 +284,12 @@ nni_plat_tcp_pipe_fini(nni_plat_tcp_pipe *pipe)
NNI_FREE_STRUCT(pipe);
}
-extern int nni_tcp_parse_url(char *, char **, char **, char **, char **);
-
int
-nni_plat_tcp_ep_init(nni_plat_tcp_ep **epp, const char *url, int mode)
+nni_plat_tcp_ep_init(nni_plat_tcp_ep **epp, const nni_sockaddr *lsa,
+ const nni_sockaddr *rsa, int mode)
{
- char buf[NNG_MAXADDRLEN];
nni_plat_tcp_ep *ep;
- char * rhost;
- char * rserv;
- char * lhost;
- char * lserv;
int rv;
- nni_aio aio;
SOCKET s;
DWORD nbytes;
GUID guid1 = WSAID_CONNECTEX;
@@ -308,55 +300,13 @@ nni_plat_tcp_ep_init(nni_plat_tcp_ep **epp, const char *url, int mode)
}
ZeroMemory(ep, sizeof(ep));
- ep->mode = mode;
- ep->s = INVALID_SOCKET;
-
- nni_aio_init(&aio, NULL, NULL);
+ ep->s = INVALID_SOCKET;
- snprintf(buf, sizeof(buf), "%s", url);
- if (mode == NNI_EP_MODE_DIAL) {
- rv = nni_tcp_parse_url(buf, &rhost, &rserv, &lhost, &lserv);
- if (rv != 0) {
- goto fail;
- }
- // Have to ahve a remote destination.
- if ((rhost == NULL) || (rserv == NULL)) {
- rv = NNG_EADDRINVAL;
- goto fail;
- }
- } else {
- rv = nni_tcp_parse_url(buf, &lhost, &lserv, &rhost, &rserv);
- if (rv != 0) {
- goto fail;
- }
- // Remote destination makes no sense when listening.
- if ((rhost != NULL) || (rserv != NULL)) {
- rv = NNG_EADDRINVAL;
- goto fail;
- }
- if (lserv == NULL) {
- // missing port to listen on!
- rv = NNG_EADDRINVAL;
- goto fail;
- }
+ if (rsa->s_un.s_family != NNG_AF_UNSPEC) {
+ ep->remlen = nni_win_tcp_addr(&ep->remaddr, rsa);
}
-
- if ((rserv != NULL) || (rhost != NULL)) {
- nni_plat_tcp_resolv(rhost, rserv, NNG_AF_INET6, 0, &aio);
- nni_aio_wait(&aio);
- if ((rv = nni_aio_result(&aio)) != 0) {
- goto fail;
- }
- ep->remlen = nni_win_tcp_addr(&ep->remaddr, &aio.a_addrs[0]);
- }
-
- if ((lserv != NULL) || (lhost != NULL)) {
- nni_plat_tcp_resolv(lhost, lserv, NNG_AF_INET6, 1, &aio);
- nni_aio_wait(&aio);
- if ((rv = nni_aio_result(&aio)) != 0) {
- goto fail;
- }
- ep->loclen = nni_win_tcp_addr(&ep->locaddr, &aio.a_addrs[0]);
+ if (lsa->s_un.s_family != NNG_AF_UNSPEC) {
+ ep->loclen = nni_win_tcp_addr(&ep->locaddr, lsa);
}
// Create a scratch socket for use with ioctl.
@@ -392,7 +342,6 @@ nni_plat_tcp_ep_init(nni_plat_tcp_ep **epp, const char *url, int mode)
goto fail;
}
- nni_aio_fini(&aio);
*epp = ep;
return (0);
@@ -401,7 +350,6 @@ fail:
closesocket(s);
}
nni_plat_tcp_ep_fini(ep);
- nni_aio_fini(&aio);
return (rv);
}
@@ -433,14 +381,11 @@ nni_win_tcp_listen(nni_plat_tcp_ep *ep)
BOOL yes;
SOCKET s;
- if (ep->mode != NNI_EP_MODE_LISTEN) {
- return (NNG_EINVAL);
- }
if (ep->started) {
return (NNG_EBUSY);
}
- s = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
+ s = socket(ep->locaddr.ss_family, SOCK_STREAM, IPPROTO_TCP);
if (s == INVALID_SOCKET) {
rv = nni_win_error(GetLastError());
goto fail;
@@ -598,7 +543,7 @@ nni_win_tcp_con_finish(nni_win_event *evt, nni_aio *aio)
s = ep->s;
ep->s = INVALID_SOCKET;
- // The socket was already registere with the IOCP.
+ // The socket was already registered with the IOCP.
if (((rv = evt->status) != 0) ||
((rv = nni_win_tcp_pipe_init(&pipe, s)) != 0)) {
@@ -621,8 +566,15 @@ nni_win_tcp_con_start(nni_win_event *evt, nni_aio *aio)
SOCKADDR_STORAGE bss;
int len;
int rv;
+ int family;
- s = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
+ if (ep->loclen > 0) {
+ family = ep->locaddr.ss_family;
+ } else {
+ family = ep->remaddr.ss_family;
+ }
+
+ s = socket(family, SOCK_STREAM, IPPROTO_TCP);
if (s == INVALID_SOCKET) {
evt->status = nni_win_error(GetLastError());
evt->count = 0;
@@ -632,7 +584,7 @@ nni_win_tcp_con_start(nni_win_event *evt, nni_aio *aio)
nni_win_tcp_sockinit(s);
// Windows ConnectEx requires the socket to be bound first.
- if (ep->loclen != 0) {
+ if (ep->loclen > 0) {
bss = ep->locaddr;
len = ep->loclen;
} else {
@@ -644,6 +596,7 @@ nni_win_tcp_con_start(nni_win_event *evt, nni_aio *aio)
evt->status = nni_win_error(GetLastError());
evt->count = 0;
closesocket(s);
+
return (1);
}
// Register with the I/O completion port so we can get the
diff --git a/src/platform/windows/win_resolv.c b/src/platform/windows/win_resolv.c
index d157cf0f..331a2a56 100644
--- a/src/platform/windows/win_resolv.c
+++ b/src/platform/windows/win_resolv.c
@@ -104,92 +104,66 @@ nni_win_resolv_task(void *arg)
struct addrinfo hints;
struct addrinfo * results;
struct addrinfo * probe;
- int i, rv;
+ int rv;
results = NULL;
- switch (item->family) {
- case AF_INET:
- case AF_INET6:
- case AF_UNSPEC:
- // We treat these all as IP addresses. The service and the
- // host part are split.
- memset(&hints, 0, sizeof(hints));
- if (item->passive) {
- hints.ai_flags |= AI_PASSIVE;
- }
- hints.ai_flags |= AI_ADDRCONFIG;
- hints.ai_protocol = item->proto;
- hints.ai_family = item->family;
- if (item->family == AF_INET6) {
- hints.ai_flags |= AI_V4MAPPED;
- }
+ // We treat these all as IP addresses. The service and the
+ // host part are split.
+ memset(&hints, 0, sizeof(hints));
+ if (item->passive) {
+ hints.ai_flags |= AI_PASSIVE;
+ }
+ hints.ai_flags |= AI_ADDRCONFIG;
+ hints.ai_protocol = item->proto;
+ hints.ai_family = item->family;
+ if (item->family == AF_INET6) {
+ hints.ai_flags |= AI_V4MAPPED;
+ }
- rv = getaddrinfo(item->name, item->serv, &hints, &results);
- if (rv != 0) {
- rv = nni_win_gai_errno(rv);
+ rv = getaddrinfo(item->name, item->serv, &hints, &results);
+ if (rv != 0) {
+ rv = nni_win_gai_errno(rv);
+ goto done;
+ }
+
+ // We only take the first matching address. Presumably
+ // DNS load balancing is done by the resolver/server.
+
+ rv = NNG_EADDRINVAL;
+ for (probe = results; probe != NULL; probe = probe->ai_next) {
+ if ((probe->ai_addr->sa_family == AF_INET) ||
+ (probe->ai_addr->sa_family == AF_INET6)) {
break;
}
+ }
- // Count the total number of results.
- aio->a_naddrs = 0;
- for (probe = results; probe != NULL; probe = probe->ai_next) {
- // Only count v4 and v6 addresses.
- switch (probe->ai_addr->sa_family) {
- case AF_INET:
- case AF_INET6:
- aio->a_naddrs++;
- break;
- }
- }
- // If the only results were not IPv4 or IPv6...
- if (aio->a_naddrs == 0) {
- rv = NNG_EADDRINVAL;
+ if (probe != NULL) {
+ struct sockaddr_in * sin;
+ struct sockaddr_in6 *sin6;
+ nng_sockaddr * sa = aio->a_addr;
+
+ switch (probe->ai_addr->sa_family) {
+ case AF_INET:
+ rv = 0;
+ sin = (void *) probe->ai_addr;
+ sa->s_un.s_in.sa_family = NNG_AF_INET;
+ sa->s_un.s_in.sa_port = sin->sin_port;
+ sa->s_un.s_in.sa_addr = sin->sin_addr.s_addr;
break;
- }
- aio->a_addrs = NNI_ALLOC_STRUCTS(aio->a_addrs, aio->a_naddrs);
- if (aio->a_addrs == NULL) {
- aio->a_naddrs = 0;
- rv = NNG_ENOMEM;
+ case AF_INET6:
+ rv = 0;
+ sin6 = (void *) probe->ai_addr;
+ sa->s_un.s_in6.sa_family = NNG_AF_INET6;
+ sa->s_un.s_in6.sa_port = sin6->sin6_port;
+ memcpy(sa->s_un.s_in6.sa_addr, sin6->sin6_addr.s6_addr,
+ 16);
break;
}
- i = 0;
- for (probe = results; probe != NULL; probe = probe->ai_next) {
- struct sockaddr_in * sin;
- struct sockaddr_in6 *sin6;
- nng_sockaddr * sa = &aio->a_addrs[i];
-
- switch (probe->ai_addr->sa_family) {
- case AF_INET:
- sin = (void *) probe->ai_addr;
- sa->s_un.s_in.sa_family = NNG_AF_INET;
- sa->s_un.s_in.sa_port = sin->sin_port;
- sa->s_un.s_in.sa_addr = sin->sin_addr.s_addr;
- i++;
- break;
- case AF_INET6:
- sin6 = (void *) probe->ai_addr;
- sa->s_un.s_in6.sa_family = NNG_AF_INET6;
- sa->s_un.s_in6.sa_port = sin6->sin6_port;
- memcpy(sa->s_un.s_in6.sa_addr,
- sin6->sin6_addr.s6_addr, 16);
- i++;
- break;
- default:
- // Other address types are ignored.
- break;
- }
- }
- // Resolution complete!
- rv = 0;
- break;
-
- default:
- // Some other family requested we don't understand.
- rv = NNG_ENOTSUP;
- break;
}
+done:
+
if (results != NULL) {
freeaddrinfo(results);
}
@@ -204,35 +178,37 @@ nni_win_resolv_ip(const char *host, const char *serv, int passive, int family,
{
nni_win_resolv_item *item;
int rv;
-
- if ((aio->a_naddrs != 0) && (aio->a_addrs != NULL)) {
- NNI_FREE_STRUCTS(aio->a_addrs, aio->a_naddrs);
- }
- if ((item = NNI_ALLOC_STRUCT(item)) == NULL) {
- nni_aio_finish(aio, NNG_ENOMEM, 0);
- return;
- }
-
- nni_task_init(
- nni_win_resolv_tq, &item->task, nni_win_resolv_task, item);
+ int fam;
switch (family) {
case NNG_AF_INET:
- item->family = AF_INET;
+ fam = AF_INET;
break;
case NNG_AF_INET6:
- item->family = AF_INET6;
+ fam = AF_INET6;
break;
case NNG_AF_UNSPEC:
- item->family = AF_UNSPEC;
+ fam = AF_UNSPEC;
break;
+ default:
+ nni_aio_finish_error(aio, NNG_ENOTSUP);
+ return;
}
- // NB: host and serv must remain valid until this is completed.
+
+ if ((item = NNI_ALLOC_STRUCT(item)) == NULL) {
+ nni_aio_finish_error(aio, NNG_ENOMEM);
+ return;
+ }
+
+ nni_task_init(
+ nni_win_resolv_tq, &item->task, nni_win_resolv_task, item);
+
item->passive = passive;
item->name = host;
item->serv = serv;
item->proto = proto;
item->aio = aio;
+ item->family = fam;
nni_mtx_lock(&nni_win_resolv_mtx);
// If we were stopped, we're done...