From fe8a1f43065eb6e02702cd4c4c95243b2ad9e7e5 Mon Sep 17 00:00:00 2001 From: Jason Rhinelander Date: Thu, 2 Dec 2021 18:58:57 -0400 Subject: [PATCH] Disable IPv6 by default libzmq's IPv6 support is buggy when also using DNS hostname: in particular, if you try to connect to a DNS name that has an IPv6 address, then zmq will *only* try an IPv6 connection, even if the local client has no IPv6 connectivity, and even if the remote is only listening on its IPv4 address. This is much too unreliable to enable by default. --- CMakeLists.txt | 2 +- oxenmq/connections.cpp | 4 +++- oxenmq/oxenmq.h | 9 +++++++++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4efc0d5..6701391 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,7 +17,7 @@ cmake_minimum_required(VERSION 3.7) set(CMAKE_OSX_DEPLOYMENT_TARGET 10.12 CACHE STRING "macOS deployment target (Apple clang only)") project(liboxenmq - VERSION 1.2.9 + VERSION 1.2.10 LANGUAGES CXX C) include(GNUInstallDirs) diff --git a/oxenmq/connections.cpp b/oxenmq/connections.cpp index d72349e..001f6da 100644 --- a/oxenmq/connections.cpp +++ b/oxenmq/connections.cpp @@ -40,7 +40,9 @@ void OxenMQ::setup_external_socket(zmq::socket_t& socket) { socket.set(zmq::sockopt::reconnect_ivl_max, (int) RECONNECT_INTERVAL_MAX.count()); socket.set(zmq::sockopt::handshake_ivl, (int) HANDSHAKE_TIME.count()); socket.set(zmq::sockopt::maxmsgsize, MAX_MSG_SIZE); - socket.set(zmq::sockopt::ipv6, 1); + if (IPV6) + socket.set(zmq::sockopt::ipv6, 1); + if (CONN_HEARTBEAT > 0s) { socket.set(zmq::sockopt::heartbeat_ivl, (int) CONN_HEARTBEAT.count()); if (CONN_HEARTBEAT_TIMEOUT > 0s) diff --git a/oxenmq/oxenmq.h b/oxenmq/oxenmq.h index 17ce052..719b682 100644 --- a/oxenmq/oxenmq.h +++ b/oxenmq/oxenmq.h @@ -296,6 +296,15 @@ public: */ int SOCKET_UID = -1; + /** If true then enable IPv6 connectivity on incoming/outgoing sockets. This is disabled by + * default because enabling it in libzmq breaks IPv4-only clients trying to connect to + * dual-stack IPv6+IPv4 hosts by hostname (the client will *only* try IPv6 if it finds an IPv6 + * address, even if it has no IPv6 connectivity). + * + * This only has an effect for sockets created *after* it is changed. + */ + bool IPV6 = false; + /// A special TaggedThreadID value that always refers to the proxy thread; the main use of this is /// to direct very simple batch completion jobs to be executed directly in the proxy thread. inline static constexpr TaggedThreadID run_in_proxy{-1};