blob: 7b11780d1eae8b2d6ee0d6a2607e043306396a39 [file] [log] [blame]
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001/*
2 * Copyright 2004 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
Steve Anton10542f22019-01-11 09:11:00 -080011#ifndef RTC_BASE_PHYSICAL_SOCKET_SERVER_H_
12#define RTC_BASE_PHYSICAL_SOCKET_SERVER_H_
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000013
Markus Handell9a21c492022-08-25 11:40:13 +000014#include "api/units/time_delta.h"
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020015#if defined(WEBRTC_POSIX) && defined(WEBRTC_LINUX)
16#include <sys/epoll.h>
17#define WEBRTC_USE_EPOLL 1
18#endif
jbauchde4db112017-05-31 13:09:18 -070019
Markus Handellb7c63ab2020-05-26 18:09:55 +020020#include <array>
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020021#include <memory>
Taylor Brandstetter7b69a442020-08-20 23:43:13 +000022#include <unordered_map>
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020023#include <vector>
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000024
Mirko Bonadeie5f4c6b2021-01-15 10:41:01 +010025#include "rtc_base/async_resolver.h"
26#include "rtc_base/async_resolver_interface.h"
Markus Handell3cb525b2020-07-16 16:16:09 +020027#include "rtc_base/deprecated/recursive_critical_section.h"
Steve Anton10542f22019-01-11 09:11:00 -080028#include "rtc_base/socket_server.h"
Niels Möller6d176022021-02-09 14:44:48 +010029#include "rtc_base/synchronization/mutex.h"
Mirko Bonadei35214fc2019-09-23 14:54:28 +020030#include "rtc_base/system/rtc_export.h"
Niels Möller8ce078d2020-05-18 10:17:41 +020031#include "rtc_base/thread_annotations.h"
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020032
33#if defined(WEBRTC_POSIX)
34typedef int SOCKET;
Yves Gerey665174f2018-06-19 15:03:05 +020035#endif // WEBRTC_POSIX
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020036
37namespace rtc {
38
39// Event constants for the Dispatcher class.
40enum DispatcherEvent {
Yves Gerey665174f2018-06-19 15:03:05 +020041 DE_READ = 0x0001,
42 DE_WRITE = 0x0002,
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020043 DE_CONNECT = 0x0004,
Yves Gerey665174f2018-06-19 15:03:05 +020044 DE_CLOSE = 0x0008,
45 DE_ACCEPT = 0x0010,
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020046};
47
48class Signaler;
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020049
50class Dispatcher {
51 public:
52 virtual ~Dispatcher() {}
53 virtual uint32_t GetRequestedEvents() = 0;
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020054 virtual void OnEvent(uint32_t ff, int err) = 0;
55#if defined(WEBRTC_WIN)
56 virtual WSAEVENT GetWSAEvent() = 0;
57 virtual SOCKET GetSocket() = 0;
58 virtual bool CheckSignalClose() = 0;
59#elif defined(WEBRTC_POSIX)
60 virtual int GetDescriptor() = 0;
61 virtual bool IsDescriptorClosed() = 0;
62#endif
63};
64
65// A socket server that provides the real sockets of the underlying OS.
Mirko Bonadei35214fc2019-09-23 14:54:28 +020066class RTC_EXPORT PhysicalSocketServer : public SocketServer {
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020067 public:
68 PhysicalSocketServer();
69 ~PhysicalSocketServer() override;
70
71 // SocketFactory:
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020072 Socket* CreateSocket(int family, int type) override;
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020073
74 // Internal Factory for Accept (virtual so it can be overwritten in tests).
Niels Möllerd0b88792021-08-12 10:32:30 +020075 virtual Socket* WrapSocket(SOCKET s);
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020076
77 // SocketServer:
Markus Handell9a21c492022-08-25 11:40:13 +000078 bool Wait(webrtc::TimeDelta max_wait_duration, bool process_io) override;
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020079 void WakeUp() override;
80
81 void Add(Dispatcher* dispatcher);
82 void Remove(Dispatcher* dispatcher);
83 void Update(Dispatcher* dispatcher);
84
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020085 private:
Markus Handellb7c63ab2020-05-26 18:09:55 +020086 // The number of events to process with one call to "epoll_wait".
87 static constexpr size_t kNumEpollEvents = 128;
Markus Handell9a21c492022-08-25 11:40:13 +000088 // A local historical definition of "foreverness", in milliseconds.
89 static constexpr int kForeverMs = -1;
Markus Handellb7c63ab2020-05-26 18:09:55 +020090
Markus Handell9a21c492022-08-25 11:40:13 +000091 static int ToCmsWait(webrtc::TimeDelta max_wait_duration);
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020092#if defined(WEBRTC_POSIX)
Markus Handell9a21c492022-08-25 11:40:13 +000093 bool WaitSelect(int cmsWait, bool process_io);
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020094#endif // WEBRTC_POSIX
95#if defined(WEBRTC_USE_EPOLL)
Taylor Brandstetter7b69a442020-08-20 23:43:13 +000096 void AddEpoll(Dispatcher* dispatcher, uint64_t key);
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020097 void RemoveEpoll(Dispatcher* dispatcher);
Taylor Brandstetter7b69a442020-08-20 23:43:13 +000098 void UpdateEpoll(Dispatcher* dispatcher, uint64_t key);
Markus Handell9a21c492022-08-25 11:40:13 +000099 bool WaitEpoll(int cmsWait);
100 bool WaitPoll(int cmsWait, Dispatcher* dispatcher);
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200101
Markus Handellb7c63ab2020-05-26 18:09:55 +0200102 // This array is accessed in isolation by a thread calling into Wait().
103 // It's useless to use a SequenceChecker to guard it because a socket
104 // server can outlive the thread it's bound to, forcing the Wait call
105 // to have to reset the sequence checker on Wait calls.
106 std::array<epoll_event, kNumEpollEvents> epoll_events_;
Niels Möller611fba42020-05-13 14:42:22 +0200107 const int epoll_fd_ = INVALID_SOCKET;
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200108#endif // WEBRTC_USE_EPOLL
Taylor Brandstetter7b69a442020-08-20 23:43:13 +0000109 // uint64_t keys are used to uniquely identify a dispatcher in order to avoid
110 // the ABA problem during the epoll loop (a dispatcher being destroyed and
111 // replaced by one with the same address).
112 uint64_t next_dispatcher_key_ RTC_GUARDED_BY(crit_) = 0;
113 std::unordered_map<uint64_t, Dispatcher*> dispatcher_by_key_
114 RTC_GUARDED_BY(crit_);
115 // Reverse lookup necessary for removals/updates.
116 std::unordered_map<Dispatcher*, uint64_t> key_by_dispatcher_
117 RTC_GUARDED_BY(crit_);
118 // A list of dispatcher keys that we're interested in for the current
119 // select() or WSAWaitForMultipleEvents() loop. Again, used to avoid the ABA
120 // problem (a socket being destroyed and a new one created with the same
121 // handle, erroneously receiving the events from the destroyed socket).
122 //
123 // Kept as a member variable just for efficiency.
124 std::vector<uint64_t> current_dispatcher_keys_;
Niels Möller8ce078d2020-05-18 10:17:41 +0200125 Signaler* signal_wakeup_; // Assigned in constructor only
Markus Handell3cb525b2020-07-16 16:16:09 +0200126 RecursiveCriticalSection crit_;
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200127#if defined(WEBRTC_WIN)
Niels Möller611fba42020-05-13 14:42:22 +0200128 const WSAEVENT socket_ev_;
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200129#endif
Niels Möller611fba42020-05-13 14:42:22 +0200130 bool fWait_;
Taylor Brandstetter7b69a442020-08-20 23:43:13 +0000131 // Are we currently in a select()/epoll()/WSAWaitForMultipleEvents loop?
132 // Used for a DCHECK, because we don't support reentrant waiting.
133 bool waiting_ = false;
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200134};
135
Niels Möllerd0b88792021-08-12 10:32:30 +0200136class PhysicalSocket : public Socket, public sigslot::has_slots<> {
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200137 public:
138 PhysicalSocket(PhysicalSocketServer* ss, SOCKET s = INVALID_SOCKET);
139 ~PhysicalSocket() override;
140
141 // Creates the underlying OS socket (same as the "socket" function).
142 virtual bool Create(int family, int type);
143
144 SocketAddress GetLocalAddress() const override;
145 SocketAddress GetRemoteAddress() const override;
146
147 int Bind(const SocketAddress& bind_addr) override;
148 int Connect(const SocketAddress& addr) override;
149
150 int GetError() const override;
151 void SetError(int error) override;
152
153 ConnState GetState() const override;
154
155 int GetOption(Option opt, int* value) override;
156 int SetOption(Option opt, int value) override;
157
158 int Send(const void* pv, size_t cb) override;
159 int SendTo(const void* buffer,
160 size_t length,
161 const SocketAddress& addr) override;
162
163 int Recv(void* buffer, size_t length, int64_t* timestamp) override;
164 int RecvFrom(void* buffer,
165 size_t length,
166 SocketAddress* out_addr,
167 int64_t* timestamp) override;
168
169 int Listen(int backlog) override;
Niels Möllerd0b88792021-08-12 10:32:30 +0200170 Socket* Accept(SocketAddress* out_addr) override;
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200171
172 int Close() override;
173
174 SocketServer* socketserver() { return ss_; }
175
Artem Titov32740512023-01-26 12:54:49 +0100176 SOCKET GetSocketFD() const { return s_; }
177
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200178 protected:
179 int DoConnect(const SocketAddress& connect_addr);
180
181 // Make virtual so ::accept can be overwritten in tests.
182 virtual SOCKET DoAccept(SOCKET socket, sockaddr* addr, socklen_t* addrlen);
183
184 // Make virtual so ::send can be overwritten in tests.
185 virtual int DoSend(SOCKET socket, const char* buf, int len, int flags);
186
187 // Make virtual so ::sendto can be overwritten in tests.
Yves Gerey665174f2018-06-19 15:03:05 +0200188 virtual int DoSendTo(SOCKET socket,
189 const char* buf,
190 int len,
191 int flags,
192 const struct sockaddr* dest_addr,
193 socklen_t addrlen);
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200194
Per Kjellanderfdcfefa2022-11-08 12:48:52 +0100195 int DoReadFromSocket(void* buffer,
196 size_t length,
197 SocketAddress* out_addr,
198 int64_t* timestamp);
199
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200200 void OnResolveResult(AsyncResolverInterface* resolver);
201
202 void UpdateLastError();
203 void MaybeRemapSendError();
204
205 uint8_t enabled_events() const { return enabled_events_; }
206 virtual void SetEnabledEvents(uint8_t events);
207 virtual void EnableEvents(uint8_t events);
208 virtual void DisableEvents(uint8_t events);
209
Taylor Brandstetterecd6fc82020-02-05 17:26:37 -0800210 int TranslateOption(Option opt, int* slevel, int* sopt);
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200211
212 PhysicalSocketServer* ss_;
213 SOCKET s_;
214 bool udp_;
Taylor Brandstetterecd6fc82020-02-05 17:26:37 -0800215 int family_ = 0;
Niels Möller6d176022021-02-09 14:44:48 +0100216 mutable webrtc::Mutex mutex_;
217 int error_ RTC_GUARDED_BY(mutex_);
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200218 ConnState state_;
219 AsyncResolver* resolver_;
220
221#if !defined(NDEBUG)
222 std::string dbg_addr_;
223#endif
224
225 private:
Per Kjellanderfdcfefa2022-11-08 12:48:52 +0100226 const bool read_scm_timestamp_experiment_;
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200227 uint8_t enabled_events_ = 0;
228};
229
230class SocketDispatcher : public Dispatcher, public PhysicalSocket {
231 public:
Yves Gerey665174f2018-06-19 15:03:05 +0200232 explicit SocketDispatcher(PhysicalSocketServer* ss);
233 SocketDispatcher(SOCKET s, PhysicalSocketServer* ss);
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200234 ~SocketDispatcher() override;
235
236 bool Initialize();
237
238 virtual bool Create(int type);
239 bool Create(int family, int type) override;
240
241#if defined(WEBRTC_WIN)
242 WSAEVENT GetWSAEvent() override;
243 SOCKET GetSocket() override;
244 bool CheckSignalClose() override;
245#elif defined(WEBRTC_POSIX)
246 int GetDescriptor() override;
247 bool IsDescriptorClosed() override;
248#endif
249
250 uint32_t GetRequestedEvents() override;
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200251 void OnEvent(uint32_t ff, int err) override;
252
253 int Close() override;
254
255#if defined(WEBRTC_USE_EPOLL)
256 protected:
257 void StartBatchedEventUpdates();
258 void FinishBatchedEventUpdates();
259
260 void SetEnabledEvents(uint8_t events) override;
261 void EnableEvents(uint8_t events) override;
262 void DisableEvents(uint8_t events) override;
263#endif
264
265 private:
266#if defined(WEBRTC_WIN)
267 static int next_id_;
268 int id_;
269 bool signal_close_;
270 int signal_err_;
Yves Gerey665174f2018-06-19 15:03:05 +0200271#endif // WEBRTC_WIN
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200272#if defined(WEBRTC_USE_EPOLL)
273 void MaybeUpdateDispatcher(uint8_t old_events);
274
275 int saved_enabled_events_ = -1;
276#endif
277};
278
Yves Gerey665174f2018-06-19 15:03:05 +0200279} // namespace rtc
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200280
Steve Anton10542f22019-01-11 09:11:00 -0800281#endif // RTC_BASE_PHYSICAL_SOCKET_SERVER_H_