aboutsummaryrefslogtreecommitdiff
path: root/src/transport
diff options
context:
space:
mode:
authorGarrett D'Amore <garrett@damore.org>2017-08-20 10:45:27 -0700
committerGarrett D'Amore <garrett@damore.org>2017-08-21 07:18:31 -0700
commit75adda86be49e6839e50443f0bae5875d9910897 (patch)
treee29b8b449c863be01e5f02945940dc390b239462 /src/transport
parent6305e16ab64e42fd9791819d416a6e3534439b0b (diff)
downloadnng-75adda86be49e6839e50443f0bae5875d9910897.tar.gz
nng-75adda86be49e6839e50443f0bae5875d9910897.tar.bz2
nng-75adda86be49e6839e50443f0bae5875d9910897.zip
fixes #41 Move DNS out of tcp transport
This moves the DNS related functionality into common code, and also removes all the URL parsing stuff out of the platform specific code and into the transports. Now the transports just take sockaddr's on initialization. (We may want to move this until later.) We also add UDP resolution as another separate API.
Diffstat (limited to 'src/transport')
-rw-r--r--src/transport/ipc/ipc.c12
-rw-r--r--src/transport/tcp/tcp.c118
2 files changed, 97 insertions, 33 deletions
diff --git a/src/transport/ipc/ipc.c b/src/transport/ipc/ipc.c
index 11bfceb9..3430ceb3 100644
--- a/src/transport/ipc/ipc.c
+++ b/src/transport/ipc/ipc.c
@@ -485,18 +485,24 @@ nni_ipc_ep_fini(void *arg)
static int
nni_ipc_ep_init(void **epp, const char *url, nni_sock *sock, int mode)
{
- nni_ipc_ep *ep;
- int rv;
+ nni_ipc_ep * ep;
+ int rv;
+ nni_sockaddr sa;
if ((strlen(url) > NNG_MAXADDRLEN - 1) ||
(strncmp(url, "ipc://", strlen("ipc://")) != 0)) {
return (NNG_EADDRINVAL);
}
+ sa.s_un.s_path.sa_family = NNG_AF_IPC;
+ (void) snprintf(sa.s_un.s_path.sa_path, sizeof(sa.s_un.s_path.sa_path),
+ "%s", url + strlen("ipc://"));
+
if ((ep = NNI_ALLOC_STRUCT(ep)) == NULL) {
return (NNG_ENOMEM);
}
- if ((rv = nni_plat_ipc_ep_init(&ep->iep, url, mode)) != 0) {
+ url += strlen("ipc://");
+ if ((rv = nni_plat_ipc_ep_init(&ep->iep, &sa, mode)) != 0) {
NNI_FREE_STRUCT(ep);
return (rv);
}
diff --git a/src/transport/tcp/tcp.c b/src/transport/tcp/tcp.c
index 99e59302..24362fcd 100644
--- a/src/transport/tcp/tcp.c
+++ b/src/transport/tcp/tcp.c
@@ -458,19 +458,15 @@ nni_tcp_parse_pair(char *pair, char **hostp, char **servp)
serv++;
}
}
- if (hostp != NULL) {
- if ((strlen(host) == 0) || (strcmp(host, "*") == 0)) {
- *hostp = NULL;
- } else {
- *hostp = host;
- }
+ if ((strlen(host) == 0) || (strcmp(host, "*") == 0)) {
+ *hostp = NULL;
+ } else {
+ *hostp = host;
}
- if (servp != NULL) {
- if (strlen(serv) == 0) {
- *servp = NULL;
- } else {
- *servp = serv;
- }
+ if (strlen(serv) == 0) {
+ *servp = NULL;
+ } else {
+ *servp = serv;
}
// Stash the port in big endian (network) byte order.
return (0);
@@ -478,8 +474,8 @@ nni_tcp_parse_pair(char *pair, char **hostp, char **servp)
// Note that the url *must* be in a modifiable buffer.
int
-nni_tcp_parse_url(
- char *url, char **host1, char **serv1, char **host2, char **serv2)
+nni_tcp_parse_url(char *url, char **lhost, char **lserv, char **rhost,
+ char **rserv, int mode)
{
char *h1;
int rv;
@@ -488,27 +484,40 @@ nni_tcp_parse_url(
return (NNG_EADDRINVAL);
}
url += strlen("tcp://");
- if ((h1 = strchr(url, ';')) != 0) {
- // For these we want the second part first, because
- // the "primary" address is the remote address, and the
- // "secondary" is the local (bind) address. This is only
- // used for dial side.
+ if ((mode == NNI_EP_MODE_DIAL) && ((h1 = strchr(url, ';')) != 0)) {
+ // The local address is the first part, the remote address
+ // is the second part.
*h1 = '\0';
h1++;
- if (((rv = nni_tcp_parse_pair(h1, host1, serv1)) != 0) ||
- ((rv = nni_tcp_parse_pair(url, host2, serv2)) != 0)) {
+ if (((rv = nni_tcp_parse_pair(h1, rhost, rserv)) != 0) ||
+ ((rv = nni_tcp_parse_pair(url, lhost, lserv)) != 0)) {
return (rv);
}
- } else {
- if (host2 != NULL) {
- *host2 = NULL;
+ if ((*rserv == NULL) || (*rhost == NULL)) {
+ // We have to know where to connect to!
+ return (NNG_EADDRINVAL);
}
- if (serv2 != NULL) {
- *serv2 = NULL;
+ } else if (mode == NNI_EP_MODE_DIAL) {
+ *lhost = NULL;
+ *lserv = NULL;
+ if ((rv = nni_tcp_parse_pair(url, rhost, rserv)) != 0) {
+ return (rv);
+ }
+ if ((*rserv == NULL) || (*rhost == NULL)) {
+ // We have to know where to connect to!
+ return (NNG_EADDRINVAL);
}
- if ((rv = nni_tcp_parse_pair(url, host1, serv1)) != 0) {
+ } else {
+ NNI_ASSERT(mode == NNI_EP_MODE_LISTEN);
+ *rhost = NULL;
+ *rserv = NULL;
+ if ((rv = nni_tcp_parse_pair(url, lhost, lserv)) != 0) {
return (rv);
}
+ // We have to have a port to listen on!
+ if (*lserv == NULL) {
+ return (NNG_EADDRINVAL);
+ }
}
return (0);
}
@@ -559,16 +568,65 @@ nni_tcp_ep_fini(void *arg)
static int
nni_tcp_ep_init(void **epp, const char *url, nni_sock *sock, int mode)
{
- nni_tcp_ep *ep;
- int rv;
+ nni_tcp_ep * ep;
+ int rv;
+ char buf[NNG_MAXADDRLEN + 1];
+ char * rhost;
+ char * rserv;
+ char * lhost;
+ char * lserv;
+ nni_sockaddr rsa, lsa;
+ nni_aio aio;
+ int passive;
+
+ // Make a copy of the url (to allow for destructive operations)
+ snprintf(buf, sizeof(buf), "%s", url);
+
+ // Parse the URLs first.
+ rv = nni_tcp_parse_url(buf, &lhost, &lserv, &rhost, &rserv, mode);
+ if (rv != 0) {
+ return (rv);
+ }
+ passive = (mode == NNI_EP_MODE_DIAL ? 0 : 1);
+
+ nni_aio_init(&aio, NULL, NULL);
+
+ // XXX: arguably we could defer this part to the point we do a bind
+ // or connect!
+
+ if ((rhost != NULL) || (rserv != NULL)) {
+ aio.a_addr = &rsa;
+ nni_plat_tcp_resolv(
+ rhost, rserv, NNG_AF_UNSPEC, passive, &aio);
+ nni_aio_wait(&aio);
+ if ((rv = nni_aio_result(&aio)) != 0) {
+ return (rv);
+ }
+ } else {
+ rsa.s_un.s_family = NNG_AF_UNSPEC;
+ }
+
+ if ((lhost != NULL) || (lserv != NULL)) {
+ aio.a_addr = &lsa;
+ nni_plat_tcp_resolv(
+ lhost, lserv, NNG_AF_UNSPEC, passive, &aio);
+ nni_aio_wait(&aio);
+ if ((rv = nni_aio_result(&aio)) != 0) {
+ return (rv);
+ }
+ } else {
+ lsa.s_un.s_family = NNG_AF_UNSPEC;
+ }
if ((ep = NNI_ALLOC_STRUCT(ep)) == NULL) {
return (NNG_ENOMEM);
}
- if ((rv = nni_plat_tcp_ep_init(&ep->tep, url, mode)) != 0) {
+
+ if ((rv = nni_plat_tcp_ep_init(&ep->tep, &lsa, &rsa, mode)) != 0) {
NNI_FREE_STRUCT(ep);
return (rv);
}
+
nni_mtx_init(&ep->mtx);
nni_aio_init(&ep->aio, nni_tcp_ep_cb, ep);