aboutsummaryrefslogtreecommitdiff
path: root/src/platform
diff options
context:
space:
mode:
Diffstat (limited to 'src/platform')
-rw-r--r--src/platform/posix/posix_resolv_gai.c73
-rw-r--r--src/platform/resolver_test.c57
-rw-r--r--src/platform/windows/win_resolv.c74
3 files changed, 106 insertions, 98 deletions
diff --git a/src/platform/posix/posix_resolv_gai.c b/src/platform/posix/posix_resolv_gai.c
index f85c27c1..7a0f8e1f 100644
--- a/src/platform/posix/posix_resolv_gai.c
+++ b/src/platform/posix/posix_resolv_gai.c
@@ -10,6 +10,7 @@
#include "core/init.h"
#include "core/nng_impl.h"
+#include "nng/nng.h"
#ifdef NNG_USE_POSIX_RESOLV_GAI
@@ -17,6 +18,7 @@
#include <errno.h>
#include <netdb.h>
#include <netinet/in.h>
+#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
@@ -49,8 +51,8 @@ typedef struct resolv_item resolv_item;
struct resolv_item {
int family;
bool passive;
- char *host;
- char *serv;
+ char host[256];
+ char serv[8];
nni_aio *aio;
nng_sockaddr *sa;
};
@@ -58,8 +60,6 @@ struct resolv_item {
static void
resolv_free_item(resolv_item *item)
{
- nni_strfree(item->serv);
- nni_strfree(item->host);
NNI_FREE_STRUCT(item);
}
@@ -155,29 +155,12 @@ resolv_task(resolv_item *item)
}
hints.ai_family = item->family;
hints.ai_socktype = SOCK_STREAM;
-
- // Check to see if this is a numeric port number, and if it is
- // make sure that it's in the valid range (because Windows may
- // incorrectly simple do a conversion and mask off upper bits.
- if (item->serv != NULL) {
- long port;
- char *end;
- port = strtol(item->serv, &end, 10);
- if (*end == '\0') { // we fully converted it as a number...
- hints.ai_flags |= AI_NUMERICSERV;
-
- // Not a valid port number. Fail.
- if ((port < 0) || (port > 0xffff)) {
- rv = NNG_EADDRINVAL;
- goto done;
- }
- }
- }
+ hints.ai_flags |= AI_NUMERICSERV;
// We can pass any non-zero service number, but we have to pass
// *something*, in case we are using a NULL hostname.
- if ((rv = getaddrinfo(item->host, item->serv, &hints, &results)) !=
- 0) {
+ if ((rv = getaddrinfo(item->host[0] != 0 ? item->host : NULL,
+ item->serv, &hints, &results)) != 0) {
rv = posix_gai_errno(rv);
goto done;
}
@@ -237,7 +220,7 @@ done:
}
void
-nni_resolv_ip(const char *host, const char *serv, int af, bool passive,
+nni_resolv_ip(const char *host, uint16_t port, int af, bool passive,
nng_sockaddr *sa, nni_aio *aio)
{
resolv_item *item;
@@ -247,6 +230,10 @@ nni_resolv_ip(const char *host, const char *serv, int af, bool passive,
if (nni_aio_begin(aio) != 0) {
return;
}
+ if (host != NULL && strlen(host) >= sizeof(item->host)) {
+ nni_aio_finish_error(aio, NNG_EADDRINVAL);
+ return;
+ }
switch (af) {
case NNG_AF_INET:
fam = AF_INET;
@@ -275,19 +262,11 @@ nni_resolv_ip(const char *host, const char *serv, int af, bool passive,
return;
}
- if (serv == NULL || strcmp(serv, "") == 0) {
- item->serv = NULL;
- } else if ((item->serv = nni_strdup(serv)) == NULL) {
- nni_aio_finish_error(aio, NNG_ENOMEM);
- resolv_free_item(item);
- return;
- }
+ snprintf(item->serv, sizeof(item->serv), "%u", port);
if (host == NULL) {
- item->host = NULL;
- } else if ((item->host = nni_strdup(host)) == NULL) {
- nni_aio_finish_error(aio, NNG_ENOMEM);
- resolv_free_item(item);
- return;
+ item->host[0] = '\0';
+ } else {
+ snprintf(item->host, sizeof(item->host), "%s", host);
}
item->aio = aio;
@@ -478,6 +457,26 @@ nni_parse_ip_port(const char *addr, nni_sockaddr *sa)
}
int
+nni_get_port_by_name(const char *name, uint16_t *portp)
+{
+ struct servent *se;
+ long port;
+ char *end = NULL;
+
+ port = strtol(name, &end, 10);
+ if ((*end == '\0') && (port >= 0) && (port <= 0xffff)) {
+ *portp = (uint16_t) port;
+ return (0);
+ }
+
+ if ((se = getservbyname(name, "tcp")) != NULL) {
+ *portp = (uint16_t) ntohs(se->s_port);
+ return (0);
+ }
+ return (NNG_EADDRINVAL);
+}
+
+int
nni_posix_resolv_sysinit(nng_init_params *params)
{
resolv_fini = false;
diff --git a/src/platform/resolver_test.c b/src/platform/resolver_test.c
index 64554291..9c7db2c0 100644
--- a/src/platform/resolver_test.c
+++ b/src/platform/resolver_test.c
@@ -9,6 +9,7 @@
//
#include "core/nng_impl.h"
+#include "core/platform.h"
#include <nuts.h>
@@ -41,8 +42,8 @@ test_google_dns(void)
nng_sockaddr sa;
NUTS_PASS(nng_aio_alloc(&aio, NULL, NULL));
- nni_resolv_ip("google-public-dns-a.google.com", "80", NNG_AF_INET,
- true, &sa, aio);
+ nni_resolv_ip(
+ "google-public-dns-a.google.com", 80, NNG_AF_INET, true, &sa, aio);
nng_aio_wait(aio);
NUTS_PASS(nng_aio_result(aio));
NUTS_TRUE(sa.s_in.sa_family == NNG_AF_INET);
@@ -52,13 +53,29 @@ test_google_dns(void)
}
void
+test_hostname_too_long(void)
+{
+ nng_aio *aio;
+ nng_sockaddr sa;
+ char buffer[512];
+
+ memset(buffer, 'a', sizeof(buffer) - 1);
+ buffer[sizeof(buffer) - 1] = '\0';
+ NUTS_PASS(nng_aio_alloc(&aio, NULL, NULL));
+ nni_resolv_ip(buffer, 80, NNG_AF_INET, true, &sa, aio);
+ nng_aio_wait(aio);
+ NUTS_FAIL(nng_aio_result(aio), NNG_EADDRINVAL);
+ nng_aio_free(aio);
+}
+
+void
test_numeric_addr(void)
{
nng_aio *aio;
nng_sockaddr sa;
NUTS_PASS(nng_aio_alloc(&aio, NULL, NULL));
- nni_resolv_ip("8.8.4.4", "69", NNG_AF_INET, true, &sa, aio);
+ nni_resolv_ip("8.8.4.4", 69, NNG_AF_INET, true, &sa, aio);
nng_aio_wait(aio);
NUTS_PASS(nng_aio_result(aio));
NUTS_TRUE(sa.s_in.sa_family == NNG_AF_INET);
@@ -79,7 +96,7 @@ test_numeric_v6(void)
}
NUTS_MSG("IPV6 support present");
NUTS_PASS(nng_aio_alloc(&aio, NULL, NULL));
- nni_resolv_ip("::1", "80", NNG_AF_INET6, true, &sa, aio);
+ nni_resolv_ip("::1", 80, NNG_AF_INET6, true, &sa, aio);
nng_aio_wait(aio);
NUTS_PASS(nng_aio_result(aio));
NUTS_TRUE(sa.s_in6.sa_family == NNG_AF_INET6);
@@ -94,14 +111,21 @@ test_service_names(void)
{
nng_aio *aio;
nng_sockaddr sa;
+ uint16_t port;
NUTS_PASS(nng_aio_alloc(&aio, NULL, NULL));
- nni_resolv_ip("8.8.4.4", "http", NNG_AF_INET, true, &sa, aio);
+ nni_resolv_ip("8.8.4.4", 80, NNG_AF_INET, true, &sa, aio);
nng_aio_wait(aio);
NUTS_PASS(nng_aio_result(aio));
NUTS_TRUE(sa.s_in.sa_port == nuts_be16(80));
NUTS_TRUE(sa.s_in.sa_addr = nuts_be32(0x08080404));
nng_aio_free(aio);
+
+ NUTS_PASS(nni_get_port_by_name("http", &port));
+ NUTS_TRUE(port == 80);
+
+ NUTS_PASS(nni_get_port_by_name("25", &port));
+ NUTS_TRUE(port == 25);
}
void
@@ -111,7 +135,7 @@ test_localhost_v4(void)
nng_sockaddr sa;
NUTS_PASS(nng_aio_alloc(&aio, NULL, NULL));
- nni_resolv_ip("localhost", "80", NNG_AF_INET, true, &sa, aio);
+ nni_resolv_ip("localhost", 80, NNG_AF_INET, true, &sa, aio);
nng_aio_wait(aio);
NUTS_PASS(nng_aio_result(aio));
NUTS_TRUE(sa.s_in.sa_family == NNG_AF_INET);
@@ -127,7 +151,7 @@ test_localhost_unspecified(void)
nng_sockaddr sa;
NUTS_PASS(nng_aio_alloc(&aio, NULL, NULL));
- nni_resolv_ip("localhost", "80", NNG_AF_UNSPEC, true, &sa, aio);
+ nni_resolv_ip("localhost", 80, NNG_AF_UNSPEC, true, &sa, aio);
nng_aio_wait(aio);
NUTS_PASS(nng_aio_result(aio));
NUTS_TRUE(
@@ -154,7 +178,7 @@ test_null_passive(void)
nng_sockaddr sa;
NUTS_PASS(nng_aio_alloc(&aio, NULL, NULL));
- nni_resolv_ip(NULL, "80", NNG_AF_INET, true, &sa, aio);
+ nni_resolv_ip(NULL, 80, NNG_AF_INET, true, &sa, aio);
nng_aio_wait(aio);
NUTS_PASS(nng_aio_result(aio));
NUTS_TRUE(sa.s_in.sa_family == NNG_AF_INET);
@@ -170,7 +194,7 @@ test_null_not_passive(void)
nng_sockaddr sa;
NUTS_PASS(nng_aio_alloc(&aio, NULL, NULL));
- nni_resolv_ip(NULL, "80", NNG_AF_INET, false, &sa, aio);
+ nni_resolv_ip(NULL, 80, NNG_AF_INET, false, &sa, aio);
nng_aio_wait(aio);
// We can either get invalid address, or a loopback address.
// Most systems do the former, but Linux does the latter.
@@ -184,21 +208,9 @@ test_null_not_passive(void)
nng_aio_free(aio);
}
-void
-test_bad_port_number(void)
-{
- nng_aio *aio;
- nng_sockaddr sa;
-
- NUTS_PASS(nng_aio_alloc(&aio, NULL, NULL));
- nni_resolv_ip("1.1.1.1", "1000000", NNG_AF_INET, true, &sa, aio);
- nng_aio_wait(aio);
- NUTS_FAIL(nng_aio_result(aio), NNG_EADDRINVAL);
- nng_aio_free(aio);
-}
-
NUTS_TESTS = {
{ "resolve google dns", test_google_dns },
+ { "resolve hostname too long", test_hostname_too_long },
{ "resolve numeric addr", test_numeric_addr },
#ifdef NNG_ENABLE_IPV6
{ "resolve numeric v6", test_numeric_v6 },
@@ -208,6 +220,5 @@ NUTS_TESTS = {
{ "resolve localhost unspecified", test_localhost_unspecified },
{ "resolve null passive", test_null_passive },
{ "resolve null not passive", test_null_not_passive },
- { "resolve bad port number", test_bad_port_number },
{ NULL, NULL },
};
diff --git a/src/platform/windows/win_resolv.c b/src/platform/windows/win_resolv.c
index 1b1ae7b9..ece14655 100644
--- a/src/platform/windows/win_resolv.c
+++ b/src/platform/windows/win_resolv.c
@@ -33,8 +33,8 @@ typedef struct resolv_item resolv_item;
struct resolv_item {
int family;
bool passive;
- char *host;
- char *serv;
+ char host[256];
+ char serv[8];
nni_aio *aio;
nng_sockaddr *sa;
};
@@ -42,8 +42,6 @@ struct resolv_item {
static void
resolv_free_item(resolv_item *item)
{
- nni_strfree(item->serv);
- nni_strfree(item->host);
NNI_FREE_STRUCT(item);
}
@@ -118,27 +116,10 @@ resolv_task(resolv_item *item)
}
hints.ai_family = item->family;
hints.ai_socktype = SOCK_STREAM;
+ hints.ai_flags |= AI_NUMERICSERV;
- // Check to see if this is a numeric port number, and if it is
- // make sure that it's in the valid range (because Windows may
- // incorrectly simple do a conversion and mask off upper bits.
- if (item->serv != NULL) {
- long port;
- char *end;
- port = strtol(item->serv, &end, 10);
- if (*end == '\0') { // we fully converted it as a number...
- hints.ai_flags |= AI_NUMERICSERV;
-
- // Not a valid port number. Fail.
- if ((port < 0) || (port > 0xffff)) {
- rv = NNG_EADDRINVAL;
- goto done;
- }
- }
- }
-
- if ((rv = getaddrinfo(item->host, item->serv, &hints, &results)) !=
- 0) {
+ if ((rv = getaddrinfo(item->host[0] != 0 ? item->host : NULL,
+ item->serv, &hints, &results)) != 0) {
rv = resolv_errno(rv);
goto done;
}
@@ -199,7 +180,7 @@ done:
}
void
-nni_resolv_ip(const char *host, const char *serv, int family, bool passive,
+nni_resolv_ip(const char *host, uint16_t port, int family, bool passive,
nng_sockaddr *sa, nni_aio *aio)
{
resolv_item *item;
@@ -209,6 +190,11 @@ nni_resolv_ip(const char *host, const char *serv, int family, bool passive,
if (nni_aio_begin(aio) != 0) {
return;
}
+ if (host != NULL && strlen(host) >= sizeof(item->host)) {
+ nni_aio_finish_error(aio, NNG_EADDRINVAL);
+ return;
+ }
+
switch (family) {
case NNG_AF_INET:
fam = AF_INET;
@@ -234,20 +220,12 @@ nni_resolv_ip(const char *host, const char *serv, int family, bool passive,
nni_aio_finish_error(aio, NNG_ENOMEM);
return;
}
- if (host == NULL) {
- item->host = NULL;
- } else if ((item->host = nni_strdup(host)) == NULL) {
- nni_aio_finish_error(aio, NNG_ENOMEM);
- resolv_free_item(item);
- return;
- }
- if (serv == NULL) {
- item->serv = NULL;
- } else if ((item->serv = nni_strdup(serv)) == NULL) {
- nni_aio_finish_error(aio, NNG_ENOMEM);
- resolv_free_item(item);
- return;
+ snprintf(item->serv, sizeof(item->serv), "%u", port);
+ if (host == NULL) {
+ item->host[0] = '\0';
+ } else {
+ snprintf(item->host, sizeof(item->host), "%s", host);
}
item->sa = sa;
@@ -432,6 +410,26 @@ nni_parse_ip_port(const char *addr, nni_sockaddr *sa)
}
int
+nni_get_port_by_name(const char *name, uint16_t *portp)
+{
+ struct servent *se;
+ long port;
+ char *end = NULL;
+
+ port = strtol(name, &end, 10);
+ if ((*end == '\0') && (port >= 0) && (port <= 0xffff)) {
+ *portp = (uint16_t) port;
+ return (0);
+ }
+
+ if ((se = getservbyname(name, "tcp")) != NULL) {
+ *portp = (uint16_t) ntohs(se->s_port);
+ return (0);
+ }
+ return (NNG_EADDRINVAL);
+}
+
+int
nni_win_resolv_sysinit(nng_init_params *params)
{
nni_aio_list_init(&resolv_aios);