mirror of
https://github.com/zeromq/libzmq.git
synced 2024-12-31 01:43:02 +08:00
Problem: code duplication in getsockopt/setsockopt
Solution: extracted common code into do_getsockopt/do_setsockopt functions
This commit is contained in:
parent
494c2a71f8
commit
6f967c3a13
412
src/options.cpp
412
src/options.cpp
@ -44,6 +44,146 @@
|
|||||||
#define BINDDEVSIZ 16
|
#define BINDDEVSIZ 16
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static int sockopt_invalid ()
|
||||||
|
{
|
||||||
|
#if defined(ZMQ_ACT_MILITANT)
|
||||||
|
zmq_assert (false);
|
||||||
|
#endif
|
||||||
|
errno = EINVAL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int zmq::do_getsockopt (void *const optval_,
|
||||||
|
size_t *const optvallen_,
|
||||||
|
const std::string &value_)
|
||||||
|
{
|
||||||
|
return do_getsockopt (optval_, optvallen_, value_.c_str (),
|
||||||
|
value_.size () + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int zmq::do_getsockopt (void *const optval_,
|
||||||
|
size_t *const optvallen_,
|
||||||
|
const void *value_,
|
||||||
|
const size_t value_len_)
|
||||||
|
{
|
||||||
|
// TODO behaviour is inconsistent with options_t::getsockopt; there, an
|
||||||
|
// *exact* length match is required except for string-like (but not the
|
||||||
|
// CURVE keys!) (and therefore null-ing remaining memory is a no-op, see
|
||||||
|
// comment below)
|
||||||
|
if (*optvallen_ < value_len_) {
|
||||||
|
return sockopt_invalid ();
|
||||||
|
}
|
||||||
|
memcpy (optval_, value_, value_len_);
|
||||||
|
// TODO why is the remaining memory null-ed?
|
||||||
|
memset ((char *) optval_ + value_len_, 0, *optvallen_ - value_len_);
|
||||||
|
*optvallen_ = value_len_;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef ZMQ_HAVE_CURVE
|
||||||
|
static int do_getsockopt_curve_key (void *const optval_,
|
||||||
|
size_t *const optvallen_,
|
||||||
|
const uint8_t (&curve_key_)[CURVE_KEYSIZE])
|
||||||
|
{
|
||||||
|
if (*optvallen_ == CURVE_KEYSIZE) {
|
||||||
|
memcpy (optval_, curve_key_, CURVE_KEYSIZE);
|
||||||
|
return 0;
|
||||||
|
} else if (*optvallen_ == CURVE_KEYSIZE_Z85 + 1) {
|
||||||
|
zmq_z85_encode ((char *) optval_, curve_key_, CURVE_KEYSIZE);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return sockopt_invalid ();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
int do_setsockopt (const void *const optval_,
|
||||||
|
const size_t optvallen_,
|
||||||
|
T *const out_value_)
|
||||||
|
{
|
||||||
|
if (optvallen_ == sizeof (T)) {
|
||||||
|
memcpy (out_value_, optval_, sizeof (T));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return sockopt_invalid ();
|
||||||
|
}
|
||||||
|
|
||||||
|
int zmq::do_setsockopt_int_as_bool_strict (const void *const optval_,
|
||||||
|
const size_t optvallen_,
|
||||||
|
bool *const out_value_)
|
||||||
|
{
|
||||||
|
// TODO handling of values other than 0 or 1 is not consistent,
|
||||||
|
// here it is disallowed, but for other options such as
|
||||||
|
// ZMQ_ROUTER_RAW any positive value is accepted
|
||||||
|
int value;
|
||||||
|
if (do_setsockopt (optval_, optvallen_, &value) == -1)
|
||||||
|
return -1;
|
||||||
|
if (value == 0 || value == 1) {
|
||||||
|
*out_value_ = (value != 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return sockopt_invalid ();
|
||||||
|
}
|
||||||
|
|
||||||
|
int zmq::do_setsockopt_int_as_bool_relaxed (const void *const optval_,
|
||||||
|
const size_t optvallen_,
|
||||||
|
bool *const out_value_)
|
||||||
|
{
|
||||||
|
int value;
|
||||||
|
if (do_setsockopt (optval_, optvallen_, &value) == -1)
|
||||||
|
return -1;
|
||||||
|
*out_value_ = (value != 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
do_setsockopt_string_allow_empty_strict (const void *const optval_,
|
||||||
|
const size_t optvallen_,
|
||||||
|
std::string *const out_value_,
|
||||||
|
const size_t max_len_)
|
||||||
|
{
|
||||||
|
// TODO why is optval_ != NULL not allowed in case of optvallen_== 0?
|
||||||
|
// TODO why are empty strings allowed for some socket options, but not for others?
|
||||||
|
if (optval_ == NULL && optvallen_ == 0) {
|
||||||
|
out_value_->clear ();
|
||||||
|
return 0;
|
||||||
|
} else if (optval_ != NULL && optvallen_ > 0 && optvallen_ <= max_len_) {
|
||||||
|
out_value_->assign ((const char *) optval_, optvallen_);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return sockopt_invalid ();
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
do_setsockopt_string_allow_empty_relaxed (const void *const optval_,
|
||||||
|
const size_t optvallen_,
|
||||||
|
std::string *const out_value_,
|
||||||
|
const size_t max_len_)
|
||||||
|
{
|
||||||
|
// TODO use either do_setsockopt_string_allow_empty_relaxed or
|
||||||
|
// do_setsockopt_string_allow_empty_strict everywhere
|
||||||
|
if (optvallen_ > 0 && optvallen_ <= max_len_) {
|
||||||
|
out_value_->assign ((const char *) optval_, optvallen_);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return sockopt_invalid ();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
int do_setsockopt_set (const void *const optval_,
|
||||||
|
const size_t optvallen_,
|
||||||
|
std::set<T> *const set_)
|
||||||
|
{
|
||||||
|
if (optvallen_ == 0 && optval_ == NULL) {
|
||||||
|
set_->clear ();
|
||||||
|
return 0;
|
||||||
|
} else if (optvallen_ == sizeof (T) && optval_ != NULL) {
|
||||||
|
set_->insert (*((const T *) optval_));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return sockopt_invalid ();
|
||||||
|
}
|
||||||
|
|
||||||
zmq::options_t::options_t () :
|
zmq::options_t::options_t () :
|
||||||
sndhwm (1000),
|
sndhwm (1000),
|
||||||
rcvhwm (1000),
|
rcvhwm (1000),
|
||||||
@ -166,11 +306,7 @@ int zmq::options_t::setsockopt (int option_,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case ZMQ_AFFINITY:
|
case ZMQ_AFFINITY:
|
||||||
if (optvallen_ == sizeof (uint64_t)) {
|
return do_setsockopt (optval_, optvallen_, &affinity);
|
||||||
affinity = *((uint64_t *) optval_);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ZMQ_ROUTING_ID:
|
case ZMQ_ROUTING_ID:
|
||||||
// Routing id is any binary string from 1 to 255 octets
|
// Routing id is any binary string from 1 to 255 octets
|
||||||
@ -259,11 +395,7 @@ int zmq::options_t::setsockopt (int option_,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case ZMQ_MAXMSGSIZE:
|
case ZMQ_MAXMSGSIZE:
|
||||||
if (optvallen_ == sizeof (int64_t)) {
|
return do_setsockopt (optval_, optvallen_, &maxmsgsize);
|
||||||
maxmsgsize = *((int64_t *) optval_);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ZMQ_MULTICAST_HOPS:
|
case ZMQ_MULTICAST_HOPS:
|
||||||
if (is_int && value > 0) {
|
if (is_int && value > 0) {
|
||||||
@ -294,31 +426,23 @@ int zmq::options_t::setsockopt (int option_,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
/* Deprecated in favor of ZMQ_IPV6 */
|
/* Deprecated in favor of ZMQ_IPV6 */
|
||||||
case ZMQ_IPV4ONLY:
|
case ZMQ_IPV4ONLY: {
|
||||||
if (is_int && (value == 0 || value == 1)) {
|
bool value;
|
||||||
ipv6 = (value == 0);
|
int rc =
|
||||||
return 0;
|
do_setsockopt_int_as_bool_strict (optval_, optvallen_, &value);
|
||||||
}
|
if (rc == 0)
|
||||||
break;
|
ipv6 = !value;
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
/* To replace the somewhat surprising IPV4ONLY */
|
/* To replace the somewhat surprising IPV4ONLY */
|
||||||
case ZMQ_IPV6:
|
case ZMQ_IPV6:
|
||||||
if (is_int && (value == 0 || value == 1)) {
|
return do_setsockopt_int_as_bool_strict (optval_, optvallen_,
|
||||||
ipv6 = (value != 0);
|
&ipv6);
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ZMQ_SOCKS_PROXY:
|
case ZMQ_SOCKS_PROXY:
|
||||||
if (optval_ == NULL && optvallen_ == 0) {
|
return do_setsockopt_string_allow_empty_strict (
|
||||||
socks_proxy_address.clear ();
|
optval_, optvallen_, &socks_proxy_address, SIZE_MAX);
|
||||||
return 0;
|
|
||||||
} else if (optval_ != NULL && optvallen_ > 0) {
|
|
||||||
socks_proxy_address =
|
|
||||||
std::string ((const char *) optval_, optvallen_);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ZMQ_TCP_KEEPALIVE:
|
case ZMQ_TCP_KEEPALIVE:
|
||||||
if (is_int && (value == -1 || value == 0 || value == 1)) {
|
if (is_int && (value == -1 || value == 0 || value == 1)) {
|
||||||
@ -349,60 +473,46 @@ int zmq::options_t::setsockopt (int option_,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case ZMQ_IMMEDIATE:
|
case ZMQ_IMMEDIATE:
|
||||||
|
// TODO why is immediate not bool (and called non_immediate, as its meaning appears to be reversed)
|
||||||
if (is_int && (value == 0 || value == 1)) {
|
if (is_int && (value == 0 || value == 1)) {
|
||||||
immediate = value;
|
immediate = value;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ZMQ_TCP_ACCEPT_FILTER:
|
case ZMQ_TCP_ACCEPT_FILTER: {
|
||||||
if (optvallen_ == 0 && optval_ == NULL) {
|
std::string filter_str;
|
||||||
tcp_accept_filters.clear ();
|
int rc = do_setsockopt_string_allow_empty_strict (
|
||||||
return 0;
|
optval_, optvallen_, &filter_str, 255);
|
||||||
} else if (optvallen_ > 0 && optvallen_ < 256 && optval_ != NULL
|
if (rc == 0) {
|
||||||
&& *((const char *) optval_) != 0) {
|
if (filter_str.empty ()) {
|
||||||
std::string filter_str ((const char *) optval_, optvallen_);
|
tcp_accept_filters.clear ();
|
||||||
tcp_address_mask_t mask;
|
} else {
|
||||||
int rc = mask.resolve (filter_str.c_str (), ipv6);
|
tcp_address_mask_t mask;
|
||||||
if (rc == 0) {
|
rc = mask.resolve (filter_str.c_str (), ipv6);
|
||||||
tcp_accept_filters.push_back (mask);
|
if (rc == 0) {
|
||||||
return 0;
|
tcp_accept_filters.push_back (mask);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
#if defined ZMQ_HAVE_SO_PEERCRED || defined ZMQ_HAVE_LOCAL_PEERCRED
|
#if defined ZMQ_HAVE_SO_PEERCRED || defined ZMQ_HAVE_LOCAL_PEERCRED
|
||||||
case ZMQ_IPC_FILTER_UID:
|
case ZMQ_IPC_FILTER_UID:
|
||||||
if (optvallen_ == 0 && optval_ == NULL) {
|
return do_setsockopt_set (optval_, optvallen_,
|
||||||
ipc_uid_accept_filters.clear ();
|
&ipc_uid_accept_filters);
|
||||||
return 0;
|
|
||||||
} else if (optvallen_ == sizeof (uid_t) && optval_ != NULL) {
|
|
||||||
ipc_uid_accept_filters.insert (*((uid_t *) optval_));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ZMQ_IPC_FILTER_GID:
|
case ZMQ_IPC_FILTER_GID:
|
||||||
if (optvallen_ == 0 && optval_ == NULL) {
|
return do_setsockopt_set (optval_, optvallen_,
|
||||||
ipc_gid_accept_filters.clear ();
|
&ipc_gid_accept_filters);
|
||||||
return 0;
|
|
||||||
} else if (optvallen_ == sizeof (gid_t) && optval_ != NULL) {
|
|
||||||
ipc_gid_accept_filters.insert (*((gid_t *) optval_));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined ZMQ_HAVE_SO_PEERCRED
|
#if defined ZMQ_HAVE_SO_PEERCRED
|
||||||
case ZMQ_IPC_FILTER_PID:
|
case ZMQ_IPC_FILTER_PID:
|
||||||
if (optvallen_ == 0 && optval_ == NULL) {
|
return do_setsockopt_set (optval_, optvallen_,
|
||||||
ipc_pid_accept_filters.clear ();
|
&ipc_pid_accept_filters);
|
||||||
return 0;
|
|
||||||
} else if (optvallen_ == sizeof (pid_t) && optval_ != NULL) {
|
|
||||||
ipc_pid_accept_filters.insert (*((pid_t *) optval_));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
case ZMQ_PLAIN_SERVER:
|
case ZMQ_PLAIN_SERVER:
|
||||||
@ -438,10 +548,8 @@ int zmq::options_t::setsockopt (int option_,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case ZMQ_ZAP_DOMAIN:
|
case ZMQ_ZAP_DOMAIN:
|
||||||
if (optvallen_ < 256) {
|
return do_setsockopt_string_allow_empty_relaxed (
|
||||||
zap_domain.assign ((const char *) optval_, optvallen_);
|
optval_, optvallen_, &zap_domain, 255);
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// If curve encryption isn't built, these options provoke EINVAL
|
// If curve encryption isn't built, these options provoke EINVAL
|
||||||
@ -475,11 +583,8 @@ int zmq::options_t::setsockopt (int option_,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
case ZMQ_CONFLATE:
|
case ZMQ_CONFLATE:
|
||||||
if (is_int && (value == 0 || value == 1)) {
|
return do_setsockopt_int_as_bool_strict (optval_, optvallen_,
|
||||||
conflate = (value != 0);
|
&conflate);
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
// If libgssapi isn't installed, these options provoke EINVAL
|
// If libgssapi isn't installed, these options provoke EINVAL
|
||||||
#ifdef HAVE_LIBGSSAPI_KRB5
|
#ifdef HAVE_LIBGSSAPI_KRB5
|
||||||
@ -510,11 +615,8 @@ int zmq::options_t::setsockopt (int option_,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case ZMQ_GSSAPI_PLAINTEXT:
|
case ZMQ_GSSAPI_PLAINTEXT:
|
||||||
if (is_int && (value == 0 || value == 1)) {
|
return do_setsockopt_int_as_bool_strict (optval_, optvallen_,
|
||||||
gss_plaintext = (value != 0);
|
&gss_plaintext);
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ZMQ_GSSAPI_PRINCIPAL_NAMETYPE:
|
case ZMQ_GSSAPI_PRINCIPAL_NAMETYPE:
|
||||||
if (is_int
|
if (is_int
|
||||||
@ -545,11 +647,8 @@ int zmq::options_t::setsockopt (int option_,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case ZMQ_INVERT_MATCHING:
|
case ZMQ_INVERT_MATCHING:
|
||||||
if (is_int) {
|
return do_setsockopt_int_as_bool_relaxed (optval_, optvallen_,
|
||||||
invert_matching = (value != 0);
|
&invert_matching);
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ZMQ_HEARTBEAT_IVL:
|
case ZMQ_HEARTBEAT_IVL:
|
||||||
if (is_int && value >= 0) {
|
if (is_int && value >= 0) {
|
||||||
@ -576,32 +675,16 @@ int zmq::options_t::setsockopt (int option_,
|
|||||||
|
|
||||||
#ifdef ZMQ_HAVE_VMCI
|
#ifdef ZMQ_HAVE_VMCI
|
||||||
case ZMQ_VMCI_BUFFER_SIZE:
|
case ZMQ_VMCI_BUFFER_SIZE:
|
||||||
if (optvallen_ == sizeof (uint64_t)) {
|
return do_setsockopt (optval_, optvallen_, &vmci_buffer_size);
|
||||||
vmci_buffer_size = *((uint64_t *) optval_);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ZMQ_VMCI_BUFFER_MIN_SIZE:
|
case ZMQ_VMCI_BUFFER_MIN_SIZE:
|
||||||
if (optvallen_ == sizeof (uint64_t)) {
|
return do_setsockopt (optval_, optvallen_, &vmci_buffer_min_size);
|
||||||
vmci_buffer_min_size = *((uint64_t *) optval_);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ZMQ_VMCI_BUFFER_MAX_SIZE:
|
case ZMQ_VMCI_BUFFER_MAX_SIZE:
|
||||||
if (optvallen_ == sizeof (uint64_t)) {
|
return do_setsockopt (optval_, optvallen_, &vmci_buffer_max_size);
|
||||||
vmci_buffer_max_size = *((uint64_t *) optval_);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ZMQ_VMCI_CONNECT_TIMEOUT:
|
case ZMQ_VMCI_CONNECT_TIMEOUT:
|
||||||
if (optvallen_ == sizeof (int)) {
|
return do_setsockopt (optval_, optvallen_, &vmci_connect_timeout);
|
||||||
vmci_connect_timeout = *((int *) optval_);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
case ZMQ_USE_FD:
|
case ZMQ_USE_FD:
|
||||||
@ -612,30 +695,16 @@ int zmq::options_t::setsockopt (int option_,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case ZMQ_BINDTODEVICE:
|
case ZMQ_BINDTODEVICE:
|
||||||
if (optval_ == NULL && optvallen_ == 0) {
|
return do_setsockopt_string_allow_empty_strict (
|
||||||
bound_device.clear ();
|
optval_, optvallen_, &bound_device, BINDDEVSIZ);
|
||||||
return 0;
|
|
||||||
} else if (optval_ != NULL && optvallen_ > 0
|
|
||||||
&& optvallen_ <= BINDDEVSIZ) {
|
|
||||||
bound_device = std::string ((const char *) optval_, optvallen_);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ZMQ_ZAP_ENFORCE_DOMAIN:
|
case ZMQ_ZAP_ENFORCE_DOMAIN:
|
||||||
if (is_int) {
|
return do_setsockopt_int_as_bool_relaxed (optval_, optvallen_,
|
||||||
zap_enforce_domain = (value != 0);
|
&zap_enforce_domain);
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ZMQ_LOOPBACK_FASTPATH:
|
case ZMQ_LOOPBACK_FASTPATH:
|
||||||
if (is_int) {
|
return do_setsockopt_int_as_bool_relaxed (optval_, optvallen_,
|
||||||
loopback_fastpath = (value != 0);
|
&loopback_fastpath);
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
#if defined(ZMQ_ACT_MILITANT)
|
#if defined(ZMQ_ACT_MILITANT)
|
||||||
@ -647,6 +716,12 @@ int zmq::options_t::setsockopt (int option_,
|
|||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO mechanism should either be set explicitly, or determined when
|
||||||
|
// connecting. currently, it depends on the order of setsockopt calls
|
||||||
|
// if there is some inconsistency, which is confusing. in addition,
|
||||||
|
// the assumed or set mechanism should be queryable (as a socket option)
|
||||||
|
|
||||||
#if defined(ZMQ_ACT_MILITANT)
|
#if defined(ZMQ_ACT_MILITANT)
|
||||||
// There is no valid use case for passing an error back to the application
|
// There is no valid use case for passing an error back to the application
|
||||||
// when it sent malformed arguments to a socket option. Use ./configure
|
// when it sent malformed arguments to a socket option. Use ./configure
|
||||||
@ -691,11 +766,8 @@ int zmq::options_t::getsockopt (int option_,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case ZMQ_ROUTING_ID:
|
case ZMQ_ROUTING_ID:
|
||||||
if (*optvallen_ >= routing_id_size) {
|
return do_getsockopt (optval_, optvallen_, routing_id,
|
||||||
memcpy (optval_, routing_id, routing_id_size);
|
routing_id_size);
|
||||||
*optvallen_ = routing_id_size;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ZMQ_RATE:
|
case ZMQ_RATE:
|
||||||
@ -840,12 +912,7 @@ int zmq::options_t::getsockopt (int option_,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case ZMQ_SOCKS_PROXY:
|
case ZMQ_SOCKS_PROXY:
|
||||||
if (*optvallen_ >= socks_proxy_address.size () + 1) {
|
return do_getsockopt (optval_, optvallen_, socks_proxy_address);
|
||||||
memcpy (optval_, socks_proxy_address.c_str (),
|
|
||||||
socks_proxy_address.size () + 1);
|
|
||||||
*optvallen_ = socks_proxy_address.size () + 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ZMQ_TCP_KEEPALIVE:
|
case ZMQ_TCP_KEEPALIVE:
|
||||||
@ -891,29 +958,15 @@ int zmq::options_t::getsockopt (int option_,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case ZMQ_PLAIN_USERNAME:
|
case ZMQ_PLAIN_USERNAME:
|
||||||
if (*optvallen_ >= plain_username.size () + 1) {
|
return do_getsockopt (optval_, optvallen_, plain_username);
|
||||||
memcpy (optval_, plain_username.c_str (),
|
|
||||||
plain_username.size () + 1);
|
|
||||||
*optvallen_ = plain_username.size () + 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ZMQ_PLAIN_PASSWORD:
|
case ZMQ_PLAIN_PASSWORD:
|
||||||
if (*optvallen_ >= plain_password.size () + 1) {
|
return do_getsockopt (optval_, optvallen_, plain_password);
|
||||||
memcpy (optval_, plain_password.c_str (),
|
|
||||||
plain_password.size () + 1);
|
|
||||||
*optvallen_ = plain_password.size () + 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ZMQ_ZAP_DOMAIN:
|
case ZMQ_ZAP_DOMAIN:
|
||||||
if (*optvallen_ >= zap_domain.size () + 1) {
|
return do_getsockopt (optval_, optvallen_, zap_domain);
|
||||||
memcpy (optval_, zap_domain.c_str (), zap_domain.size () + 1);
|
|
||||||
*optvallen_ = zap_domain.size () + 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// If curve encryption isn't built, these options provoke EINVAL
|
// If curve encryption isn't built, these options provoke EINVAL
|
||||||
@ -926,36 +979,18 @@ int zmq::options_t::getsockopt (int option_,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case ZMQ_CURVE_PUBLICKEY:
|
case ZMQ_CURVE_PUBLICKEY:
|
||||||
if (*optvallen_ == CURVE_KEYSIZE) {
|
return do_getsockopt_curve_key (optval_, optvallen_,
|
||||||
memcpy (optval_, curve_public_key, CURVE_KEYSIZE);
|
curve_public_key);
|
||||||
return 0;
|
|
||||||
} else if (*optvallen_ == CURVE_KEYSIZE_Z85 + 1) {
|
|
||||||
zmq_z85_encode ((char *) optval_, curve_public_key,
|
|
||||||
CURVE_KEYSIZE);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ZMQ_CURVE_SECRETKEY:
|
case ZMQ_CURVE_SECRETKEY:
|
||||||
if (*optvallen_ == CURVE_KEYSIZE) {
|
return do_getsockopt_curve_key (optval_, optvallen_,
|
||||||
memcpy (optval_, curve_secret_key, CURVE_KEYSIZE);
|
curve_secret_key);
|
||||||
return 0;
|
|
||||||
} else if (*optvallen_ == CURVE_KEYSIZE_Z85 + 1) {
|
|
||||||
zmq_z85_encode ((char *) optval_, curve_secret_key,
|
|
||||||
CURVE_KEYSIZE);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ZMQ_CURVE_SERVERKEY:
|
case ZMQ_CURVE_SERVERKEY:
|
||||||
if (*optvallen_ == CURVE_KEYSIZE) {
|
return do_getsockopt_curve_key (optval_, optvallen_,
|
||||||
memcpy (optval_, curve_server_key, CURVE_KEYSIZE);
|
curve_server_key);
|
||||||
return 0;
|
|
||||||
} else if (*optvallen_ == CURVE_KEYSIZE_Z85 + 1) {
|
|
||||||
zmq_z85_encode ((char *) optval_, curve_server_key,
|
|
||||||
CURVE_KEYSIZE);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -976,21 +1011,11 @@ int zmq::options_t::getsockopt (int option_,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case ZMQ_GSSAPI_PRINCIPAL:
|
case ZMQ_GSSAPI_PRINCIPAL:
|
||||||
if (*optvallen_ >= gss_principal.size () + 1) {
|
return do_getsockopt (optval_, optvallen_, gss_principal);
|
||||||
memcpy (optval_, gss_principal.c_str (),
|
|
||||||
gss_principal.size () + 1);
|
|
||||||
*optvallen_ = gss_principal.size () + 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ZMQ_GSSAPI_SERVICE_PRINCIPAL:
|
case ZMQ_GSSAPI_SERVICE_PRINCIPAL:
|
||||||
if (*optvallen_ >= gss_service_principal.size () + 1) {
|
return do_getsockopt (optval_, optvallen_, gss_service_principal);
|
||||||
memcpy (optval_, gss_service_principal.c_str (),
|
|
||||||
gss_service_principal.size () + 1);
|
|
||||||
*optvallen_ = gss_service_principal.size () + 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ZMQ_GSSAPI_PLAINTEXT:
|
case ZMQ_GSSAPI_PLAINTEXT:
|
||||||
@ -1058,12 +1083,7 @@ int zmq::options_t::getsockopt (int option_,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case ZMQ_BINDTODEVICE:
|
case ZMQ_BINDTODEVICE:
|
||||||
if (*optvallen_ >= bound_device.size () + 1) {
|
return do_getsockopt (optval_, optvallen_, bound_device);
|
||||||
memcpy (optval_, bound_device.c_str (),
|
|
||||||
bound_device.size () + 1);
|
|
||||||
*optvallen_ = bound_device.size () + 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ZMQ_ZAP_ENFORCE_DOMAIN:
|
case ZMQ_ZAP_ENFORCE_DOMAIN:
|
||||||
|
@ -46,6 +46,10 @@
|
|||||||
#include <sys/ucred.h>
|
#include <sys/ucred.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if __cplusplus >= 201103L
|
||||||
|
#include <type_traits>
|
||||||
|
#endif
|
||||||
|
|
||||||
// Normal base 256 key is 32 bytes
|
// Normal base 256 key is 32 bytes
|
||||||
#define CURVE_KEYSIZE 32
|
#define CURVE_KEYSIZE 32
|
||||||
// Key encoded using Z85 is 40 bytes
|
// Key encoded using Z85 is 40 bytes
|
||||||
@ -255,6 +259,33 @@ struct options_t
|
|||||||
// Use zero copy strategy for storing message content when decoding.
|
// Use zero copy strategy for storing message content when decoding.
|
||||||
bool zero_copy;
|
bool zero_copy;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
int do_getsockopt (void *const optval_,
|
||||||
|
size_t *const optvallen_,
|
||||||
|
const void *value_,
|
||||||
|
const size_t value_len_);
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
int do_getsockopt (void *const optval_, size_t *const optvallen_, T value_)
|
||||||
|
{
|
||||||
|
#if __cplusplus >= 201103L && (!defined(__GNUC__) || __GNUC__ > 5)
|
||||||
|
static_assert (std::is_trivially_copyable<T>::value,
|
||||||
|
"invalid use of do_getsockopt");
|
||||||
|
#endif
|
||||||
|
return do_getsockopt (optval_, optvallen_, &value_, sizeof (T));
|
||||||
|
}
|
||||||
|
|
||||||
|
int do_getsockopt (void *const optval_,
|
||||||
|
size_t *const optvallen_,
|
||||||
|
const std::string &value_);
|
||||||
|
|
||||||
|
int do_setsockopt_int_as_bool_strict (const void *const optval_,
|
||||||
|
const size_t optvallen_,
|
||||||
|
bool *out_value_);
|
||||||
|
|
||||||
|
int do_setsockopt_int_as_bool_relaxed (const void *const optval_,
|
||||||
|
const size_t optvallen_,
|
||||||
|
bool *out_value_);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -106,6 +106,8 @@ int zmq::router_t::xsetsockopt (int option_,
|
|||||||
|
|
||||||
switch (option_) {
|
switch (option_) {
|
||||||
case ZMQ_CONNECT_ROUTING_ID:
|
case ZMQ_CONNECT_ROUTING_ID:
|
||||||
|
// TODO why isn't it possible to set an empty connect_routing_id
|
||||||
|
// (which is the default value)
|
||||||
if (optval_ && optvallen_) {
|
if (optval_ && optvallen_) {
|
||||||
connect_routing_id.assign ((char *) optval_, optvallen_);
|
connect_routing_id.assign ((char *) optval_, optvallen_);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -97,7 +97,6 @@
|
|||||||
#include "scatter.hpp"
|
#include "scatter.hpp"
|
||||||
#include "dgram.hpp"
|
#include "dgram.hpp"
|
||||||
|
|
||||||
|
|
||||||
bool zmq::socket_base_t::check_tag ()
|
bool zmq::socket_base_t::check_tag ()
|
||||||
{
|
{
|
||||||
return tag == 0xbaddecaf;
|
return tag == 0xbaddecaf;
|
||||||
@ -395,77 +394,41 @@ int zmq::socket_base_t::getsockopt (int option_,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (option_ == ZMQ_RCVMORE) {
|
if (option_ == ZMQ_RCVMORE) {
|
||||||
if (*optvallen_ < sizeof (int)) {
|
return do_getsockopt<int> (optval_, optvallen_, rcvmore ? 1 : 0);
|
||||||
errno = EINVAL;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
memset (optval_, 0, *optvallen_);
|
|
||||||
*((int *) optval_) = rcvmore ? 1 : 0;
|
|
||||||
*optvallen_ = sizeof (int);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (option_ == ZMQ_FD) {
|
if (option_ == ZMQ_FD) {
|
||||||
if (*optvallen_ < sizeof (fd_t)) {
|
|
||||||
errno = EINVAL;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (thread_safe) {
|
if (thread_safe) {
|
||||||
// thread safe socket doesn't provide file descriptor
|
// thread safe socket doesn't provide file descriptor
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
*((fd_t *) optval_) = ((mailbox_t *) mailbox)->get_fd ();
|
return do_getsockopt<fd_t> (optval_, optvallen_,
|
||||||
*optvallen_ = sizeof (fd_t);
|
((mailbox_t *) mailbox)->get_fd ());
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (option_ == ZMQ_EVENTS) {
|
if (option_ == ZMQ_EVENTS) {
|
||||||
if (*optvallen_ < sizeof (int)) {
|
|
||||||
errno = EINVAL;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
int rc = process_commands (0, false);
|
int rc = process_commands (0, false);
|
||||||
if (rc != 0 && (errno == EINTR || errno == ETERM)) {
|
if (rc != 0 && (errno == EINTR || errno == ETERM)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
errno_assert (rc == 0);
|
errno_assert (rc == 0);
|
||||||
*((int *) optval_) = 0;
|
|
||||||
if (has_out ())
|
return do_getsockopt<int> (optval_, optvallen_,
|
||||||
*((int *) optval_) |= ZMQ_POLLOUT;
|
(has_out () ? ZMQ_POLLOUT : 0)
|
||||||
if (has_in ())
|
| (has_in () ? ZMQ_POLLIN : 0));
|
||||||
*((int *) optval_) |= ZMQ_POLLIN;
|
|
||||||
*optvallen_ = sizeof (int);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (option_ == ZMQ_LAST_ENDPOINT) {
|
if (option_ == ZMQ_LAST_ENDPOINT) {
|
||||||
if (*optvallen_ < last_endpoint.size () + 1) {
|
return do_getsockopt (optval_, optvallen_, last_endpoint);
|
||||||
errno = EINVAL;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
strncpy (static_cast<char *> (optval_), last_endpoint.c_str (),
|
|
||||||
last_endpoint.size () + 1);
|
|
||||||
*optvallen_ = last_endpoint.size () + 1;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (option_ == ZMQ_THREAD_SAFE) {
|
if (option_ == ZMQ_THREAD_SAFE) {
|
||||||
if (*optvallen_ < sizeof (int)) {
|
return do_getsockopt<int> (optval_, optvallen_, thread_safe ? 1 : 0);
|
||||||
errno = EINVAL;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
memset (optval_, 0, *optvallen_);
|
|
||||||
*((int *) optval_) = thread_safe ? 1 : 0;
|
|
||||||
*optvallen_ = sizeof (int);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int rc = options.getsockopt (option_, optval_, optvallen_);
|
return options.getsockopt (option_, optval_, optvallen_);
|
||||||
return rc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int zmq::socket_base_t::join (const char *group_)
|
int zmq::socket_base_t::join (const char *group_)
|
||||||
|
@ -175,13 +175,10 @@ int zmq::stream_t::xsetsockopt (int option_,
|
|||||||
const void *optval_,
|
const void *optval_,
|
||||||
size_t optvallen_)
|
size_t optvallen_)
|
||||||
{
|
{
|
||||||
bool is_int = (optvallen_ == sizeof (int));
|
|
||||||
int value = 0;
|
|
||||||
if (is_int)
|
|
||||||
memcpy (&value, optval_, sizeof (int));
|
|
||||||
|
|
||||||
switch (option_) {
|
switch (option_) {
|
||||||
case ZMQ_CONNECT_ROUTING_ID:
|
case ZMQ_CONNECT_ROUTING_ID:
|
||||||
|
// TODO why isn't it possible to set an empty connect_routing_id
|
||||||
|
// (which is the default value)
|
||||||
if (optval_ && optvallen_) {
|
if (optval_ && optvallen_) {
|
||||||
connect_routing_id.assign ((char *) optval_, optvallen_);
|
connect_routing_id.assign ((char *) optval_, optvallen_);
|
||||||
return 0;
|
return 0;
|
||||||
@ -189,10 +186,8 @@ int zmq::stream_t::xsetsockopt (int option_,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case ZMQ_STREAM_NOTIFY:
|
case ZMQ_STREAM_NOTIFY:
|
||||||
if (is_int && (value == 0 || value == 1)) {
|
return do_setsockopt_int_as_bool_strict (optval_, optvallen_,
|
||||||
options.raw_notify = (value != 0);
|
&options.raw_notify);
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -59,10 +59,7 @@ int zmq::sub_t::xsetsockopt (int option_,
|
|||||||
int rc = msg.init_size (optvallen_ + 1);
|
int rc = msg.init_size (optvallen_ + 1);
|
||||||
errno_assert (rc == 0);
|
errno_assert (rc == 0);
|
||||||
unsigned char *data = (unsigned char *) msg.data ();
|
unsigned char *data = (unsigned char *) msg.data ();
|
||||||
if (option_ == ZMQ_SUBSCRIBE)
|
*data = (option_ == ZMQ_SUBSCRIBE);
|
||||||
*data = 1;
|
|
||||||
else if (option_ == ZMQ_UNSUBSCRIBE)
|
|
||||||
*data = 0;
|
|
||||||
// We explicitly allow a NULL subscription with size zero
|
// We explicitly allow a NULL subscription with size zero
|
||||||
if (optvallen_) {
|
if (optvallen_) {
|
||||||
assert (optval_);
|
assert (optval_);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user