aboutsummaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/endpt.c12
-rw-r--r--src/core/options.c206
-rw-r--r--src/core/options.h42
-rw-r--r--src/core/pipe.c6
-rw-r--r--src/core/protocol.h2
-rw-r--r--src/core/socket.c96
-rw-r--r--src/core/transport.h4
7 files changed, 184 insertions, 184 deletions
diff --git a/src/core/endpt.c b/src/core/endpt.c
index 131ee1db..d4bc9b01 100644
--- a/src/core/endpt.c
+++ b/src/core/endpt.c
@@ -649,12 +649,8 @@ nni_ep_getopt(nni_ep *ep, const char *name, void *valp, size_t *szp, int t)
if (eo->eo_getopt == NULL) {
return (NNG_EWRITEONLY);
}
- if ((t != NNI_TYPE_OPAQUE) &&
- (eo->eo_type != NNI_TYPE_OPAQUE) && (t != eo->eo_type)) {
- return (NNG_EBADTYPE);
- }
nni_mtx_lock(&ep->ep_mtx);
- rv = eo->eo_getopt(ep->ep_data, valp, szp);
+ rv = eo->eo_getopt(ep->ep_data, valp, szp, t);
nni_mtx_unlock(&ep->ep_mtx);
return (rv);
}
@@ -663,11 +659,7 @@ nni_ep_getopt(nni_ep *ep, const char *name, void *valp, size_t *szp, int t)
// override. This allows the URL to be created with wildcards,
// that are resolved later.
if (strcmp(name, NNG_OPT_URL) == 0) {
- if (t != NNI_TYPE_OPAQUE) {
- // XXX: Add NNI_TYPE_STRING.
- return (NNG_EBADTYPE);
- }
- return (nni_getopt_str(ep->ep_url->u_rawurl, valp, szp));
+ return (nni_copyout_str(ep->ep_url->u_rawurl, valp, szp, t));
}
return (nni_sock_getopt(ep->ep_sock, name, valp, szp, t));
diff --git a/src/core/options.c b/src/core/options.c
index f51a6abe..9410de5f 100644
--- a/src/core/options.c
+++ b/src/core/options.c
@@ -129,140 +129,166 @@ nni_setopt_size(size_t *sp, const void *v, size_t sz, size_t minv, size_t maxv)
}
int
-nni_getopt_ms(nni_duration u, void *val, size_t *sizep)
+nni_setopt_buf(nni_msgq *mq, const void *val, size_t sz)
{
- size_t sz = sizeof(u);
+ int len;
- if (sz > *sizep) {
- sz = *sizep;
+ if (sz < sizeof(len)) {
+ return (NNG_EINVAL);
}
- *sizep = sizeof(u);
- memcpy(val, &u, sz);
- return (0);
+ memcpy(&len, val, sizeof(len));
+ if (len < 0) {
+ return (NNG_EINVAL);
+ }
+ if (len > 8192) {
+ // put a reasonable uppper limit on queue depth.
+ // This is a count in messages, so the total queue
+ // size could be quite large indeed in this case.
+ return (NNG_EINVAL);
+ }
+ return (nni_msgq_resize(mq, len));
}
int
-nni_getopt_sockaddr(const nng_sockaddr *sa, void *val, size_t *sizep)
+nni_copyout(const void *src, size_t srcsz, void *dst, size_t *dstszp)
{
- size_t sz = sizeof(*sa);
-
- if (sz > *sizep) {
- sz = *sizep;
+ int rv = 0;
+ size_t copysz = *dstszp;
+ // Assumption is that this is type NNI_TYPE_OPAQUE.
+ if (copysz > srcsz) {
+ copysz = srcsz;
+ } else if (srcsz > copysz) {
+ // destination too small.
+ rv = NNG_EINVAL;
}
- *sizep = sizeof(*sa);
- memcpy(val, sa, sz);
- return (0);
+ *dstszp = srcsz;
+ memcpy(dst, src, copysz);
+ return (rv);
}
int
-nni_getopt_int(int i, void *val, size_t *sizep)
+nni_copyout_bool(bool b, void *dst, size_t *szp, int typ)
{
- size_t sz = sizeof(i);
-
- if (sz > *sizep) {
- sz = *sizep;
+ switch (typ) {
+ case NNI_TYPE_BOOL:
+ NNI_ASSERT(*szp == sizeof(b));
+ *(bool *) dst = b;
+ return (0);
+ case NNI_TYPE_OPAQUE:
+ return (nni_copyout(&b, sizeof(b), dst, szp));
+ default:
+ return (NNG_EBADTYPE);
}
- *sizep = sizeof(i);
- memcpy(val, &i, sz);
- return (0);
}
int
-nni_getopt_u64(uint64_t u, void *val, size_t *sizep)
+nni_copyout_int(int i, void *dst, size_t *szp, int typ)
{
- size_t sz = sizeof(u);
-
- if (sz > *sizep) {
- sz = *sizep;
+ switch (typ) {
+ case NNI_TYPE_INT32:
+ NNI_ASSERT(*szp == sizeof(i));
+ *(int *) dst = i;
+ return (0);
+ case NNI_TYPE_OPAQUE:
+ return (nni_copyout(&i, sizeof(i), dst, szp));
+ default:
+ return (NNG_EBADTYPE);
}
- *sizep = sizeof(u);
- memcpy(val, &u, sz);
- return (0);
}
int
-nni_getopt_str(const char *ptr, void *val, size_t *sizep)
+nni_copyout_ms(nng_duration d, void *dst, size_t *szp, int typ)
{
- size_t len = strlen(ptr) + 1;
- size_t sz;
-
- sz = (len > *sizep) ? *sizep : len;
- *sizep = len;
- memcpy(val, ptr, sz);
- return (0);
+ switch (typ) {
+ case NNI_TYPE_DURATION:
+ NNI_ASSERT(*szp == sizeof(d));
+ *(nng_duration *) dst = d;
+ return (0);
+ case NNI_TYPE_OPAQUE:
+ return (nni_copyout(&d, sizeof(d), dst, szp));
+ default:
+ return (NNG_EBADTYPE);
+ }
}
int
-nni_getopt_size(size_t u, void *val, size_t *sizep)
+nni_copyout_ptr(void *p, void *dst, size_t *szp, int typ)
{
- size_t sz = sizeof(u);
-
- if (sz > *sizep) {
- sz = *sizep;
+ switch (typ) {
+ case NNI_TYPE_POINTER:
+ NNI_ASSERT(*szp == sizeof(p));
+ *(void **) dst = p;
+ return (0);
+ case NNI_TYPE_OPAQUE:
+ return (nni_copyout(&p, sizeof(p), dst, szp));
+ default:
+ return (NNG_EBADTYPE);
}
- *sizep = sizeof(u);
- memcpy(val, &u, sz);
- return (0);
}
int
-nni_getopt_bool(bool b, void *val, size_t *sizep)
+nni_copyout_size(size_t s, void *dst, size_t *szp, int typ)
{
- size_t sz = sizeof(b);
-
- if (sz > *sizep) {
- sz = *sizep;
+ switch (typ) {
+ case NNI_TYPE_SIZE:
+ NNI_ASSERT(*szp == sizeof(s));
+ *(size_t *) dst = s;
+ return (0);
+ case NNI_TYPE_OPAQUE:
+ return (nni_copyout(&s, sizeof(s), dst, szp));
+ default:
+ return (NNG_EBADTYPE);
}
- *sizep = sizeof(b);
- memcpy(val, &b, sz);
- return (0);
}
int
-nni_getopt_ptr(void *ptr, void *val, size_t *sizep)
+nni_copyout_sockaddr(const nng_sockaddr *sap, void *dst, size_t *szp, int typ)
{
- size_t sz = sizeof(ptr);
-
- if (sz > *sizep) {
- sz = *sizep;
+ switch (typ) {
+ case NNI_TYPE_SOCKADDR:
+ NNI_ASSERT(*szp == sizeof(*sap));
+ *(nng_sockaddr *) dst = *sap;
+ return (0);
+ case NNI_TYPE_OPAQUE:
+ return (nni_copyout(sap, sizeof(*sap), dst, szp));
+ default:
+ return (NNG_EBADTYPE);
}
- *sizep = sizeof(ptr);
- memcpy(val, &ptr, sz);
- return (0);
}
int
-nni_setopt_buf(nni_msgq *mq, const void *val, size_t sz)
+nni_copyout_u64(uint64_t u, void *dst, size_t *szp, int typ)
{
- int len;
-
- if (sz < sizeof(len)) {
- return (NNG_EINVAL);
+ switch (typ) {
+ case NNI_TYPE_UINT64:
+ NNI_ASSERT(*szp == sizeof(u));
+ *(uint64_t *) dst = u;
+ return (0);
+ case NNI_TYPE_OPAQUE:
+ return (nni_copyout(&u, sizeof(u), dst, szp));
+ default:
+ return (NNG_EBADTYPE);
}
- memcpy(&len, val, sizeof(len));
- if (len < 0) {
- return (NNG_EINVAL);
- }
- if (len > 8192) {
- // put a reasonable uppper limit on queue depth.
- // This is a count in messages, so the total queue
- // size could be quite large indeed in this case.
- return (NNG_EINVAL);
- }
- return (nni_msgq_resize(mq, len));
}
int
-nni_getopt_buf(nni_msgq *mq, void *val, size_t *sizep)
+nni_copyout_str(const char *str, void *dst, size_t *szp, int typ)
{
- int len = nni_msgq_cap(mq);
-
- size_t sz = *sizep;
-
- if (sz > sizeof(len)) {
- sz = sizeof(len);
+ char *s;
+
+ switch (typ) {
+ case NNI_TYPE_STRING:
+ NNI_ASSERT(*szp == sizeof(char *));
+ if ((s = nni_strdup(str)) == NULL) {
+ return (NNG_ENOMEM);
+ }
+ *(char **) dst = s;
+ return (0);
+
+ case NNI_TYPE_OPAQUE:
+ return (nni_copyout(str, strlen(str) + 1, dst, szp));
+
+ default:
+ return (NNG_EBADTYPE);
}
- memcpy(val, &len, sz);
- *sizep = sizeof(len);
- return (0);
-} \ No newline at end of file
+}
diff --git a/src/core/options.h b/src/core/options.h
index f5743aae..35c3232f 100644
--- a/src/core/options.h
+++ b/src/core/options.h
@@ -18,22 +18,13 @@
// nni_setopt_buf sets the queue size for the message queue.
extern int nni_setopt_buf(nni_msgq *, const void *, size_t);
-// nni_getopt_buf gets the queue size for the message queue.
-extern int nni_getopt_buf(nni_msgq *, void *, size_t *);
-
// nni_setopt_duration sets the duration. Durations must be legal,
// either a positive value, 0, or -1 to indicate forever.
extern int nni_setopt_ms(nni_duration *, const void *, size_t);
-// nni_getopt_duration gets the duration.
-extern int nni_getopt_ms(nni_duration, void *, size_t *);
-
// nni_setopt_bool sets a bool, or _Bool
extern int nni_setopt_bool(bool *, const void *, size_t);
-// nni_getopt_bool gets a bool (or _Bool)
-extern int nni_getopt_bool(bool, void *, size_t *);
-
// nni_setopt_int sets an integer, which must be between the minimum and
// maximum values (inclusive).
extern int nni_setopt_int(int *, const void *, size_t, int, int);
@@ -41,18 +32,6 @@ extern int nni_setopt_int(int *, const void *, size_t, int, int);
#define NNI_MAXINT ((int) 2147483647)
#define NNI_MININT ((int) -2147483648)
-// nni_getopt_int gets an integer.
-extern int nni_getopt_int(int, void *, size_t *);
-
-// nni_getopt_u64 gets an unsigned 64 bit number.
-extern int nni_getopt_u64(uint64_t, void *, size_t *);
-
-// nni_getopt_str gets a C style string.
-extern int nni_getopt_str(const char *, void *, size_t *);
-
-// nni_getopt_sockaddr gets an nng_sockaddr.
-extern int nni_getopt_sockaddr(const nng_sockaddr *, void *, size_t *);
-
// nni_setopt_size sets a size_t option.
extern int nni_setopt_size(size_t *, const void *, size_t, size_t, size_t);
@@ -61,15 +40,24 @@ extern int nni_setopt_size(size_t *, const void *, size_t, size_t, size_t);
#define NNI_MINSZ (0)
#define NNI_MAXSZ ((size_t) 0xffffffff)
-// nni_getopt_size obtains a size_t option.
-extern int nni_getopt_size(size_t, void *, size_t *);
-
-// nni_getopt_ptr obtains a pointer option.
-extern int nni_getopt_ptr(void *, void *, size_t *);
-
extern int nni_chkopt_bool(size_t);
extern int nni_chkopt_ms(const void *, size_t);
extern int nni_chkopt_int(const void *, size_t, int, int);
extern int nni_chkopt_size(const void *, size_t, size_t, size_t);
+// nni_copyout_xxx copies out a type of the named value. It assumes that
+// the type is aligned and the size correct, unless NNI_TYPE_OPAQUE is passed.
+extern int nni_copyout(const void *, size_t, void *, size_t *);
+extern int nni_copyout_bool(bool, void *, size_t *, int);
+extern int nni_copyout_int(int, void *, size_t *, int);
+extern int nni_copyout_ms(nng_duration, void *, size_t *, int);
+extern int nni_copyout_ptr(void *, void *, size_t *, int);
+extern int nni_copyout_size(size_t, void *, size_t *, int);
+extern int nni_copyout_sockaddr(const nng_sockaddr *, void *, size_t *, int);
+extern int nni_copyout_u64(uint64_t, void *, size_t *, int);
+
+// nni_copyout_str copies out a string. If the type is NNI_TYPE_STRING,
+// then it passes through a pointer, created by nni_strdup().
+extern int nni_copyout_str(const char *, void *, size_t *, int);
+
#endif // CORE_OPTIONS_H
diff --git a/src/core/pipe.c b/src/core/pipe.c
index 40720906..a4148c65 100644
--- a/src/core/pipe.c
+++ b/src/core/pipe.c
@@ -297,11 +297,7 @@ nni_pipe_getopt(nni_pipe *p, const char *name, void *val, size_t *szp, int typ)
if (strcmp(po->po_name, name) != 0) {
continue;
}
- if ((typ != NNI_TYPE_OPAQUE) &&
- (po->po_type != NNI_TYPE_OPAQUE) && (typ != po->po_type)) {
- return (NNG_EBADTYPE);
- }
- return (po->po_getopt(p->p_tran_data, val, szp));
+ return (po->po_getopt(p->p_tran_data, val, szp, typ));
}
// Maybe the endpoint knows?
return (nni_ep_getopt(p->p_ep, name, val, szp, typ));
diff --git a/src/core/protocol.h b/src/core/protocol.h
index e0e0e0d7..1c341241 100644
--- a/src/core/protocol.h
+++ b/src/core/protocol.h
@@ -50,7 +50,7 @@ struct nni_proto_pipe_ops {
struct nni_proto_sock_option {
const char *pso_name;
int pso_type;
- int (*pso_getopt)(void *, void *, size_t *);
+ int (*pso_getopt)(void *, void *, size_t *, int);
int (*pso_setopt)(void *, const void *, size_t);
};
diff --git a/src/core/socket.c b/src/core/socket.c
index 40fdc9c8..9e98a9d9 100644
--- a/src/core/socket.c
+++ b/src/core/socket.c
@@ -22,7 +22,7 @@ static nni_mtx nni_sock_lk;
typedef struct nni_socket_option {
const char *so_name;
int so_type;
- int (*so_getopt)(nni_sock *, void *, size_t *);
+ int (*so_getopt)(nni_sock *, void *, size_t *, int);
int (*so_setopt)(nni_sock *, const void *, size_t);
} nni_socket_option;
@@ -100,17 +100,13 @@ nni_sock_can_recv_cb(void *arg, int flags)
}
static int
-nni_sock_getopt_fd(nni_sock *s, int flag, void *val, size_t *szp)
+nni_sock_get_fd(nni_sock *s, int flag, int *fdp)
{
int rv;
nni_notifyfd *fd;
nni_msgq * mq;
nni_msgq_cb cb;
- if ((*szp < sizeof(int))) {
- return (NNG_EINVAL);
- }
-
if ((flag & nni_sock_flags(s)) == 0) {
return (NNG_ENOTSUP);
}
@@ -131,35 +127,43 @@ nni_sock_getopt_fd(nni_sock *s, int flag, void *val, size_t *szp)
return (NNG_EINVAL);
}
- // If we already inited this, just give back the same file descriptor.
- if (fd->sn_init) {
- memcpy(val, &fd->sn_rfd, sizeof(int));
- *szp = sizeof(int);
- return (0);
- }
+ // Open if not already done.
+ if (!fd->sn_init) {
+ if ((rv = nni_plat_pipe_open(&fd->sn_wfd, &fd->sn_rfd)) != 0) {
+ return (rv);
+ }
- if ((rv = nni_plat_pipe_open(&fd->sn_wfd, &fd->sn_rfd)) != 0) {
- return (rv);
- }
+ nni_msgq_set_cb(mq, cb, fd);
- nni_msgq_set_cb(mq, cb, fd);
+ fd->sn_init = 1;
+ }
- fd->sn_init = 1;
- *szp = sizeof(int);
- memcpy(val, &fd->sn_rfd, sizeof(int));
+ *fdp = fd->sn_rfd;
return (0);
}
static int
-nni_sock_getopt_sendfd(nni_sock *s, void *buf, size_t *szp)
+nni_sock_getopt_sendfd(nni_sock *s, void *buf, size_t *szp, int typ)
{
- return (nni_sock_getopt_fd(s, NNI_PROTO_FLAG_SND, buf, szp));
+ int fd;
+ int rv;
+
+ if ((rv = nni_sock_get_fd(s, NNI_PROTO_FLAG_SND, &fd)) != 0) {
+ return (rv);
+ }
+ return (nni_copyout_int(fd, buf, szp, typ));
}
static int
-nni_sock_getopt_recvfd(nni_sock *s, void *buf, size_t *szp)
+nni_sock_getopt_recvfd(nni_sock *s, void *buf, size_t *szp, int typ)
{
- return (nni_sock_getopt_fd(s, NNI_PROTO_FLAG_RCV, buf, szp));
+ int fd;
+ int rv;
+
+ if ((rv = nni_sock_get_fd(s, NNI_PROTO_FLAG_RCV, &fd)) != 0) {
+ return (rv);
+ }
+ return (nni_copyout_int(fd, buf, szp, typ));
}
static int
@@ -169,9 +173,9 @@ nni_sock_setopt_recvtimeo(nni_sock *s, const void *buf, size_t sz)
}
static int
-nni_sock_getopt_recvtimeo(nni_sock *s, void *buf, size_t *szp)
+nni_sock_getopt_recvtimeo(nni_sock *s, void *buf, size_t *szp, int typ)
{
- return (nni_getopt_ms(s->s_rcvtimeo, buf, szp));
+ return (nni_copyout_ms(s->s_rcvtimeo, buf, szp, typ));
}
static int
@@ -181,9 +185,9 @@ nni_sock_setopt_sendtimeo(nni_sock *s, const void *buf, size_t sz)
}
static int
-nni_sock_getopt_sendtimeo(nni_sock *s, void *buf, size_t *szp)
+nni_sock_getopt_sendtimeo(nni_sock *s, void *buf, size_t *szp, int typ)
{
- return (nni_getopt_ms(s->s_sndtimeo, buf, szp));
+ return (nni_copyout_ms(s->s_sndtimeo, buf, szp, typ));
}
static int
@@ -193,9 +197,9 @@ nni_sock_setopt_reconnmint(nni_sock *s, const void *buf, size_t sz)
}
static int
-nni_sock_getopt_reconnmint(nni_sock *s, void *buf, size_t *szp)
+nni_sock_getopt_reconnmint(nni_sock *s, void *buf, size_t *szp, int typ)
{
- return (nni_getopt_ms(s->s_reconn, buf, szp));
+ return (nni_copyout_ms(s->s_reconn, buf, szp, typ));
}
static int
@@ -205,9 +209,9 @@ nni_sock_setopt_reconnmaxt(nni_sock *s, const void *buf, size_t sz)
}
static int
-nni_sock_getopt_reconnmaxt(nni_sock *s, void *buf, size_t *szp)
+nni_sock_getopt_reconnmaxt(nni_sock *s, void *buf, size_t *szp, int typ)
{
- return (nni_getopt_ms(s->s_reconnmax, buf, szp));
+ return (nni_copyout_ms(s->s_reconnmax, buf, szp, typ));
}
static int
@@ -217,9 +221,11 @@ nni_sock_setopt_recvbuf(nni_sock *s, const void *buf, size_t sz)
}
static int
-nni_sock_getopt_recvbuf(nni_sock *s, void *buf, size_t *szp)
+nni_sock_getopt_recvbuf(nni_sock *s, void *buf, size_t *szp, int typ)
{
- return (nni_getopt_buf(s->s_urq, buf, szp));
+ int len = nni_msgq_cap(s->s_urq);
+
+ return (nni_copyout_int(len, buf, szp, typ));
}
static int
@@ -229,15 +235,17 @@ nni_sock_setopt_sendbuf(nni_sock *s, const void *buf, size_t sz)
}
static int
-nni_sock_getopt_sendbuf(nni_sock *s, void *buf, size_t *szp)
+nni_sock_getopt_sendbuf(nni_sock *s, void *buf, size_t *szp, int typ)
{
- return (nni_getopt_buf(s->s_uwq, buf, szp));
+ int len = nni_msgq_cap(s->s_uwq);
+
+ return (nni_copyout_int(len, buf, szp, typ));
}
static int
-nni_sock_getopt_sockname(nni_sock *s, void *buf, size_t *szp)
+nni_sock_getopt_sockname(nni_sock *s, void *buf, size_t *szp, int typ)
{
- return (nni_getopt_str(s->s_name, buf, szp));
+ return (nni_copyout_str(s->s_name, buf, szp, typ));
}
static int
@@ -1051,12 +1059,7 @@ nni_sock_getopt(nni_sock *s, const char *name, void *val, size_t *szp, int t)
nni_mtx_unlock(&s->s_mx);
return (NNG_EWRITEONLY);
}
- if ((pso->pso_type != NNI_TYPE_OPAQUE) &&
- (t != NNI_TYPE_OPAQUE) && (t != pso->pso_type)) {
- nni_mtx_unlock(&s->s_mx);
- return (NNG_EBADTYPE);
- }
- rv = pso->pso_getopt(s->s_data, val, szp);
+ rv = pso->pso_getopt(s->s_data, val, szp, t);
nni_mtx_unlock(&s->s_mx);
return (rv);
}
@@ -1070,12 +1073,7 @@ nni_sock_getopt(nni_sock *s, const char *name, void *val, size_t *szp, int t)
nni_mtx_unlock(&s->s_mx);
return (NNG_EWRITEONLY);
}
- if ((sso->so_type != NNI_TYPE_OPAQUE) &&
- (t != NNI_TYPE_OPAQUE) && (t != sso->so_type)) {
- nni_mtx_unlock(&s->s_mx);
- return (NNG_EBADTYPE);
- }
- rv = sso->so_getopt(s, val, szp);
+ rv = sso->so_getopt(s, val, szp, t);
nni_mtx_unlock(&s->s_mx);
return (rv);
}
diff --git a/src/core/transport.h b/src/core/transport.h
index ebc14e83..7085126f 100644
--- a/src/core/transport.h
+++ b/src/core/transport.h
@@ -58,7 +58,7 @@ struct nni_tran_ep_option {
int eo_type;
// eo_getopt retrieves the value of the option.
- int (*eo_getopt)(void *, void *, size_t *);
+ int (*eo_getopt)(void *, void *, size_t *, int);
// eo_set sets the value of the option. If the first argument
// (the endpoint) is NULL, then no actual set operation should be
@@ -121,7 +121,7 @@ struct nni_tran_pipe_option {
int po_type;
// po_getopt retrieves the value of the option.
- int (*po_getopt)(void *, void *, size_t *);
+ int (*po_getopt)(void *, void *, size_t *, int);
};
// Pipe operations are entry points called by the socket. These may be called