mirror of
https://github.com/zeromq/libzmq.git
synced 2024-12-27 15:41:05 +08:00
Added configuration for PLAIN security
* ZMQ_PLAIN_SERVER, ZMQ_PLAIN_USERNAME, ZMQ_PLAIN_PASSWORD options * Man page changes to zmq_setsockopt and zmq_getsockopt * Man pages for ZMQ_NULL, ZMQ_PLAIN, and ZMQ_CURVE * Test program test_security
This commit is contained in:
parent
8ea779c8f7
commit
e1f797b048
1
.gitignore
vendored
1
.gitignore
vendored
@ -47,6 +47,7 @@ tests/test_raw_sock
|
|||||||
tests/test_disconnect_inproc
|
tests/test_disconnect_inproc
|
||||||
tests/test_ctx_options
|
tests/test_ctx_options
|
||||||
tests/test_iov
|
tests/test_iov
|
||||||
|
tests/test_security
|
||||||
src/platform.hpp*
|
src/platform.hpp*
|
||||||
src/stamp-h1
|
src/stamp-h1
|
||||||
perf/local_lat
|
perf/local_lat
|
||||||
|
@ -8,9 +8,10 @@ MAN3 = zmq_bind.3 zmq_unbind.3 zmq_connect.3 zmq_disconnect.3 zmq_close.3 \
|
|||||||
zmq_getsockopt.3 zmq_setsockopt.3 \
|
zmq_getsockopt.3 zmq_setsockopt.3 \
|
||||||
zmq_socket.3 zmq_socket_monitor.3 zmq_poll.3 \
|
zmq_socket.3 zmq_socket_monitor.3 zmq_poll.3 \
|
||||||
zmq_errno.3 zmq_strerror.3 zmq_version.3 zmq_proxy.3 \
|
zmq_errno.3 zmq_strerror.3 zmq_version.3 zmq_proxy.3 \
|
||||||
zmq_sendmsg.3 zmq_recvmsg.3 zmq_init.3 zmq_term.3
|
zmq_sendmsg.3 zmq_recvmsg.3 zmq_init.3 zmq_term.3
|
||||||
|
|
||||||
MAN7 = zmq.7 zmq_tcp.7 zmq_pgm.7 zmq_epgm.7 zmq_inproc.7 zmq_ipc.7
|
MAN7 = zmq.7 zmq_tcp.7 zmq_pgm.7 zmq_epgm.7 zmq_inproc.7 zmq_ipc.7 \
|
||||||
|
zmq_null.7 zmq_plain.7 zmq_curve.7
|
||||||
|
|
||||||
MAN_DOC = $(MAN1) $(MAN3) $(MAN7)
|
MAN_DOC = $(MAN1) $(MAN3) $(MAN7)
|
||||||
|
|
||||||
|
17
doc/zmq.txt
17
doc/zmq.txt
@ -177,6 +177,23 @@ two sockets, opaquely. A proxy may optionally capture all traffic to a third
|
|||||||
socket. To start a proxy in an application thread, use linkzmq:zmq_proxy[3].
|
socket. To start a proxy in an application thread, use linkzmq:zmq_proxy[3].
|
||||||
|
|
||||||
|
|
||||||
|
Security
|
||||||
|
~~~~~~~~
|
||||||
|
A 0MQ socket can select a security mechanism. Both peers must use the same
|
||||||
|
security mechanism.
|
||||||
|
|
||||||
|
The following security mechanisms are provided for IPC and TCP connections:
|
||||||
|
|
||||||
|
Null security::
|
||||||
|
linkzmq:zmq_null[7]
|
||||||
|
|
||||||
|
Clear-text authentication using username and password::
|
||||||
|
linkzmq:zmq_clear[7]
|
||||||
|
|
||||||
|
Secure authentication and encryption::
|
||||||
|
linkzmq:zmq_curve[7]
|
||||||
|
|
||||||
|
|
||||||
ERROR HANDLING
|
ERROR HANDLING
|
||||||
--------------
|
--------------
|
||||||
The 0MQ library functions handle errors using the standard conventions found on
|
The 0MQ library functions handle errors using the standard conventions found on
|
||||||
|
40
doc/zmq_curve.txt
Normal file
40
doc/zmq_curve.txt
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
zmq_curve(7)
|
||||||
|
============
|
||||||
|
|
||||||
|
|
||||||
|
NAME
|
||||||
|
----
|
||||||
|
zmq_curve - clear-text authentication
|
||||||
|
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
--------
|
||||||
|
The CURVE mechanism defines a mechanism for secure authentication and
|
||||||
|
confidentiality for communications between a client and a server. CURVE
|
||||||
|
is intended for use on public networks. The CURVE mechanism is defined
|
||||||
|
by this document: <http://rfc.zeromq.org/spec:25>.
|
||||||
|
|
||||||
|
|
||||||
|
SERVER AND CLIENT ROLES
|
||||||
|
-----------------------
|
||||||
|
To use CURVE, the server shall set the ZMQ_CURVE_SERVER option, and the
|
||||||
|
client shall set the ZMQ_CURVE_PUBLICKEY and ZMQ_CURVE_SERVERKEY socket
|
||||||
|
options. Which peer binds, and which connects, is not relevant.
|
||||||
|
|
||||||
|
NOTE: this isn't implemented and not fully defined. The server keypair
|
||||||
|
needs to be persistent, and it would be sensible to define a format for
|
||||||
|
this in CurveZMQ
|
||||||
|
|
||||||
|
|
||||||
|
SEE ALSO
|
||||||
|
--------
|
||||||
|
linkzmq:zmq_setsockopt[3]
|
||||||
|
linkzmq:zmq_null[7]
|
||||||
|
linkzmq:zmq_plain[7]
|
||||||
|
linkzmq:zmq[7]
|
||||||
|
|
||||||
|
|
||||||
|
AUTHORS
|
||||||
|
-------
|
||||||
|
This page was written by the 0MQ community. To make a change please
|
||||||
|
read the 0MQ Contribution Policy at <http://www.zeromq.org/docs:contributing>.
|
@ -431,7 +431,7 @@ a ZMQ DSN. Note that if the TCP host is INADDR_ANY, indicated by a *, then
|
|||||||
the returned address will be 0.0.0.0 (for IPv4).
|
the returned address will be 0.0.0.0 (for IPv4).
|
||||||
|
|
||||||
[horizontal]
|
[horizontal]
|
||||||
Option value type:: character string
|
Option value type:: NULL-terminated character string
|
||||||
Option value unit:: N/A
|
Option value unit:: N/A
|
||||||
Default value:: NULL
|
Default value:: NULL
|
||||||
Applicable socket types:: all, when binding TCP or IPC transports
|
Applicable socket types:: all, when binding TCP or IPC transports
|
||||||
@ -451,8 +451,9 @@ Applicable socket types:: all, when using TCP transports.
|
|||||||
|
|
||||||
ZMQ_TCP_KEEPALIVE_IDLE: Override TCP_KEEPCNT(or TCP_KEEPALIVE on some OS)
|
ZMQ_TCP_KEEPALIVE_IDLE: Override TCP_KEEPCNT(or TCP_KEEPALIVE on some OS)
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
Override 'TCP_KEEPCNT'(or 'TCP_KEEPALIVE' on some OS) socket option(where supported by OS).
|
Override 'TCP_KEEPCNT'(or 'TCP_KEEPALIVE' on some OS) socket option (where
|
||||||
The default value of `-1` means to skip any overrides and leave it to OS default.
|
supported by OS). The default value of `-1` means to skip any overrides and
|
||||||
|
leave it to OS default.
|
||||||
|
|
||||||
[horizontal]
|
[horizontal]
|
||||||
Option value type:: int
|
Option value type:: int
|
||||||
@ -485,6 +486,57 @@ Default value:: -1 (leave to OS default)
|
|||||||
Applicable socket types:: all, when using TCP transports.
|
Applicable socket types:: all, when using TCP transports.
|
||||||
|
|
||||||
|
|
||||||
|
ZMQ_MECHANISM: Retrieve the current security mechanism
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
The 'ZMQ_MECHANISM' option shall retrieve the current security mechanism
|
||||||
|
for the socket.
|
||||||
|
|
||||||
|
[horizontal]
|
||||||
|
Option value type:: int
|
||||||
|
Option value unit:: ZMQ_NULL, ZMQ_PLAIN, or ZMQ_CURVE
|
||||||
|
Default value:: ZMQ_NULL
|
||||||
|
Applicable socket types:: all, when using TCP or IPC transports
|
||||||
|
|
||||||
|
|
||||||
|
ZMQ_PLAIN_SERVER: Retrieve the PLAIN server role
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
Returns the 'ZMQ_PLAIN_SERVER' option, if any, previously set on the socket.
|
||||||
|
|
||||||
|
[horizontal]
|
||||||
|
Option value type:: int
|
||||||
|
Option value unit:: 0, 1
|
||||||
|
Default value:: int
|
||||||
|
Applicable socket types:: all, when using TCP or IPC transports
|
||||||
|
|
||||||
|
|
||||||
|
ZMQ_PLAIN_USERNAME: Retrieve the last username set
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
The 'ZMQ_PLAIN_USERNAME' option shall retrieve the last username set for
|
||||||
|
the PLAIN security mechanism. The returned value shall be a NULL-terminated
|
||||||
|
string and MAY be empty. The returned size SHALL include the terminating
|
||||||
|
null byte.
|
||||||
|
|
||||||
|
[horizontal]
|
||||||
|
Option value type:: NULL-terminated character string
|
||||||
|
Option value unit:: N/A
|
||||||
|
Default value:: null string
|
||||||
|
Applicable socket types:: all, when using TCP or IPC transports
|
||||||
|
|
||||||
|
|
||||||
|
ZMQ_PLAIN_PASSWORD: Retrieve the last password set
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
The 'ZMQ_PLAIN_PASSWORD' option shall retrieve the last password set for
|
||||||
|
the PLAIN security mechanism. The returned value shall be a NULL-terminated
|
||||||
|
string and MAY be empty. The returned size SHALL include the terminating
|
||||||
|
null byte.
|
||||||
|
|
||||||
|
[horizontal]
|
||||||
|
Option value type:: NULL-terminated character string
|
||||||
|
Option value unit:: N/A
|
||||||
|
Default value:: null string
|
||||||
|
Applicable socket types:: all, when using TCP or IPC transports
|
||||||
|
|
||||||
|
|
||||||
RETURN VALUE
|
RETURN VALUE
|
||||||
------------
|
------------
|
||||||
The _zmq_getsockopt()_ function shall return zero if successful. Otherwise it
|
The _zmq_getsockopt()_ function shall return zero if successful. Otherwise it
|
||||||
|
27
doc/zmq_null.txt
Normal file
27
doc/zmq_null.txt
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
zmq_null(7)
|
||||||
|
===========
|
||||||
|
|
||||||
|
|
||||||
|
NAME
|
||||||
|
----
|
||||||
|
zmq_null - no security or confidentiality
|
||||||
|
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
--------
|
||||||
|
The NULL mechanism is defined by the ZMTP 3.0 specification:
|
||||||
|
<http://rfc.zeromq.org/spec:23>. This is the default security mechanism
|
||||||
|
for ZeroMQ sockets.
|
||||||
|
|
||||||
|
|
||||||
|
SEE ALSO
|
||||||
|
--------
|
||||||
|
linkzmq:zmq_plain[7]
|
||||||
|
linkzmq:zmq_curve[7]
|
||||||
|
linkzmq:zmq[7]
|
||||||
|
|
||||||
|
|
||||||
|
AUTHORS
|
||||||
|
-------
|
||||||
|
This page was written by the 0MQ community. To make a change please
|
||||||
|
read the 0MQ Contribution Policy at <http://www.zeromq.org/docs:contributing>.
|
37
doc/zmq_plain.txt
Normal file
37
doc/zmq_plain.txt
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
zmq_plain(7)
|
||||||
|
============
|
||||||
|
|
||||||
|
|
||||||
|
NAME
|
||||||
|
----
|
||||||
|
zmq_plain - clear-text authentication
|
||||||
|
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
--------
|
||||||
|
The PLAIN mechanism defines a simple username/password mechanism that
|
||||||
|
lets a server authenticate a client. PLAIN makes no attempt at security
|
||||||
|
or confidentiality. It is intended for use on internal networks where
|
||||||
|
security requirements are low. The PLAIN mechanism is defined by this
|
||||||
|
document: <http://rfc.zeromq.org/spec:24>.
|
||||||
|
|
||||||
|
|
||||||
|
USAGE
|
||||||
|
-----
|
||||||
|
To use PLAIN, the server shall set the ZMQ_PLAIN_SERVER option, and the
|
||||||
|
client shall set the ZMQ_PLAIN_USERNAME and ZMQ_PLAIN_PASSWORD socket
|
||||||
|
options. Which peer binds, and which connects, is not relevant.
|
||||||
|
|
||||||
|
|
||||||
|
SEE ALSO
|
||||||
|
--------
|
||||||
|
linkzmq:zmq_setsockopt[3]
|
||||||
|
linkzmq:zmq_null[7]
|
||||||
|
linkzmq:zmq_curve[7]
|
||||||
|
linkzmq:zmq[7]
|
||||||
|
|
||||||
|
|
||||||
|
AUTHORS
|
||||||
|
-------
|
||||||
|
This page was written by the 0MQ community. To make a change please
|
||||||
|
read the 0MQ Contribution Policy at <http://www.zeromq.org/docs:contributing>.
|
@ -437,6 +437,7 @@ Applicable socket types:: ZMQ_XPUB
|
|||||||
|
|
||||||
ZMQ_TCP_KEEPALIVE: Override SO_KEEPALIVE socket option
|
ZMQ_TCP_KEEPALIVE: Override SO_KEEPALIVE socket option
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
Override 'SO_KEEPALIVE' socket option(where supported by OS).
|
Override 'SO_KEEPALIVE' socket option(where supported by OS).
|
||||||
The default value of `-1` means to skip any overrides and leave it to OS default.
|
The default value of `-1` means to skip any overrides and leave it to OS default.
|
||||||
|
|
||||||
@ -449,8 +450,10 @@ Applicable socket types:: all, when using TCP transports.
|
|||||||
|
|
||||||
ZMQ_TCP_KEEPALIVE_IDLE: Override TCP_KEEPCNT(or TCP_KEEPALIVE on some OS)
|
ZMQ_TCP_KEEPALIVE_IDLE: Override TCP_KEEPCNT(or TCP_KEEPALIVE on some OS)
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
Override 'TCP_KEEPCNT'(or 'TCP_KEEPALIVE' on some OS) socket option(where supported by OS).
|
|
||||||
The default value of `-1` means to skip any overrides and leave it to OS default.
|
Override 'TCP_KEEPCNT'(or 'TCP_KEEPALIVE' on some OS) socket option (where
|
||||||
|
supported by OS). The default value of `-1` means to skip any overrides and
|
||||||
|
leave it to OS default.
|
||||||
|
|
||||||
[horizontal]
|
[horizontal]
|
||||||
Option value type:: int
|
Option value type:: int
|
||||||
@ -461,8 +464,9 @@ Applicable socket types:: all, when using TCP transports.
|
|||||||
|
|
||||||
ZMQ_TCP_KEEPALIVE_CNT: Override TCP_KEEPCNT socket option
|
ZMQ_TCP_KEEPALIVE_CNT: Override TCP_KEEPCNT socket option
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
Override 'TCP_KEEPCNT' socket option(where supported by OS).
|
|
||||||
The default value of `-1` means to skip any overrides and leave it to OS default.
|
Override 'TCP_KEEPCNT' socket option(where supported by OS). The default
|
||||||
|
value of `-1` means to skip any overrides and leave it to OS default.
|
||||||
|
|
||||||
[horizontal]
|
[horizontal]
|
||||||
Option value type:: int
|
Option value type:: int
|
||||||
@ -473,8 +477,9 @@ Applicable socket types:: all, when using TCP transports.
|
|||||||
|
|
||||||
ZMQ_TCP_KEEPALIVE_INTVL: Override TCP_KEEPINTVL socket option
|
ZMQ_TCP_KEEPALIVE_INTVL: Override TCP_KEEPINTVL socket option
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
Override 'TCP_KEEPINTVL' socket option(where supported by OS).
|
|
||||||
The default value of `-1` means to skip any overrides and leave it to OS default.
|
Override 'TCP_KEEPINTVL' socket option(where supported by OS). The default
|
||||||
|
value of `-1` means to skip any overrides and leave it to OS default.
|
||||||
|
|
||||||
[horizontal]
|
[horizontal]
|
||||||
Option value type:: int
|
Option value type:: int
|
||||||
@ -485,11 +490,12 @@ Applicable socket types:: all, when using TCP transports.
|
|||||||
|
|
||||||
ZMQ_TCP_ACCEPT_FILTER: Assign filters to allow new TCP connections
|
ZMQ_TCP_ACCEPT_FILTER: Assign filters to allow new TCP connections
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
Assign arbitrary number of filters that will be applied for each new TCP transport
|
|
||||||
connection on a listening socket.
|
Assign an arbitrary number of filters that will be applied for each new TCP
|
||||||
If no filters applied, then TCP transport allows connections from any ip.
|
transport connection on a listening socket. If no filters are applied, then
|
||||||
If at least one filter is applied then new connection source ip should be matched.
|
the TCP transport allows connections from any IP address. If at least one
|
||||||
To clear all filters call zmq_setsockopt(socket, ZMQ_TCP_ACCEPT_FILTER, NULL, 0).
|
filter is applied then new connection source ip should be matched. To clear
|
||||||
|
all filters call zmq_setsockopt(socket, ZMQ_TCP_ACCEPT_FILTER, NULL, 0).
|
||||||
Filter is a null-terminated string with ipv6 or ipv4 CIDR.
|
Filter is a null-terminated string with ipv6 or ipv4 CIDR.
|
||||||
|
|
||||||
[horizontal]
|
[horizontal]
|
||||||
@ -499,6 +505,52 @@ Default value:: no filters (allow from all)
|
|||||||
Applicable socket types:: all listening sockets, when using TCP transports.
|
Applicable socket types:: all listening sockets, when using TCP transports.
|
||||||
|
|
||||||
|
|
||||||
|
ZMQ_PLAIN_SERVER: Set PLAIN server role
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Defines whether the socket will act as server for PLAIN security, see
|
||||||
|
linkzmq:zmq_plain[3]. A value of '1' means the socket will act as
|
||||||
|
PLAIN server. A value of '0' means the socket will not act as PLAIN
|
||||||
|
server, and its security role then depends on other option settings.
|
||||||
|
Setting this to '0' shall reset the socket security to NULL.
|
||||||
|
|
||||||
|
[horizontal]
|
||||||
|
Option value type:: int
|
||||||
|
Option value unit:: 0, 1
|
||||||
|
Default value:: 0
|
||||||
|
Applicable socket types:: all, when using TCP or IPC transports
|
||||||
|
|
||||||
|
|
||||||
|
ZMQ_PLAIN_USERNAME: Set PLAIN security username
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Sets the username for outgoing connections over TCP or IPC. If you set this
|
||||||
|
to a non-null value, the security mechanism used for connections shall be
|
||||||
|
PLAIN, see linkzmq:zmq_plain[3]. If you set this to a null value, the security
|
||||||
|
mechanism used for connections shall be NULL, see linkzmq:zmq_null[3].
|
||||||
|
|
||||||
|
[horizontal]
|
||||||
|
Option value type:: character string
|
||||||
|
Option value unit:: N/A
|
||||||
|
Default value:: not set
|
||||||
|
Applicable socket types:: all, when using TCP or IPC transports
|
||||||
|
|
||||||
|
|
||||||
|
ZMQ_PLAIN_PASSWORD: Set PLAIN security password
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Sets the password for outgoing connections over TCP or IPC. If you set this
|
||||||
|
to a non-null value, the security mechanism used for connections shall be
|
||||||
|
PLAIN, see linkzmq:zmq_plain[7]. If you set this to a null value, the security
|
||||||
|
mechanism used for connections shall be NULL, see linkzmq:zmq_null[3].
|
||||||
|
|
||||||
|
[horizontal]
|
||||||
|
Option value type:: character string
|
||||||
|
Option value unit:: N/A
|
||||||
|
Default value:: not set
|
||||||
|
Applicable socket types:: all, when using TCP or IPC transports
|
||||||
|
|
||||||
|
|
||||||
RETURN VALUE
|
RETURN VALUE
|
||||||
------------
|
------------
|
||||||
The _zmq_setsockopt()_ function shall return zero if successful. Otherwise it
|
The _zmq_setsockopt()_ function shall return zero if successful. Otherwise it
|
||||||
@ -550,6 +602,8 @@ SEE ALSO
|
|||||||
--------
|
--------
|
||||||
linkzmq:zmq_getsockopt[3]
|
linkzmq:zmq_getsockopt[3]
|
||||||
linkzmq:zmq_socket[3]
|
linkzmq:zmq_socket[3]
|
||||||
|
linkzmq:zmq_plain[7]
|
||||||
|
linkzmq:zmq_curve[7]
|
||||||
linkzmq:zmq[7]
|
linkzmq:zmq[7]
|
||||||
|
|
||||||
|
|
||||||
|
@ -253,6 +253,13 @@ ZMQ_EXPORT int zmq_msg_set (zmq_msg_t *msg, int option, int optval);
|
|||||||
#define ZMQ_XPUB_VERBOSE 40
|
#define ZMQ_XPUB_VERBOSE 40
|
||||||
#define ZMQ_ROUTER_RAW 41
|
#define ZMQ_ROUTER_RAW 41
|
||||||
#define ZMQ_IPV6 42
|
#define ZMQ_IPV6 42
|
||||||
|
#define ZMQ_MECHANISM 43
|
||||||
|
#define ZMQ_PLAIN_SERVER 44
|
||||||
|
#define ZMQ_PLAIN_USERNAME 45
|
||||||
|
#define ZMQ_PLAIN_PASSWORD 46
|
||||||
|
#define ZMQ_CURVE_SERVER 47
|
||||||
|
#define ZMQ_CURVE_PUBLICKEY 48
|
||||||
|
#define ZMQ_CURVE_SERVERKEY 49
|
||||||
|
|
||||||
/* Message options */
|
/* Message options */
|
||||||
#define ZMQ_MORE 1
|
#define ZMQ_MORE 1
|
||||||
@ -261,6 +268,11 @@ ZMQ_EXPORT int zmq_msg_set (zmq_msg_t *msg, int option, int optval);
|
|||||||
#define ZMQ_DONTWAIT 1
|
#define ZMQ_DONTWAIT 1
|
||||||
#define ZMQ_SNDMORE 2
|
#define ZMQ_SNDMORE 2
|
||||||
|
|
||||||
|
/* Security mechanisms */
|
||||||
|
#define ZMQ_NULL 0
|
||||||
|
#define ZMQ_PLAIN 1
|
||||||
|
#define ZMQ_CURVE 2
|
||||||
|
|
||||||
/* Deprecated aliases */
|
/* Deprecated aliases */
|
||||||
#define ZMQ_DELAY_ATTACH_ON_CONNECT ZMQ_IMMEDIATE
|
#define ZMQ_DELAY_ATTACH_ON_CONNECT ZMQ_IMMEDIATE
|
||||||
#define ZMQ_NOBLOCK ZMQ_DONTWAIT
|
#define ZMQ_NOBLOCK ZMQ_DONTWAIT
|
||||||
|
597
src/options.cpp
597
src/options.cpp
@ -51,6 +51,8 @@ zmq::options_t::options_t () :
|
|||||||
tcp_keepalive_cnt (-1),
|
tcp_keepalive_cnt (-1),
|
||||||
tcp_keepalive_idle (-1),
|
tcp_keepalive_idle (-1),
|
||||||
tcp_keepalive_intvl (-1),
|
tcp_keepalive_intvl (-1),
|
||||||
|
mechanism (ZMQ_NULL),
|
||||||
|
plain_server (0),
|
||||||
socket_id (0)
|
socket_id (0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -58,30 +60,29 @@ 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));
|
bool is_int = (optvallen_ == sizeof (int));
|
||||||
int value = is_int? *((int *) optval_): 0;
|
int value = is_int? *((int *) optval_): 0;
|
||||||
|
|
||||||
switch (option_) {
|
switch (option_) {
|
||||||
case ZMQ_SNDHWM:
|
case ZMQ_SNDHWM:
|
||||||
if (is_int && value >= 0)
|
if (is_int && value >= 0) {
|
||||||
sndhwm = value;
|
sndhwm = value;
|
||||||
else
|
return 0;
|
||||||
valid = false;
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ZMQ_RCVHWM:
|
case ZMQ_RCVHWM:
|
||||||
if (is_int && value >= 0)
|
if (is_int && value >= 0) {
|
||||||
rcvhwm = value;
|
rcvhwm = value;
|
||||||
else
|
return 0;
|
||||||
valid = false;
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ZMQ_AFFINITY:
|
case ZMQ_AFFINITY:
|
||||||
if (optvallen_ == sizeof (uint64_t))
|
if (optvallen_ == sizeof (uint64_t)) {
|
||||||
affinity = *((uint64_t*) optval_);
|
affinity = *((uint64_t*) optval_);
|
||||||
else
|
return 0;
|
||||||
valid = false;
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ZMQ_IDENTITY:
|
case ZMQ_IDENTITY:
|
||||||
@ -92,405 +93,419 @@ int zmq::options_t::setsockopt (int option_, const void *optval_,
|
|||||||
&& *((const unsigned char *) optval_) != 0) {
|
&& *((const unsigned char *) optval_) != 0) {
|
||||||
identity_size = optvallen_;
|
identity_size = optvallen_;
|
||||||
memcpy (identity, optval_, identity_size);
|
memcpy (identity, optval_, identity_size);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
valid = false;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ZMQ_RATE:
|
case ZMQ_RATE:
|
||||||
if (is_int && value > 0)
|
if (is_int && value > 0) {
|
||||||
rate = value;
|
rate = value;
|
||||||
else
|
return 0;
|
||||||
valid = false;
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ZMQ_RECOVERY_IVL:
|
case ZMQ_RECOVERY_IVL:
|
||||||
if (is_int && value >= 0)
|
if (is_int && value >= 0) {
|
||||||
recovery_ivl = value;
|
recovery_ivl = value;
|
||||||
else
|
return 0;
|
||||||
valid = false;
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case ZMQ_SNDBUF:
|
case ZMQ_SNDBUF:
|
||||||
if (is_int && value >= 0)
|
if (is_int && value >= 0) {
|
||||||
sndbuf = value;
|
sndbuf = value;
|
||||||
else
|
return 0;
|
||||||
valid = false;
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ZMQ_RCVBUF:
|
case ZMQ_RCVBUF:
|
||||||
if (is_int && value >= 0)
|
if (is_int && value >= 0) {
|
||||||
rcvbuf = value;
|
rcvbuf = value;
|
||||||
else
|
return 0;
|
||||||
valid = false;
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ZMQ_LINGER:
|
case ZMQ_LINGER:
|
||||||
if (is_int && value >= -1)
|
if (is_int && value >= -1) {
|
||||||
linger = value;
|
linger = value;
|
||||||
else
|
return 0;
|
||||||
valid = false;
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ZMQ_RECONNECT_IVL:
|
case ZMQ_RECONNECT_IVL:
|
||||||
if (is_int && value >= -1)
|
if (is_int && value >= -1) {
|
||||||
reconnect_ivl = value;
|
reconnect_ivl = value;
|
||||||
else
|
return 0;
|
||||||
valid = false;
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ZMQ_RECONNECT_IVL_MAX:
|
case ZMQ_RECONNECT_IVL_MAX:
|
||||||
if (is_int && value >= 0)
|
if (is_int && value >= 0) {
|
||||||
reconnect_ivl_max = value;
|
reconnect_ivl_max = value;
|
||||||
else
|
return 0;
|
||||||
valid = false;
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ZMQ_BACKLOG:
|
case ZMQ_BACKLOG:
|
||||||
if (is_int && value >= 0)
|
if (is_int && value >= 0) {
|
||||||
backlog = value;
|
backlog = value;
|
||||||
else
|
return 0;
|
||||||
valid = false;
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ZMQ_MAXMSGSIZE:
|
case ZMQ_MAXMSGSIZE:
|
||||||
if (optvallen_ == sizeof (int64_t))
|
if (optvallen_ == sizeof (int64_t)) {
|
||||||
maxmsgsize = *((int64_t *) optval_);
|
maxmsgsize = *((int64_t *) optval_);
|
||||||
else
|
return 0;
|
||||||
valid = false;
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ZMQ_MULTICAST_HOPS:
|
case ZMQ_MULTICAST_HOPS:
|
||||||
if (is_int && value > 0)
|
if (is_int && value > 0) {
|
||||||
multicast_hops = value;
|
multicast_hops = value;
|
||||||
else
|
return 0;
|
||||||
valid = false;
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ZMQ_RCVTIMEO:
|
case ZMQ_RCVTIMEO:
|
||||||
if (is_int && value >= -1)
|
if (is_int && value >= -1) {
|
||||||
rcvtimeo = value;
|
rcvtimeo = value;
|
||||||
else
|
return 0;
|
||||||
valid = false;
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ZMQ_SNDTIMEO:
|
case ZMQ_SNDTIMEO:
|
||||||
if (is_int && value >= -1)
|
if (is_int && value >= -1) {
|
||||||
sndtimeo = value;
|
sndtimeo = value;
|
||||||
else
|
return 0;
|
||||||
valid = false;
|
}
|
||||||
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))
|
if (is_int && (value == 0 || value == 1)) {
|
||||||
ipv6 = (value == 0);
|
ipv6 = (value == 0);
|
||||||
else
|
return 0;
|
||||||
valid = false;
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* 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))
|
if (is_int && (value == 0 || value == 1)) {
|
||||||
ipv6 = (value != 0);
|
ipv6 = (value != 0);
|
||||||
else
|
return 0;
|
||||||
valid = false;
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ZMQ_TCP_KEEPALIVE:
|
case ZMQ_TCP_KEEPALIVE:
|
||||||
if (is_int && (value >= -1 || value <= 1))
|
if (is_int && (value >= -1 || value <= 1)) {
|
||||||
tcp_keepalive = value;
|
tcp_keepalive = value;
|
||||||
else
|
return 0;
|
||||||
valid = false;
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ZMQ_TCP_KEEPALIVE_CNT:
|
case ZMQ_TCP_KEEPALIVE_CNT:
|
||||||
if (is_int && (value == -1 || value >= 0))
|
if (is_int && (value == -1 || value >= 0)) {
|
||||||
tcp_keepalive_cnt = value;
|
tcp_keepalive_cnt = value;
|
||||||
else
|
return 0;
|
||||||
valid = false;
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ZMQ_TCP_KEEPALIVE_IDLE:
|
case ZMQ_TCP_KEEPALIVE_IDLE:
|
||||||
if (is_int && (value == -1 || value >= 0))
|
if (is_int && (value == -1 || value >= 0)) {
|
||||||
tcp_keepalive_idle = value;
|
tcp_keepalive_idle = value;
|
||||||
else
|
return 0;
|
||||||
valid = false;
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ZMQ_TCP_KEEPALIVE_INTVL:
|
case ZMQ_TCP_KEEPALIVE_INTVL:
|
||||||
if (is_int && (value == -1 || value >= 0))
|
if (is_int && (value == -1 || value >= 0)) {
|
||||||
tcp_keepalive_intvl = value;
|
tcp_keepalive_intvl = value;
|
||||||
else
|
return 0;
|
||||||
valid = false;
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ZMQ_IMMEDIATE:
|
case ZMQ_IMMEDIATE:
|
||||||
if (is_int && (value == 0 || value == 1))
|
if (is_int && (value == 0 || value == 1)) {
|
||||||
immediate = value;
|
immediate = value;
|
||||||
else
|
return 0;
|
||||||
valid = false;
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
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_ > 0 && optvallen_ < 256 && optval_ != NULL && *((const char*) optval_) != 0) {
|
||||||
valid = false;
|
|
||||||
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 (), ipv6);
|
int rc = mask.resolve (filter_str.c_str (), ipv6);
|
||||||
if (rc == 0)
|
if (rc == 0) {
|
||||||
tcp_accept_filters.push_back (mask);
|
tcp_accept_filters.push_back (mask);
|
||||||
else
|
return 0;
|
||||||
valid = false;
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ZMQ_PLAIN_SERVER:
|
||||||
|
if (is_int && (value == 0 || value == 1)) {
|
||||||
|
plain_server = value;
|
||||||
|
mechanism = value? ZMQ_PLAIN: ZMQ_NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ZMQ_PLAIN_USERNAME:
|
||||||
|
if (optvallen_ == 0 && optval_ == NULL) {
|
||||||
|
mechanism = ZMQ_NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (optvallen_ >= 0 && optvallen_ < 256 && optval_ != NULL) {
|
||||||
|
plain_username.assign ((const char *) optval_, optvallen_);
|
||||||
|
plain_server = false;
|
||||||
|
mechanism = ZMQ_PLAIN;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ZMQ_PLAIN_PASSWORD:
|
||||||
|
if (optvallen_ == 0 && optval_ == NULL) {
|
||||||
|
mechanism = ZMQ_NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (optvallen_ >= 0 && optvallen_ < 256 && optval_ != NULL) {
|
||||||
|
plain_password.assign ((const char *) optval_, optvallen_);
|
||||||
|
plain_server = false;
|
||||||
|
mechanism = ZMQ_PLAIN;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
valid = false;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (valid)
|
errno = EINVAL;
|
||||||
return 0;
|
return -1;
|
||||||
else {
|
|
||||||
errno = EINVAL;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int zmq::options_t::getsockopt (int option_, void *optval_, size_t *optvallen_)
|
int zmq::options_t::getsockopt (int option_, void *optval_, size_t *optvallen_)
|
||||||
{
|
{
|
||||||
|
bool is_int = (*optvallen_ == sizeof (int));
|
||||||
|
int *value = (int *) optval_;
|
||||||
|
|
||||||
switch (option_) {
|
switch (option_) {
|
||||||
|
case ZMQ_SNDHWM:
|
||||||
|
if (is_int) {
|
||||||
|
*value = sndhwm;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case ZMQ_SNDHWM:
|
case ZMQ_RCVHWM:
|
||||||
if (*optvallen_ < sizeof (int)) {
|
if (is_int) {
|
||||||
errno = EINVAL;
|
*value = rcvhwm;
|
||||||
return -1;
|
return 0;
|
||||||
}
|
}
|
||||||
*((int*) optval_) = sndhwm;
|
break;
|
||||||
*optvallen_ = sizeof (int);
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
case ZMQ_RCVHWM:
|
case ZMQ_AFFINITY:
|
||||||
if (*optvallen_ < sizeof (int)) {
|
if (*optvallen_ == sizeof (uint64_t)) {
|
||||||
errno = EINVAL;
|
*((uint64_t *) optval_) = affinity;
|
||||||
return -1;
|
return 0;
|
||||||
}
|
}
|
||||||
*((int*) optval_) = rcvhwm;
|
break;
|
||||||
*optvallen_ = sizeof (int);
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
case ZMQ_AFFINITY:
|
case ZMQ_IDENTITY:
|
||||||
if (*optvallen_ < sizeof (uint64_t)) {
|
if (*optvallen_ >= identity_size) {
|
||||||
errno = EINVAL;
|
memcpy (optval_, identity, identity_size);
|
||||||
return -1;
|
*optvallen_ = identity_size;
|
||||||
}
|
return 0;
|
||||||
*((uint64_t*) optval_) = affinity;
|
}
|
||||||
*optvallen_ = sizeof (uint64_t);
|
break;
|
||||||
return 0;
|
|
||||||
|
|
||||||
case ZMQ_IDENTITY:
|
case ZMQ_RATE:
|
||||||
if (*optvallen_ < identity_size) {
|
if (is_int) {
|
||||||
errno = EINVAL;
|
*value = rate;
|
||||||
return -1;
|
return 0;
|
||||||
}
|
}
|
||||||
memcpy (optval_, identity, identity_size);
|
break;
|
||||||
*optvallen_ = identity_size;
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
case ZMQ_RATE:
|
case ZMQ_RECOVERY_IVL:
|
||||||
if (*optvallen_ < sizeof (int)) {
|
if (is_int) {
|
||||||
errno = EINVAL;
|
*value = recovery_ivl;
|
||||||
return -1;
|
return 0;
|
||||||
}
|
}
|
||||||
*((int*) optval_) = rate;
|
break;
|
||||||
*optvallen_ = sizeof (int);
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
case ZMQ_RECOVERY_IVL:
|
case ZMQ_SNDBUF:
|
||||||
if (*optvallen_ < sizeof (int)) {
|
if (is_int) {
|
||||||
errno = EINVAL;
|
*value = sndbuf;
|
||||||
return -1;
|
return 0;
|
||||||
}
|
}
|
||||||
*((int*) optval_) = recovery_ivl;
|
break;
|
||||||
*optvallen_ = sizeof (int);
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
case ZMQ_SNDBUF:
|
case ZMQ_RCVBUF:
|
||||||
if (*optvallen_ < sizeof (int)) {
|
if (is_int) {
|
||||||
errno = EINVAL;
|
*value = rcvbuf;
|
||||||
return -1;
|
return 0;
|
||||||
}
|
}
|
||||||
*((int*) optval_) = sndbuf;
|
break;
|
||||||
*optvallen_ = sizeof (int);
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
case ZMQ_RCVBUF:
|
case ZMQ_TYPE:
|
||||||
if (*optvallen_ < sizeof (int)) {
|
if (is_int) {
|
||||||
errno = EINVAL;
|
*value = type;
|
||||||
return -1;
|
return 0;
|
||||||
}
|
}
|
||||||
*((int*) optval_) = rcvbuf;
|
break;
|
||||||
*optvallen_ = sizeof (int);
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
case ZMQ_TYPE:
|
case ZMQ_LINGER:
|
||||||
if (*optvallen_ < sizeof (int)) {
|
if (is_int) {
|
||||||
errno = EINVAL;
|
*value = linger;
|
||||||
return -1;
|
return 0;
|
||||||
}
|
}
|
||||||
*((int*) optval_) = type;
|
break;
|
||||||
*optvallen_ = sizeof (int);
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
case ZMQ_LINGER:
|
case ZMQ_RECONNECT_IVL:
|
||||||
if (*optvallen_ < sizeof (int)) {
|
if (is_int) {
|
||||||
errno = EINVAL;
|
*value = reconnect_ivl;
|
||||||
return -1;
|
return 0;
|
||||||
}
|
}
|
||||||
*((int*) optval_) = linger;
|
break;
|
||||||
*optvallen_ = sizeof (int);
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
case ZMQ_RECONNECT_IVL:
|
case ZMQ_RECONNECT_IVL_MAX:
|
||||||
if (*optvallen_ < sizeof (int)) {
|
if (is_int) {
|
||||||
errno = EINVAL;
|
*value = reconnect_ivl_max;
|
||||||
return -1;
|
return 0;
|
||||||
}
|
}
|
||||||
*((int*) optval_) = reconnect_ivl;
|
break;
|
||||||
*optvallen_ = sizeof (int);
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
case ZMQ_RECONNECT_IVL_MAX:
|
case ZMQ_BACKLOG:
|
||||||
if (*optvallen_ < sizeof (int)) {
|
if (is_int) {
|
||||||
errno = EINVAL;
|
*value = backlog;
|
||||||
return -1;
|
return 0;
|
||||||
}
|
}
|
||||||
*((int*) optval_) = reconnect_ivl_max;
|
break;
|
||||||
*optvallen_ = sizeof (int);
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
case ZMQ_BACKLOG:
|
case ZMQ_MAXMSGSIZE:
|
||||||
if (*optvallen_ < sizeof (int)) {
|
if (*optvallen_ == sizeof (int64_t)) {
|
||||||
errno = EINVAL;
|
*((int64_t *) optval_) = maxmsgsize;
|
||||||
return -1;
|
*optvallen_ = sizeof (int64_t);
|
||||||
}
|
return 0;
|
||||||
*((int*) optval_) = backlog;
|
}
|
||||||
*optvallen_ = sizeof (int);
|
break;
|
||||||
return 0;
|
|
||||||
|
|
||||||
case ZMQ_MAXMSGSIZE:
|
case ZMQ_MULTICAST_HOPS:
|
||||||
if (*optvallen_ < sizeof (int64_t)) {
|
if (is_int) {
|
||||||
errno = EINVAL;
|
*value = multicast_hops;
|
||||||
return -1;
|
return 0;
|
||||||
}
|
}
|
||||||
*((int64_t*) optval_) = maxmsgsize;
|
break;
|
||||||
*optvallen_ = sizeof (int64_t);
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
case ZMQ_MULTICAST_HOPS:
|
case ZMQ_RCVTIMEO:
|
||||||
if (*optvallen_ < sizeof (int)) {
|
if (is_int) {
|
||||||
errno = EINVAL;
|
*value = rcvtimeo;
|
||||||
return -1;
|
return 0;
|
||||||
}
|
}
|
||||||
*((int*) optval_) = multicast_hops;
|
break;
|
||||||
*optvallen_ = sizeof (int);
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
case ZMQ_RCVTIMEO:
|
case ZMQ_SNDTIMEO:
|
||||||
if (*optvallen_ < sizeof (int)) {
|
if (is_int) {
|
||||||
errno = EINVAL;
|
*value = sndtimeo;
|
||||||
return -1;
|
return 0;
|
||||||
}
|
}
|
||||||
*((int*) optval_) = rcvtimeo;
|
break;
|
||||||
*optvallen_ = sizeof (int);
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
case ZMQ_SNDTIMEO:
|
case ZMQ_IPV4ONLY:
|
||||||
if (*optvallen_ < sizeof (int)) {
|
if (is_int) {
|
||||||
errno = EINVAL;
|
*value = 1 - ipv6;
|
||||||
return -1;
|
return 0;
|
||||||
}
|
}
|
||||||
*((int*) optval_) = sndtimeo;
|
break;
|
||||||
*optvallen_ = sizeof (int);
|
|
||||||
return 0;
|
case ZMQ_IPV6:
|
||||||
|
if (is_int) {
|
||||||
|
*value = ipv6;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case ZMQ_IPV4ONLY:
|
case ZMQ_IMMEDIATE:
|
||||||
if (*optvallen_ < sizeof (int)) {
|
if (is_int) {
|
||||||
errno = EINVAL;
|
*value = immediate;
|
||||||
return -1;
|
return 0;
|
||||||
}
|
}
|
||||||
*((int*) optval_) = 1 - ipv6;
|
break;
|
||||||
*optvallen_ = sizeof (int);
|
|
||||||
return 0;
|
case ZMQ_TCP_KEEPALIVE:
|
||||||
|
if (is_int) {
|
||||||
|
*value = tcp_keepalive;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ZMQ_TCP_KEEPALIVE_CNT:
|
||||||
|
if (is_int) {
|
||||||
|
*value = tcp_keepalive_cnt;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ZMQ_TCP_KEEPALIVE_IDLE:
|
||||||
|
if (is_int) {
|
||||||
|
*value = tcp_keepalive_idle;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ZMQ_TCP_KEEPALIVE_INTVL:
|
||||||
|
if (is_int) {
|
||||||
|
*value = tcp_keepalive_intvl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ZMQ_LAST_ENDPOINT:
|
||||||
|
if (*optvallen_ >= last_endpoint.size () + 1) {
|
||||||
|
memcpy (optval_, last_endpoint.c_str (), last_endpoint.size () + 1);
|
||||||
|
*optvallen_ = last_endpoint.size () + 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case ZMQ_IPV6:
|
case ZMQ_MECHANISM:
|
||||||
if (*optvallen_ < sizeof (int)) {
|
if (is_int) {
|
||||||
errno = EINVAL;
|
*value = mechanism;
|
||||||
return -1;
|
return 0;
|
||||||
}
|
}
|
||||||
*((int*) optval_) = ipv6;
|
break;
|
||||||
*optvallen_ = sizeof (int);
|
|
||||||
return 0;
|
case ZMQ_PLAIN_SERVER:
|
||||||
|
if (is_int) {
|
||||||
case ZMQ_IMMEDIATE:
|
*value = plain_server;
|
||||||
if (*optvallen_ < sizeof (int)) {
|
return 0;
|
||||||
errno = EINVAL;
|
}
|
||||||
return -1;
|
break;
|
||||||
}
|
|
||||||
*((int*) optval_) = immediate;
|
case ZMQ_PLAIN_USERNAME:
|
||||||
*optvallen_ = sizeof (int);
|
if (*optvallen_ >= plain_username.size () + 1) {
|
||||||
return 0;
|
memcpy (optval_, plain_username.c_str (), plain_username.size () + 1);
|
||||||
|
*optvallen_ = plain_username.size () + 1;
|
||||||
case ZMQ_TCP_KEEPALIVE:
|
return 0;
|
||||||
if (*optvallen_ < sizeof (int)) {
|
}
|
||||||
errno = EINVAL;
|
break;
|
||||||
return -1;
|
|
||||||
}
|
case ZMQ_PLAIN_PASSWORD:
|
||||||
*((int*) optval_) = tcp_keepalive;
|
if (*optvallen_ >= plain_password.size () + 1) {
|
||||||
*optvallen_ = sizeof (int);
|
memcpy (optval_, plain_password.c_str (), plain_password.size () + 1);
|
||||||
return 0;
|
*optvallen_ = plain_password.size () + 1;
|
||||||
|
return 0;
|
||||||
case ZMQ_TCP_KEEPALIVE_CNT:
|
}
|
||||||
if (*optvallen_ < sizeof (int)) {
|
break;
|
||||||
errno = EINVAL;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
*((int*) optval_) = tcp_keepalive_cnt;
|
|
||||||
*optvallen_ = sizeof (int);
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
case ZMQ_TCP_KEEPALIVE_IDLE:
|
|
||||||
if (*optvallen_ < sizeof (int)) {
|
|
||||||
errno = EINVAL;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
*((int*) optval_) = tcp_keepalive_idle;
|
|
||||||
*optvallen_ = sizeof (int);
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
case ZMQ_TCP_KEEPALIVE_INTVL:
|
|
||||||
if (*optvallen_ < sizeof (int)) {
|
|
||||||
errno = EINVAL;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
*((int*) optval_) = tcp_keepalive_intvl;
|
|
||||||
*optvallen_ = sizeof (int);
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
case ZMQ_LAST_ENDPOINT:
|
|
||||||
/* don't allow string which cannot contain the entire message */
|
|
||||||
if (*optvallen_ < last_endpoint.size() + 1) {
|
|
||||||
errno = EINVAL;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
memcpy (optval_, last_endpoint.c_str(), last_endpoint.size()+1);
|
|
||||||
*optvallen_ = last_endpoint.size()+1;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -123,10 +123,17 @@ namespace zmq
|
|||||||
typedef std::vector <tcp_address_mask_t> tcp_accept_filters_t;
|
typedef std::vector <tcp_address_mask_t> tcp_accept_filters_t;
|
||||||
tcp_accept_filters_t tcp_accept_filters;
|
tcp_accept_filters_t tcp_accept_filters;
|
||||||
|
|
||||||
|
// Security mechanism for all connections on this socket
|
||||||
|
int mechanism;
|
||||||
|
|
||||||
|
// Security credentials for PLAIN mechanism
|
||||||
|
std::string plain_username;
|
||||||
|
std::string plain_password;
|
||||||
|
int plain_server;
|
||||||
|
|
||||||
// ID of the socket.
|
// ID of the socket.
|
||||||
int socket_id;
|
int socket_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -376,7 +376,9 @@ int zmq_send (void *s_, const void *buf_, size_t len_, int flags_)
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Send multiple messages.
|
// Send multiple messages.
|
||||||
|
// TODO: this function has no man page
|
||||||
//
|
//
|
||||||
// If flag bit ZMQ_SNDMORE is set the vector is treated as
|
// If flag bit ZMQ_SNDMORE is set the vector is treated as
|
||||||
// a single multi-part message, i.e. the last message has
|
// a single multi-part message, i.e. the last message has
|
||||||
@ -477,7 +479,7 @@ int zmq_recv (void *s_, void *buf_, size_t len_, int flags_)
|
|||||||
//
|
//
|
||||||
// The iov_base* buffers of each iovec *a_ filled in by this
|
// The iov_base* buffers of each iovec *a_ filled in by this
|
||||||
// function may be freed using free().
|
// function may be freed using free().
|
||||||
//
|
// TODO: this function has no man page
|
||||||
//
|
//
|
||||||
int zmq_recviov (void *s_, iovec *a_, size_t *count_, int flags_)
|
int zmq_recviov (void *s_, iovec *a_, size_t *count_, int flags_)
|
||||||
{
|
{
|
||||||
|
@ -21,6 +21,7 @@ noinst_PROGRAMS = test_pair_inproc \
|
|||||||
test_raw_sock \
|
test_raw_sock \
|
||||||
test_disconnect_inproc \
|
test_disconnect_inproc \
|
||||||
test_ctx_options \
|
test_ctx_options \
|
||||||
|
test_security \
|
||||||
test_iov
|
test_iov
|
||||||
|
|
||||||
if !ON_MINGW
|
if !ON_MINGW
|
||||||
@ -49,6 +50,7 @@ test_raw_sock_SOURCES = test_raw_sock.cpp
|
|||||||
test_disconnect_inproc_SOURCES = test_disconnect_inproc.cpp
|
test_disconnect_inproc_SOURCES = test_disconnect_inproc.cpp
|
||||||
test_ctx_options_SOURCES = test_ctx_options.cpp
|
test_ctx_options_SOURCES = test_ctx_options.cpp
|
||||||
test_iov_SOURCES = test_iov.cpp
|
test_iov_SOURCES = test_iov.cpp
|
||||||
|
test_security_SOURCES = test_security.cpp
|
||||||
if !ON_MINGW
|
if !ON_MINGW
|
||||||
test_shutdown_stress_SOURCES = test_shutdown_stress.cpp
|
test_shutdown_stress_SOURCES = test_shutdown_stress.cpp
|
||||||
test_pair_ipc_SOURCES = test_pair_ipc.cpp testutil.hpp
|
test_pair_ipc_SOURCES = test_pair_ipc.cpp testutil.hpp
|
||||||
|
117
tests/test_security.cpp
Normal file
117
tests/test_security.cpp
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2007-2013 Contributors as noted in the AUTHORS file
|
||||||
|
|
||||||
|
This file is part of 0MQ.
|
||||||
|
|
||||||
|
0MQ is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU Lesser General Public License as published by
|
||||||
|
the Free Software Foundation; either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
0MQ is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "../include/zmq.h"
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#undef NDEBUG
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
int main (void)
|
||||||
|
{
|
||||||
|
void *ctx = zmq_ctx_new ();
|
||||||
|
assert (ctx);
|
||||||
|
|
||||||
|
// Server socket will accept connections
|
||||||
|
void *server = zmq_socket (ctx, ZMQ_DEALER);
|
||||||
|
assert (server);
|
||||||
|
|
||||||
|
// Client socket that will try to connect to server
|
||||||
|
void *client = zmq_socket (ctx, ZMQ_DEALER);
|
||||||
|
assert (client);
|
||||||
|
|
||||||
|
// Check NULL security configuration
|
||||||
|
int rc;
|
||||||
|
size_t optsize;
|
||||||
|
int mechanism;
|
||||||
|
|
||||||
|
optsize = sizeof (int);
|
||||||
|
rc = zmq_getsockopt (client, ZMQ_MECHANISM, &mechanism, &optsize);
|
||||||
|
assert (rc == 0);
|
||||||
|
assert (mechanism == ZMQ_NULL);
|
||||||
|
|
||||||
|
optsize = sizeof (int);
|
||||||
|
rc = zmq_getsockopt (server, ZMQ_MECHANISM, &mechanism, &optsize);
|
||||||
|
assert (rc == 0);
|
||||||
|
assert (mechanism == ZMQ_NULL);
|
||||||
|
|
||||||
|
// Check PLAIN security
|
||||||
|
char username [256];
|
||||||
|
optsize = 256;
|
||||||
|
rc = zmq_getsockopt (client, ZMQ_PLAIN_USERNAME, username, &optsize);
|
||||||
|
assert (rc == 0);
|
||||||
|
assert (optsize == 1); // Null string is one byte long
|
||||||
|
|
||||||
|
char password [256];
|
||||||
|
optsize = 256;
|
||||||
|
rc = zmq_getsockopt (client, ZMQ_PLAIN_PASSWORD, password, &optsize);
|
||||||
|
assert (rc == 0);
|
||||||
|
assert (optsize == 1); // Null string is one byte long
|
||||||
|
|
||||||
|
strcpy (username, "admin");
|
||||||
|
strcpy (password, "password");
|
||||||
|
rc = zmq_setsockopt (client, ZMQ_PLAIN_USERNAME, username, strlen (username));
|
||||||
|
assert (rc == 0);
|
||||||
|
rc = zmq_setsockopt (client, ZMQ_PLAIN_PASSWORD, password, strlen (password));
|
||||||
|
assert (rc == 0);
|
||||||
|
|
||||||
|
optsize = 256;
|
||||||
|
rc = zmq_getsockopt (client, ZMQ_PLAIN_USERNAME, username, &optsize);
|
||||||
|
assert (rc == 0);
|
||||||
|
assert (optsize == 5 + 1);
|
||||||
|
optsize = 256;
|
||||||
|
rc = zmq_getsockopt (client, ZMQ_PLAIN_PASSWORD, password, &optsize);
|
||||||
|
assert (rc == 0);
|
||||||
|
assert (optsize == 8 + 1);
|
||||||
|
|
||||||
|
optsize = sizeof (int);
|
||||||
|
rc = zmq_getsockopt (client, ZMQ_MECHANISM, &mechanism, &optsize);
|
||||||
|
assert (rc == 0);
|
||||||
|
assert (mechanism == ZMQ_PLAIN);
|
||||||
|
|
||||||
|
int as_server = 1;
|
||||||
|
rc = zmq_setsockopt (server, ZMQ_PLAIN_SERVER, &as_server, sizeof (int));
|
||||||
|
assert (rc == 0);
|
||||||
|
|
||||||
|
optsize = sizeof (int);
|
||||||
|
rc = zmq_getsockopt (server, ZMQ_MECHANISM, &mechanism, &optsize);
|
||||||
|
assert (rc == 0);
|
||||||
|
assert (mechanism == ZMQ_PLAIN);
|
||||||
|
|
||||||
|
// Check we can switch back to NULL security
|
||||||
|
rc = zmq_setsockopt (client, ZMQ_PLAIN_USERNAME, NULL, 0);
|
||||||
|
assert (rc == 0);
|
||||||
|
rc = zmq_setsockopt (client, ZMQ_PLAIN_PASSWORD, NULL, 0);
|
||||||
|
assert (rc == 0);
|
||||||
|
optsize = sizeof (int);
|
||||||
|
rc = zmq_getsockopt (client, ZMQ_MECHANISM, &mechanism, &optsize);
|
||||||
|
assert (rc == 0);
|
||||||
|
assert (mechanism == ZMQ_NULL);
|
||||||
|
|
||||||
|
rc = zmq_close (client);
|
||||||
|
assert (rc == 0);
|
||||||
|
|
||||||
|
rc = zmq_close (server);
|
||||||
|
assert (rc == 0);
|
||||||
|
|
||||||
|
rc = zmq_ctx_term (ctx);
|
||||||
|
assert (rc == 0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user