Skip to content

Commit b586110

Browse files
committed
net: add connect() and getsockopt() wrappers to Sock
Extend the `Sock` class with wrappers to `connect()` and `getsockopt()`. This will make it possible to mock code which uses those.
1 parent 5a887d4 commit b586110

File tree

3 files changed

+66
-2
lines changed

3 files changed

+66
-2
lines changed

src/test/fuzz/util.h

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -685,6 +685,47 @@ class FuzzedSock : public Sock
685685
return random_bytes.size();
686686
}
687687

688+
int Connect(const sockaddr*, socklen_t) const override
689+
{
690+
// Have a permanent error at connect_errnos[0] because when the fuzzed data is exhausted
691+
// SetFuzzedErrNo() will always return the first element and we want to avoid Connect()
692+
// returning -1 and setting errno to EAGAIN repeatedly.
693+
constexpr std::array connect_errnos{
694+
ECONNREFUSED,
695+
EAGAIN,
696+
ECONNRESET,
697+
EHOSTUNREACH,
698+
EINPROGRESS,
699+
EINTR,
700+
ENETUNREACH,
701+
ETIMEDOUT,
702+
};
703+
if (m_fuzzed_data_provider.ConsumeBool()) {
704+
SetFuzzedErrNo(m_fuzzed_data_provider, connect_errnos);
705+
return -1;
706+
}
707+
return 0;
708+
}
709+
710+
int GetSockOpt(int level, int opt_name, void* opt_val, socklen_t* opt_len) const override
711+
{
712+
constexpr std::array getsockopt_errnos{
713+
ENOMEM,
714+
ENOBUFS,
715+
};
716+
if (m_fuzzed_data_provider.ConsumeBool()) {
717+
SetFuzzedErrNo(m_fuzzed_data_provider, getsockopt_errnos);
718+
return -1;
719+
}
720+
if (opt_val == nullptr) {
721+
return 0;
722+
}
723+
std::memcpy(opt_val,
724+
ConsumeFixedLengthByteVector(m_fuzzed_data_provider, *opt_len).data(),
725+
*opt_len);
726+
return 0;
727+
}
728+
688729
bool Wait(std::chrono::milliseconds timeout, Event requested, Event* occurred = nullptr) const override
689730
{
690731
return m_fuzzed_data_provider.ConsumeBool();

src/util/sock.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,16 @@ ssize_t Sock::Recv(void* buf, size_t len, int flags) const
6666
return recv(m_socket, static_cast<char*>(buf), len, flags);
6767
}
6868

69+
int Sock::Connect(const sockaddr* addr, socklen_t addr_len) const
70+
{
71+
return connect(m_socket, addr, addr_len);
72+
}
73+
74+
int Sock::GetSockOpt(int level, int opt_name, void* opt_val, socklen_t* opt_len) const
75+
{
76+
return getsockopt(m_socket, level, opt_name, static_cast<char*>(opt_val), opt_len);
77+
}
78+
6979
bool Sock::Wait(std::chrono::milliseconds timeout, Event requested, Event* occurred) const
7080
{
7181
#ifdef USE_POLL

src/util/sock.h

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,16 +80,29 @@ class Sock
8080

8181
/**
8282
* send(2) wrapper. Equivalent to `send(this->Get(), data, len, flags);`. Code that uses this
83-
* wrapper can be unit-tested if this method is overridden by a mock Sock implementation.
83+
* wrapper can be unit tested if this method is overridden by a mock Sock implementation.
8484
*/
8585
virtual ssize_t Send(const void* data, size_t len, int flags) const;
8686

8787
/**
8888
* recv(2) wrapper. Equivalent to `recv(this->Get(), buf, len, flags);`. Code that uses this
89-
* wrapper can be unit-tested if this method is overridden by a mock Sock implementation.
89+
* wrapper can be unit tested if this method is overridden by a mock Sock implementation.
9090
*/
9191
virtual ssize_t Recv(void* buf, size_t len, int flags) const;
9292

93+
/**
94+
* connect(2) wrapper. Equivalent to `connect(this->Get(), addr, addrlen)`. Code that uses this
95+
* wrapper can be unit tested if this method is overridden by a mock Sock implementation.
96+
*/
97+
virtual int Connect(const sockaddr* addr, socklen_t addr_len) const;
98+
99+
/**
100+
* getsockopt(2) wrapper. Equivalent to
101+
* `getsockopt(this->Get(), level, opt_name, opt_val, opt_len)`. Code that uses this
102+
* wrapper can be unit tested if this method is overridden by a mock Sock implementation.
103+
*/
104+
virtual int GetSockOpt(int level, int opt_name, void* opt_val, socklen_t* opt_len) const;
105+
93106
using Event = uint8_t;
94107

95108
/**

0 commit comments

Comments
 (0)