From 52d37858451ad23f077294fc78b1a3f56255c32f Mon Sep 17 00:00:00 2001 From: Garrett D'Amore Date: Fri, 6 Oct 2017 12:26:42 -0700 Subject: Add NNG_OPT_DOMAIN and NNG_OPT_SOCKNAME support for legacy compat. The NNG_OPT_SOCKNAME option is settable, to a limit of 64 bytes. The NNG_OPT_DOMAIN is read-only, but changes to match the setting of the NNG_OPT_RAW field. New applications should not use the NNG_OPT_DOMAIN option -- it is provided solely for use with the legacy NN_DOMAIN option in the compatibility layer. --- src/core/socket.c | 62 ++++++++++++++++++++++++++++++++++++++----------------- src/nng.h | 2 ++ src/nng_compat.c | 13 ++++++++++-- tests/sock.c | 42 +++++++++++++++++++++++++++++++++++++ 4 files changed, 98 insertions(+), 21 deletions(-) diff --git a/src/core/socket.c b/src/core/socket.c index d613ac0e..c64ab995 100644 --- a/src/core/socket.c +++ b/src/core/socket.c @@ -10,6 +10,7 @@ #include "core/nng_impl.h" +#include #include // Socket implementation. @@ -36,6 +37,7 @@ struct nni_socket { nni_mtx s_mx; nni_cv s_cv; nni_cv s_close_cv; + int s_raw; uint64_t s_id; uint32_t s_flags; @@ -59,6 +61,7 @@ struct nni_socket { nni_duration s_reconnmax; // max reconnect time size_t s_rcvmaxsz; // max receive size nni_list s_options; // opts not handled by sock/proto + char s_name[64]; // socket name (legacy compat) nni_list s_eps; // active endpoints nni_list s_pipes; // active pipes @@ -77,25 +80,6 @@ struct nni_socket { nni_notifyfd s_recv_fd; }; -#if 0 -if (opt == nni_optid_reconnmint) { - rv = nni_setopt_usec(&s->s_reconn, val, size); -} else if (opt == nni_optid_reconnmaxt) { - rv = nni_setopt_usec(&s->s_reconnmax, val, size); -} else if (opt == nni_optid_recvtimeo) { - rv = nni_setopt_usec(&s->s_rcvtimeo, val, size); -} else if (opt == nni_optid_sendtimeo) { - rv = nni_setopt_usec(&s->s_sndtimeo, val, size); -} else if (opt == nni_optid_sendbuf) { - rv = nni_setopt_buf(s->s_uwq, val, size); -} else if (opt == nni_optid_recvbuf) { - rv = nni_setopt_buf(s->s_urq, val, size); -} else if ((opt == nni_optid_sendfd) || (opt == nni_optid_recvfd) || - (opt == nni_optid_locaddr) || (opt == nni_optid_remaddr)) { - // these options can be read, but cannot be set - rv = NNG_EINVAL; -#endif - static int nni_sock_getopt_sendfd(nni_sock *s, void *buf, size_t *szp) { @@ -180,6 +164,28 @@ nni_sock_getopt_sendbuf(nni_sock *s, void *buf, size_t *szp) return (nni_getopt_buf(s->s_uwq, buf, szp)); } +static int +nni_sock_getopt_sockname(nni_sock *s, void *buf, size_t *szp) +{ + return (nni_getopt_str(s->s_name, buf, szp)); +} + +static int +nni_sock_setopt_sockname(nni_sock *s, const void *buf, size_t sz) +{ + if (nni_strnlen(buf, sz) > sizeof(s->s_name) - 1) { + return (NNG_EINVAL); + } + nni_strlcpy(s->s_name, buf, sizeof(s->s_name)); + return (0); +} + +static int +nni_sock_getopt_domain(nni_sock *s, void *buf, size_t *szp) +{ + return (nni_getopt_int(s->s_raw + 1, buf, szp)); +} + static const nni_socket_option nni_sock_options[] = { { .so_name = NNG_OPT_RECVTIMEO, @@ -221,6 +227,16 @@ static const nni_socket_option nni_sock_options[] = { .so_getopt = nni_sock_getopt_reconnmaxt, .so_setopt = nni_sock_setopt_reconnmaxt, }, + { + .so_name = NNG_OPT_SOCKNAME, + .so_getopt = nni_sock_getopt_sockname, + .so_setopt = nni_sock_setopt_sockname, + }, + { + .so_name = NNG_OPT_DOMAIN, + .so_getopt = nni_sock_getopt_domain, + .so_setopt = NULL, + }, // terminate list { NULL, NULL, NULL }, }; @@ -587,6 +603,9 @@ nni_sock_open(nni_sock **sockp, const nni_proto *proto) s->s_sock_ops.sock_open(s->s_data); *sockp = s; } + // Set the sockname. + (void) snprintf( + s->s_name, sizeof(s->s_name), "%u", (unsigned) s->s_id); nni_mtx_unlock(&nni_sock_lk); return (rv); @@ -969,6 +988,11 @@ nni_sock_setopt(nni_sock *s, const char *name, const void *val, size_t size) return (NNG_EREADONLY); } rv = pso->pso_setopt(s->s_data, val, size); + if ((rv == 0) && (strcmp(name, NNG_OPT_RAW) == 0) && + (size >= sizeof(int))) { + // Save the raw option -- we use this for the DOMAIN. + memcpy(&s->s_raw, val, sizeof(int)); + } nni_mtx_unlock(&s->s_mx); return (rv); } diff --git a/src/nng.h b/src/nng.h index f9ed54b0..700ee869 100644 --- a/src/nng.h +++ b/src/nng.h @@ -408,6 +408,8 @@ NNG_DECL int nng_respondent0_open(nng_socket *); #define nng_respondent_open nng_respondent0_open // Options. +#define NNG_OPT_SOCKNAME "socket-name" +#define NNG_OPT_DOMAIN "compat:domain" // legacy compat only #define NNG_OPT_RAW "raw" #define NNG_OPT_LINGER "linger" #define NNG_OPT_RECVBUF "recv-buffer" diff --git a/src/nng_compat.c b/src/nng_compat.c index 994c1332..dedbda0d 100644 --- a/src/nng_compat.c +++ b/src/nng_compat.c @@ -583,11 +583,13 @@ static struct { { NN_SOL_SOCKET, NN_MAXTTL }, { NN_SOL_SOCKET, NN_RCVTIMEO }, { NN_SOL_SOCKET, NN_SNDTIMEO }, + { NN_SOL_SOCKET, NN_DOMAIN }, + { NN_SOL_SOCKET, NN_SOCKET_NAME }, { NN_REQ, NN_REQ_RESEND_IVL }, { NN_SUB, NN_SUB_SUBSCRIBE }, { NN_SUB, NN_SUB_UNSUBSCRIBE }, { NN_SURVEYOR, NN_SURVEYOR_DEADLINE }, - // XXX: DOMAIN, IPV4ONLY, SOCKETNAME, SNDPRIO, RCVPRIO + // XXX: IPV4ONLY, SNDPRIO, RCVPRIO // clang-format on }; @@ -642,6 +644,12 @@ init_opts(void) case NN_SNDTIMEO: SETOPT(NNG_OPT_SENDTIMEO, 1); break; + case NN_SOCKET_NAME: + SETOPT(NNG_OPT_SOCKNAME, 0); + break; + case NN_DOMAIN: + SETOPT(NNG_OPT_DOMAIN, 0); + break; } break; case NN_REQ: @@ -693,7 +701,8 @@ nn_getsockopt(int s, int nnlevel, int nnopt, void *valp, size_t *szp) } if (name == NULL) { - return (ENOPROTOOPT); + errno = ENOPROTOOPT; + return (-1); } if (mscvt) { diff --git a/tests/sock.c b/tests/sock.c index f2afde4c..e21e687d 100644 --- a/tests/sock.c +++ b/tests/sock.c @@ -109,6 +109,48 @@ TestMain("Socket Operations", { NNG_EREADONLY); So(nng_setopt(s1, NNG_OPT_LOCADDR, "a", 1) == NNG_EREADONLY); + So(nng_setopt_int(s1, NNG_OPT_DOMAIN, 3) == + NNG_EREADONLY); + }); + + Convey("Sockname option works", { + char name[128]; // 64 is max + size_t sz; + sz = sizeof(name); + So(nng_getopt( + s1, NNG_OPT_SOCKNAME, name, &sz) == 0); + So(sz > 0 && sz < 64); + So(sz == nni_strnlen(name, 64) + 1); + So(atoi(name) == (unsigned) s1); + + So(nng_setopt( + s1, NNG_OPT_SOCKNAME, "hello", 6) == 0); + sz = sizeof(name); + So(nng_getopt( + s1, NNG_OPT_SOCKNAME, name, &sz) == 0); + So(sz == 6); + So(strcmp(name, "hello") == 0); + + memset(name, 'A', 64); + name[64] = '\0'; + So(nng_setopt(s1, NNG_OPT_SOCKNAME, name, + strlen(name)) == NNG_EINVAL); + + So(nng_getopt( + s1, NNG_OPT_SOCKNAME, name, &sz) == 0); + So(sz == 6); + So(strcmp(name, "hello") == 0); + }); + + Convey("Domain option works", { + int dom; + So(nng_getopt_int(s1, NNG_OPT_DOMAIN, &dom) == + 0); + So(dom == 1); // NN_AF_SP + So(nng_setopt_int(s1, NNG_OPT_RAW, 1) == 0); + So(nng_getopt_int(s1, NNG_OPT_DOMAIN, &dom) == + 0); + So(dom == 2); // NN_AF_SP_RAW }); Convey("URL option works", { -- cgit v1.2.3-70-g09d2