Skip to content

Commit ba29911

Browse files
committed
Merge bitcoin#25426: net: add new method Sock::GetSockName() that wraps getsockname() and use it in GetBindAddress()
a8d6abb net: change GetBindAddress() to take Sock argument (Vasil Dimov) 748dbcd net: add new method Sock::GetSockName() that wraps getsockname() (Vasil Dimov) Pull request description: _This is a piece of bitcoin#21878, chopped off to ease review._ Wrap the syscall `getsockname()` in `Sock::GetSockName()` and change `GetBindAddress()` to take a `Sock` argument so that it can use the wrapper. This further encapsulates syscalls inside the `Sock` class and makes the callers mockable. ACKs for top commit: laanwj: Code review ACK a8d6abb Tree-SHA512: 3a73463258c0057487fb3fd67215816b03a1c5160f45e45930eaeef86bb3611ec385794cdb08339aa074feba8ad67cd2bfd3836f6cbd40834e15d933214a05dc
2 parents 1b56108 + a8d6abb commit ba29911

File tree

6 files changed

+39
-5
lines changed

6 files changed

+39
-5
lines changed

src/net.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -422,13 +422,13 @@ bool CConnman::CheckIncomingNonce(uint64_t nonce)
422422
}
423423

424424
/** Get the bind address for a socket as CAddress */
425-
static CAddress GetBindAddress(SOCKET sock)
425+
static CAddress GetBindAddress(const Sock& sock)
426426
{
427427
CAddress addr_bind;
428428
struct sockaddr_storage sockaddr_bind;
429429
socklen_t sockaddr_bind_len = sizeof(sockaddr_bind);
430-
if (sock != INVALID_SOCKET) {
431-
if (!getsockname(sock, (struct sockaddr*)&sockaddr_bind, &sockaddr_bind_len)) {
430+
if (sock.Get() != INVALID_SOCKET) {
431+
if (!sock.GetSockName((struct sockaddr*)&sockaddr_bind, &sockaddr_bind_len)) {
432432
addr_bind.SetSockAddr((const struct sockaddr*)&sockaddr_bind);
433433
} else {
434434
LogPrintLevel(BCLog::NET, BCLog::Level::Warning, "getsockname failed\n");
@@ -540,7 +540,7 @@ CNode* CConnman::ConnectNode(CAddress addrConnect, const char *pszDest, bool fCo
540540
NodeId id = GetNewNodeId();
541541
uint64_t nonce = GetDeterministicRandomizer(RANDOMIZER_ID_LOCALHOSTNONCE).Write(id).Finalize();
542542
if (!addr_bind.IsValid()) {
543-
addr_bind = GetBindAddress(sock->Get());
543+
addr_bind = GetBindAddress(*sock);
544544
}
545545
CNode* pnode = new CNode(id,
546546
nLocalServices,
@@ -1154,7 +1154,7 @@ void CConnman::AcceptConnection(const ListenSocket& hListenSocket) {
11541154
addr = CAddress{MaybeFlipIPv6toCJDNS(addr), NODE_NONE};
11551155
}
11561156

1157-
const CAddress addr_bind{MaybeFlipIPv6toCJDNS(GetBindAddress(sock->Get())), NODE_NONE};
1157+
const CAddress addr_bind{MaybeFlipIPv6toCJDNS(GetBindAddress(*sock)), NODE_NONE};
11581158

11591159
NetPermissionFlags permissionFlags = NetPermissionFlags::None;
11601160
hListenSocket.AddSocketPermissionFlags(permissionFlags);

src/test/fuzz/util.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,20 @@ int FuzzedSock::SetSockOpt(int, int, const void*, socklen_t) const
201201
return 0;
202202
}
203203

204+
int FuzzedSock::GetSockName(sockaddr* name, socklen_t* name_len) const
205+
{
206+
constexpr std::array getsockname_errnos{
207+
ECONNRESET,
208+
ENOBUFS,
209+
};
210+
if (m_fuzzed_data_provider.ConsumeBool()) {
211+
SetFuzzedErrNo(m_fuzzed_data_provider, getsockname_errnos);
212+
return -1;
213+
}
214+
*name_len = m_fuzzed_data_provider.ConsumeData(name, *name_len);
215+
return 0;
216+
}
217+
204218
bool FuzzedSock::Wait(std::chrono::milliseconds timeout, Event requested, Event* occurred) const
205219
{
206220
constexpr std::array wait_errnos{

src/test/fuzz/util.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ class FuzzedSock : public Sock
6767

6868
int SetSockOpt(int level, int opt_name, const void* opt_val, socklen_t opt_len) const override;
6969

70+
int GetSockName(sockaddr* name, socklen_t* name_len) const override;
71+
7072
bool Wait(std::chrono::milliseconds timeout, Event requested, Event* occurred = nullptr) const override;
7173

7274
bool WaitMany(std::chrono::milliseconds timeout, EventsPerSock& events_per_sock) const override;

src/test/util/net.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,12 @@ class StaticContentsSock : public Sock
147147

148148
int SetSockOpt(int, int, const void*, socklen_t) const override { return 0; }
149149

150+
int GetSockName(sockaddr* name, socklen_t* name_len) const override
151+
{
152+
std::memset(name, 0x0, *name_len);
153+
return 0;
154+
}
155+
150156
bool Wait(std::chrono::milliseconds timeout,
151157
Event requested,
152158
Event* occurred = nullptr) const override

src/util/sock.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,11 @@ int Sock::SetSockOpt(int level, int opt_name, const void* opt_val, socklen_t opt
102102
return setsockopt(m_socket, level, opt_name, static_cast<const char*>(opt_val), opt_len);
103103
}
104104

105+
int Sock::GetSockName(sockaddr* name, socklen_t* name_len) const
106+
{
107+
return getsockname(m_socket, name, name_len);
108+
}
109+
105110
bool Sock::Wait(std::chrono::milliseconds timeout, Event requested, Event* occurred) const
106111
{
107112
// We need a `shared_ptr` owning `this` for `WaitMany()`, but don't want

src/util/sock.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,13 @@ class Sock
114114
const void* opt_val,
115115
socklen_t opt_len) const;
116116

117+
/**
118+
* getsockname(2) wrapper. Equivalent to
119+
* `getsockname(this->Get(), name, name_len)`. Code that uses this
120+
* wrapper can be unit tested if this method is overridden by a mock Sock implementation.
121+
*/
122+
[[nodiscard]] virtual int GetSockName(sockaddr* name, socklen_t* name_len) const;
123+
117124
using Event = uint8_t;
118125

119126
/**

0 commit comments

Comments
 (0)