Coverage Report

Created: 2026-10-24 08:16

/work/testing/support/doubles/fake_sockets.hh
Line
Count
Source (jump to first uncovered line)
1
#ifndef C_TOXCORE_TESTING_SUPPORT_DOUBLES_FAKE_SOCKETS_H
2
#define C_TOXCORE_TESTING_SUPPORT_DOUBLES_FAKE_SOCKETS_H
3
4
#include <atomic>
5
#include <cstddef>
6
#include <cstdint>
7
#include <deque>
8
#include <functional>
9
#include <memory>
10
#include <mutex>
11
#include <optional>
12
#include <vector>
13
14
#ifdef _WIN32
15
#define WIN32_LEAN_AND_MEAN
16
#define NOMINMAX
17
#include <winsock2.h>
18
#else
19
#include <sys/socket.h>
20
#endif
21
22
#include "../../../toxcore/attributes.h"
23
#include "../../../toxcore/network.h"
24
25
namespace tox::test {
26
27
class NetworkUniverse;
28
struct Packet;
29
30
/**
31
 * @brief Abstract base class for all fake sockets.
32
 */
33
class FakeSocket {
34
public:
35
    FakeSocket(NetworkUniverse &universe, int type);
36
    virtual ~FakeSocket();
37
38
    virtual int bind(const IP_Port *_Nonnull addr) = 0;
39
    virtual int connect(const IP_Port *_Nonnull addr) = 0;
40
    virtual int listen(int backlog) = 0;
41
    virtual std::unique_ptr<FakeSocket> accept(IP_Port *_Nullable addr) = 0;
42
43
    virtual int send(const uint8_t *_Nonnull buf, std::size_t len) = 0;
44
    virtual int recv(uint8_t *_Nonnull buf, std::size_t len) = 0;
45
46
0
    virtual std::size_t recv_buffer_size() { return 0; }
47
0
    virtual bool is_readable() { return recv_buffer_size() > 0; }
48
0
    virtual bool is_writable() { return true; }
49
50
    virtual int sendto(const uint8_t *_Nonnull buf, std::size_t len, const IP_Port *_Nonnull addr)
51
        = 0;
52
    virtual int recvfrom(uint8_t *_Nonnull buf, std::size_t len, IP_Port *_Nonnull addr) = 0;
53
54
    virtual int getsockopt(
55
        int level, int optname, void *_Nonnull optval, std::size_t *_Nonnull optlen);
56
    virtual int setsockopt(int level, int optname, const void *_Nonnull optval, std::size_t optlen);
57
    virtual int socket_nonblock(bool nonblock);
58
59
    virtual int close();
60
61
0
    bool is_nonblocking() const { return nonblocking_; }
62
2.31k
    int type() const { return type_; }
63
2.87k
    uint16_t local_port() const { return local_port_; }
64
0
    const IP &ip_address() const { return ip_; }
65
66
8.92k
    void set_ip(const IP &ip) { ip_ = ip; }
67
68
protected:
69
    NetworkUniverse &universe_;
70
    int type_;
71
    bool nonblocking_ = false;
72
    uint16_t local_port_ = 0;
73
    IP ip_;
74
    std::mutex mutex_;  // Use regular mutex (recursive_mutex not fully supported in MinGW)
75
};
76
77
/**
78
 * @brief Implements UDP logic.
79
 */
80
class FakeUdpSocket : public FakeSocket {
81
public:
82
    static constexpr std::size_t kMaxQueueSize = 1024;
83
84
    explicit FakeUdpSocket(NetworkUniverse &universe);
85
    ~FakeUdpSocket() override;
86
87
    int bind(const IP_Port *_Nonnull addr) override;
88
    int connect(const IP_Port *_Nonnull addr) override;
89
    int listen(int backlog) override;
90
    std::unique_ptr<FakeSocket> accept(IP_Port *_Nullable addr) override;
91
    int close() override;
92
93
    int send(const uint8_t *_Nonnull buf, std::size_t len) override;
94
    int recv(uint8_t *_Nonnull buf, std::size_t len) override;
95
    std::size_t recv_buffer_size() override;
96
97
    int sendto(const uint8_t *_Nonnull buf, std::size_t len, const IP_Port *_Nonnull addr) override;
98
    int recvfrom(uint8_t *_Nonnull buf, std::size_t len, IP_Port *_Nonnull addr) override;
99
100
    // Called by Universe to deliver a packet
101
    void push_packet(std::vector<uint8_t> data, IP_Port from);
102
103
    using PacketSource = std::function<bool(std::vector<uint8_t> &data, IP_Port &from)>;
104
    void set_packet_source(PacketSource source);
105
106
    using RecvObserver = std::function<void(const std::vector<uint8_t> &data, const IP_Port &from)>;
107
    void set_recv_observer(RecvObserver observer);
108
109
private:
110
    void close_impl();
111
112
    struct PendingPacket {
113
        std::vector<uint8_t> data;
114
        IP_Port from;
115
    };
116
    std::deque<PendingPacket> recv_queue_;
117
    PacketSource packet_source_;
118
    RecvObserver recv_observer_;
119
};
120
121
/**
122
 * @brief Implements TCP logic (Simplified for simulation).
123
 *
124
 * Supports:
125
 * - 3-way handshake simulation (instant or delayed)
126
 * - Stream buffering
127
 * - Connection states
128
 */
129
class FakeTcpSocket : public FakeSocket {
130
public:
131
    enum State { CLOSED, LISTEN, SYN_SENT, SYN_RECEIVED, ESTABLISHED, CLOSE_WAIT };
132
133
    static constexpr std::size_t kMaxBufferSize = 1024 * 1024;
134
    static constexpr std::size_t kMaxBacklog = 128;
135
136
    explicit FakeTcpSocket(NetworkUniverse &universe);
137
    ~FakeTcpSocket() override;
138
139
    int bind(const IP_Port *_Nonnull addr) override;
140
    int connect(const IP_Port *_Nonnull addr) override;
141
    int listen(int backlog) override;
142
    std::unique_ptr<FakeSocket> accept(IP_Port *_Nullable addr) override;
143
    int close() override;
144
145
    int send(const uint8_t *_Nonnull buf, std::size_t len) override;
146
    int recv(uint8_t *_Nonnull buf, std::size_t len) override;
147
    std::size_t recv_buffer_size() override;
148
    bool is_readable() override;
149
    bool is_writable() override;
150
151
    int sendto(const uint8_t *_Nonnull buf, std::size_t len, const IP_Port *_Nonnull addr) override;
152
    int recvfrom(uint8_t *_Nonnull buf, std::size_t len, IP_Port *_Nonnull addr) override;
153
154
    int getsockopt(
155
        int level, int optname, void *_Nonnull optval, std::size_t *_Nonnull optlen) override;
156
157
    // Internal events
158
    bool handle_packet(const Packet &p);
159
160
155
    State state() const { return state_; }
161
77
    const IP_Port &remote_addr() const { return remote_addr_; }
162
163
    // Factory for accepting connections
164
    static std::unique_ptr<FakeTcpSocket> create_connected(
165
        NetworkUniverse &universe, const IP_Port &remote, uint16_t local_port);
166
167
private:
168
    void close_impl();
169
170
    State state_ = CLOSED;
171
    IP_Port remote_addr_;
172
    std::deque<uint8_t> recv_buffer_;
173
    std::deque<std::unique_ptr<FakeTcpSocket>> pending_connections_;
174
    int backlog_ = 0;
175
176
    uint32_t next_seq_ = 0;
177
    uint32_t last_ack_ = 0;
178
};
179
180
std::ostream &operator<<(std::ostream &os, FakeTcpSocket::State state);
181
182
}  // namespace tox::test
183
184
#endif  // C_TOXCORE_TESTING_SUPPORT_DOUBLES_FAKE_SOCKETS_H