5#ifndef BITCOIN_TEST_UTIL_NET_H
6#define BITCOIN_TEST_UTIL_NET_H
24#include <condition_variable>
30#include <unordered_map>
57 m_nodes.push_back(&
node);
59 if (
node.IsManualOrFullOutboundConn()) ++m_network_conn_counts[
node.addr.GetNetwork()];
72 bool successfully_connected,
148 ssize_t
Send(
const void*,
size_t len,
int)
const override;
150 ssize_t
Recv(
void* buf,
size_t len,
int flags)
const override;
152 int Connect(
const sockaddr*, socklen_t)
const override;
154 int Bind(
const sockaddr*, socklen_t)
const override;
156 int Listen(
int)
const override;
158 std::unique_ptr<Sock>
Accept(sockaddr* addr, socklen_t* addr_len)
const override;
160 int GetSockOpt(
int level,
int opt_name,
void* opt_val, socklen_t* opt_len)
const override;
162 int SetSockOpt(
int,
int,
const void*, socklen_t)
const override;
170 bool Wait(std::chrono::milliseconds timeout,
172 Event* occurred =
nullptr)
const override;
194 ssize_t
Recv(
void* buf,
size_t len,
int flags)
const override;
246 template <
typename... Args>
278 using S = std::unique_ptr<DynSock>;
283 m_queue.push(std::move(
s));
289 if (m_queue.empty()) {
292 S front{std::move(m_queue.front())};
300 return m_queue.empty();
313 explicit DynSock(std::shared_ptr<Pipes> pipes, std::shared_ptr<Queue> accept_sockets);
317 ssize_t
Recv(
void* buf,
size_t len,
int flags)
const override;
319 ssize_t
Send(
const void* buf,
size_t len,
int)
const override;
321 std::unique_ptr<Sock>
Accept(sockaddr* addr, socklen_t* addr_len)
const override;
323 bool Wait(std::chrono::milliseconds timeout,
325 Event* occurred =
nullptr)
const override;
336template <
typename... Args>
348 const auto& [bytes, _more, _msg_type] = transport.GetBytesToSend(
true);
352 m_data.insert(m_data.end(), bytes.begin(), bytes.end());
353 transport.MarkBytesSent(bytes.size());
A CService with information about it as peer.
bool AlreadyConnectedToAddress(const CAddress &addr)
Determine whether we're already connected to a given address, in order to avoid initiating duplicate ...
CConnman(uint64_t seed0, uint64_t seed1, AddrMan &addrman, const NetGroupManager &netgroupman, const CChainParams ¶ms, bool network_active=true)
std::atomic< bool > flagInterruptMsgProc
RecursiveMutex m_nodes_mutex
Mutex m_unused_i2p_sessions_mutex
Mutex protecting m_i2p_sam_sessions.
Information about a peer.
Unidirectional bytes or CNetMessage queue (FIFO).
ssize_t GetBytes(void *buf, size_t len, int flags=0) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
Get bytes and remove them from the pipe.
void WaitForDataOrEof(UniqueLock< Mutex > &lock) EXCLUSIVE_LOCKS_REQUIRED(m_mutex)
Return when there is some data to read or EOF has been signaled.
void Eof() EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
Signal end-of-file on the receiving end (GetBytes() or GetNetMsg()).
std::condition_variable m_cond
std::optional< CNetMessage > GetNetMsg() EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
Deserialize a CNetMessage and remove it from the pipe.
void PushNetMsg(const std::string &type, Args &&... payload) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
Construct and push CNetMessage to the pipe.
std::vector< uint8_t > m_data GUARDED_BY(m_mutex)
void PushBytes(const void *buf, size_t len) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
Push bytes to the pipe.
bool m_eof GUARDED_BY(m_mutex)
A basic thread-safe queue, used for queuing sockets to be returned by Accept().
std::unique_ptr< DynSock > S
std::optional< S > Pop() EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
std::queue< S > m_queue GUARDED_BY(m_mutex)
void Push(S s) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
bool Empty() const EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
A mocked Sock alternative that allows providing the data to be returned by Recv() and inspecting the ...
DynSock & operator=(Sock &&) override
Move assignment operator, grab the socket from another object and close ours (if set).
ssize_t Recv(void *buf, size_t len, int flags) const override
recv(2) wrapper.
std::shared_ptr< Pipes > m_pipes
std::shared_ptr< Queue > m_accept_sockets
bool Wait(std::chrono::milliseconds timeout, Event requested, Event *occurred=nullptr) const override
Wait for readiness for input (recv) or output (send).
std::unique_ptr< Sock > Accept(sockaddr *addr, socklen_t *addr_len) const override
accept(2) wrapper.
ssize_t Send(const void *buf, size_t len, int) const override
send(2) wrapper.
DynSock(std::shared_ptr< Pipes > pipes, std::shared_ptr< Queue > accept_sockets)
Create a new mocked sock.
bool WaitMany(std::chrono::milliseconds timeout, EventsPerSock &events_per_sock) const override
Same as Wait(), but wait on many sockets within the same timeout.
Interface for message handling.
static Mutex g_msgproc_mutex
Mutex for anything that is only accessed via the msg processing thread.
RAII helper class that manages a socket and closes it automatically when it goes out of scope.
std::unordered_map< std::shared_ptr< const Sock >, Events, HashSharedPtrSock, EqualSharedPtrSock > EventsPerSock
On which socket to wait for what events in WaitMany().
A Span is an object that can refer to a contiguous sequence of objects.
A mocked Sock alternative that returns a statically contained data upon read and succeeds and ignores...
bool IsConnected(std::string &) const override
Check if still connected.
const std::string m_contents
StaticContentsSock & operator=(Sock &&other) override
Move assignment operator, grab the socket from another object and close ours (if set).
StaticContentsSock(const std::string &contents)
ssize_t Recv(void *buf, size_t len, int flags) const override
Return parts of the contents that was provided at construction until it is exhausted and then return ...
Wrapper around std::unique_lock style lock for MutexType.
bool SetMessageToSend(CSerializedNetMsg &msg) noexcept override EXCLUSIVE_LOCKS_REQUIRED(!m_send_mutex)
Set the next message to send.
A mocked Sock alternative that succeeds on all operations.
int GetSockOpt(int level, int opt_name, void *opt_val, socklen_t *opt_len) const override
getsockopt(2) wrapper.
bool Wait(std::chrono::milliseconds timeout, Event requested, Event *occurred=nullptr) const override
Wait for readiness for input (recv) or output (send).
bool WaitMany(std::chrono::milliseconds timeout, EventsPerSock &events_per_sock) const override
Same as Wait(), but wait on many sockets within the same timeout.
int GetSockName(sockaddr *name, socklen_t *name_len) const override
getsockname(2) wrapper.
int Listen(int) const override
listen(2) wrapper.
int Bind(const sockaddr *, socklen_t) const override
bind(2) wrapper.
int Connect(const sockaddr *, socklen_t) const override
connect(2) wrapper.
ssize_t Send(const void *, size_t len, int) const override
send(2) wrapper.
std::unique_ptr< Sock > Accept(sockaddr *addr, socklen_t *addr_len) const override
accept(2) wrapper.
bool SetNonBlocking() const override
Set the non-blocking option on the socket.
ssize_t Recv(void *buf, size_t len, int flags) const override
recv(2) wrapper.
ZeroSock & operator=(Sock &&other) override
Move assignment operator, grab the socket from another object and close ours (if set).
int SetSockOpt(int, int, const void *, socklen_t) const override
setsockopt(2) wrapper.
bool IsSelectable() const override
Check if the underlying socket can be used for select(2) (or the Wait() method).
ConnectionType
Different types of connections to a peer.
@ BLOCK_RELAY
We use block-relay-only connections to help prevent against partition attacks.
@ MANUAL
We open manual connections to addresses that users explicitly requested via the addnode RPC or the -a...
@ OUTBOUND_FULL_RELAY
These are the default connections that we use to connect with the network.
@ FEELER
Feeler connections are short-lived connections made to check that a node is alive.
@ INBOUND
Inbound connections are those initiated by a peer.
@ ADDR_FETCH
AddrFetch connections are short lived connections used to solicit addresses from peers.
CSerializedNetMsg Make(std::string msg_type, Args &&... args)
@ NET_ONION
TOR (v2 or v3)
@ NET_UNROUTABLE
Addresses from these networks are not publicly routable on the global Internet.
@ NET_INTERNAL
A set of addresses that represent the hash of a string or FQDN.
ServiceFlags
nServices flags
bool ReceiveMsgFrom(CNode &node, CSerializedNetMsg &&ser_msg) const
CNode * ConnectNodePublic(PeerManager &peerman, const char *pszDest, ConnectionType conn_type) EXCLUSIVE_LOCKS_REQUIRED(!m_unused_i2p_sessions_mutex)
bool AlreadyConnectedPublic(const CAddress &addr)
void NodeReceiveMsgBytes(CNode &node, Span< const uint8_t > msg_bytes, bool &complete) const
void SetMsgProc(NetEventsInterface *msgproc)
void AddTestNode(CNode &node)
void Handshake(CNode &node, bool successfully_connected, ServiceFlags remote_services, ServiceFlags local_services, int32_t version, bool relay_txs) EXCLUSIVE_LOCKS_REQUIRED(NetEventsInterface bool ProcessMessagesOnce(CNode &node) EXCLUSIVE_LOCKS_REQUIRED(NetEventsInterface
std::vector< CNode * > TestNodes()
void FlushSendBuffer(CNode &node) const
void SetPeerConnectTimeout(std::chrono::seconds timeout)
std::vector< NodeEvictionCandidate > GetRandomNodeEvictionCandidates(int n_candidates, FastRandomContext &random_context)
constexpr ServiceFlags ALL_SERVICE_FLAGS[]
constexpr ConnectionType ALL_CONNECTION_TYPES[]
constexpr auto ALL_NETWORKS
constexpr NetPermissionFlags ALL_NET_PERMISSION_FLAGS[]
#define EXCLUSIVE_LOCKS_REQUIRED(...)