Commit 18a14aed authored by Pieter Hintjens's avatar Pieter Hintjens

Added ZMQ_IPV6 option, cleaned up setsockopt code, it was nasty

parent aa21e090
...@@ -241,7 +241,7 @@ ZMQ_EXPORT int zmq_msg_set (zmq_msg_t *msg, int option, int optval); ...@@ -241,7 +241,7 @@ ZMQ_EXPORT int zmq_msg_set (zmq_msg_t *msg, int option, int optval);
#define ZMQ_MULTICAST_HOPS 25 #define ZMQ_MULTICAST_HOPS 25
#define ZMQ_RCVTIMEO 27 #define ZMQ_RCVTIMEO 27
#define ZMQ_SNDTIMEO 28 #define ZMQ_SNDTIMEO 28
#define ZMQ_IPV4ONLY 31 #define ZMQ_IPV4ONLY 31 /* Request replacement by IPV6 */
#define ZMQ_LAST_ENDPOINT 32 #define ZMQ_LAST_ENDPOINT 32
#define ZMQ_ROUTER_MANDATORY 33 #define ZMQ_ROUTER_MANDATORY 33
#define ZMQ_TCP_KEEPALIVE 34 #define ZMQ_TCP_KEEPALIVE 34
...@@ -252,6 +252,7 @@ ZMQ_EXPORT int zmq_msg_set (zmq_msg_t *msg, int option, int optval); ...@@ -252,6 +252,7 @@ ZMQ_EXPORT int zmq_msg_set (zmq_msg_t *msg, int option, int optval);
#define ZMQ_DELAY_ATTACH_ON_CONNECT 39 #define ZMQ_DELAY_ATTACH_ON_CONNECT 39
#define ZMQ_XPUB_VERBOSE 40 #define ZMQ_XPUB_VERBOSE 40
#define ZMQ_ROUTER_RAW 41 #define ZMQ_ROUTER_RAW 41
#define ZMQ_IPV6 42
/* Message options */ /* Message options */
......
...@@ -61,281 +61,203 @@ zmq::options_t::options_t () : ...@@ -61,281 +61,203 @@ zmq::options_t::options_t () :
int zmq::options_t::setsockopt (int option_, const void *optval_, int zmq::options_t::setsockopt (int option_, const void *optval_,
size_t optvallen_) size_t optvallen_)
{ {
bool valid = true;
bool is_int = (optvallen_ == sizeof (int));
int value = is_int? *((int *) optval_): 0;
switch (option_) { switch (option_) {
case ZMQ_SNDHWM:
if (is_int && value >= 0)
sndhwm = value;
else
valid = false;
break;
case ZMQ_RCVHWM:
if (is_int && value >= 0)
rcvhwm = value;
else
valid = false;
break;
case ZMQ_SNDHWM: case ZMQ_AFFINITY:
if (optvallen_ != sizeof (int) || *((int*) optval_) < 0) { if (optvallen_ == sizeof (uint64_t))
errno = EINVAL; affinity = *((uint64_t*) optval_);
return -1; else
} valid = false;
sndhwm = *((int*) optval_); break;
return 0;
case ZMQ_IDENTITY:
case ZMQ_RCVHWM: // Empty identity is invalid as well as identity longer than
if (optvallen_ != sizeof (int) || *((int*) optval_) < 0) { // 255 bytes. Identity starting with binary zero is invalid
errno = EINVAL; // as these are used for auto-generated identities.
return -1; if (optvallen_ > 0 && optvallen_ < 256
} && *((const unsigned char *) optval_) != 0) {
rcvhwm = *((int*) optval_); identity_size = optvallen_;
return 0; memcpy (identity, optval_, identity_size);
}
else
valid = false;
break;
case ZMQ_AFFINITY: case ZMQ_RATE:
if (optvallen_ != sizeof (uint64_t)) { if (is_int && value > 0)
errno = EINVAL; rate = value;
return -1; else
} valid = false;
affinity = *((uint64_t*) optval_); break;
return 0;
case ZMQ_IDENTITY: case ZMQ_RECOVERY_IVL:
if (is_int && value >= 0)
recovery_ivl = value;
else
valid = false;
// Empty identity is invalid as well as identity longer than case ZMQ_SNDBUF:
// 255 bytes. Identity starting with binary zero is invalid if (is_int && value >= 0)
// as these are used for auto-generated identities. sndbuf = value;
if (optvallen_ < 1 || optvallen_ > 255 || else
*((const unsigned char*) optval_) == 0) { valid = false;
errno = EINVAL; break;
return -1;
}
identity_size = optvallen_;
memcpy (identity, optval_, identity_size);
return 0;
case ZMQ_RATE: case ZMQ_RCVBUF:
if (optvallen_ != sizeof (int) || *((int*) optval_) <= 0) { if (is_int && value >= 0)
errno = EINVAL; rcvbuf = value;
return -1; else
} valid = false;
rate = *((int*) optval_); break;
return 0;
case ZMQ_RECOVERY_IVL: case ZMQ_LINGER:
if (optvallen_ != sizeof (int) || *((int*) optval_) < 0) { if (is_int && value >= -1)
errno = EINVAL; linger = value;
return -1; else
} valid = false;
recovery_ivl = *((int*) optval_); break;
return 0;
case ZMQ_SNDBUF: case ZMQ_RECONNECT_IVL:
if (optvallen_ != sizeof (int) || *((int*) optval_) < 0) { if (is_int && value >= -1)
errno = EINVAL; reconnect_ivl = value;
return -1; else
} valid = false;
sndbuf = *((int*) optval_); break;
return 0;
case ZMQ_RCVBUF: case ZMQ_RECONNECT_IVL_MAX:
if (optvallen_ != sizeof (int) || *((int*) optval_) < 0) { if (is_int && value >= 0)
errno = EINVAL; reconnect_ivl_max = value;
return -1; else
} valid = false;
rcvbuf = *((int*) optval_); break;
return 0;
case ZMQ_LINGER: case ZMQ_BACKLOG:
if (optvallen_ != sizeof (int)) { if (is_int && value >= 0)
errno = EINVAL; backlog = value;
return -1; else
} valid = false;
linger = *((int*) optval_); break;
return 0;
case ZMQ_RECONNECT_IVL: case ZMQ_MAXMSGSIZE:
if (optvallen_ != sizeof (int)) { if (optvallen_ == sizeof (int64_t))
errno = EINVAL; maxmsgsize = *((int64_t *) optval_);
return -1; else
} valid = false;
if (*((int*) optval_) < -1) {
errno = EINVAL;
return -1;
}
reconnect_ivl = *((int*) optval_);
return 0;
case ZMQ_RECONNECT_IVL_MAX: case ZMQ_MULTICAST_HOPS:
if (optvallen_ != sizeof (int)) { if (is_int && value > 0)
errno = EINVAL; multicast_hops = value;
return -1; else
} valid = false;
if (*((int*) optval_) < 0) { break;
errno = EINVAL;
return -1;
}
reconnect_ivl_max = *((int*) optval_);
return 0;
case ZMQ_BACKLOG: case ZMQ_RCVTIMEO:
if (optvallen_ != sizeof (int)) { if (is_int && value >= -1)
errno = EINVAL; rcvtimeo = value;
return -1; else
} valid = false;
backlog = *((int*) optval_); break;
return 0;
case ZMQ_MAXMSGSIZE: case ZMQ_SNDTIMEO:
if (optvallen_ != sizeof (int64_t)) { if (is_int && value >= -1)
errno = EINVAL; sndtimeo = value;
return -1; else
} valid = false;
maxmsgsize = *((int64_t*) optval_); break;
return 0;
case ZMQ_MULTICAST_HOPS: case ZMQ_IPV4ONLY:
if (optvallen_ != sizeof (int) || *((int*) optval_) <= 0) { if (is_int && (value == 0 || value == 1))
errno = EINVAL; ipv4only = value;
return -1; else
} valid = false;
multicast_hops = *((int*) optval_); break;
return 0;
case ZMQ_RCVTIMEO: /* To replace the somewhat surprising IPV4ONLY */
if (optvallen_ != sizeof (int)) { case ZMQ_IPV6:
errno = EINVAL; if (is_int && (value == 0 || value == 1))
return -1; ipv4only = 1 - value;
} else
rcvtimeo = *((int*) optval_); valid = false;
return 0; break;
case ZMQ_SNDTIMEO: case ZMQ_TCP_KEEPALIVE:
if (optvallen_ != sizeof (int)) { if (is_int && (value >= -1 || value <= 1))
errno = EINVAL; tcp_keepalive = value;
return -1; else
} valid = false;
sndtimeo = *((int*) optval_); break;
return 0;
case ZMQ_IPV4ONLY: case ZMQ_TCP_KEEPALIVE_CNT:
{ if (is_int && (value == -1 || value >= 0))
if (optvallen_ != sizeof (int)) { tcp_keepalive_cnt = value;
errno = EINVAL; else
return -1; valid = false;
} break;
int val = *((int*) optval_);
if (val != 0 && val != 1) {
errno = EINVAL;
return -1;
}
ipv4only = val;
return 0;
}
case ZMQ_TCP_KEEPALIVE: case ZMQ_TCP_KEEPALIVE_IDLE:
{ if (is_int && (value == -1 || value >= 0))
if (optvallen_ != sizeof (int)) { tcp_keepalive_idle = value;
errno = EINVAL; else
return -1; valid = false;
} break;
int val = *((int*) optval_);
if (val != -1 && val != 0 && val != 1) {
errno = EINVAL;
return -1;
}
#if defined ZMQ_HAVE_SO_KEEPALIVE
tcp_keepalive = val;
#endif
return 0;
}
case ZMQ_TCP_KEEPALIVE_INTVL:
if (is_int && (value == -1 || value >= 0))
tcp_keepalive_intvl = value;
else
valid = false;
break;
case ZMQ_DELAY_ATTACH_ON_CONNECT: case ZMQ_DELAY_ATTACH_ON_CONNECT:
{ if (is_int && (value == 0 || value == 1))
if (optvallen_ != sizeof (int)) { delay_attach_on_connect = value;
errno = EINVAL; else
return -1; valid = false;
} break;
int val = *((int*) optval_);
if (val != 0 && val != 1) {
errno = EINVAL;
return -1;
}
delay_attach_on_connect = val;
return 0;
}
case ZMQ_TCP_KEEPALIVE_CNT:
{
if (optvallen_ != sizeof (int)) {
errno = EINVAL;
return -1;
}
int val = *((int*) optval_);
if (val <= 0 && val != -1) {
errno = EINVAL;
return -1;
}
#if defined ZMQ_HAVE_SO_KEEPALIVE && defined ZMQ_HAVE_TCP_KEEPCNT
tcp_keepalive_cnt = val;
#endif
return 0;
}
case ZMQ_TCP_KEEPALIVE_IDLE:
{
if (optvallen_ != sizeof (int)) {
errno = EINVAL;
return -1;
}
int val = *((int*) optval_);
if (val <= 0 && val != -1) {
errno = EINVAL;
return -1;
}
#if defined ZMQ_HAVE_SO_KEEPALIVE && (defined ZMQ_HAVE_TCP_KEEPIDLE || defined ZMQ_HAVE_TCP_KEEPALIVE)
tcp_keepalive_idle = val;
#endif
return 0;
}
case ZMQ_TCP_KEEPALIVE_INTVL:
{
if (optvallen_ != sizeof (int)) {
errno = EINVAL;
return -1;
}
int val = *((int*) optval_);
if (val <= 0 && val != -1) {
errno = EINVAL;
return -1;
}
#if defined ZMQ_HAVE_SO_KEEPALIVE && defined ZMQ_HAVE_TCP_KEEPINTVL
tcp_keepalive_intvl = val;
#endif
return 0;
}
case ZMQ_TCP_ACCEPT_FILTER: case ZMQ_TCP_ACCEPT_FILTER:
{ if (optvallen_ == 0 && optval_ == NULL)
if (optvallen_ == 0 && optval_ == NULL) {
tcp_accept_filters.clear (); tcp_accept_filters.clear ();
return 0;
}
else else
if (optvallen_ < 1 || optvallen_ > 255 || optval_ == NULL || *((const char*) optval_) == 0) { if (optvallen_ < 1 || optvallen_ > 255 || optval_ == NULL || *((const char*) optval_) == 0)
errno = EINVAL; valid = false;
return -1;
}
else { else {
std::string filter_str ((const char*) optval_, optvallen_); std::string filter_str ((const char *) optval_, optvallen_);
tcp_address_mask_t mask; tcp_address_mask_t mask;
int rc = mask.resolve (filter_str.c_str (), ipv4only ? true : false); int rc = mask.resolve (filter_str.c_str (), ipv4only);
if (rc != 0) { if (rc == 0)
errno = EINVAL; tcp_accept_filters.push_back (mask);
return -1; else
} valid = false;
tcp_accept_filters.push_back(mask);
return 0;
} }
} break;
default:
{ default:
errno = EINVAL; valid = false;
return -1; break;
} }
if (valid)
return 0;
else {
errno = EINVAL;
return -1;
} }
} }
...@@ -505,6 +427,15 @@ int zmq::options_t::getsockopt (int option_, void *optval_, size_t *optvallen_) ...@@ -505,6 +427,15 @@ int zmq::options_t::getsockopt (int option_, void *optval_, size_t *optvallen_)
*optvallen_ = sizeof (int); *optvallen_ = sizeof (int);
return 0; return 0;
case ZMQ_IPV6:
if (*optvallen_ < sizeof (int)) {
errno = EINVAL;
return -1;
}
*((int*) optval_) = 1 - ipv4only;
*optvallen_ = sizeof (int);
return 0;
case ZMQ_DELAY_ATTACH_ON_CONNECT: case ZMQ_DELAY_ATTACH_ON_CONNECT:
if (*optvallen_ < sizeof (int)) { if (*optvallen_ < sizeof (int)) {
errno = EINVAL; errno = EINVAL;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment