diff options
Diffstat (limited to 'src/zmq/zmqpublishnotifier.cpp')
-rw-r--r-- | src/zmq/zmqpublishnotifier.cpp | 43 |
1 files changed, 36 insertions, 7 deletions
diff --git a/src/zmq/zmqpublishnotifier.cpp b/src/zmq/zmqpublishnotifier.cpp index 168ba841c8..2c6f24a239 100644 --- a/src/zmq/zmqpublishnotifier.cpp +++ b/src/zmq/zmqpublishnotifier.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 The Bitcoin Core developers +// Copyright (c) 2015-2021 The Bitcoin Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -6,10 +6,12 @@ #include <chain.h> #include <chainparams.h> +#include <netbase.h> +#include <node/blockstorage.h> #include <rpc/server.h> #include <streams.h> #include <util/system.h> -#include <validation.h> +#include <validation.h> // For cs_main #include <zmq/zmqutil.h> #include <zmq.h> @@ -21,6 +23,8 @@ #include <string> #include <utility> +using node::ReadBlockFromDisk; + static std::multimap<std::string, CZMQAbstractPublishNotifier*> mapPublishNotifiers; static const char *MSG_HASHBLOCK = "hashblock"; @@ -72,6 +76,20 @@ static int zmq_send_multipart(void *sock, const void* data, size_t size, ...) return 0; } +static bool IsZMQAddressIPV6(const std::string &zmq_address) +{ + const std::string tcp_prefix = "tcp://"; + const size_t tcp_index = zmq_address.rfind(tcp_prefix); + const size_t colon_index = zmq_address.rfind(":"); + if (tcp_index == 0 && colon_index != std::string::npos) { + const std::string ip = zmq_address.substr(tcp_prefix.length(), colon_index - tcp_prefix.length()); + CNetAddr addr; + LookupHost(ip, addr, false); + if (addr.IsIPv6()) return true; + } + return false; +} + bool CZMQAbstractPublishNotifier::Initialize(void *pcontext) { assert(!psocket); @@ -106,6 +124,15 @@ bool CZMQAbstractPublishNotifier::Initialize(void *pcontext) return false; } + // On some systems (e.g. OpenBSD) the ZMQ_IPV6 must not be enabled, if the address to bind isn't IPv6 + const int enable_ipv6 { IsZMQAddressIPV6(address) ? 1 : 0}; + rc = zmq_setsockopt(psocket, ZMQ_IPV6, &enable_ipv6, sizeof(enable_ipv6)); + if (rc != 0) { + zmqError("Failed to set ZMQ_IPV6"); + zmq_close(psocket); + return false; + } + rc = zmq_bind(psocket, address.c_str()); if (rc != 0) { @@ -167,7 +194,7 @@ bool CZMQAbstractPublishNotifier::SendZmqMessage(const char *command, const void /* send three parts, command & data & a LE 4byte sequence number */ unsigned char msgseq[sizeof(uint32_t)]; - WriteLE32(&msgseq[0], nSequence); + WriteLE32(msgseq, nSequence); int rc = zmq_send_multipart(psocket, command, strlen(command), data, size, msgseq, (size_t)sizeof(uint32_t), nullptr); if (rc == -1) return false; @@ -182,9 +209,10 @@ bool CZMQPublishHashBlockNotifier::NotifyBlock(const CBlockIndex *pindex) { uint256 hash = pindex->GetBlockHash(); LogPrint(BCLog::ZMQ, "zmq: Publish hashblock %s to %s\n", hash.GetHex(), this->address); - char data[32]; - for (unsigned int i = 0; i < 32; i++) + uint8_t data[32]; + for (unsigned int i = 0; i < 32; i++) { data[31 - i] = hash.begin()[i]; + } return SendZmqMessage(MSG_HASHBLOCK, data, 32); } @@ -192,9 +220,10 @@ bool CZMQPublishHashTransactionNotifier::NotifyTransaction(const CTransaction &t { uint256 hash = transaction.GetHash(); LogPrint(BCLog::ZMQ, "zmq: Publish hashtx %s to %s\n", hash.GetHex(), this->address); - char data[32]; - for (unsigned int i = 0; i < 32; i++) + uint8_t data[32]; + for (unsigned int i = 0; i < 32; i++) { data[31 - i] = hash.begin()[i]; + } return SendZmqMessage(MSG_HASHTX, data, 32); } |