Compare commits

...

66 Commits

Author SHA1 Message Date
Pieter Hintjens
f8cebb460a Revert "replace macro constants with enum types for user facing constants"
This reverts commit 4fb74539250d83e82e40e85d39e2e756eccdb8a3.
2013-10-08 15:02:58 +02:00
Pieter Hintjens
d62e7a0734 Revert "distinguish between options and defaults"
This reverts commit e7db680f5b709ce821f79b1e8956f4cbd1931c11.
2013-10-08 15:02:47 +02:00
Pieter Hintjens
a44bd65d03 Fixed NEWS for 4.0.1 release 2013-10-08 10:46:47 +02:00
Pieter Hintjens
437e4070a3 Merge pull request #19 from hintjens/master
Updated NEWS for 4.0.1
2013-10-08 01:36:58 -07:00
Pieter Hintjens
0bfcd4da2f Updated NEWS for 4.0.1 2013-10-08 10:33:50 +02:00
Pieter Hintjens
c852620f5f Merge pull request #18 from hintjens/master
Cherry picking changes from libzmq master
2013-10-08 00:20:40 -07:00
Volodymyr Korniichuk
ca122e9d01 Typo in type name "emTPy_slots_t"
https://zeromq.jira.com/browse/LIBZMQ-565
2013-10-08 09:20:15 +02:00
Dylan Cali
e7db680f5b distinguish between options and defaults 2013-10-08 09:19:55 +02:00
Dylan Cali
4fb7453925 replace macro constants with enum types for user facing constants 2013-10-08 09:19:49 +02:00
Brandon Carpenter
813166019e Add tests/test_abstract_ipc to .gitignore. 2013-10-07 20:53:20 +02:00
Brandon Carpenter
127cd7585a Fix detection of abstract ipc pathname and length calculation.
Abstract socket pathnames must have a NULL character in the first
position, but the second character must also be checked to differentiate
an abstract name from the empty string.  The address length must also
indicate the length of the pathname because the kernel uses the entire
address as the name, including NULL characters.  ZMQ uses
NULL-terminated strings for the address, so the abstract address length
is the length of the string following the initial NULL byte plus 3; two
bytes for the address family and one for the initial NULL character.
2013-10-07 20:53:10 +02:00
Brandon Carpenter
0666152b21 Add note on Linux abstract namespace to ipc documentation. 2013-10-07 20:53:00 +02:00
Volodymyr Korniichuk
9293153f71 useless checks were removed 2013-10-05 09:22:56 +02:00
Pieter Hintjens
163aebbacf Merge pull request #17 from hintjens/master
Cherry picking changes from libzmq master
2013-10-05 00:20:49 -07:00
Brandon Carpenter
80d657a2c5 Add test for abstract namespace support in ipc sockets on Linux.
See issue 567.
2013-10-05 09:20:20 +02:00
Brandon Carpenter
668f000cb1 Add abstract namespace support for IPC sockets on Linux.
Converts an initial strudel or "at sign" (@) in the Unix socket path to
a NULL character ('\0') indicating that the socket uses the abstract
namespace instead of the filesystem namespace.  For instance, binding a
socket to 'ipc://@/tmp/tester' will not create a file associated with
the socket whereas binding to 'ipc:///tmp/tester' will create the file
/tmp/tester.  See issue 567 for more information.
2013-10-05 09:20:13 +02:00
KIU Shueng Chuan
a570b18931 WinSock2.h filename should be all lowercase 2013-10-05 09:20:06 +02:00
KIU Shueng Chuan
5493d4d180 test for _MSC_VER before using MSVC specific code 2013-10-05 09:19:58 +02:00
Pieter Hintjens
b20573c841 Merge pull request #16 from hintjens/master
Cherry picking changes from libzmq master
2013-10-04 00:19:57 -07:00
Martin Hurton
814b93e0cf Stop curve handshake when cookie box verification fails 2013-10-04 09:19:11 +02:00
Pieter Hintjens
d723b08c13 Updated libzmq CURVE to track RFC 27
* The INITIATE command vouch box is Box[C',S](C->S') instead of Box[C'](C->S),
  as recommended by https://codesinchaos.wordpress.com/2012/09/09/curvecp-1/,
  to reduce the risk of client impersonation.

* Mirrors the change in libcurve and CurveZMQ specifications.
2013-10-04 09:19:04 +02:00
Matt Connolly
62fd6fa861 git ignore test run output files: tests/test*.{log|trs} 2013-10-04 09:17:34 +02:00
Pieter Hintjens
a78ccf293f Disabled randomly failing part of test 2013-10-04 09:13:35 +02:00
Pieter Hintjens
d82ba6bd53 Clarified that zmq.h constants are part of the public contract 2013-10-04 09:13:17 +02:00
Dylan Cali
9da52ddf59 fix minor typo in zmq_ctx_get doc example 2013-10-04 09:13:11 +02:00
Pieter Hintjens
a69fa9ecde Packaging for zmq_curve_keypair function
* Added new man page for this
* Added test case, in tests/test_security_curve.cpp
* Noted in zmq_utils.h that these methods are documented
2013-10-04 09:13:05 +02:00
MinRK
facb96ffca use zmq_curve_keypair in curve_keygen 2013-10-04 09:12:56 +02:00
MinRK
3c469d04c1 return NULL and set EINVAL on bad z85 input
asserts aren't appropriate for checking user input.
2013-10-04 09:12:33 +02:00
MinRK
870233522c add zmq_curve_keypair to zmq_utils 2013-10-04 09:12:09 +02:00
Pieter Hintjens
34471cd591 Merge pull request #12 from hintjens/master
Backporting fixes from master
2013-09-29 08:04:10 -07:00
Pieter Hintjens
453ceb65b4 Fixed merge conflict error 2013-09-29 17:03:44 +02:00
Matt Connolly
4d82544c34 config for libsodium in alternate path, using CPP flags for both C and C++ sources. 2013-09-29 17:01:15 +02:00
MinRK
bd6bca7c82 include missing platform.hpp in curve_keygen
it was excluded, so HAVE_SODIUM would never be defined,
leading to curve_keygen always reporting "recompile with libsodium"
2013-09-29 17:01:00 +02:00
MinRK
087ddac593 declare z85_encode / decode in zmq_utils
they are used by curve_keygen, but not available
2013-09-29 17:00:22 +02:00
Matt Connolly
d1b686b644 Disable compiler warning for Solaris 2013-09-27 13:39:10 +02:00
Matt Connolly
4dc36c0dba Add '-lssp' linker flag for Solaris. Check for libraries after host specific setup. 2013-09-27 13:38:55 +02:00
Pieter Hintjens
17d12a6be1 Merge pull request #9 from hintjens/master
Cherry picking changes from libzmq master
2013-09-26 05:48:49 -07:00
Pieter Hintjens
89b97cbe59 Updated CMake project for test_issue_566 2013-09-26 14:46:49 +02:00
Pieter Hintjens
b0059211d5 Added test case for issue 566
* Tests dealer-to-router connection 100 times
* This was failing in ZMQ v4.0.0 RC1
2013-09-26 14:46:35 +02:00
Pieter Hintjens
cd452d5019 Merge pull request #8 from hintjens/master
Backporting fixes from master
2013-09-26 03:32:10 -07:00
Pieter Hintjens
dd185e13bf Bumped version for 4.0.1 2013-09-26 12:31:43 +02:00
Pieter Hintjens
517601de10 curve_keygen needed assert.h 2013-09-26 12:17:36 +02:00
Pieter Hintjens
5e25b32c36 Build/test errors on OS/X with clang++ 2013-09-26 12:17:28 +02:00
Martin Hurton
a5152245bd Call flush after writing the identity message 2013-09-26 10:07:29 +02:00
Pieter Hintjens
9cbcc49a4a Merge pull request #6 from ipechorin/master
stdint.h is not available on all platforms
2013-09-24 03:32:02 -07:00
Pieter Hintjens
2d5bad96e3 Merge pull request #7 from hintjens/master
Fixed build for MSVC 2008
2013-09-24 03:31:08 -07:00
Pieter Hintjens
c99b727f6d Fixed build for MSVC 2008 2013-09-24 12:29:29 +02:00
Ivan Pechorin
8a931a7554 stdint.h is not available on all platforms 2013-09-24 14:00:08 +04:00
Pieter Hintjens
b04df2c530 Merge pull request #4 from hintjens/master
Updated library ABI version
2013-09-24 00:12:03 -07:00
Pieter Hintjens
4df7cb043e Bumped library version and age 2013-09-24 09:11:17 +02:00
Pieter Hintjens
201454e866 Move away from port 8080 which is occupied on some boxes 2013-09-20 23:17:01 +02:00
Richard Newton
ad1bae2160 Merge pull request #3 from vortechs2000/fix_aix
Revert "Reference platform.h by ../src/platform.h - AIX is ignoring -I flags"
2013-09-20 12:48:29 -07:00
AJ Lewis
77f394a681 Revert "Reference platform.h by ../src/platform.h - AIX is ignoring -I flags"
This reverts commit 1e8e4d79c885b27831e2196d94987cc2817e0f04.
2013-09-20 14:39:01 -05:00
Pieter Hintjens
61d8bf9b11 Merge pull request #2 from vortechs2000/fix_aix
Reference platform.h by ../src/platform.h - AIX is ignoring -I flags
2013-09-20 09:54:03 -07:00
AJ Lewis
1e8e4d79c8 Reference platform.h by ../src/platform.h - AIX is ignoring -I flags 2013-09-20 11:43:53 -05:00
Pieter Hintjens
c0c8ce5508 File was missing from Makefile.am 2013-09-20 16:41:08 +02:00
Pieter Hintjens
66b1bc6d7f Added link to security tutorial 2013-09-20 16:15:53 +02:00
Pieter Hintjens
f5ecc826d9 Merge pull request #1 from hintjens/master
Preparation for 4.0.0 release
2013-09-20 07:06:48 -07:00
Pieter Hintjens
a31fe9565a Source distribution was broken 2013-09-20 16:03:14 +02:00
Pieter Hintjens
2f4905500d Version number is 4.0.0 2013-09-20 16:02:55 +02:00
Pieter Hintjens
c10a3ec526 Updated NEWS for 4.0.0 2013-09-20 15:53:27 +02:00
Pieter Hintjens
e0676a2b26 Renamed new socket options to be clearer
* ZMQ_REQ_STRICT was negative option (default 1) which goes against
  the standard, where defaults are zero. I renamed this to
  ZMQ_REQ_RELAXED.

* ZMQ_REQ_REQUEST_IDS felt clumsy and describes the technical solution
  rather than the problem/requirement. I changed to ZMQ_REQ_CORRELATE
  which seems more explicit.
2013-09-20 15:50:25 +02:00
Pieter Hintjens
b411a3561d Removed inaccurate note in zmq_poll man page 2013-09-20 15:35:20 +02:00
Pieter Hintjens
4ce9b42405 Built zmq_send_const man page properly 2013-09-20 15:35:11 +02:00
Pieter Hintjens
fef4fa8fc5 Renamed test_connect_delay to test_immediate
* The ZMQ_CONNECT_DELAY option was renamed to ZMQ_IMMEDIATE
2013-09-20 15:34:55 +02:00
Pieter Hintjens
4298f71cbf Updated NEWS for 3.2.x releases 2013-09-20 13:28:25 +02:00
45 changed files with 712 additions and 154 deletions

10
.gitignore vendored
View File

@ -22,6 +22,7 @@ autom4te.cache
.*~
tools/curve_keygen.o
tools/curve_keygen
tests/test_issue_566
tests/test_ctx_destroy
tests/test_term_endpoint
tests/test_system
@ -43,7 +44,7 @@ tests/test_invalid_rep
tests/test_msg_flags
tests/test_ts_context
tests/test_connect_resolve
tests/test_connect_delay
tests/test_immediate
tests/test_term_endpoint
tests/test_router_mandatory
tests/test_disconnect_inproc
@ -60,14 +61,17 @@ tests/test_spec_pushpull
tests/test_spec_rep
tests/test_spec_req
tests/test_spec_router
tests/test_req_request_ids
tests/test_req_strict
tests/test_req_correlate
tests/test_req_relaxed
tests/test_fork
tests/test_conflate
tests/test_inproc_connect
tests/test_linger
tests/test_security_null
tests/test_security_plain
tests/test_abstract_ipc
tests/test*.log
tests/test*.trs
src/platform.hpp*
src/stamp-h1
perf/local_lat

View File

@ -20,6 +20,7 @@ Ben Gray <ben@benjamg.com>
Bernd Prager <bernd@prager.ws>
Bernd Melchers <melchers@ZEDAT.FU-Berlin.DE>
Bob Beaty <rbeaty@peak6.com>
Brandon Carpenter <hashstat@yahoo.com>
Brian Buchanan <bwb@holo.org>
Brett Cameron <Brett.Cameron@hp.com>
Burak Arslan <burak-github@arskom.com.tr>

View File

@ -579,7 +579,7 @@ endif()
enable_testing()
set(tests
test_system
test_connect_delay
test_immediate
test_connect_resolve
test_ctx_destroy
test_ctx_options
@ -592,8 +592,8 @@ set(tests
test_pair_inproc
test_pair_tcp
test_probe_router
test_req_request_ids
test_req_strict
test_req_correlate
test_req_relaxed
test_reqrep_device
test_reqrep_inproc
test_reqrep_tcp
@ -610,7 +610,8 @@ set(tests
test_sub_forward
test_term_endpoint
test_timeo
test_inproc_connect)
test_inproc_connect
test_issue_566)
if(NOT WIN32)
list(APPEND tests
test_monitor

188
NEWS
View File

@ -1,3 +1,189 @@
0MQ version 4.0.1 stable, released on 2013/10/08
================================================
Changes
-------
* Updated CURVE mechanism to track revised RFC 27 (INITIATE vouch).
The INITIATE command vouch box is Box[C',S](C->S') instead of
Box[C'](C->S), to reduce the risk of client impersonation, as per
https://codesinchaos.wordpress.com/2012/09/09/curvecp-1/.
* Fixed LIBZMQ-567, adding abstract namespaces for IPC sockets on Linux.
Converts an initial strudel or "at sign" (@) in the Unix socket path to
a NULL character ('\0') indicating that the socket uses the abstract
namespace instead of the filesystem namespace. For instance, binding a
socket to 'ipc://@/tmp/tester' will not create a file associated with
the socket whereas binding to 'ipc:///tmp/tester' will create the file
/tmp/tester. See issue 567 for more information.
* Added zmq_z85_encode and zmq_z85_decode to core libzmq API.
* Added zmq_curve_keypair to core libzmq API.
* Replaced macro constants in zmq.h with enum types for user-facing
constants (except ZMQ version numbers).
* Bumped library ABI version to 4:0:1.
Bug fixes
---------
* Fixed some build/test errors on OS/X + Clang++.
* Fixed LIBZMQ-565, typo in code.
* Fixed LIBZMQ-566, dealer-to-router connections sometimes failing.
* Fixed builds for AIX, MSVC 2008, OS/X with clang++, Solaris.
* Improved CURVE handshake error handling.
0MQ version 4.0.0 (RC1), released on 2013/09/20
===============================================
Major changes
-------------
* New wire level protocol, ZMTP/3.0, see http://rfc.zeromq.org/spec:23.
Does not yet implement the SUBSCRIBE, CANCEL, PING, and PONG commands.
* New security framework, from plain user+password to strong encryption,
see section below. See http://hintjens.com/blog:49 for a tutorial.
* New ZMQ_STREAM socket type for working as a TCP client or server. See:
tests/test_stream.cpp.
Improvements
------------
* You can now connect to an inproc:// endpoint that does not already
exist. This means inproc:// no longer needs careful set-up, but it may
break code that relied on the old behaviour. See:
tests/test_inproc_connect.cpp.
* Libzmq now checks socket types at connection time, so that trying to
connect a 'wrong' socket type will fail.
* New zmq_ctx_shutdown API method will shutdown a context and send ETERM
to blocking calls, without blocking. Use zmq_ctx_term to finalise the
process.
* The regression test suite has been significantly extended and improved.
* Contexts can now be terminated in forked child processes. See:
tests/test_fork.cpp.
* zmq_disconnect now respects the linger setting on sockets.
* New zmq_send_const API method to send constant data (without copying).
See: tests/test_inproc_connect.cpp.
* Added CMake support for static libraries.
* Added test cases for socket semantics as defined in RFCs 28, 29, 30, 31.
See: tests/test_spec_*.cpp.
* New socket option, ZMQ_PROBE_ROUTER triggers an empty message on connect.
See: tests/test_probe_router.cpp.
* New socket option, ZMQ_REQ_CORRELATE allows for correlation of replies
from a REP socket. See: tests/test_req_correlate.cpp.
* New socket option, ZMQ_REQ_RELAXED, lets you disable the state machine
on a REQ socket, so you can send multiple requests without waiting for
replies, and without getting an EFSM error. See:
tests/test_req_relaxed.cpp.
* New socket option, ZMQ_CONFLATE restricts the outgoing and incoming
socket buffers to a single message. See: tests/test_conflate.cpp.
Deprecated Options
------------------
* ZMQ_IPV4ONLY deprecated and renamed to ZMQ_IPV6 so that options are
consistently "off" by default.
* ZMQ_DELAY_ATTACH_ON_CONNECT deprecated, and renamed to ZMQ_IMMEDIATE.
See: tests/test_immediate.cpp.
Security Framework
------------------
Based on new ZMTP wire level protocol that negotiates a security
"mechanism" between client and server before exchanging any other data.
Security mechanisms are extensible. ZMTP defines three by default:
* NULL - classic ZeroMQ, with no authentication. See
http://rfc.zeromq.org/spec:23.
* PLAIN - plain-text username + password authentication. See
http://rfc.zeromq.org/spec:24.
* CURVE - secure authentication and encryption based on elliptic curve
cryptography, using the Curve25519 algorithm from Daniel Bernstein and
based on CurveCP's security handshake. See http://rfc.zeromq.org/spec:25,
http://rfc.zeromq.org/spec:26, and http://curvecp.org.
Authentication is done by pluggable "authenticators" that connect to libzmq
over an inproc endpoint, see http://rfc.zeromq.org/spec:27.
Socket options to configure PLAIN security on client or server:
* ZMQ_PLAIN_SERVER, ZMQ_PLAIN_USERNAME, ZMQ_PLAIN_PASSWORD. See
tests/test_security_plain.
Socket options to configure CURVE security on client or server:
* ZMQ_CURVE_SERVER, ZMQ_CURVE_PUBLICKEY, ZMQ_CURVE_SECRETKEY,
ZMQ_CURVE_SERVERKEY. See tests/test_security_curve.cpp.
Socket options to configure "domain" for ZAP handler:
* ZMQ_ZAP_DOMAIN, see tests/test_security_null.cpp.
Support for encoding/decoding CURVE binary keys to ASCII:
* zmq_z85_encode, zmq_z85_decode.
Other issues addressed in this release
--------------------------------------
* LIBZMQ-525 Multipart upstreaming from XSUB to XPUB
0MQ version 3.2.4 stable, released on 2013/09/20
================================================
* LIBZMQ-84 (Windows) Assertion failed: Address already in use at signaler.cpp:80
* LIBZMQ-456 ZMQ_XPUB_VERBOSE does not propagate in a tree of XPUB/XSUB devices
* LIBZMQ-532 (Windows) critical section not released on error
* LIBZMQ-569 Detect OpenPGM 5.2 system library
* LIBZMQ-563 Subscribers sometimes stopped receiving messages (aka LIBZMQ-541)
* LIBZMQ-XXX Added support for Travis Continuous Integration
* LIBZMQ-XXX Several improvements to MSVC support
0MQ version 3.2.3 stable, released on 2013/05/02
================================================
Issues addressed in this release
--------------------------------
* LIBZMQ-526 Assertion failure "Invalid argument (tcp_connecter.cpp:285)"
* LIBZMQ-446 Setting the DSCP bits by default causes CAP_NET_ADMIN error
* LIBZMQ-496 Crash on heavy socket opening/closing: Device or resource busy (mutex.hpp:90)
* LIBZMQ-462 test_connect_delay fails at test_connect_delay.cpp:80
* LIBZMQ-497 Messages getting dropped
* LIBZMQ-488 signaler.cpp leaks the win32 Event Handle
* LIBZMQ-476 zmq_disconnect has no effect for inproc sockets
* LIBZMQ-475 zmq_disconnect does not sent unsubscribe messages
0MQ version 3.2.2 stable, released on 2012/11/23
================================================
@ -13,7 +199,6 @@ Issues addressed in this release
* LIBZMQ-450 lt-test_monitor: fails with assertion at test_monitor.cpp:81
* LIBZMQ-451 ZMQ_ROUTER_MANDATORY blocks forever
* LIBZMQ-452 test_connect_delay.cpp:175:12: error: 'sleep' was not declared in this scope
* LIBZMQ-456 ZMQ_XPUB_VERBOSE does not propagate in a tree of XPUB/XSUB devices
* LIBZMQ-458 lt-test_router_mandatory fails with assertion at test_router_mandatory.cpp:53
* LIBZMQ-459 Assertion failed: encoder (stream_engine.cpp:266
* LIBZMQ-464 PUB socket with HWM set leaks memory
@ -21,6 +206,7 @@ Issues addressed in this release
* LIBZMQ-468 ZMQ_XPUB_VERBOSE & unsubscribe
* LIBZMQ-472 Segfault in zmq_poll in REQ to ROUTER dialog
0MQ version 3.2.1 (RC2), released on 2012/10/15
===============================================

View File

@ -29,9 +29,10 @@ AC_SUBST(PACKAGE_VERSION)
# ZeroMQ versions 2.1.x: 1:0:0 (ABI version 1)
# ZeroMQ version 3.0: 2:0:0 (ABI version 2)
# ZeroMQ version 3.1: 3:0:0 (ABI version 3)
# ZeroMQ version 4.0: 4:0:1 (ABI version 4)
#
# libzmq -version-info current:revision:age
LTVER="3:0:0"
LTVER="4:0:1"
AC_SUBST(LTVER)
# Take a copy of original flags
@ -62,10 +63,44 @@ LIBZMQ_CHECK_ENABLE_DEBUG
# Check wheter to enable code coverage
LIBZMQ_WITH_GCOV
# Checks for libraries
AC_CHECK_LIB([pthread], [pthread_create])
AC_CHECK_LIB([rt], [clock_gettime])
AC_CHECK_LIB([sodium], [sodium_init],,AC_MSG_WARN(libsodium is needed for CURVE security))
# Allow libsodium to be installed in a custom path:
AC_ARG_WITH([libsodium],
[AS_HELP_STRING([--with-libsodium],
[Specify libsodium prefix])],
[zmq_search_libsodium="yes"],
[])
if test "x$zmq_search_libsodium" = "xyes"; then
if test -r "${with_libsodium}/include/sodium.h"; then
CPPFLAGS="-I${with_libsodium}/include ${CPPFLAGS}"
LDFLAGS="-L${with_libsodium}/lib ${LDFLAGS}"
fi
fi
AC_ARG_WITH([libsodium-include-dir],
[AS_HELP_STRING([--with-libsodium-include-dir],
[Specify libsodium include prefix])],
[zmq_search_libsodium_include="yes"],
[])
if test "x$zmq_search_libsodium_include" = "xyes"; then
if test -r "${with_libsodium_include_dir}/sodium.h"; then
CPPFLAGS="-I${with_libsodium_include_dir}/include ${CPPFLAGS}"
fi
fi
AC_ARG_WITH([libsodium_lib_dir],
[AS_HELP_STRING([--with-libsodium-lib-dir],
[Specify libsodium library prefix])],
[zmq_search_libsodium_lib="yes"],
[])
if test "x$zmq_search_libsodium_lib" = "xyes"; then
if test -r "${with_libsodium_lib_dir}/libsodium.{a|so|dylib}"; then
LDFLAGS="-L${with_libsodium}/lib ${LDFLAGS}"
fi
fi
# Set pedantic
libzmq_pedantic="yes"
@ -79,6 +114,7 @@ libzmq_dso_visibility="yes"
# Platform specific checks
libzmq_on_mingw32="no"
libzmq_on_android="no"
libzmq_on_linux="no"
# Set some default features required by 0MQ code.
CPPFLAGS="-D_REENTRANT -D_THREAD_SAFE $CPPFLAGS"
@ -94,6 +130,7 @@ case "${host_os}" in
CPPFLAGS="-D_GNU_SOURCE $CPPFLAGS"
fi
AC_DEFINE(ZMQ_HAVE_LINUX, 1, [Have Linux OS])
libzmq_on_linux="yes"
case "${host_os}" in
*android*)
@ -121,6 +158,9 @@ case "${host_os}" in
if test "x$solaris_has_atomic" = "xno"; then
AC_DEFINE(ZMQ_FORCE_MUTEXES, 1, [Force to use mutexes])
fi
# ssp library is required for libsodium on Solaris-like systems
LDFLAGS="-lssp $LDFLAGS"
CPPFLAGS="$CPPFLAGS -Wno-long-long"
;;
*freebsd*)
# Define on FreeBSD to enable all library features
@ -214,6 +254,11 @@ case "${host_os}" in
;;
esac
# Checks for libraries
AC_CHECK_LIB([pthread], [pthread_create])
AC_CHECK_LIB([rt], [clock_gettime])
AC_CHECK_LIB([sodium], [sodium_init],,AC_MSG_WARN(libsodium is needed for CURVE security))
#
# Check if the compiler supports -fvisibility=hidden flag. MinGW32 uses __declspec
#
@ -385,6 +430,7 @@ AC_LANG_POP([C++])
AM_CONDITIONAL(BUILD_PGM, test "x$libzmq_pgm_ext" = "xyes")
AM_CONDITIONAL(ON_MINGW, test "x$libzmq_on_mingw32" = "xyes")
AM_CONDITIONAL(ON_ANDROID, test "x$libzmq_on_android" = "xyes")
AM_CONDITIONAL(ON_LINUX, test "x$libzmq_on_linux" = "xyes")
# Checks for library functions.
AC_TYPE_SIGNAL

View File

@ -3,13 +3,13 @@ MAN3 = zmq_bind.3 zmq_unbind.3 zmq_connect.3 zmq_disconnect.3 zmq_close.3 \
zmq_msg_init.3 zmq_msg_init_data.3 zmq_msg_init_size.3 \
zmq_msg_move.3 zmq_msg_copy.3 zmq_msg_size.3 zmq_msg_data.3 zmq_msg_close.3 \
zmq_msg_send.3 zmq_msg_recv.3 \
zmq_send.3 zmq_recv.3 \
zmq_send.3 zmq_recv.3 zmq_send_const.3 \
zmq_msg_get.3 zmq_msg_set.3 zmq_msg_more.3 \
zmq_getsockopt.3 zmq_setsockopt.3 \
zmq_socket.3 zmq_socket_monitor.3 zmq_poll.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_z85_encode.3 zmq_z85_decode.3
zmq_z85_encode.3 zmq_z85_decode.3 zmq_curve_keypair.3
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

View File

@ -140,6 +140,7 @@ Sending and receiving messages::
linkzmq:zmq_msg_recv[3]
linkzmq:zmq_send[3]
linkzmq:zmq_recv[3]
linkzmq:zmq_send_const[3]
.Input/output multiplexing
0MQ provides a mechanism for applications to multiplex input/output events over
@ -193,6 +194,15 @@ Plain-text authentication using username and password::
Elliptic curve authentication and encryption::
linkzmq:zmq_curve[7]
Generate a CURVE keypair in armored text format:
linkzmq:zmq_curve_keypair[3]
Convert an armored key into a 32-byte binary key:
linkzmq:zmq_z85_decode[3]
Convert a 32-byte binary CURVE key to an armored text string:
linkzmq:zmq_z85_encode[3]
ERROR HANDLING
--------------

View File

@ -54,7 +54,7 @@ EXAMPLE
.Setting a limit on the number of sockets
----
void *context = zmq_ctx_new ();
zmq_ctx_get (context, ZMQ_MAX_SOCKETS, 256);
zmq_ctx_set (context, ZMQ_MAX_SOCKETS, 256);
int max_sockets = zmq_ctx_get (context, ZMQ_MAX_SOCKETS);
assert (max_sockets == 256);
----

56
doc/zmq_curve_keypair.txt Normal file
View File

@ -0,0 +1,56 @@
zmq_curve_keypair(3)
====================
NAME
----
zmq_curve_keypair - generate a new CURVE keypair
SYNOPSIS
--------
*int zmq_curve_keypair (char *z85_public_key, char *z85_secret_key);*
DESCRIPTION
-----------
The _zmq_curve_keypair()_ function shall return a newly generated random
keypair consisting of a public key and a secret key. The caller provides
two buffers, each at least 41 octets large, in which this method will
store the keys. The keys are encoded using linkzmq:zmq_z85_encode[3].
RETURN VALUE
------------
The _zmq_curve_keypair()_ function shall return 0 if successful, else it
shall return `-1` and set 'errno' to one of the values defined below.
ERRORS
------
*ENOTSUP*::
The libzmq library was not built with cryptographic support (libsodium).
EXAMPLE
-------
.Generating a new CURVE keypair
----
char public_key [41];
char secret_key [41];
int rc = crypto_box_keypair (public_key, secret_key);
assert (rc == 0);
----
SEE ALSO
--------
linkzmq:zmq_z85_decode[3]
linkzmq:zmq_z85_encode[3]
linkzmq:zmq_curve[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>.

View File

@ -352,8 +352,8 @@ Default value:: 1 (true)
Applicable socket types:: all, when using TCP transports.
ZMQ_DELAY_ATTACH_ON_CONNECT: Retrieve attach-on-connect value
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ZMQ_IMMEDIATE: Retrieve attach-on-connect value
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Retrieve the state of the attach on connect value. If set to `1`, will delay the
attachment of a pipe on connect until the underlying connection has completed.
This will cause the socket to block if there are no other connections, but will

View File

@ -48,6 +48,11 @@ NOTE: the endpoint pathname must be writable by the process. When the endpoint
starts with '/', e.g., `ipc:///pathname`, this will be an _absolute_ pathname.
If the endpoint specifies a directory that does not exist, the bind shall fail.
NOTE: on Linux only, when the endpoint pathname starts with `@`, the abstract
namespace shall be used. The abstract namespace is independent of the
filesystem and if a process attempts to bind an endpoint already bound by a
process, it will fail. See unix(7) for details.
Connecting a socket
~~~~~~~~~~~~~~~~~~~
When connecting a 'socket' to a peer address using _zmq_connect()_ with the

View File

@ -73,10 +73,6 @@ NOTE: The _zmq_poll()_ function may be implemented or emulated using operating
system interfaces other than _poll()_, and as such may be subject to the limits
of those interfaces in ways not defined in this documentation.
NOTE: The _zmq_send()_ function will clear all pending events on a socket. Thus,
if you use _zmq_poll()_ to monitor input on a socket, use it before output as
well, and process all events after each _zmq_poll()_ call.
RETURN VALUE
------------
Upon successful completion, the _zmq_poll()_ function shall return the number

View File

@ -1,5 +1,5 @@
zmq_send_const(3)
===========
=================
NAME

View File

@ -14,7 +14,7 @@ SYNOPSIS
Caution: All options, with the exception of ZMQ_SUBSCRIBE, ZMQ_UNSUBSCRIBE,
ZMQ_LINGER, ZMQ_ROUTER_MANDATORY, ZMQ_PROBE_ROUTER, ZMQ_XPUB_VERBOSE,
ZMQ_REQ_STRICT, ZMQ_REQ_REQUEST_IDS only take effect for subsequent socket
ZMQ_REQ_CORRELATE, and ZMQ_REQ_RELAXED, only take effect for subsequent socket
bind/connects.
Specifically, security options take effect for subsequent bind/connect calls,
@ -461,11 +461,11 @@ Default value:: 0
Applicable socket types:: ZMQ_XPUB
ZMQ_REQ_REQUEST_IDS: enable extra request identity frames
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ZMQ_REQ_CORRELATE: match replies with requests
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The default behavior of REQ sockets is to rely on the ordering of messages
to match requests and responses and that is usually sufficient. When this option
The default behavior of REQ sockets is to rely on the ordering of messages to
match requests and responses and that is usually sufficient. When this option
is set to 1, the REQ socket will prefix outgoing messages with an extra frame
containing a request id. That means the full message is (request id, 0,
user frames...). The REQ socket will discard all incoming messages that don't
@ -478,25 +478,25 @@ Default value:: 0
Applicable socket types:: ZMQ_REQ
ZMQ_REQ_STRICT: enforce strict alternation between request and reply
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ZMQ_REQ_RELAXED: relax strict alternation between request and reply
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
When set to 1, a REQ socket does not allow initiating a new request with
By default, a REQ socket does not allow initiating a new request with
_zmq_send(3)_ until the reply to the previous one has been received.
When set to 0, sending another message is allowed and has the effect of
When set to 1, sending another message is allowed and has the effect of
disconnecting the underlying connection to the peer from which the reply was
expected, triggering a reconnection attempt on transports that support it.
The request-reply state machine is reset and a new request is sent to the
next available peer.
If set to 0, also enable ZMQ_REQ_REQUEST_IDS to ensure correct
matching of requests and replies. Otherwise a late reply to an aborted request
can be reported as the reply to the superseding request.
If set to 1, also enable ZMQ_REQ_CORRELATE to ensure correct matching of
requests and replies. Otherwise a late reply to an aborted request can be
reported as the reply to the superseding request.
[horizontal]
Option value type:: int
Option value unit:: 0, 1
Default value:: 1
Default value:: 0
Applicable socket types:: ZMQ_REQ

View File

@ -31,7 +31,6 @@ EXAMPLE
-------
.Decoding a CURVE key
----
#include <sodium.h>
char decoded [] = "rq:rM>}U?@Lns47E1%kR.o@n%FcmmsL/@{H8]yf7";
uint8_t public_key [32];
zmq_z85_decode (public_key, decoded);
@ -41,6 +40,7 @@ zmq_z85_decode (public_key, decoded);
SEE ALSO
--------
linkzmq:zmq_z85_decode[3]
linkzmq:zmq_curve_keypair[3]
linkzmq:zmq_curve[7]

View File

@ -47,6 +47,7 @@ puts (encoded);
SEE ALSO
--------
linkzmq:zmq_z85_decode[3]
linkzmq:zmq_curve_keypair[3]
linkzmq:zmq_curve[7]

View File

@ -15,6 +15,14 @@
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/>.
*************************************************************************
NOTE to contributors. This file comprises the principal public contract
for ZeroMQ API users (along with zmq_utils.h). Any change to this file
supplied in a stable release SHOULD not break existing applications.
In practice this means that the value of constants must not change, and
that old values may not be reused for new constants.
*************************************************************************
*/
#ifndef __ZMQ_H_INCLUDED__
@ -62,6 +70,9 @@ typedef __int32 int32_t;
# ifndef uint16_t
typedef unsigned __int16 uint16_t;
# endif
# ifndef uint8_t
typedef unsigned __int8 uint8_t;
# endif
#else
# include <stdint.h>
#endif
@ -72,9 +83,9 @@ typedef unsigned __int16 uint16_t;
/******************************************************************************/
/* Version macros for compile-time API version detection */
#define ZMQ_VERSION_MAJOR 3
#define ZMQ_VERSION_MINOR 3
#define ZMQ_VERSION_PATCH 0
#define ZMQ_VERSION_MAJOR 4
#define ZMQ_VERSION_MINOR 0
#define ZMQ_VERSION_PATCH 1
#define ZMQ_MAKE_VERSION(major, minor, patch) \
((major) * 10000 + (minor) * 100 + (patch))
@ -277,8 +288,8 @@ ZMQ_EXPORT int zmq_msg_set (zmq_msg_t *msg, int option, int optval);
#define ZMQ_CURVE_SECRETKEY 49
#define ZMQ_CURVE_SERVERKEY 50
#define ZMQ_PROBE_ROUTER 51
#define ZMQ_REQ_REQUEST_IDS 52
#define ZMQ_REQ_STRICT 53
#define ZMQ_REQ_CORRELATE 52
#define ZMQ_REQ_RELAXED 53
#define ZMQ_CONFLATE 54
#define ZMQ_ZAP_DOMAIN 55

View File

@ -22,9 +22,22 @@
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <stdlib.h>
/* Define integer types needed for event interface */
#if defined ZMQ_HAVE_SOLARIS || defined ZMQ_HAVE_OPENVMS
# include <inttypes.h>
#elif defined _MSC_VER && _MSC_VER < 1600
# ifndef int32_t
typedef __int32 int32_t;
# endif
# ifndef uint16_t
typedef unsigned __int16 uint16_t;
# endif
#else
# include <stdint.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
@ -48,8 +61,22 @@ extern "C" {
# endif
#endif
/* These functions are documented by man pages */
/* Encode data with Z85 encoding. Returns encoded data */
ZMQ_EXPORT char *zmq_z85_encode (char *dest, uint8_t *data, size_t size);
/* Decode data with Z85 encoding. Returns decoded data */
ZMQ_EXPORT uint8_t *zmq_z85_decode (uint8_t *dest, char *string);
/* Generate z85-encoded public and private keypair with libsodium. */
/* Returns 0 on success. */
ZMQ_EXPORT int zmq_curve_keypair (char *z85_public_key, char *z85_secret_key);
typedef void (zmq_thread_fn) (void*);
/* These functions are not documented by man pages */
/* Helper functions are used by perf tests so that they don't have to care */
/* about minutiae of time-related functions on different OS platforms. */

View File

@ -88,7 +88,7 @@ libzmq_la_SOURCES = \
dealer.hpp \
xsub.hpp \
ypipe.hpp \
ypipe_flat.hpp \
ypipe_base.hpp \
yqueue.hpp \
address.cpp \
clock.cpp \

View File

@ -74,13 +74,11 @@ zmq::ctx_t::~ctx_t ()
delete io_threads [i];
// Deallocate the reaper thread object.
if (reaper)
delete reaper;
// Deallocate the array of mailboxes. No special work is
// needed as mailboxes themselves were deallocated with their
// corresponding io_thread/socket objects.
if (slots)
free (slots);
// Remove the tag, so that the object is considered dead.

View File

@ -132,8 +132,8 @@ namespace zmq
sockets_t sockets;
// List of unused thread slots.
typedef std::vector <uint32_t> emtpy_slots_t;
emtpy_slots_t empty_slots;
typedef std::vector <uint32_t> empty_slots_t;
empty_slots_t empty_slots;
// If true, zmq_init has been called but no socket has been created
// yet. Launching of I/O threads is delayed.

View File

@ -297,34 +297,38 @@ int zmq::curve_client_t::process_welcome (msg_t *msg_)
int zmq::curve_client_t::produce_initiate (msg_t *msg_)
{
uint8_t vouch_nonce [crypto_box_NONCEBYTES];
uint8_t vouch_plaintext [crypto_box_ZEROBYTES + 32];
uint8_t vouch_box [crypto_box_BOXZEROBYTES + 48];
uint8_t vouch_plaintext [crypto_box_ZEROBYTES + 64];
uint8_t vouch_box [crypto_box_BOXZEROBYTES + 80];
// Create vouch = Box [C'](C->S)
// Create vouch = Box [C',S](C->S')
memset (vouch_plaintext, 0, crypto_box_ZEROBYTES);
memcpy (vouch_plaintext + crypto_box_ZEROBYTES, cn_public, 32);
memcpy (vouch_plaintext + crypto_box_ZEROBYTES + 32, server_key, 32);
memcpy (vouch_nonce, "VOUCH---", 8);
randombytes (vouch_nonce + 8, 16);
int rc = crypto_box (vouch_box, vouch_plaintext,
sizeof vouch_plaintext,
vouch_nonce, server_key, secret_key);
vouch_nonce, cn_server, secret_key);
zmq_assert (rc == 0);
// Assume here that metadata is limited to 256 bytes
uint8_t initiate_nonce [crypto_box_NONCEBYTES];
uint8_t initiate_plaintext [crypto_box_ZEROBYTES + 96 + 256];
uint8_t initiate_box [crypto_box_BOXZEROBYTES + 112 + 256];
uint8_t initiate_plaintext [crypto_box_ZEROBYTES + 128 + 256];
uint8_t initiate_box [crypto_box_BOXZEROBYTES + 144 + 256];
// Create Box [C + vouch + metadata](C'->S')
memset (initiate_plaintext, 0, crypto_box_ZEROBYTES);
memcpy (initiate_plaintext + crypto_box_ZEROBYTES, public_key, 32);
memcpy (initiate_plaintext + crypto_box_ZEROBYTES,
public_key, 32);
memcpy (initiate_plaintext + crypto_box_ZEROBYTES + 32,
vouch_nonce + 8, 16);
memcpy (initiate_plaintext + crypto_box_ZEROBYTES + 48,
vouch_box + crypto_box_BOXZEROBYTES, 48);
vouch_box + crypto_box_BOXZEROBYTES, 80);
uint8_t *ptr = initiate_plaintext + crypto_box_ZEROBYTES + 96;
// Metadata starts after vouch
uint8_t *ptr = initiate_plaintext + crypto_box_ZEROBYTES + 128;
// Add socket type property
const char *socket_type = socket_type_string (options.type);
@ -359,7 +363,6 @@ int zmq::curve_client_t::produce_initiate (msg_t *msg_)
// Box [C + vouch + metadata](C'->S')
memcpy (initiate + 113, initiate_box + crypto_box_BOXZEROBYTES,
mlen - crypto_box_BOXZEROBYTES);
cn_nonce++;
return 0;

View File

@ -338,7 +338,7 @@ int zmq::curve_server_t::produce_welcome (msg_t *msg_)
int zmq::curve_server_t::process_initiate (msg_t *msg_)
{
if (msg_->size () < 225) {
if (msg_->size () < 257) {
errno = EPROTO;
return -1;
}
@ -369,19 +369,17 @@ int zmq::curve_server_t::process_initiate (msg_t *msg_)
}
// Check cookie plain text is as expected [C' + s']
if (memcmp (cookie_plaintext + crypto_secretbox_ZEROBYTES,
cn_client, 32)
|| memcmp (cookie_plaintext + crypto_secretbox_ZEROBYTES + 32,
cn_secret, 32)) {
errno = EAGAIN;
if (memcmp (cookie_plaintext + crypto_secretbox_ZEROBYTES, cn_client, 32)
|| memcmp (cookie_plaintext + crypto_secretbox_ZEROBYTES + 32, cn_secret, 32)) {
errno = EPROTO;
return -1;
}
const size_t clen = (msg_->size () - 113) + crypto_box_BOXZEROBYTES;
uint8_t initiate_nonce [crypto_box_NONCEBYTES];
uint8_t initiate_plaintext [crypto_box_ZEROBYTES + 96 + 256];
uint8_t initiate_box [crypto_box_BOXZEROBYTES + 112 + 256];
uint8_t initiate_plaintext [crypto_box_ZEROBYTES + 128 + 256];
uint8_t initiate_box [crypto_box_BOXZEROBYTES + 144 + 256];
// Open Box [C + vouch + metadata](C'->S')
memset (initiate_box, 0, crypto_box_BOXZEROBYTES);
@ -401,13 +399,13 @@ int zmq::curve_server_t::process_initiate (msg_t *msg_)
const uint8_t *client_key = initiate_plaintext + crypto_box_ZEROBYTES;
uint8_t vouch_nonce [crypto_box_NONCEBYTES];
uint8_t vouch_plaintext [crypto_box_ZEROBYTES + 32];
uint8_t vouch_box [crypto_box_BOXZEROBYTES + 48];
uint8_t vouch_plaintext [crypto_box_ZEROBYTES + 64];
uint8_t vouch_box [crypto_box_BOXZEROBYTES + 80];
// Open Box [C'](C->S) and check contents
// Open Box Box [C',S](C->S') and check contents
memset (vouch_box, 0, crypto_box_BOXZEROBYTES);
memcpy (vouch_box + crypto_box_BOXZEROBYTES,
initiate_plaintext + crypto_box_ZEROBYTES + 48, 48);
initiate_plaintext + crypto_box_ZEROBYTES + 48, 80);
memcpy (vouch_nonce, "VOUCH---", 8);
memcpy (vouch_nonce + 8,
@ -415,7 +413,7 @@ int zmq::curve_server_t::process_initiate (msg_t *msg_)
rc = crypto_box_open (vouch_plaintext, vouch_box,
sizeof vouch_box,
vouch_nonce, client_key, secret_key);
vouch_nonce, client_key, cn_secret);
if (rc != 0) {
errno = EPROTO;
return -1;
@ -443,8 +441,8 @@ int zmq::curve_server_t::process_initiate (msg_t *msg_)
}
}
return parse_metadata (initiate_plaintext + crypto_box_ZEROBYTES + 96,
clen - crypto_box_ZEROBYTES - 96);
return parse_metadata (initiate_plaintext + crypto_box_ZEROBYTES + 128,
clen - crypto_box_ZEROBYTES - 128);
}
int zmq::curve_server_t::produce_ready (msg_t *msg_)

View File

@ -51,9 +51,20 @@ int zmq::ipc_address_t::resolve (const char *path_)
errno = ENAMETOOLONG;
return -1;
}
#if defined ZMQ_HAVE_LINUX
if (path_[0] == '@' && !path_[1]) {
errno = EINVAL;
return -1;
}
#endif
address.sun_family = AF_UNIX;
strcpy (address.sun_path, path_);
#if defined ZMQ_HAVE_LINUX
/* Abstract sockets on Linux start with '\0' */
if (path_[0] == '@')
*address.sun_path = '\0';
#endif
return 0;
}
@ -65,7 +76,15 @@ int zmq::ipc_address_t::to_string (std::string &addr_)
}
std::stringstream s;
#if !defined ZMQ_HAVE_LINUX
s << "ipc://" << address.sun_path;
#else
s << "ipc://";
if (!address.sun_path[0] && address.sun_path[1])
s << "@" << address.sun_path + 1;
else
s << address.sun_path;
#endif
addr_ = s.str ();
return 0;
}
@ -77,6 +96,10 @@ const sockaddr *zmq::ipc_address_t::addr () const
socklen_t zmq::ipc_address_t::addrlen () const
{
#if defined ZMQ_HAVE_LINUX
if (!address.sun_path[0] && address.sun_path[1])
return (socklen_t) strlen(address.sun_path + 1) + sizeof (sa_family_t) + 1;
#endif
return (socklen_t) sizeof (address);
}

