diff options
Diffstat (limited to 'src/platform/windows')
| -rw-r--r-- | src/platform/windows/win_ipc.c | 10 | ||||
| -rw-r--r-- | src/platform/windows/win_net.c | 85 | ||||
| -rw-r--r-- | src/platform/windows/win_resolv.c | 154 |
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... |
