Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
L
libzmq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
libzmq
Commits
ec58ba04
Unverified
Commit
ec58ba04
authored
Mar 06, 2018
by
Luca Boccassi
Committed by
GitHub
Mar 06, 2018
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #2972 from sigiesec/reduce-sockopt-code-duplication
Problem: code duplication in getsockopt/setsockopt
parents
10d2b288
6f967c3a
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
264 additions
and
256 deletions
+264
-256
options.cpp
src/options.cpp
+216
-196
options.hpp
src/options.hpp
+31
-0
router.cpp
src/router.cpp
+2
-0
socket_base.cpp
src/socket_base.cpp
+10
-47
stream.cpp
src/stream.cpp
+4
-9
sub.cpp
src/sub.cpp
+1
-4
No files found.
src/options.cpp
View file @
ec58ba04
...
...
@@ -44,6 +44,146 @@
#define BINDDEVSIZ 16
#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
()
:
sndhwm
(
1000
),
rcvhwm
(
1000
),
...
...
@@ -166,11 +306,7 @@ int zmq::options_t::setsockopt (int option_,
break
;
case
ZMQ_AFFINITY
:
if
(
optvallen_
==
sizeof
(
uint64_t
))
{
affinity
=
*
((
uint64_t
*
)
optval_
);
return
0
;
}
break
;
return
do_setsockopt
(
optval_
,
optvallen_
,
&
affinity
);
case
ZMQ_ROUTING_ID
:
// Routing id is any binary string from 1 to 255 octets
...
...
@@ -259,11 +395,7 @@ int zmq::options_t::setsockopt (int option_,
break
;
case
ZMQ_MAXMSGSIZE
:
if
(
optvallen_
==
sizeof
(
int64_t
))
{
maxmsgsize
=
*
((
int64_t
*
)
optval_
);
return
0
;
}
break
;
return
do_setsockopt
(
optval_
,
optvallen_
,
&
maxmsgsize
);
case
ZMQ_MULTICAST_HOPS
:
if
(
is_int
&&
value
>
0
)
{
...
...
@@ -294,31 +426,23 @@ int zmq::options_t::setsockopt (int option_,
break
;
/* Deprecated in favor of ZMQ_IPV6 */
case
ZMQ_IPV4ONLY
:
if
(
is_int
&&
(
value
==
0
||
value
==
1
))
{
ipv6
=
(
value
==
0
);
return
0
;
}
break
;
case
ZMQ_IPV4ONLY
:
{
bool
value
;
int
rc
=
do_setsockopt_int_as_bool_strict
(
optval_
,
optvallen_
,
&
value
);
if
(
rc
==
0
)
ipv6
=
!
value
;
return
rc
;
}
/* To replace the somewhat surprising IPV4ONLY */
case
ZMQ_IPV6
:
if
(
is_int
&&
(
value
==
0
||
value
==
1
))
{
ipv6
=
(
value
!=
0
);
return
0
;
}
break
;
return
do_setsockopt_int_as_bool_strict
(
optval_
,
optvallen_
,
&
ipv6
);
case
ZMQ_SOCKS_PROXY
:
if
(
optval_
==
NULL
&&
optvallen_
==
0
)
{
socks_proxy_address
.
clear
();
return
0
;
}
else
if
(
optval_
!=
NULL
&&
optvallen_
>
0
)
{
socks_proxy_address
=
std
::
string
((
const
char
*
)
optval_
,
optvallen_
);
return
0
;
}
break
;
return
do_setsockopt_string_allow_empty_strict
(
optval_
,
optvallen_
,
&
socks_proxy_address
,
SIZE_MAX
);
case
ZMQ_TCP_KEEPALIVE
:
if
(
is_int
&&
(
value
==
-
1
||
value
==
0
||
value
==
1
))
{
...
...
@@ -349,60 +473,46 @@ int zmq::options_t::setsockopt (int option_,
break
;
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
))
{
immediate
=
value
;
return
0
;
}
break
;
case
ZMQ_TCP_ACCEPT_FILTER
:
if
(
optvallen_
==
0
&&
optval_
==
NULL
)
{
tcp_accept_filters
.
clear
();
return
0
;
}
else
if
(
optvallen_
>
0
&&
optvallen_
<
256
&&
optval_
!=
NULL
&&
*
((
const
char
*
)
optval_
)
!=
0
)
{
std
::
string
filter_str
((
const
char
*
)
optval_
,
optvallen_
);
tcp_address_mask_t
mask
;
int
rc
=
mask
.
resolve
(
filter_str
.
c_str
(),
ipv6
);
if
(
rc
==
0
)
{
tcp_accept_filters
.
push_back
(
mask
);
return
0
;
case
ZMQ_TCP_ACCEPT_FILTER
:
{
std
::
string
filter_str
;
int
rc
=
do_setsockopt_string_allow_empty_strict
(
optval_
,
optvallen_
,
&
filter_str
,
255
);
if
(
rc
==
0
)
{
if
(
filter_str
.
empty
())
{
tcp_accept_filters
.
clear
();
}
else
{
tcp_address_mask_t
mask
;
rc
=
mask
.
resolve
(
filter_str
.
c_str
(),
ipv6
);
if
(
rc
==
0
)
{
tcp_accept_filters
.
push_back
(
mask
);
}
}
}
break
;
return
rc
;
}
#if defined ZMQ_HAVE_SO_PEERCRED || defined ZMQ_HAVE_LOCAL_PEERCRED
case
ZMQ_IPC_FILTER_UID
:
if
(
optvallen_
==
0
&&
optval_
==
NULL
)
{
ipc_uid_accept_filters
.
clear
();
return
0
;
}
else
if
(
optvallen_
==
sizeof
(
uid_t
)
&&
optval_
!=
NULL
)
{
ipc_uid_accept_filters
.
insert
(
*
((
uid_t
*
)
optval_
));
return
0
;
}
break
;
return
do_setsockopt_set
(
optval_
,
optvallen_
,
&
ipc_uid_accept_filters
);
case
ZMQ_IPC_FILTER_GID
:
if
(
optvallen_
==
0
&&
optval_
==
NULL
)
{
ipc_gid_accept_filters
.
clear
();
return
0
;
}
else
if
(
optvallen_
==
sizeof
(
gid_t
)
&&
optval_
!=
NULL
)
{
ipc_gid_accept_filters
.
insert
(
*
((
gid_t
*
)
optval_
));
return
0
;
}
break
;
return
do_setsockopt_set
(
optval_
,
optvallen_
,
&
ipc_gid_accept_filters
);
#endif
#if defined ZMQ_HAVE_SO_PEERCRED
case
ZMQ_IPC_FILTER_PID
:
if
(
optvallen_
==
0
&&
optval_
==
NULL
)
{
ipc_pid_accept_filters
.
clear
();
return
0
;
}
else
if
(
optvallen_
==
sizeof
(
pid_t
)
&&
optval_
!=
NULL
)
{
ipc_pid_accept_filters
.
insert
(
*
((
pid_t
*
)
optval_
));
return
0
;
}
break
;
return
do_setsockopt_set
(
optval_
,
optvallen_
,
&
ipc_pid_accept_filters
);
#endif
case
ZMQ_PLAIN_SERVER
:
...
...
@@ -438,10 +548,8 @@ int zmq::options_t::setsockopt (int option_,
break
;
case
ZMQ_ZAP_DOMAIN
:
if
(
optvallen_
<
256
)
{
zap_domain
.
assign
((
const
char
*
)
optval_
,
optvallen_
);
return
0
;
}
return
do_setsockopt_string_allow_empty_relaxed
(
optval_
,
optvallen_
,
&
zap_domain
,
255
);
break
;
// If curve encryption isn't built, these options provoke EINVAL
...
...
@@ -475,11 +583,8 @@ int zmq::options_t::setsockopt (int option_,
#endif
case
ZMQ_CONFLATE
:
if
(
is_int
&&
(
value
==
0
||
value
==
1
))
{
conflate
=
(
value
!=
0
);
return
0
;
}
break
;
return
do_setsockopt_int_as_bool_strict
(
optval_
,
optvallen_
,
&
conflate
);
// If libgssapi isn't installed, these options provoke EINVAL
#ifdef HAVE_LIBGSSAPI_KRB5
...
...
@@ -510,11 +615,8 @@ int zmq::options_t::setsockopt (int option_,
break
;
case
ZMQ_GSSAPI_PLAINTEXT
:
if
(
is_int
&&
(
value
==
0
||
value
==
1
))
{
gss_plaintext
=
(
value
!=
0
);
return
0
;
}
break
;
return
do_setsockopt_int_as_bool_strict
(
optval_
,
optvallen_
,
&
gss_plaintext
);
case
ZMQ_GSSAPI_PRINCIPAL_NAMETYPE
:
if
(
is_int
...
...
@@ -545,11 +647,8 @@ int zmq::options_t::setsockopt (int option_,
break
;
case
ZMQ_INVERT_MATCHING
:
if
(
is_int
)
{
invert_matching
=
(
value
!=
0
);
return
0
;
}
break
;
return
do_setsockopt_int_as_bool_relaxed
(
optval_
,
optvallen_
,
&
invert_matching
);
case
ZMQ_HEARTBEAT_IVL
:
if
(
is_int
&&
value
>=
0
)
{
...
...
@@ -576,32 +675,16 @@ int zmq::options_t::setsockopt (int option_,
#ifdef ZMQ_HAVE_VMCI
case
ZMQ_VMCI_BUFFER_SIZE
:
if
(
optvallen_
==
sizeof
(
uint64_t
))
{
vmci_buffer_size
=
*
((
uint64_t
*
)
optval_
);
return
0
;
}
break
;
return
do_setsockopt
(
optval_
,
optvallen_
,
&
vmci_buffer_size
);
case
ZMQ_VMCI_BUFFER_MIN_SIZE
:
if
(
optvallen_
==
sizeof
(
uint64_t
))
{
vmci_buffer_min_size
=
*
((
uint64_t
*
)
optval_
);
return
0
;
}
break
;
return
do_setsockopt
(
optval_
,
optvallen_
,
&
vmci_buffer_min_size
);
case
ZMQ_VMCI_BUFFER_MAX_SIZE
:
if
(
optvallen_
==
sizeof
(
uint64_t
))
{
vmci_buffer_max_size
=
*
((
uint64_t
*
)
optval_
);
return
0
;
}
break
;
return
do_setsockopt
(
optval_
,
optvallen_
,
&
vmci_buffer_max_size
);
case
ZMQ_VMCI_CONNECT_TIMEOUT
:
if
(
optvallen_
==
sizeof
(
int
))
{
vmci_connect_timeout
=
*
((
int
*
)
optval_
);
return
0
;
}
break
;
return
do_setsockopt
(
optval_
,
optvallen_
,
&
vmci_connect_timeout
);
#endif
case
ZMQ_USE_FD
:
...
...
@@ -612,30 +695,16 @@ int zmq::options_t::setsockopt (int option_,
break
;
case
ZMQ_BINDTODEVICE
:
if
(
optval_
==
NULL
&&
optvallen_
==
0
)
{
bound_device
.
clear
();
return
0
;
}
else
if
(
optval_
!=
NULL
&&
optvallen_
>
0
&&
optvallen_
<=
BINDDEVSIZ
)
{
bound_device
=
std
::
string
((
const
char
*
)
optval_
,
optvallen_
);
return
0
;
}
break
;
return
do_setsockopt_string_allow_empty_strict
(
optval_
,
optvallen_
,
&
bound_device
,
BINDDEVSIZ
);
case
ZMQ_ZAP_ENFORCE_DOMAIN
:
if
(
is_int
)
{
zap_enforce_domain
=
(
value
!=
0
);
return
0
;
}
break
;
return
do_setsockopt_int_as_bool_relaxed
(
optval_
,
optvallen_
,
&
zap_enforce_domain
);
case
ZMQ_LOOPBACK_FASTPATH
:
if
(
is_int
)
{
loopback_fastpath
=
(
value
!=
0
);
return
0
;
}
break
;
return
do_setsockopt_int_as_bool_relaxed
(
optval_
,
optvallen_
,
&
loopback_fastpath
);
default
:
#if defined(ZMQ_ACT_MILITANT)
...
...
@@ -647,6 +716,12 @@ int zmq::options_t::setsockopt (int option_,
#endif
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)
// 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
...
...
@@ -691,11 +766,8 @@ int zmq::options_t::getsockopt (int option_,
break
;
case
ZMQ_ROUTING_ID
:
if
(
*
optvallen_
>=
routing_id_size
)
{
memcpy
(
optval_
,
routing_id
,
routing_id_size
);
*
optvallen_
=
routing_id_size
;
return
0
;
}
return
do_getsockopt
(
optval_
,
optvallen_
,
routing_id
,
routing_id_size
);
break
;
case
ZMQ_RATE
:
...
...
@@ -840,12 +912,7 @@ int zmq::options_t::getsockopt (int option_,
break
;
case
ZMQ_SOCKS_PROXY
:
if
(
*
optvallen_
>=
socks_proxy_address
.
size
()
+
1
)
{
memcpy
(
optval_
,
socks_proxy_address
.
c_str
(),
socks_proxy_address
.
size
()
+
1
);
*
optvallen_
=
socks_proxy_address
.
size
()
+
1
;
return
0
;
}
return
do_getsockopt
(
optval_
,
optvallen_
,
socks_proxy_address
);
break
;
case
ZMQ_TCP_KEEPALIVE
:
...
...
@@ -891,29 +958,15 @@ int zmq::options_t::getsockopt (int option_,
break
;
case
ZMQ_PLAIN_USERNAME
:
if
(
*
optvallen_
>=
plain_username
.
size
()
+
1
)
{
memcpy
(
optval_
,
plain_username
.
c_str
(),
plain_username
.
size
()
+
1
);
*
optvallen_
=
plain_username
.
size
()
+
1
;
return
0
;
}
return
do_getsockopt
(
optval_
,
optvallen_
,
plain_username
);
break
;
case
ZMQ_PLAIN_PASSWORD
:
if
(
*
optvallen_
>=
plain_password
.
size
()
+
1
)
{
memcpy
(
optval_
,
plain_password
.
c_str
(),
plain_password
.
size
()
+
1
);
*
optvallen_
=
plain_password
.
size
()
+
1
;
return
0
;
}
return
do_getsockopt
(
optval_
,
optvallen_
,
plain_password
);
break
;
case
ZMQ_ZAP_DOMAIN
:
if
(
*
optvallen_
>=
zap_domain
.
size
()
+
1
)
{
memcpy
(
optval_
,
zap_domain
.
c_str
(),
zap_domain
.
size
()
+
1
);
*
optvallen_
=
zap_domain
.
size
()
+
1
;
return
0
;
}
return
do_getsockopt
(
optval_
,
optvallen_
,
zap_domain
);
break
;
// If curve encryption isn't built, these options provoke EINVAL
...
...
@@ -926,36 +979,18 @@ int zmq::options_t::getsockopt (int option_,
break
;
case
ZMQ_CURVE_PUBLICKEY
:
if
(
*
optvallen_
==
CURVE_KEYSIZE
)
{
memcpy
(
optval_
,
curve_public_key
,
CURVE_KEYSIZE
);
return
0
;
}
else
if
(
*
optvallen_
==
CURVE_KEYSIZE_Z85
+
1
)
{
zmq_z85_encode
((
char
*
)
optval_
,
curve_public_key
,
CURVE_KEYSIZE
);
return
0
;
}
return
do_getsockopt_curve_key
(
optval_
,
optvallen_
,
curve_public_key
);
break
;
case
ZMQ_CURVE_SECRETKEY
:
if
(
*
optvallen_
==
CURVE_KEYSIZE
)
{
memcpy
(
optval_
,
curve_secret_key
,
CURVE_KEYSIZE
);
return
0
;
}
else
if
(
*
optvallen_
==
CURVE_KEYSIZE_Z85
+
1
)
{
zmq_z85_encode
((
char
*
)
optval_
,
curve_secret_key
,
CURVE_KEYSIZE
);
return
0
;
}
return
do_getsockopt_curve_key
(
optval_
,
optvallen_
,
curve_secret_key
);
break
;
case
ZMQ_CURVE_SERVERKEY
:
if
(
*
optvallen_
==
CURVE_KEYSIZE
)
{
memcpy
(
optval_
,
curve_server_key
,
CURVE_KEYSIZE
);
return
0
;
}
else
if
(
*
optvallen_
==
CURVE_KEYSIZE_Z85
+
1
)
{
zmq_z85_encode
((
char
*
)
optval_
,
curve_server_key
,
CURVE_KEYSIZE
);
return
0
;
}
return
do_getsockopt_curve_key
(
optval_
,
optvallen_
,
curve_server_key
);
break
;
#endif
...
...
@@ -976,21 +1011,11 @@ int zmq::options_t::getsockopt (int option_,
break
;
case
ZMQ_GSSAPI_PRINCIPAL
:
if
(
*
optvallen_
>=
gss_principal
.
size
()
+
1
)
{
memcpy
(
optval_
,
gss_principal
.
c_str
(),
gss_principal
.
size
()
+
1
);
*
optvallen_
=
gss_principal
.
size
()
+
1
;
return
0
;
}
return
do_getsockopt
(
optval_
,
optvallen_
,
gss_principal
);
break
;
case
ZMQ_GSSAPI_SERVICE_PRINCIPAL
:
if
(
*
optvallen_
>=
gss_service_principal
.
size
()
+
1
)
{
memcpy
(
optval_
,
gss_service_principal
.
c_str
(),
gss_service_principal
.
size
()
+
1
);
*
optvallen_
=
gss_service_principal
.
size
()
+
1
;
return
0
;
}
return
do_getsockopt
(
optval_
,
optvallen_
,
gss_service_principal
);
break
;
case
ZMQ_GSSAPI_PLAINTEXT
:
...
...
@@ -1058,12 +1083,7 @@ int zmq::options_t::getsockopt (int option_,
break
;
case
ZMQ_BINDTODEVICE
:
if
(
*
optvallen_
>=
bound_device
.
size
()
+
1
)
{
memcpy
(
optval_
,
bound_device
.
c_str
(),
bound_device
.
size
()
+
1
);
*
optvallen_
=
bound_device
.
size
()
+
1
;
return
0
;
}
return
do_getsockopt
(
optval_
,
optvallen_
,
bound_device
);
break
;
case
ZMQ_ZAP_ENFORCE_DOMAIN
:
...
...
src/options.hpp
View file @
ec58ba04
...
...
@@ -46,6 +46,10 @@
#include <sys/ucred.h>
#endif
#if __cplusplus >= 201103L
#include <type_traits>
#endif
// Normal base 256 key is 32 bytes
#define CURVE_KEYSIZE 32
// Key encoded using Z85 is 40 bytes
...
...
@@ -255,6 +259,33 @@ struct options_t
// Use zero copy strategy for storing message content when decoding.
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
src/router.cpp
View file @
ec58ba04
...
...
@@ -106,6 +106,8 @@ int zmq::router_t::xsetsockopt (int option_,
switch
(
option_
)
{
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_
)
{
connect_routing_id
.
assign
((
char
*
)
optval_
,
optvallen_
);
return
0
;
...
...
src/socket_base.cpp
View file @
ec58ba04
...
...
@@ -97,7 +97,6 @@
#include "scatter.hpp"
#include "dgram.hpp"
bool
zmq
::
socket_base_t
::
check_tag
()
{
return
tag
==
0xbaddecaf
;
...
...
@@ -395,77 +394,41 @@ int zmq::socket_base_t::getsockopt (int option_,
}
if
(
option_
==
ZMQ_RCVMORE
)
{
if
(
*
optvallen_
<
sizeof
(
int
))
{
errno
=
EINVAL
;
return
-
1
;
}
memset
(
optval_
,
0
,
*
optvallen_
);
*
((
int
*
)
optval_
)
=
rcvmore
?
1
:
0
;
*
optvallen_
=
sizeof
(
int
);
return
0
;
return
do_getsockopt
<
int
>
(
optval_
,
optvallen_
,
rcvmore
?
1
:
0
);
}
if
(
option_
==
ZMQ_FD
)
{
if
(
*
optvallen_
<
sizeof
(
fd_t
))
{
errno
=
EINVAL
;
return
-
1
;
}
if
(
thread_safe
)
{
// thread safe socket doesn't provide file descriptor
errno
=
EINVAL
;
return
-
1
;
}
*
((
fd_t
*
)
optval_
)
=
((
mailbox_t
*
)
mailbox
)
->
get_fd
();
*
optvallen_
=
sizeof
(
fd_t
);
return
0
;
return
do_getsockopt
<
fd_t
>
(
optval_
,
optvallen_
,
((
mailbox_t
*
)
mailbox
)
->
get_fd
());
}
if
(
option_
==
ZMQ_EVENTS
)
{
if
(
*
optvallen_
<
sizeof
(
int
))
{
errno
=
EINVAL
;
return
-
1
;
}
int
rc
=
process_commands
(
0
,
false
);
if
(
rc
!=
0
&&
(
errno
==
EINTR
||
errno
==
ETERM
))
{
return
-
1
;
}
errno_assert
(
rc
==
0
);
*
((
int
*
)
optval_
)
=
0
;
if
(
has_out
())
*
((
int
*
)
optval_
)
|=
ZMQ_POLLOUT
;
if
(
has_in
())
*
((
int
*
)
optval_
)
|=
ZMQ_POLLIN
;
*
optvallen_
=
sizeof
(
int
);
return
0
;
return
do_getsockopt
<
int
>
(
optval_
,
optvallen_
,
(
has_out
()
?
ZMQ_POLLOUT
:
0
)
|
(
has_in
()
?
ZMQ_POLLIN
:
0
));
}
if
(
option_
==
ZMQ_LAST_ENDPOINT
)
{
if
(
*
optvallen_
<
last_endpoint
.
size
()
+
1
)
{
errno
=
EINVAL
;
return
-
1
;
}
strncpy
(
static_cast
<
char
*>
(
optval_
),
last_endpoint
.
c_str
(),
last_endpoint
.
size
()
+
1
);
*
optvallen_
=
last_endpoint
.
size
()
+
1
;
return
0
;
return
do_getsockopt
(
optval_
,
optvallen_
,
last_endpoint
);
}
if
(
option_
==
ZMQ_THREAD_SAFE
)
{
if
(
*
optvallen_
<
sizeof
(
int
))
{
errno
=
EINVAL
;
return
-
1
;
}
memset
(
optval_
,
0
,
*
optvallen_
);
*
((
int
*
)
optval_
)
=
thread_safe
?
1
:
0
;
*
optvallen_
=
sizeof
(
int
);
return
0
;
return
do_getsockopt
<
int
>
(
optval_
,
optvallen_
,
thread_safe
?
1
:
0
);
}
int
rc
=
options
.
getsockopt
(
option_
,
optval_
,
optvallen_
);
return
rc
;
return
options
.
getsockopt
(
option_
,
optval_
,
optvallen_
);
}
int
zmq
::
socket_base_t
::
join
(
const
char
*
group_
)
...
...
src/stream.cpp
View file @
ec58ba04
...
...
@@ -175,13 +175,10 @@ int zmq::stream_t::xsetsockopt (int option_,
const
void
*
optval_
,
size_t
optvallen_
)
{
bool
is_int
=
(
optvallen_
==
sizeof
(
int
));
int
value
=
0
;
if
(
is_int
)
memcpy
(
&
value
,
optval_
,
sizeof
(
int
));
switch
(
option_
)
{
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_
)
{
connect_routing_id
.
assign
((
char
*
)
optval_
,
optvallen_
);
return
0
;
...
...
@@ -189,10 +186,8 @@ int zmq::stream_t::xsetsockopt (int option_,
break
;
case
ZMQ_STREAM_NOTIFY
:
if
(
is_int
&&
(
value
==
0
||
value
==
1
))
{
options
.
raw_notify
=
(
value
!=
0
);
return
0
;
}
return
do_setsockopt_int_as_bool_strict
(
optval_
,
optvallen_
,
&
options
.
raw_notify
);
break
;
default
:
...
...
src/sub.cpp
View file @
ec58ba04
...
...
@@ -59,10 +59,7 @@ int zmq::sub_t::xsetsockopt (int option_,
int
rc
=
msg
.
init_size
(
optvallen_
+
1
);
errno_assert
(
rc
==
0
);
unsigned
char
*
data
=
(
unsigned
char
*
)
msg
.
data
();
if
(
option_
==
ZMQ_SUBSCRIBE
)
*
data
=
1
;
else
if
(
option_
==
ZMQ_UNSUBSCRIBE
)
*
data
=
0
;
*
data
=
(
option_
==
ZMQ_SUBSCRIBE
);
// We explicitly allow a NULL subscription with size zero
if
(
optvallen_
)
{
assert
(
optval_
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment