diff options
| author | Garrett D'Amore <garrett@damore.org> | 2017-07-06 14:45:53 -0700 |
|---|---|---|
| committer | Garrett D'Amore <garrett@damore.org> | 2017-07-06 14:45:53 -0700 |
| commit | 3da27f7c9c1077f285f53b1e80a1befffe104770 (patch) | |
| tree | dad07400dced42b061d036c9dd86aaf501592dfc | |
| parent | 82c70435ec9be9c607de4fbd62d4de9ae7d7c081 (diff) | |
| download | nng-3da27f7c9c1077f285f53b1e80a1befffe104770.tar.gz nng-3da27f7c9c1077f285f53b1e80a1befffe104770.tar.bz2 nng-3da27f7c9c1077f285f53b1e80a1befffe104770.zip | |
Fixes for async resolver, plus a test suite for it.
| -rw-r--r-- | src/core/aio.c | 4 | ||||
| -rw-r--r-- | src/platform/posix/posix_impl.h | 2 | ||||
| -rw-r--r-- | src/platform/posix/posix_resolv_gai.c | 12 | ||||
| -rw-r--r-- | src/platform/posix/posix_thread.c | 12 | ||||
| -rw-r--r-- | tests/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | tests/resolv.c | 164 |
6 files changed, 191 insertions, 4 deletions
diff --git a/src/core/aio.c b/src/core/aio.c index e1d7bdae..c7d2b0b0 100644 --- a/src/core/aio.c +++ b/src/core/aio.c @@ -66,6 +66,10 @@ nni_aio_fini(nni_aio *aio) // At this point the AIO is done. nni_cv_fini(&aio->a_cv); nni_mtx_fini(&aio->a_lk); + + if ((aio->a_naddrs != 0) && (aio->a_addrs != NULL)) { + NNI_FREE_STRUCTS(aio->a_addrs, aio->a_naddrs); + } } diff --git a/src/platform/posix/posix_impl.h b/src/platform/posix/posix_impl.h index 3a2e29e1..407adf74 100644 --- a/src/platform/posix/posix_impl.h +++ b/src/platform/posix/posix_impl.h @@ -69,5 +69,7 @@ struct nni_plat_cv { extern int nni_posix_pollq_sysinit(void); extern void nni_posix_pollq_sysfini(void); +extern int nni_posix_resolv_sysinit(void); +extern void nni_posix_resolv_sysfini(void); #endif // PLATFORM_POSIX_IMPL_H diff --git a/src/platform/posix/posix_resolv_gai.c b/src/platform/posix/posix_resolv_gai.c index 2b2a8436..82febf6e 100644 --- a/src/platform/posix/posix_resolv_gai.c +++ b/src/platform/posix/posix_resolv_gai.c @@ -167,7 +167,7 @@ nni_posix_resolv_task(void *arg) } } // If the only results were not IPv4 or IPv6... - if (aio->a_addrs == 0) { + if (aio->a_naddrs == 0) { rv = NNG_EADDRINVAL; break; } @@ -231,6 +231,9 @@ nni_posix_resolv_ip(const char *host, const char *serv, int passive, nni_posix_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; @@ -254,6 +257,7 @@ nni_posix_resolv_ip(const char *host, const char *serv, int passive, item->name = host; item->serv = serv; item->proto = proto; + item->aio = aio; nni_mtx_lock(&nni_posix_resolv_mtx); // If we were stopped, we're done... @@ -272,7 +276,7 @@ nni_posix_resolv_ip(const char *host, const char *serv, int passive, void -nni_plat_resolv_tcp(const char *host, const char *serv, int family, +nni_plat_tcp_resolv(const char *host, const char *serv, int family, int passive, nni_aio *aio) { nni_posix_resolv_ip(host, serv, passive, family, IPPROTO_TCP, aio); @@ -280,7 +284,7 @@ nni_plat_resolv_tcp(const char *host, const char *serv, int family, int -nni_posix_resolv_init(void) +nni_posix_resolv_sysinit(void) { int rv; @@ -296,7 +300,7 @@ nni_posix_resolv_init(void) void -nni_posix_resolv_fini(void) +nni_posix_resolv_sysfini(void) { if (nni_posix_resolv_tq != NULL) { nni_taskq_fini(nni_posix_resolv_tq); diff --git a/src/platform/posix/posix_thread.c b/src/platform/posix/posix_thread.c index 171a87b9..4137984f 100644 --- a/src/platform/posix/posix_thread.c +++ b/src/platform/posix/posix_thread.c @@ -308,8 +308,20 @@ nni_plat_init(int (*helper)(void)) return (rv); } + if ((rv = nni_posix_resolv_sysinit()) != 0) { + pthread_mutex_unlock(&nni_plat_lock); + nni_posix_pollq_sysfini(); + (void) close(nni_plat_devnull); + pthread_mutexattr_destroy(&nni_mxattr); + pthread_condattr_destroy(&nni_cvattr); + pthread_attr_destroy(&nni_pthread_attr); + return (rv); + + } + if (pthread_atfork(NULL, NULL, nni_atfork_child) != 0) { pthread_mutex_unlock(&nni_plat_lock); + nni_posix_resolv_sysfini(); nni_posix_pollq_sysfini(); (void) close(devnull); pthread_mutexattr_destroy(&nni_mxattr); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 4dc0bd60..5dcc1379 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -81,6 +81,7 @@ add_nng_test(reqrep 5) add_nng_test(pipeline 5) add_nng_test(pollfd 5) add_nng_test(pubsub 5) +add_nng_test(resolv 10) add_nng_test(sock 5) add_nng_test(survey 5) add_nng_test(tcp 5) diff --git a/tests/resolv.c b/tests/resolv.c new file mode 100644 index 00000000..9c07d35f --- /dev/null +++ b/tests/resolv.c @@ -0,0 +1,164 @@ +// +// Copyright 2016 Garrett D'Amore <garrett@damore.org> +// +// This software is supplied under the terms of the MIT License, a +// copy of which should be located in the distribution where this +// file was obtained (LICENSE.txt). A copy of the license may also be +// found online at https://opensource.org/licenses/MIT. +// + +#include "core/nng_impl.h" +#include "convey.h" +#include "stubs.h" + +#include <string.h> +#include <arpa/inet.h> + +static const char * +ip4str(void *addr) +{ + static char buf[256]; + + return (inet_ntop(AF_INET, addr, buf, sizeof (buf))); +} + + +static const char * +ip6str(void *addr) +{ + static char buf[256]; + + return (inet_ntop(AF_INET6, addr, buf, sizeof (buf))); +} + + +TestMain("TCP Resolver", { + nni_init(); + + Convey("Localhost IPv4 resolves", { + nni_aio aio; + const char *str; + memset(&aio, 0, sizeof (aio)); + nni_aio_init(&aio, NULL, NULL); + nni_plat_tcp_resolv("localhost", "80", NNG_AF_INET, 1, + &aio); + nni_aio_wait(&aio); + So(nni_aio_result(&aio) == 0); + So(aio.a_naddrs == 1); + So(aio.a_addrs[0].s_un.s_in.sa_family == NNG_AF_INET); + So(aio.a_addrs[0].s_un.s_in.sa_port == ntohs(80)); + So(aio.a_addrs[0].s_un.s_in.sa_addr == ntohl(0x7f000001)); + str = ip4str(&aio.a_addrs[0].s_un.s_in.sa_addr); + So(strcmp(str, "127.0.0.1") == 0); + nni_aio_fini(&aio); + } + ); + Convey("Localhost IPv6 resolves", { + nni_aio aio; + memset(&aio, 0, sizeof (aio)); + const char *str; + nni_aio_init(&aio, NULL, NULL); + nni_plat_tcp_resolv("localhost", "80", NNG_AF_INET6, 1, + &aio); + nni_aio_wait(&aio); + So(nni_aio_result(&aio) == 0); + So(aio.a_naddrs == 1); + So(aio.a_addrs[0].s_un.s_in6.sa_family == NNG_AF_INET6); + So(aio.a_addrs[0].s_un.s_in6.sa_port == ntohs(80)); + str = ip6str(&aio.a_addrs[0].s_un.s_in6.sa_addr); + So(strcmp(str, "::1") == 0); + nni_aio_fini(&aio); + } + ); + Convey("Localhost UNSPEC resolves", { + nni_aio aio; + memset(&aio, 0, sizeof (aio)); + const char *str; + int i; + nni_aio_init(&aio, NULL, NULL); + nni_plat_tcp_resolv("localhost", "80", NNG_AF_UNSPEC, 1, + &aio); + nni_aio_wait(&aio); + So(nni_aio_result(&aio) == 0); + So(aio.a_naddrs == 2); + for (i = 0; i < 2; i++) { + switch (aio.a_addrs[i].s_un.s_family) { + case NNG_AF_INET6: + So(aio.a_addrs[i].s_un.s_in6.sa_port == + ntohs(80)); + str = + ip6str(&aio.a_addrs[i].s_un.s_in6.sa_addr); + So(strcmp(str, "::1") == 0); + break; + + case NNG_AF_INET: + So(aio.a_addrs[i].s_un.s_in.sa_port == + ntohs(80)); + str = + ip4str(&aio.a_addrs[i].s_un.s_in.sa_addr); + So(strcmp(str, "127.0.0.1") == 0); + break; + default: + So(1 == 0); + } + } + So(aio.a_addrs[0].s_un.s_family != + aio.a_addrs[1].s_un.s_family); + nni_aio_fini(&aio); + } + ); + Convey("Google DNS IPv4 resolves", { + nni_aio aio; + const char *str; + memset(&aio, 0, sizeof (aio)); + nni_aio_init(&aio, NULL, NULL); + nni_plat_tcp_resolv("google-public-dns-a.google.com", + "80", NNG_AF_INET, 1, &aio); + nni_aio_wait(&aio); + So(nni_aio_result(&aio) == 0); + So(aio.a_naddrs == 1); + So(aio.a_addrs[0].s_un.s_in.sa_family == NNG_AF_INET); + So(aio.a_addrs[0].s_un.s_in.sa_port == ntohs(80)); + str = ip4str(&aio.a_addrs[0].s_un.s_in.sa_addr); + So(strcmp(str, "8.8.8.8") == 0); + nni_aio_fini(&aio); + } + ); + Convey("Numeric resolves", { + nni_aio aio; + const char *str; + memset(&aio, 0, sizeof (aio)); + nni_aio_init(&aio, NULL, NULL); + nni_plat_tcp_resolv("8.8.4.4", + "80", NNG_AF_INET, 1, &aio); + nni_aio_wait(&aio); + So(nni_aio_result(&aio) == 0); + So(aio.a_naddrs == 1); + So(aio.a_addrs[0].s_un.s_in.sa_family == NNG_AF_INET); + So(aio.a_addrs[0].s_un.s_in.sa_port == ntohs(80)); + str = ip4str(&aio.a_addrs[0].s_un.s_in.sa_addr); + So(strcmp(str, "8.8.4.4") == 0); + nni_aio_fini(&aio); + } + ); + Convey("Name service resolves", { + nni_aio aio; + const char *str; + memset(&aio, 0, sizeof (aio)); + nni_aio_init(&aio, NULL, NULL); + nni_plat_tcp_resolv("8.8.4.4", + "http", NNG_AF_INET, 1, &aio); + nni_aio_wait(&aio); + So(nni_aio_result(&aio) == 0); + So(aio.a_naddrs == 1); + So(aio.a_addrs[0].s_un.s_in.sa_family == NNG_AF_INET); + So(aio.a_addrs[0].s_un.s_in.sa_port == ntohs(80)); + str = ip4str(&aio.a_addrs[0].s_un.s_in.sa_addr); + So(strcmp(str, "8.8.4.4") == 0); + nni_aio_fini(&aio); + } + ); + + nni_fini(); + } + ) |