View File

@ -54,7 +54,6 @@ zmq::mtrie_t::~mtrie_t ()
else
if (count > 1) {
for (unsigned short i = 0; i != count; ++i)
if (next.table [i])
delete next.table [i];
free (next.table);
}

View File

@ -286,7 +286,7 @@ int zmq::options_t::setsockopt (int option_, const void *optval_,
break;
case ZMQ_ZAP_DOMAIN:
if (optvallen_ >= 0 && optvallen_ < 256) {
if (optvallen_ < 256) {
zap_domain.assign ((const char *) optval_, optvallen_);
return 0;
}

View File

@ -198,16 +198,16 @@ int zmq::req_t::xsetsockopt (int option_, const void *optval_, size_t optvallen_
bool is_int = (optvallen_ == sizeof (int));
int value = is_int? *((int *) optval_): 0;
switch (option_) {
case ZMQ_REQ_REQUEST_IDS:
case ZMQ_REQ_CORRELATE:
if (is_int && value >= 0) {
request_id_frames_enabled = (value != 0);
return 0;
}
break;
case ZMQ_REQ_STRICT:
case ZMQ_REQ_RELAXED:
if (is_int && value >= 0) {
strict = (value != 0);
strict = (value == 0);
return 0;
}
break;

View File

@ -96,7 +96,6 @@ zmq::session_base_t::~session_base_t ()
if (engine)
engine->terminate ();
if (addr)
delete addr;
}

View File

@ -114,11 +114,8 @@ zmq::stream_engine_t::~stream_engine_t ()
int rc = tx_msg.close ();
errno_assert (rc == 0);
if (encoder != NULL)
delete encoder;
if (decoder != NULL)
delete decoder;
if (mechanism != NULL)
delete mechanism;
}
@ -652,6 +649,7 @@ void zmq::stream_engine_t::mechanism_ready ()
return;
}
errno_assert (rc == 0);
session->flush ();
}
read_msg = &stream_engine_t::pull_and_encode;

