aboutsummaryrefslogtreecommitdiff
path: root/src/platform/windows
diff options
context:
space:
mode:
Diffstat (limited to 'src/platform/windows')
-rw-r--r--src/platform/windows/win_resolv.c104
1 files changed, 103 insertions, 1 deletions
diff --git a/src/platform/windows/win_resolv.c b/src/platform/windows/win_resolv.c
index ff356700..d80b5ddf 100644
--- a/src/platform/windows/win_resolv.c
+++ b/src/platform/windows/win_resolv.c
@@ -1,5 +1,5 @@
//
-// Copyright 2019 Staysail Systems, Inc. <info@staysail.tech>
+// Copyright 2020 Staysail Systems, Inc. <info@staysail.tech>
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
//
// This software is supplied under the terms of the MIT License, a
@@ -317,6 +317,108 @@ resolv_worker(void *notused)
}
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)
{
nni_mtx_init(&resolv_mtx);