From 3d075fad7496ec126c5087d1c36ab7a4af73ce16 Mon Sep 17 00:00:00 2001 From: Garrett D'Amore Date: Mon, 22 Jan 2018 14:05:10 -0800 Subject: fixes #219 transports should take URL structure instead of string address This eliminates a bunch of redundant URL parsing, using the common URL logic we already have in place. While here I fixed a problem with the TLS and WSS test suites that was failing on older Ubuntu -- apparently older versions of mbedTLS were unhappy if selecting OPTIONAL verification without a validate certificate chain. --- src/core/defs.h | 1 + src/core/endpt.c | 33 +++++++++++++++------------------ src/core/endpt.h | 9 ++++----- src/core/nng_impl.h | 5 ++++- src/core/pipe.c | 6 ++---- src/core/transport.c | 12 ++---------- src/core/transport.h | 4 ++-- src/core/url.c | 27 +++++++++++++++++++++++++++ src/core/url.h | 3 +-- 9 files changed, 58 insertions(+), 42 deletions(-) (limited to 'src/core') diff --git a/src/core/defs.h b/src/core/defs.h index 3a714f85..d4a8a740 100644 --- a/src/core/defs.h +++ b/src/core/defs.h @@ -43,6 +43,7 @@ typedef struct nni_tran_ep nni_tran_ep; typedef struct nni_tran_ep_option nni_tran_ep_option; typedef struct nni_tran_pipe nni_tran_pipe; typedef struct nni_tran_pipe_option nni_tran_pipe_option; +typedef struct nni_url nni_url; typedef struct nni_proto_sock_ops nni_proto_sock_ops; typedef struct nni_proto_pipe_ops nni_proto_pipe_ops; diff --git a/src/core/endpt.c b/src/core/endpt.c index 57e4bc62..cfabcc87 100644 --- a/src/core/endpt.c +++ b/src/core/endpt.c @@ -21,7 +21,7 @@ struct nni_ep { uint64_t ep_id; // endpoint id nni_list_node ep_node; // per socket list nni_sock * ep_sock; - char ep_url[NNG_MAXADDRLEN]; + nni_url * ep_url; int ep_mode; int ep_started; int ep_closed; // full shutdown @@ -82,12 +82,6 @@ nni_ep_id(nni_ep *ep) return ((uint32_t) ep->ep_id); } -const char * -nni_ep_url(nni_ep *ep) -{ - return (ep->ep_url); -} - static void nni_ep_destroy(nni_ep *ep) { @@ -119,26 +113,31 @@ nni_ep_destroy(nni_ep *ep) nni_mtx_unlock(&ep->ep_mtx); nni_cv_fini(&ep->ep_cv); nni_mtx_fini(&ep->ep_mtx); + nni_url_free(ep->ep_url); NNI_FREE_STRUCT(ep); } static int -nni_ep_create(nni_ep **epp, nni_sock *s, const char *url, int mode) +nni_ep_create(nni_ep **epp, nni_sock *s, const char *urlstr, int mode) { nni_tran *tran; nni_ep * ep; int rv; + nni_url * url; + if ((rv = nni_url_parse(&url, urlstr)) != 0) { + return (rv); + } if ((tran = nni_tran_find(url)) == NULL) { + nni_url_free(url); return (NNG_ENOTSUP); } - if (strlen(url) >= NNG_MAXADDRLEN) { - return (NNG_EINVAL); - } if ((ep = NNI_ALLOC_STRUCT(ep)) == NULL) { + nni_url_free(url); return (NNG_ENOMEM); } + ep->ep_url = url; ep->ep_closed = 0; ep->ep_started = 0; ep->ep_data = NULL; @@ -152,8 +151,6 @@ nni_ep_create(nni_ep **epp, nni_sock *s, const char *url, int mode) // dereference on hot paths. ep->ep_ops = *tran->tran_ep; - (void) nni_strlcpy(ep->ep_url, url, sizeof(ep->ep_url)); - NNI_LIST_NODE_INIT(&ep->ep_node); nni_pipe_ep_list_init(&ep->ep_pipes); @@ -177,15 +174,15 @@ nni_ep_create(nni_ep **epp, nni_sock *s, const char *url, int mode) } int -nni_ep_create_dialer(nni_ep **epp, nni_sock *s, const char *url) +nni_ep_create_dialer(nni_ep **epp, nni_sock *s, const char *urlstr) { - return (nni_ep_create(epp, s, url, NNI_EP_MODE_DIAL)); + return (nni_ep_create(epp, s, urlstr, NNI_EP_MODE_DIAL)); } int -nni_ep_create_listener(nni_ep **epp, nni_sock *s, const char *url) +nni_ep_create_listener(nni_ep **epp, nni_sock *s, const char *urlstr) { - return (nni_ep_create(epp, s, url, NNI_EP_MODE_LISTEN)); + return (nni_ep_create(epp, s, urlstr, NNI_EP_MODE_LISTEN)); } int @@ -622,7 +619,7 @@ nni_ep_getopt(nni_ep *ep, const char *name, void *valp, size_t *szp) nni_tran_ep_option *eo; if (strcmp(name, NNG_OPT_URL) == 0) { - return (nni_getopt_str(ep->ep_url, valp, szp)); + return (nni_getopt_str(ep->ep_url->u_rawurl, valp, szp)); } for (eo = ep->ep_ops.ep_options; eo && eo->eo_name; eo++) { diff --git a/src/core/endpt.h b/src/core/endpt.h index f5ad09ee..df4f345b 100644 --- a/src/core/endpt.h +++ b/src/core/endpt.h @@ -1,6 +1,6 @@ // -// Copyright 2017 Garrett D'Amore -// Copyright 2017 Capitar IT Group BV +// Copyright 2018 Staysail Systems, Inc. +// Copyright 2018 Capitar IT Group BV // // This software is supplied under the terms of the MIT License, a // copy of which should be located in the distribution where this @@ -30,9 +30,8 @@ extern void nni_ep_list_init(nni_list *); extern int nni_ep_setopt(nni_ep *, const char *, const void *, size_t); extern int nni_ep_getopt(nni_ep *, const char *, void *, size_t *); extern int nni_ep_pipe_add(nni_ep *ep, nni_pipe *); -extern void nni_ep_pipe_remove(nni_ep *, nni_pipe *); -extern const char *nni_ep_url(nni_ep *); -extern int nni_ep_mode(nni_ep *); +extern void nni_ep_pipe_remove(nni_ep *, nni_pipe *); +extern int nni_ep_mode(nni_ep *); // Endpoint modes. Currently used by transports. Remove this when we make // transport dialers and listeners explicit. diff --git a/src/core/nng_impl.h b/src/core/nng_impl.h index ea8512bb..5c750ec7 100644 --- a/src/core/nng_impl.h +++ b/src/core/nng_impl.h @@ -44,10 +44,13 @@ #include "core/taskq.h" #include "core/thread.h" #include "core/timer.h" -#include "core/transport.h" #include "core/url.h" +// transport needs to come after url +#include "core/transport.h" + // These have to come after the others - particularly transport.h + #include "core/endpt.h" #include "core/pipe.h" #include "core/socket.h" diff --git a/src/core/pipe.c b/src/core/pipe.c index 77ceaa4f..66e7ae87 100644 --- a/src/core/pipe.c +++ b/src/core/pipe.c @@ -1,6 +1,6 @@ // -// Copyright 2017 Garrett D'Amore -// Copyright 2017 Capitar IT Group BV +// Copyright 2018 Staysail Systems, Inc. +// Copyright 2018 Capitar IT Group BV // // This software is supplied under the terms of the MIT License, a // copy of which should be located in the distribution where this @@ -29,7 +29,6 @@ struct nni_pipe { int p_reap; int p_stop; int p_refcnt; - const char * p_url; nni_mtx p_mtx; nni_cv p_cv; nni_list_node p_reap_node; @@ -268,7 +267,6 @@ nni_pipe_create(nni_ep *ep, void *tdata) p->p_proto_data = NULL; p->p_ep = ep; p->p_sock = sock; - p->p_url = nni_ep_url(ep); NNI_LIST_NODE_INIT(&p->p_reap_node); NNI_LIST_NODE_INIT(&p->p_sock_node); diff --git a/src/core/transport.c b/src/core/transport.c index 0891ec8c..38f88c4d 100644 --- a/src/core/transport.c +++ b/src/core/transport.c @@ -26,7 +26,6 @@ extern nni_tran nni_ipc_tran; typedef struct nni_transport { nni_tran t_tran; - char t_prefix[16]; // e.g. "tcp://" or "tls+tcp://" nni_list_node t_node; } nni_transport; @@ -72,13 +71,6 @@ nni_tran_register(const nni_tran *tran) } t->t_tran = *tran; - sz = sizeof(t->t_prefix); - if ((nni_strlcpy(t->t_prefix, tran->tran_scheme, sz) >= sz) || - (nni_strlcat(t->t_prefix, "://", sz) >= sz)) { - nni_mtx_unlock(&nni_tran_lk); - NNI_FREE_STRUCT(t); - return (NNG_EINVAL); - } if ((rv = t->t_tran.tran_init()) != 0) { nni_mtx_unlock(&nni_tran_lk); NNI_FREE_STRUCT(t); @@ -90,14 +82,14 @@ nni_tran_register(const nni_tran *tran) } nni_tran * -nni_tran_find(const char *addr) +nni_tran_find(nni_url *url) { // address is of the form "://blah..." nni_transport *t; nni_mtx_lock(&nni_tran_lk); NNI_LIST_FOREACH (&nni_tran_list, t) { - if (strncmp(addr, t->t_prefix, strlen(t->t_prefix)) == 0) { + if (strcmp(url->u_scheme, t->t_tran.tran_scheme) == 0) { nni_mtx_unlock(&nni_tran_lk); return (&t->t_tran); } diff --git a/src/core/transport.h b/src/core/transport.h index 9a6dc31d..0ca9c409 100644 --- a/src/core/transport.h +++ b/src/core/transport.h @@ -76,7 +76,7 @@ struct nni_tran_ep_option { struct nni_tran_ep { // ep_init creates a vanilla endpoint. The value created is // used for the first argument for all other endpoint functions. - int (*ep_init)(void **, const char *, nni_sock *, int); + int (*ep_init)(void **, nni_url *, nni_sock *, int); // ep_fini frees the resources associated with the endpoint. // The endpoint will already have been closed. @@ -164,7 +164,7 @@ struct nni_tran_pipe { // These APIs are used by the framework internally, and not for use by // transport implementations. -extern nni_tran *nni_tran_find(const char *); +extern nni_tran *nni_tran_find(nni_url *); extern int nni_tran_chkopt(const char *, const void *, size_t); extern int nni_tran_sys_init(void); extern void nni_tran_sys_fini(void); diff --git a/src/core/url.c b/src/core/url.c index a5b4fd06..3d8898bd 100644 --- a/src/core/url.c +++ b/src/core/url.c @@ -453,4 +453,31 @@ nni_url_free(nni_url *url) nni_strfree(url->u_fragment); nni_strfree(url->u_rawpath); NNI_FREE_STRUCT(url); +} + +int +nni_url_clone(nni_url **dstp, const nni_url *src) +{ + nni_url *dst; + + if ((dst = NNI_ALLOC_STRUCT(dst)) == NULL) { + return (NNG_ENOMEM); + } +#define URL_COPYSTR(d, s) ((s != NULL) && ((d = nni_strdup(s)) == NULL)) + if (URL_COPYSTR(dst->u_rawurl, src->u_rawurl) || + URL_COPYSTR(dst->u_scheme, src->u_scheme) || + URL_COPYSTR(dst->u_userinfo, src->u_userinfo) || + URL_COPYSTR(dst->u_host, src->u_host) || + URL_COPYSTR(dst->u_hostname, src->u_hostname) || + URL_COPYSTR(dst->u_port, src->u_port) || + URL_COPYSTR(dst->u_rawpath, src->u_rawpath) || + URL_COPYSTR(dst->u_path, src->u_path) || + URL_COPYSTR(dst->u_query, src->u_query) || + URL_COPYSTR(dst->u_fragment, src->u_fragment)) { + nni_url_free(dst); + return (NNG_ENOMEM); + } +#undef URL_COPYSTR + *dstp = dst; + return (0); } \ No newline at end of file diff --git a/src/core/url.h b/src/core/url.h index f99d6eb4..27aec445 100644 --- a/src/core/url.h +++ b/src/core/url.h @@ -11,8 +11,6 @@ #ifndef CORE_URL_H #define CORE_URL_H -typedef struct nni_url nni_url; - struct nni_url { char *u_rawurl; // never NULL char *u_scheme; // never NULL @@ -28,5 +26,6 @@ struct nni_url { extern int nni_url_parse(nni_url **, const char *path); extern void nni_url_free(nni_url *); +extern int nni_url_clone(nni_url **, const nni_url *); #endif // CORE_URL_H -- cgit v1.2.3-70-g09d2