View File

@ -48,7 +48,6 @@ zmq::trie_t::~trie_t ()
else
if (count > 1) {
for (unsigned short i = 0; i != count; ++i)
if (next.table [i])
delete next.table [i];
free (next.table);
}

View File

@ -72,7 +72,6 @@ namespace zmq
}
chunk_t *sc = spare_chunk.xchg (NULL);
if (sc)
free (sc);
}
@ -156,7 +155,6 @@ namespace zmq
// so for cache reasons we'll get rid of the spare and
// use 'o' as the spare.
chunk_t *cs = spare_chunk.xchg (o);
if (cs)
free (cs);
}
}

View File

@ -30,6 +30,10 @@
#else
#include "windows.hpp"
#endif
#ifdef HAVE_LIBSODIUM
# include <sodium.h>
#endif
void zmq_sleep (int seconds_)
{
@ -100,10 +104,14 @@ static uint8_t decoder [96] = {
// Encode a binary frame as a string; destination string MUST be at least
// size * 5 / 4 bytes long plus 1 byte for the null terminator. Returns
// dest. Size must be a multiple of 4.
// Returns NULL and sets errno = EINVAL for invalid input.
char *zmq_z85_encode (char *dest, uint8_t *data, size_t size)
{
assert (size % 4 == 0);
if (size % 4 != 0) {
errno = EINVAL;
return NULL;
}
unsigned int char_nbr = 0;
unsigned int byte_nbr = 0;
uint32_t value = 0;
@ -130,10 +138,15 @@ char *zmq_z85_encode (char *dest, uint8_t *data, size_t size)
// Decode an encoded string into a binary frame; dest must be at least
// strlen (string) * 4 / 5 bytes long. Returns dest. strlen (string)
// must be a multiple of 5.
// Returns NULL and sets errno = EINVAL for invalid input.
uint8_t *zmq_z85_decode (uint8_t *dest, char *string)
{
assert (strlen (string) % 5 == 0);
if (strlen (string) % 5 != 0) {
errno = EINVAL;
return NULL;
}
unsigned int byte_nbr = 0;
unsigned int char_nbr = 0;
uint32_t value = 0;
@ -153,3 +166,34 @@ uint8_t *zmq_z85_decode (uint8_t *dest, char *string)
assert (byte_nbr == strlen (string) * 4 / 5);
return dest;
}
// --------------------------------------------------------------------------
// Generate a public/private keypair with libsodium.
// Generated keys will be 40 byte z85-encoded strings.
// Returns 0 on success, -1 on failure, setting errno.
// Sets errno = ENOTSUP in the absence of libsodium.
int zmq_curve_keypair (char* z85_public_key, char *z85_secret_key)
{
#ifdef HAVE_LIBSODIUM
# if crypto_box_PUBLICKEYBYTES != 32 \
|| crypto_box_SECRETKEYBYTES != 32
# error "libsodium not built correctly"
# endif
uint8_t public_key [32];
uint8_t secret_key [32];
int rc = crypto_box_keypair (public_key, secret_key);
// is there a sensible errno to set here?
if (rc) return rc;
zmq_z85_encode (z85_public_key, public_key, 32);
zmq_z85_encode (z85_secret_key, secret_key, 32);
return 0;
#else // requires libsodium
errno = ENOTSUP;
return -1;
#endif
}

View File

@ -14,7 +14,7 @@ noinst_PROGRAMS = test_system \
test_invalid_rep \
test_msg_flags \
test_connect_resolve \
test_connect_delay \
test_immediate \
test_last_endpoint \
test_term_endpoint \
test_linger \
@ -34,10 +34,12 @@ noinst_PROGRAMS = test_system \
test_spec_dealer \
test_spec_router \
test_spec_pushpull \
test_req_request_ids \
test_req_strict \
test_req_correlate \
test_req_relaxed \
test_conflate \
test_inproc_connect
test_inproc_connect \
test_issue_566 \
test_abstract_ipc
if !ON_MINGW
noinst_PROGRAMS += test_shutdown_stress \
@ -59,7 +61,7 @@ test_invalid_rep_SOURCES = test_invalid_rep.cpp
test_linger_SOURCES = test_linger.cpp
test_msg_flags_SOURCES = test_msg_flags.cpp
test_connect_resolve_SOURCES = test_connect_resolve.cpp
test_connect_delay_SOURCES = test_connect_delay.cpp
test_immediate_SOURCES = test_immediate.cpp
test_last_endpoint_SOURCES = test_last_endpoint.cpp
test_term_endpoint_SOURCES = test_term_endpoint.cpp
test_monitor_SOURCES = test_monitor.cpp
@ -78,10 +80,12 @@ test_spec_rep_SOURCES = test_spec_rep.cpp
test_spec_dealer_SOURCES = test_spec_dealer.cpp
test_spec_router_SOURCES = test_spec_router.cpp
test_spec_pushpull_SOURCES = test_spec_pushpull.cpp
test_req_request_ids_SOURCES = test_req_request_ids.cpp
test_req_strict_SOURCES = test_req_strict.cpp
test_req_correlate_SOURCES = test_req_correlate.cpp
test_req_relaxed_SOURCES = test_req_relaxed.cpp
test_conflate_SOURCES = test_conflate.cpp
test_inproc_connect_SOURCES = test_inproc_connect.cpp
test_issue_566_SOURCES = test_issue_566.cpp
test_abstract_ipc_SOURCES = test_abstract_ipc.cpp
if !ON_MINGW
test_shutdown_stress_SOURCES = test_shutdown_stress.cpp
test_pair_ipc_SOURCES = test_pair_ipc.cpp testutil.hpp
@ -93,3 +97,7 @@ endif
# Run the test cases
TESTS = $(noinst_PROGRAMS)
XFAIL_TESTS = test_linger
if !ON_LINUX
XFAIL_TESTS += test_abstract_ipc
endif

View File

@ -0,0 +1,57 @@
/*
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 "testutil.hpp"
int main (void)
{
setup_test_environment();
void *ctx = zmq_ctx_new ();
assert (ctx);
void *sb = zmq_socket (ctx, ZMQ_PAIR);
assert (sb);
int rc = zmq_bind (sb, "ipc://@/tmp/tester");
assert (rc == 0);
char endpoint[200];
size_t size = sizeof(endpoint);
rc = zmq_getsockopt (sb, ZMQ_LAST_ENDPOINT, endpoint, &size);
assert (rc == 0);
rc = strncmp(endpoint, "ipc://@/tmp/tester", size);
assert (rc == 0);
void *sc = zmq_socket (ctx, ZMQ_PAIR);
assert (sc);
rc = zmq_connect (sc, "ipc://@/tmp/tester");
assert (rc == 0);
bounce (sb, sc);
rc = zmq_close (sc);
assert (rc == 0);
rc = zmq_close (sb);
assert (rc == 0);
rc = zmq_ctx_term (ctx);
assert (rc == 0);
return 0 ;
}

View File

@ -117,7 +117,7 @@ int main (void)
// Set the key flag
val = 1;
rc = zmq_setsockopt (from, ZMQ_DELAY_ATTACH_ON_CONNECT, &val, sizeof(val));
rc = zmq_setsockopt (from, ZMQ_IMMEDIATE, &val, sizeof(val));
assert (rc == 0);
// Connect to the invalid socket
@ -170,9 +170,9 @@ int main (void)
rc = zmq_setsockopt (frontend, ZMQ_LINGER, &zero, sizeof (zero));
assert (rc == 0);
// Frontend connects to backend using DELAY_ATTACH_ON_CONNECT
// Frontend connects to backend using IMMEDIATE
int on = 1;
rc = zmq_setsockopt (frontend, ZMQ_DELAY_ATTACH_ON_CONNECT, &on, sizeof (on));
rc = zmq_setsockopt (frontend, ZMQ_IMMEDIATE, &on, sizeof (on));
assert (rc == 0);
rc = zmq_bind (backend, "tcp://127.0.0.1:5560");
assert (rc == 0);

85
tests/test_issue_566.cpp Normal file
View File

@ -0,0 +1,85 @@
/*
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 "testutil.hpp"
// Issue 566 describes a problem in libzmq v4.0.0 where a dealer to router
// connection would fail randomly. The test works when the two sockets are
// on the same context, and failed when they were on separate contexts.
// Fixed by https://github.com/zeromq/libzmq/commit/be25cf.
int main (void)
{
setup_test_environment();
void *ctx1 = zmq_ctx_new ();
assert (ctx1);
void *ctx2 = zmq_ctx_new ();
assert (ctx2);
void *router = zmq_socket (ctx1, ZMQ_ROUTER);
int on = 1;
int rc = zmq_setsockopt (router, ZMQ_ROUTER_MANDATORY, &on, sizeof (on));
assert (rc == 0);
rc = zmq_bind (router, "tcp://127.0.0.1:5555");
assert (rc != -1);
// Repeat often enough to be sure this works as it should
for (int cycle = 0; cycle < 100; cycle++) {
// Create dealer with unique explicit identity
// We assume the router learns this out-of-band
void *dealer = zmq_socket (ctx2, ZMQ_DEALER);
char identity [10];
sprintf (identity, "%09d", cycle);
rc = zmq_setsockopt (dealer, ZMQ_IDENTITY, identity, 10);
assert (rc == 0);
int rcvtimeo = 1000;
rc = zmq_setsockopt (dealer, ZMQ_RCVTIMEO, &rcvtimeo, sizeof (int));
assert (rc == 0);
rc = zmq_connect (dealer, "tcp://127.0.0.1:5555");
assert (rc == 0);
// Router will try to send to dealer, at short intervals.
// It typically takes 2-5 msec for the connection to establish
// on a loopback interface, but we'll allow up to one second
// before failing the test (e.g. for running on a debugger or
// a very slow system).
for (int attempt = 0; attempt < 500; attempt++) {
zmq_poll (0, 0, 2);
rc = zmq_send (router, identity, 10, ZMQ_SNDMORE);
if (rc == -1 && errno == EHOSTUNREACH)
continue;
assert (rc == 10);
rc = zmq_send (router, "HELLO", 5, 0);
assert (rc == 5);
break;
}
uint8_t buffer [5];
rc = zmq_recv (dealer, buffer, 5, 0);
assert (rc == 5);
assert (memcmp (buffer, "HELLO", 5) == 0);
close_zero_linger (dealer);
}
zmq_close (router);
zmq_ctx_destroy (ctx1);
zmq_ctx_destroy (ctx2);
return 0;
}

View File

@ -32,7 +32,7 @@ int main (void)
assert (router);
int enabled = 1;
int rc = zmq_setsockopt (req, ZMQ_REQ_REQUEST_IDS, &enabled, sizeof (int));
int rc = zmq_setsockopt (req, ZMQ_REQ_CORRELATE, &enabled, sizeof (int));
assert (rc == 0);
int rcvtimeo = 100;

View File

@ -28,12 +28,11 @@ int main (void)
void *req = zmq_socket (ctx, ZMQ_REQ);
assert (req);
int disabled = 0;
int rc = zmq_setsockopt (req, ZMQ_REQ_STRICT, &disabled, sizeof (int));
int enabled = 1;
int rc = zmq_setsockopt (req, ZMQ_REQ_RELAXED, &enabled, sizeof (int));
assert (rc == 0);
int enabled = 1;
rc = zmq_setsockopt (req, ZMQ_REQ_REQUEST_IDS, &enabled, sizeof (int));
rc = zmq_setsockopt (req, ZMQ_REQ_CORRELATE, &enabled, sizeof (int));
assert (rc == 0);
rc = zmq_bind (req, "tcp://127.0.0.1:5555");

View File

@ -19,11 +19,11 @@
#include "testutil.hpp"
// Test keys from the zmq_curve man page
static char client_public [] = "Yne@$w-vo<fVvi]a<NY6T1ed:M$fCG*[IaLV{hID";
static char client_secret [] = "D:)Q[IlAW!ahhC2ac:9*A}h:p?([4%wOTJ%JR%cs";
static char server_public [] = "rq:rM>}U?@Lns47E1%kR.o@n%FcmmsL/@{H8]yf7";
static char server_secret [] = "JTKVSB%%)wK0E.X)V>+}o?pNmC{O&4W4b!Ni{Lh6";
// We'll generate random test keys at startup
static char client_public [41];
static char client_secret [41];
static char server_public [41];
static char server_secret [41];
// --------------------------------------------------------------------------
// Encode a binary frame as a string; destination string MUST be at least
@ -86,6 +86,13 @@ int main (void)
printf ("libsodium not installed, skipping CURVE test\n");
return 0;
#endif
// Generate new keypairs for this test
int rc = zmq_curve_keypair (client_public, client_secret);
assert (rc == 0);
rc = zmq_curve_keypair (server_public, server_secret);
assert (rc == 0);
setup_test_environment ();
void *ctx = zmq_ctx_new ();
assert (ctx);
@ -95,7 +102,7 @@ int main (void)
// where child thread does not start up fast enough.
void *handler = zmq_socket (ctx, ZMQ_REP);
assert (handler);
int rc = zmq_bind (handler, "inproc://zeromq.zap.01");
rc = zmq_bind (handler, "inproc://zeromq.zap.01");
assert (rc == 0);
void *zap_thread = zmq_threadstart (&zap_handler, handler);
@ -175,8 +182,9 @@ int main (void)
// Check CURVE security with bogus client credentials
// This must be caught by the ZAP handler
char bogus_public [] = "8)<]6{NT{}=MZBsH)i%l0k}y*^i#80n-Yf{I8Z+P";
char bogus_secret [] = "[m9E0TW2Mf?Ke3K>fuBGCrkBpc6aJbj4jv4451Nx";
char bogus_public [41];
char bogus_secret [41];
zmq_curve_keypair (bogus_public, bogus_secret);
client = zmq_socket (ctx, ZMQ_DEALER);
assert (client);

View File

@ -57,6 +57,8 @@ void test_fair_queue_in (void *ctx)
s_send_seq (rep, "A", SEQ_END);
s_recv_seq (reqs [0], "A", SEQ_END);
// TODO: following test fails randomly on some boxes
#ifdef SOMEONE_FIXES_THIS
// send N requests
for (size_t peer = 0; peer < services; ++peer) {
char * str = strdup("A");
@ -69,12 +71,13 @@ void test_fair_queue_in (void *ctx)
for (size_t peer = 0; peer < services; ++peer) {
char * str = strdup("A");
str [0] += peer;
// Test fails here
s_recv_seq (rep, str, SEQ_END);
s_send_seq (rep, str, SEQ_END);
s_recv_seq (reqs [peer], str, SEQ_END);
free (str);
}
#endif
close_zero_linger (rep);
for (size_t peer = 0; peer < services; ++peer)

View File

@ -102,7 +102,6 @@ test_stream_to_dealer (void)
assert (rc >= 0);
bytes_read += rc;
}
assert (rc == 97);
// First two bytes are major and minor version numbers.
assert (buffer [0] == 3); // ZMTP/3.0
@ -173,12 +172,12 @@ test_stream_to_stream (void)
void *server = zmq_socket (ctx, ZMQ_STREAM);
assert (server);
rc = zmq_bind (server, "tcp://127.0.0.1:8080");
rc = zmq_bind (server, "tcp://127.0.0.1:9080");
assert (rc == 0);
void *client = zmq_socket (ctx, ZMQ_STREAM);
assert (client);
rc = zmq_connect (client, "tcp://localhost:8080");
rc = zmq_connect (client, "tcp://localhost:9080");
assert (rc == 0);
// It would be less surprising to get an empty message instead
// of having to fetch the identity like this [PH 2013/06/27]

View File

@ -20,7 +20,7 @@
#include "testutil.hpp"
#if defined (ZMQ_HAVE_WINDOWS)
# include <WinSock2.h>
# include <winsock2.h>
# include <stdexcept>
#else
# include <sys/socket.h>

View File

@ -31,8 +31,10 @@
#include <string>
#if defined _WIN32
# if defined _MSC_VER
# include <crtdbg.h>
# pragma warning(disable:4996)
# endif
#else
# include <unistd.h>
# include <signal.h>
@ -249,10 +251,12 @@ void close_zero_linger (void *socket)
void setup_test_environment()
{
#if defined _WIN32
# if defined _MSC_VER
_set_abort_behavior( 0, _WRITE_ABORT_MSG);
_CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_FILE );
_CrtSetReportFile( _CRT_ASSERT, _CRTDBG_FILE_STDERR );
# endif
#endif
}
#endif

View File

@ -1,4 +1,4 @@
EXTRA_DIST = curve_keygen.c z85_codec.h
EXTRA_DIST = curve_keygen.c
INCLUDES = -I$(top_srcdir)/include

View File

@ -24,19 +24,13 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <assert.h>
#include <platform.hpp>
#include <zmq.h>
#include <zmq_utils.h>
#ifdef HAVE_LIBSODIUM
# include <sodium.h>
#endif
int main (void)
{
#ifdef HAVE_LIBSODIUM
# if crypto_box_PUBLICKEYBYTES != 32 \
|| crypto_box_SECRETKEYBYTES != 32
# error "libsodium not built correctly"
# endif
puts ("This tool generates a CurveZMQ keypair, as two printable strings you can");
puts ("use in configuration files or source code. The encoding uses Z85, which");
puts ("is a base-85 format that is described in 0MQ RFC 32, and which has an");
@ -44,23 +38,21 @@ int main (void)
puts ("always works with the secret key held by one party and the public key");
puts ("distributed (securely!) to peers wishing to connect to it.");
uint8_t public_key [32];
uint8_t secret_key [32];
char public_key [41];
char secret_key [41];
int rc = zmq_curve_keypair (public_key, secret_key);
if (rc != 0) {
if (zmq_errno () == ENOTSUP) {
puts ("To use curve_keygen, please install libsodium and then rebuild libzmq.");
}
exit (1);
}
int rc = crypto_box_keypair (public_key, secret_key);
assert (rc == 0);
char encoded [41];
zmq_z85_encode (encoded, public_key, 32);
puts ("\n== CURVE PUBLIC KEY ==");
puts (encoded);
puts (public_key);
zmq_z85_encode (encoded, secret_key, 32);
puts ("\n== CURVE SECRET KEY ==");
puts (encoded);
puts (secret_key);
#else
puts ("To build curve_keygen, please install libsodium and then rebuild libzmq.");
#endif
exit (0);
}