aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGarrett D'Amore <garrett@damore.org>2024-11-23 09:12:29 -0800
committerGarrett D'Amore <garrett@damore.org>2024-11-23 09:40:32 -0800
commit3ed5d7e7c6bc995018ed9c3d63c18504f3983341 (patch)
treece7f482f04d8e56b4d77e1f58fec73d6606e5a64
parent8f29c19954b7e4f0e47036b37b36ab9cd386ad70 (diff)
downloadnng-3ed5d7e7c6bc995018ed9c3d63c18504f3983341.tar.gz
nng-3ed5d7e7c6bc995018ed9c3d63c18504f3983341.tar.bz2
nng-3ed5d7e7c6bc995018ed9c3d63c18504f3983341.zip
listener: add listener_create_url and listen_url
-rw-r--r--include/nng/nng.h3
-rw-r--r--src/core/listener.c80
-rw-r--r--src/core/listener.h8
-rw-r--r--src/core/sock_test.c44
-rw-r--r--src/nng.c49
5 files changed, 160 insertions, 24 deletions
diff --git a/include/nng/nng.h b/include/nng/nng.h
index 1423759f..020a3add 100644
--- a/include/nng/nng.h
+++ b/include/nng/nng.h
@@ -302,6 +302,7 @@ NNG_DECL int nng_pipe_notify(nng_socket, nng_pipe_ev, nng_pipe_cb, void *);
// nn_bind(). The underlying endpoint is returned back to the caller in the
// endpoint pointer, if it is not NULL. The flags are ignored at present.
NNG_DECL int nng_listen(nng_socket, const char *, nng_listener *, int);
+NNG_DECL int nng_listen_url(nng_socket, const nng_url *, nng_listener *, int);
// nng_dial creates a dialing endpoint, with no special options, and
// starts it dialing. Dialers have at most one active connection at a time
@@ -322,6 +323,8 @@ NNG_DECL int nng_dialer_create_url(nng_dialer *, nng_socket, const nng_url *);
// nng_listener_create creates a new listener, that is not yet started.
NNG_DECL int nng_listener_create(nng_listener *, nng_socket, const char *);
+NNG_DECL int nng_listener_create_url(
+ nng_listener *, nng_socket, const nng_url *);
// nng_dialer_start starts the endpoint dialing. This is only possible if
// the dialer is not already dialing.
diff --git a/src/core/listener.c b/src/core/listener.c
index 8d884b5e..76d9848e 100644
--- a/src/core/listener.c
+++ b/src/core/listener.c
@@ -192,29 +192,11 @@ nni_listener_bump_error(nni_listener *l, int err)
#endif
}
-// nni_listener_create creates a listener on the socket.
-// The caller should have a hold on the socket, and on success
-// the listener inherits the callers hold. (If the caller wants
-// an additional hold, it should get an extra hold before calling this
-// function.)
-int
-nni_listener_create(nni_listener **lp, nni_sock *s, const char *url_str)
+static int
+nni_listener_init(nni_listener *l, nni_sock *s, nni_sp_tran *tran)
{
- nni_sp_tran *tran;
- nni_listener *l;
- int rv;
+ int rv;
- if (((tran = nni_sp_tran_find(url_str)) == NULL) ||
- (tran->tran_listener == NULL)) {
- return (NNG_ENOTSUP);
- }
- if ((l = NNI_ALLOC_STRUCT(l)) == NULL) {
- return (NNG_ENOMEM);
- }
- if ((rv = nni_url_parse_inline(&l->l_url, url_str)) != 0) {
- NNI_FREE_STRUCT(l);
- return (rv);
- }
l->l_closed = false;
l->l_data = NULL;
l->l_ref = 1;
@@ -250,6 +232,31 @@ nni_listener_create(nni_listener **lp, nni_sock *s, const char *url_str)
#ifdef NNG_ENABLE_STATS
nni_stat_unregister(&l->st_root);
#endif
+ return (rv);
+ }
+
+ return (0);
+}
+
+int
+nni_listener_create_url(nni_listener **lp, nni_sock *s, const nng_url *url)
+{
+ nni_sp_tran *tran;
+ nni_listener *l;
+ int rv;
+
+ if (((tran = nni_sp_tran_find(nng_url_scheme(url))) == NULL) ||
+ (tran->tran_listener == NULL)) {
+ return (NNG_ENOTSUP);
+ }
+ if ((l = NNI_ALLOC_STRUCT(l)) == NULL) {
+ return (NNG_ENOMEM);
+ }
+ if ((rv = nni_url_clone_inline(&l->l_url, url)) != 0) {
+ NNI_FREE_STRUCT(l);
+ return (rv);
+ }
+ if ((rv = nni_listener_init(l, s, tran)) != 0) {
nni_listener_destroy(l);
return (rv);
}
@@ -258,6 +265,37 @@ nni_listener_create(nni_listener **lp, nni_sock *s, const char *url_str)
return (0);
}
+// nni_listener_create creates a listener on the socket.
+// The caller should have a hold on the socket, and on success
+// the listener inherits the callers hold. (If the caller wants
+// an additional hold, it should get an extra hold before calling this
+// function.)
+int
+nni_listener_create(nni_listener **lp, nni_sock *s, const char *url_str)
+{
+ nni_sp_tran *tran;
+ nni_listener *l;
+ int rv;
+
+ if (((tran = nni_sp_tran_find(url_str)) == NULL) ||
+ (tran->tran_listener == NULL)) {
+ return (NNG_ENOTSUP);
+ }
+ if ((l = NNI_ALLOC_STRUCT(l)) == NULL) {
+ return (NNG_ENOMEM);
+ }
+ if ((rv = nni_url_parse_inline(&l->l_url, url_str)) != 0) {
+ NNI_FREE_STRUCT(l);
+ return (rv);
+ }
+ if ((rv = nni_listener_init(l, s, tran)) != 0) {
+ nni_listener_destroy(l);
+ return (rv);
+ }
+ *lp = l;
+ return (0);
+}
+
int
nni_listener_find(nni_listener **lp, uint32_t id)
{
diff --git a/src/core/listener.h b/src/core/listener.h
index 74ca0a0b..eec98f2e 100644
--- a/src/core/listener.h
+++ b/src/core/listener.h
@@ -1,5 +1,5 @@
//
-// Copyright 2021 Staysail Systems, Inc. <info@staysail.tech>
+// Copyright 2024 Staysail Systems, Inc. <info@staysail.tech>
// Copyright 2018 Capitar IT Group BV <info@capitar.com>
// Copyright 2018 Devolutions <info@devolutions.net>
//
@@ -17,8 +17,10 @@ extern int nni_listener_hold(nni_listener *);
extern void nni_listener_rele(nni_listener *);
extern uint32_t nni_listener_id(nni_listener *);
extern int nni_listener_create(nni_listener **, nni_sock *, const char *);
-extern void nni_listener_close(nni_listener *);
-extern int nni_listener_start(nni_listener *, int);
+extern int nni_listener_create_url(
+ nni_listener **, nni_sock *, const nng_url *);
+extern void nni_listener_close(nni_listener *);
+extern int nni_listener_start(nni_listener *, int);
extern nni_sock *nni_listener_sock(nni_listener *);
extern int nni_listener_setopt(
diff --git a/src/core/sock_test.c b/src/core/sock_test.c
index 0e8c6d29..4c1e2c7c 100644
--- a/src/core/sock_test.c
+++ b/src/core/sock_test.c
@@ -345,6 +345,48 @@ test_listener_options(void)
}
void
+test_listener_create_url(void)
+{
+ nng_socket s1;
+ nng_listener l;
+ nng_url *u;
+ const nng_url *u2;
+
+ NUTS_OPEN(s1);
+ NUTS_PASS(nng_url_parse(&u, "inproc://listener_opts2"));
+
+ NUTS_PASS(nng_listener_create_url(&l, s1, u));
+ nng_listener_get_url(l, &u2);
+
+ NUTS_MATCH(nng_url_scheme(u), nng_url_scheme(u2));
+ NUTS_MATCH(nng_url_path(u), nng_url_path(u2));
+ nng_url_free(u);
+
+ NUTS_CLOSE(s1);
+}
+
+void
+test_listen_url(void)
+{
+ nng_socket s1;
+ nng_listener l;
+ nng_url *u;
+ const nng_url *u2;
+
+ NUTS_OPEN(s1);
+ NUTS_PASS(nng_url_parse(&u, "inproc://listen_url"));
+
+ NUTS_PASS(nng_listen_url(s1, u, &l, 0));
+ nng_listener_get_url(l, &u2);
+
+ NUTS_MATCH(nng_url_scheme(u), nng_url_scheme(u2));
+ NUTS_MATCH(nng_url_path(u), nng_url_path(u2));
+ nng_url_free(u);
+
+ NUTS_CLOSE(s1);
+}
+
+void
test_dialer_options(void)
{
nng_socket s1;
@@ -470,6 +512,8 @@ NUTS_TESTS = {
{ "bad url", test_bad_url },
{ "endpoint url", test_endpoint_url },
{ "listener options", test_listener_options },
+ { "listener create url", test_listener_create_url },
+ { "listen url", test_listen_url },
{ "dialer options", test_dialer_options },
{ "timeout options", test_timeout_options },
{ "size options", test_size_options },
diff --git a/src/nng.c b/src/nng.c
index c1843d38..2bc9986c 100644
--- a/src/nng.c
+++ b/src/nng.c
@@ -593,6 +593,34 @@ nng_listen(nng_socket sid, const char *addr, nng_listener *lp, int flags)
}
int
+nng_listen_url(nng_socket sid, const nng_url *url, nng_listener *lp, int flags)
+{
+ int rv;
+ nni_sock *s;
+ nni_listener *l;
+
+ if ((rv = nni_sock_find(&s, sid.id)) != 0) {
+ return (rv);
+ }
+ if ((rv = nni_listener_create_url(&l, s, url)) != 0) {
+ nni_sock_rele(s);
+ return (rv);
+ }
+ if ((rv = nni_listener_start(l, flags)) != 0) {
+ nni_listener_close(l);
+ return (rv);
+ }
+
+ if (lp != NULL) {
+ nng_listener lid;
+ lid.id = nni_listener_id(l);
+ *lp = lid;
+ }
+ nni_listener_rele(l);
+ return (rv);
+}
+
+int
nng_listener_create(nng_listener *lp, nng_socket sid, const char *addr)
{
nni_sock *s;
@@ -614,6 +642,27 @@ nng_listener_create(nng_listener *lp, nng_socket sid, const char *addr)
}
int
+nng_listener_create_url(nng_listener *lp, nng_socket sid, const nng_url *url)
+{
+ nni_sock *s;
+ int rv;
+ nni_listener *l;
+ nng_listener lid;
+
+ if ((rv = nni_sock_find(&s, sid.id)) != 0) {
+ return (rv);
+ }
+ if ((rv = nni_listener_create_url(&l, s, url)) != 0) {
+ nni_sock_rele(s);
+ return (rv);
+ }
+ lid.id = nni_listener_id(l);
+ *lp = lid;
+ nni_listener_rele(l);
+ return (0);
+}
+
+int
nng_listener_start(nng_listener lid, int flags)
{
nni_listener *l;