1 /*
2 * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include "test/network/fake_network_socket_server.h"
12
13 #include <algorithm>
14 #include <string>
15 #include <utility>
16 #include <vector>
17
18 #include "absl/algorithm/container.h"
19 #include "api/scoped_refptr.h"
20 #include "api/task_queue/pending_task_safety_flag.h"
21 #include "rtc_base/event.h"
22 #include "rtc_base/logging.h"
23 #include "rtc_base/thread.h"
24
25 namespace webrtc {
26 namespace test {
27 namespace {
ToString(const rtc::SocketAddress & addr)28 std::string ToString(const rtc::SocketAddress& addr) {
29 return addr.HostAsURIString() + ":" + std::to_string(addr.port());
30 }
31
32 } // namespace
33
34 // Represents a socket, which will operate with emulated network.
35 class FakeNetworkSocket : public rtc::Socket,
36 public EmulatedNetworkReceiverInterface {
37 public:
38 explicit FakeNetworkSocket(FakeNetworkSocketServer* scoket_manager,
39 rtc::Thread* thread);
40 ~FakeNetworkSocket() override;
41
42 // Will be invoked by EmulatedEndpoint to deliver packets into this socket.
43 void OnPacketReceived(EmulatedIpPacket packet) override;
44
45 // rtc::Socket methods:
46 rtc::SocketAddress GetLocalAddress() const override;
47 rtc::SocketAddress GetRemoteAddress() const override;
48 int Bind(const rtc::SocketAddress& addr) override;
49 int Connect(const rtc::SocketAddress& addr) override;
50 int Close() override;
51 int Send(const void* pv, size_t cb) override;
52 int SendTo(const void* pv,
53 size_t cb,
54 const rtc::SocketAddress& addr) override;
55 int Recv(void* pv, size_t cb, int64_t* timestamp) override;
56 int RecvFrom(void* pv,
57 size_t cb,
58 rtc::SocketAddress* paddr,
59 int64_t* timestamp) override;
60 int Listen(int backlog) override;
61 rtc::Socket* Accept(rtc::SocketAddress* paddr) override;
62 int GetError() const override;
63 void SetError(int error) override;
64 ConnState GetState() const override;
65 int GetOption(Option opt, int* value) override;
66 int SetOption(Option opt, int value) override;
67
68 private:
69 FakeNetworkSocketServer* const socket_server_;
70 rtc::Thread* const thread_;
71 EmulatedEndpointImpl* endpoint_ RTC_GUARDED_BY(&thread_);
72 rtc::SocketAddress local_addr_ RTC_GUARDED_BY(&thread_);
73 rtc::SocketAddress remote_addr_ RTC_GUARDED_BY(&thread_);
74 ConnState state_ RTC_GUARDED_BY(&thread_);
75 int error_ RTC_GUARDED_BY(&thread_);
76 std::map<Option, int> options_map_ RTC_GUARDED_BY(&thread_);
77
78 absl::optional<EmulatedIpPacket> pending_ RTC_GUARDED_BY(thread_);
79 rtc::scoped_refptr<PendingTaskSafetyFlag> alive_;
80 };
81
FakeNetworkSocket(FakeNetworkSocketServer * socket_server,rtc::Thread * thread)82 FakeNetworkSocket::FakeNetworkSocket(FakeNetworkSocketServer* socket_server,
83 rtc::Thread* thread)
84 : socket_server_(socket_server),
85 thread_(thread),
86 state_(CS_CLOSED),
87 error_(0),
88 alive_(PendingTaskSafetyFlag::Create()) {}
89
~FakeNetworkSocket()90 FakeNetworkSocket::~FakeNetworkSocket() {
91 // Abandon all pending packets.
92 alive_->SetNotAlive();
93
94 Close();
95 socket_server_->Unregister(this);
96 }
97
OnPacketReceived(EmulatedIpPacket packet)98 void FakeNetworkSocket::OnPacketReceived(EmulatedIpPacket packet) {
99 auto task = [this, packet = std::move(packet)]() mutable {
100 RTC_DCHECK_RUN_ON(thread_);
101 if (!endpoint_->Enabled())
102 return;
103 RTC_DCHECK(!pending_);
104 pending_ = std::move(packet);
105 // Note that we expect that this will trigger exactly one call to RecvFrom()
106 // where pending_packet will be read and reset. This call is done without
107 // any thread switch (see AsyncUDPSocket::OnReadEvent) so it's safe to
108 // assume that SignalReadEvent() will block until the packet has been read.
109 SignalReadEvent(this);
110 RTC_DCHECK(!pending_);
111 };
112 thread_->PostTask(SafeTask(alive_, std::move(task)));
113 socket_server_->WakeUp();
114 }
115
116
GetLocalAddress() const117 rtc::SocketAddress FakeNetworkSocket::GetLocalAddress() const {
118 RTC_DCHECK_RUN_ON(thread_);
119 return local_addr_;
120 }
121
GetRemoteAddress() const122 rtc::SocketAddress FakeNetworkSocket::GetRemoteAddress() const {
123 RTC_DCHECK_RUN_ON(thread_);
124 return remote_addr_;
125 }
126
Bind(const rtc::SocketAddress & addr)127 int FakeNetworkSocket::Bind(const rtc::SocketAddress& addr) {
128 RTC_DCHECK_RUN_ON(thread_);
129 RTC_CHECK(local_addr_.IsNil())
130 << "Socket already bound to address: " << ToString(local_addr_);
131 local_addr_ = addr;
132 endpoint_ = socket_server_->GetEndpointNode(local_addr_.ipaddr());
133 if (!endpoint_) {
134 local_addr_.Clear();
135 RTC_LOG(LS_INFO) << "No endpoint for address: " << ToString(addr);
136 error_ = EADDRNOTAVAIL;
137 return 2;
138 }
139 absl::optional<uint16_t> port =
140 endpoint_->BindReceiver(local_addr_.port(), this);
141 if (!port) {
142 local_addr_.Clear();
143 RTC_LOG(LS_INFO) << "Cannot bind to in-use address: " << ToString(addr);
144 error_ = EADDRINUSE;
145 return 1;
146 }
147 local_addr_.SetPort(port.value());
148 return 0;
149 }
150
Connect(const rtc::SocketAddress & addr)151 int FakeNetworkSocket::Connect(const rtc::SocketAddress& addr) {
152 RTC_DCHECK_RUN_ON(thread_);
153 RTC_CHECK(remote_addr_.IsNil())
154 << "Socket already connected to address: " << ToString(remote_addr_);
155 RTC_CHECK(!local_addr_.IsNil())
156 << "Socket have to be bind to some local address";
157 remote_addr_ = addr;
158 state_ = CS_CONNECTED;
159 return 0;
160 }
161
Send(const void * pv,size_t cb)162 int FakeNetworkSocket::Send(const void* pv, size_t cb) {
163 RTC_DCHECK_RUN_ON(thread_);
164 RTC_CHECK(state_ == CS_CONNECTED) << "Socket cannot send: not connected";
165 return SendTo(pv, cb, remote_addr_);
166 }
167
SendTo(const void * pv,size_t cb,const rtc::SocketAddress & addr)168 int FakeNetworkSocket::SendTo(const void* pv,
169 size_t cb,
170 const rtc::SocketAddress& addr) {
171 RTC_DCHECK_RUN_ON(thread_);
172 RTC_CHECK(!local_addr_.IsNil())
173 << "Socket have to be bind to some local address";
174 if (!endpoint_->Enabled()) {
175 error_ = ENETDOWN;
176 return -1;
177 }
178 rtc::CopyOnWriteBuffer packet(static_cast<const uint8_t*>(pv), cb);
179 endpoint_->SendPacket(local_addr_, addr, packet);
180 return cb;
181 }
182
Recv(void * pv,size_t cb,int64_t * timestamp)183 int FakeNetworkSocket::Recv(void* pv, size_t cb, int64_t* timestamp) {
184 rtc::SocketAddress paddr;
185 return RecvFrom(pv, cb, &paddr, timestamp);
186 }
187
188 // Reads 1 packet from internal queue. Reads up to `cb` bytes into `pv`
189 // and returns the length of received packet.
RecvFrom(void * pv,size_t cb,rtc::SocketAddress * paddr,int64_t * timestamp)190 int FakeNetworkSocket::RecvFrom(void* pv,
191 size_t cb,
192 rtc::SocketAddress* paddr,
193 int64_t* timestamp) {
194 RTC_DCHECK_RUN_ON(thread_);
195
196 if (timestamp) {
197 *timestamp = -1;
198 }
199 RTC_CHECK(pending_);
200
201 *paddr = pending_->from;
202 size_t data_read = std::min(cb, pending_->size());
203 memcpy(pv, pending_->cdata(), data_read);
204 *timestamp = pending_->arrival_time.us();
205
206 // According to RECV(2) Linux Man page
207 // real socket will discard data, that won't fit into provided buffer,
208 // but we won't to skip such error, so we will assert here.
209 RTC_CHECK(data_read == pending_->size())
210 << "Too small buffer is provided for socket read. "
211 "Received data size: "
212 << pending_->size() << "; Provided buffer size: " << cb;
213
214 pending_.reset();
215
216 // According to RECV(2) Linux Man page
217 // real socket will return message length, not data read. In our case it is
218 // actually the same value.
219 return static_cast<int>(data_read);
220 }
221
Listen(int backlog)222 int FakeNetworkSocket::Listen(int backlog) {
223 RTC_CHECK(false) << "Listen() isn't valid for SOCK_DGRAM";
224 }
225
Accept(rtc::SocketAddress *)226 rtc::Socket* FakeNetworkSocket::Accept(rtc::SocketAddress* /*paddr*/) {
227 RTC_CHECK(false) << "Accept() isn't valid for SOCK_DGRAM";
228 }
229
Close()230 int FakeNetworkSocket::Close() {
231 RTC_DCHECK_RUN_ON(thread_);
232 state_ = CS_CLOSED;
233 if (!local_addr_.IsNil()) {
234 endpoint_->UnbindReceiver(local_addr_.port());
235 }
236 local_addr_.Clear();
237 remote_addr_.Clear();
238 return 0;
239 }
240
GetError() const241 int FakeNetworkSocket::GetError() const {
242 RTC_DCHECK_RUN_ON(thread_);
243 return error_;
244 }
245
SetError(int error)246 void FakeNetworkSocket::SetError(int error) {
247 RTC_DCHECK_RUN_ON(thread_);
248 RTC_CHECK(error == 0);
249 error_ = error;
250 }
251
GetState() const252 rtc::Socket::ConnState FakeNetworkSocket::GetState() const {
253 RTC_DCHECK_RUN_ON(thread_);
254 return state_;
255 }
256
GetOption(Option opt,int * value)257 int FakeNetworkSocket::GetOption(Option opt, int* value) {
258 RTC_DCHECK_RUN_ON(thread_);
259 auto it = options_map_.find(opt);
260 if (it == options_map_.end()) {
261 return -1;
262 }
263 *value = it->second;
264 return 0;
265 }
266
SetOption(Option opt,int value)267 int FakeNetworkSocket::SetOption(Option opt, int value) {
268 RTC_DCHECK_RUN_ON(thread_);
269 options_map_[opt] = value;
270 return 0;
271 }
272
FakeNetworkSocketServer(EndpointsContainer * endpoints_container)273 FakeNetworkSocketServer::FakeNetworkSocketServer(
274 EndpointsContainer* endpoints_container)
275 : endpoints_container_(endpoints_container),
276 wakeup_(/*manual_reset=*/false, /*initially_signaled=*/false) {}
277 FakeNetworkSocketServer::~FakeNetworkSocketServer() = default;
278
GetEndpointNode(const rtc::IPAddress & ip)279 EmulatedEndpointImpl* FakeNetworkSocketServer::GetEndpointNode(
280 const rtc::IPAddress& ip) {
281 return endpoints_container_->LookupByLocalAddress(ip);
282 }
283
Unregister(FakeNetworkSocket * socket)284 void FakeNetworkSocketServer::Unregister(FakeNetworkSocket* socket) {
285 MutexLock lock(&lock_);
286 sockets_.erase(absl::c_find(sockets_, socket));
287 }
288
CreateSocket(int family,int type)289 rtc::Socket* FakeNetworkSocketServer::CreateSocket(int family, int type) {
290 RTC_DCHECK(family == AF_INET || family == AF_INET6);
291 // We support only UDP sockets for now.
292 RTC_DCHECK(type == SOCK_DGRAM) << "Only UDP sockets are supported";
293 RTC_DCHECK(thread_) << "must be attached to thread before creating sockets";
294 FakeNetworkSocket* out = new FakeNetworkSocket(this, thread_);
295 {
296 MutexLock lock(&lock_);
297 sockets_.push_back(out);
298 }
299 return out;
300 }
301
SetMessageQueue(rtc::Thread * thread)302 void FakeNetworkSocketServer::SetMessageQueue(rtc::Thread* thread) {
303 thread_ = thread;
304 }
305
306 // Always returns true (if return false, it won't be invoked again...)
Wait(webrtc::TimeDelta max_wait_duration,bool process_io)307 bool FakeNetworkSocketServer::Wait(webrtc::TimeDelta max_wait_duration,
308 bool process_io) {
309 RTC_DCHECK(thread_ == rtc::Thread::Current());
310 if (!max_wait_duration.IsZero())
311 wakeup_.Wait(max_wait_duration);
312
313 return true;
314 }
315
WakeUp()316 void FakeNetworkSocketServer::WakeUp() {
317 wakeup_.Set();
318 }
319
320
321 } // namespace test
322 } // namespace webrtc
323