blob: 3bab75a40b9d0bc0792f7f0882bb1b0b847d6323 [file] [log] [blame]
henrike@webrtc.orgf0488722014-05-13 18:00:261/*
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 17:11:0011#ifndef RTC_BASE_PHYSICAL_SOCKET_SERVER_H_
12#define RTC_BASE_PHYSICAL_SOCKET_SERVER_H_
henrike@webrtc.orgf0488722014-05-13 18:00:2613
Harald Alvestrand60362c12023-10-10 11:30:1814#include "api/async_dns_resolver.h"
Markus Handell9a21c492022-08-25 11:40:1315#include "api/units/time_delta.h"
Harald Alvestrand60362c12023-10-10 11:30:1816#include "rtc_base/socket.h"
17#include "rtc_base/socket_address.h"
18#include "rtc_base/third_party/sigslot/sigslot.h"
Taylor Brandstetter51366002023-03-14 23:45:4919
20#if defined(WEBRTC_POSIX)
21#if defined(WEBRTC_LINUX)
22// On Linux, use epoll.
Henrik Kjellanderec78f1c2017-06-29 05:52:5023#include <sys/epoll.h>
Harald Alvestrand60362c12023-10-10 11:30:1824
Henrik Kjellanderec78f1c2017-06-29 05:52:5025#define WEBRTC_USE_EPOLL 1
Byoungchan Leed86c0cd2024-04-16 02:06:0826#elif defined(WEBRTC_FUCHSIA) || defined(WEBRTC_MAC)
Taylor Brandstetter51366002023-03-14 23:45:4927// Fuchsia implements select and poll but not epoll, and testing shows that poll
28// is faster than select.
29#include <poll.h>
Harald Alvestrand60362c12023-10-10 11:30:1830
Taylor Brandstetter51366002023-03-14 23:45:4931#define WEBRTC_USE_POLL 1
32#else
33// On other POSIX systems, use select by default.
Byoungchan Leed86c0cd2024-04-16 02:06:0834#endif // WEBRTC_LINUX, WEBRTC_FUCHSIA, WEBRTC_MAC
Taylor Brandstetter51366002023-03-14 23:45:4935#endif // WEBRTC_POSIX
jbauchde4db112017-05-31 20:09:1836
Markus Handellb7c63ab2020-05-26 16:09:5537#include <array>
Harald Alvestrand60362c12023-10-10 11:30:1838#include <cstdint>
Henrik Kjellanderec78f1c2017-06-29 05:52:5039#include <memory>
Harald Alvestrand60362c12023-10-10 11:30:1840#include <string>
Taylor Brandstetter7b69a442020-08-20 23:43:1341#include <unordered_map>
Henrik Kjellanderec78f1c2017-06-29 05:52:5042#include <vector>
henrike@webrtc.orgf0488722014-05-13 18:00:2643
Markus Handell3cb525b2020-07-16 14:16:0944#include "rtc_base/deprecated/recursive_critical_section.h"
Steve Anton10542f22019-01-11 17:11:0045#include "rtc_base/socket_server.h"
Niels Möller6d176022021-02-09 13:44:4846#include "rtc_base/synchronization/mutex.h"
Mirko Bonadei35214fc2019-09-23 12:54:2847#include "rtc_base/system/rtc_export.h"
Niels Möller8ce078d2020-05-18 08:17:4148#include "rtc_base/thread_annotations.h"
Henrik Kjellanderec78f1c2017-06-29 05:52:5049
50#if defined(WEBRTC_POSIX)
51typedef int SOCKET;
Yves Gerey665174f2018-06-19 13:03:0552#endif // WEBRTC_POSIX
Henrik Kjellanderec78f1c2017-06-29 05:52:5053
54namespace rtc {
55
56// Event constants for the Dispatcher class.
57enum DispatcherEvent {
Yves Gerey665174f2018-06-19 13:03:0558 DE_READ = 0x0001,
59 DE_WRITE = 0x0002,
Henrik Kjellanderec78f1c2017-06-29 05:52:5060 DE_CONNECT = 0x0004,
Yves Gerey665174f2018-06-19 13:03:0561 DE_CLOSE = 0x0008,
62 DE_ACCEPT = 0x0010,
Henrik Kjellanderec78f1c2017-06-29 05:52:5063};
64
65class Signaler;
Henrik Kjellanderec78f1c2017-06-29 05:52:5066
67class Dispatcher {
68 public:
69 virtual ~Dispatcher() {}
70 virtual uint32_t GetRequestedEvents() = 0;
Henrik Kjellanderec78f1c2017-06-29 05:52:5071 virtual void OnEvent(uint32_t ff, int err) = 0;
72#if defined(WEBRTC_WIN)
73 virtual WSAEVENT GetWSAEvent() = 0;
74 virtual SOCKET GetSocket() = 0;
75 virtual bool CheckSignalClose() = 0;
76#elif defined(WEBRTC_POSIX)
77 virtual int GetDescriptor() = 0;
78 virtual bool IsDescriptorClosed() = 0;
79#endif
80};
81
82// A socket server that provides the real sockets of the underlying OS.
Mirko Bonadei35214fc2019-09-23 12:54:2883class RTC_EXPORT PhysicalSocketServer : public SocketServer {
Henrik Kjellanderec78f1c2017-06-29 05:52:5084 public:
85 PhysicalSocketServer();
86 ~PhysicalSocketServer() override;
87
88 // SocketFactory:
Henrik Kjellanderec78f1c2017-06-29 05:52:5089 Socket* CreateSocket(int family, int type) override;
Henrik Kjellanderec78f1c2017-06-29 05:52:5090
91 // Internal Factory for Accept (virtual so it can be overwritten in tests).
Niels Möllerd0b88792021-08-12 08:32:3092 virtual Socket* WrapSocket(SOCKET s);
Henrik Kjellanderec78f1c2017-06-29 05:52:5093
94 // SocketServer:
Markus Handell9a21c492022-08-25 11:40:1395 bool Wait(webrtc::TimeDelta max_wait_duration, bool process_io) override;
Henrik Kjellanderec78f1c2017-06-29 05:52:5096 void WakeUp() override;
97
98 void Add(Dispatcher* dispatcher);
99 void Remove(Dispatcher* dispatcher);
100 void Update(Dispatcher* dispatcher);
101
Henrik Kjellanderec78f1c2017-06-29 05:52:50102 private:
Markus Handellb7c63ab2020-05-26 16:09:55103 // The number of events to process with one call to "epoll_wait".
104 static constexpr size_t kNumEpollEvents = 128;
Markus Handell9a21c492022-08-25 11:40:13105 // A local historical definition of "foreverness", in milliseconds.
106 static constexpr int kForeverMs = -1;
Markus Handellb7c63ab2020-05-26 16:09:55107
Markus Handell9a21c492022-08-25 11:40:13108 static int ToCmsWait(webrtc::TimeDelta max_wait_duration);
Taylor Brandstetter51366002023-03-14 23:45:49109
Henrik Kjellanderec78f1c2017-06-29 05:52:50110#if defined(WEBRTC_POSIX)
Markus Handell9a21c492022-08-25 11:40:13111 bool WaitSelect(int cmsWait, bool process_io);
Taylor Brandstetter51366002023-03-14 23:45:49112
Henrik Kjellanderec78f1c2017-06-29 05:52:50113#if defined(WEBRTC_USE_EPOLL)
Taylor Brandstetter7b69a442020-08-20 23:43:13114 void AddEpoll(Dispatcher* dispatcher, uint64_t key);
Henrik Kjellanderec78f1c2017-06-29 05:52:50115 void RemoveEpoll(Dispatcher* dispatcher);
Taylor Brandstetter7b69a442020-08-20 23:43:13116 void UpdateEpoll(Dispatcher* dispatcher, uint64_t key);
Markus Handell9a21c492022-08-25 11:40:13117 bool WaitEpoll(int cmsWait);
Taylor Brandstetter51366002023-03-14 23:45:49118 bool WaitPollOneDispatcher(int cmsWait, Dispatcher* dispatcher);
Henrik Kjellanderec78f1c2017-06-29 05:52:50119
Markus Handellb7c63ab2020-05-26 16:09:55120 // This array is accessed in isolation by a thread calling into Wait().
121 // It's useless to use a SequenceChecker to guard it because a socket
122 // server can outlive the thread it's bound to, forcing the Wait call
123 // to have to reset the sequence checker on Wait calls.
124 std::array<epoll_event, kNumEpollEvents> epoll_events_;
Niels Möller611fba42020-05-13 12:42:22125 const int epoll_fd_ = INVALID_SOCKET;
Taylor Brandstetter51366002023-03-14 23:45:49126
127#elif defined(WEBRTC_USE_POLL)
Taylor Brandstetter51366002023-03-14 23:45:49128 bool WaitPoll(int cmsWait, bool process_io);
129
130#endif // WEBRTC_USE_EPOLL, WEBRTC_USE_POLL
131#endif // WEBRTC_POSIX
132
Taylor Brandstetter7b69a442020-08-20 23:43:13133 // uint64_t keys are used to uniquely identify a dispatcher in order to avoid
134 // the ABA problem during the epoll loop (a dispatcher being destroyed and
135 // replaced by one with the same address).
136 uint64_t next_dispatcher_key_ RTC_GUARDED_BY(crit_) = 0;
137 std::unordered_map<uint64_t, Dispatcher*> dispatcher_by_key_
138 RTC_GUARDED_BY(crit_);
139 // Reverse lookup necessary for removals/updates.
140 std::unordered_map<Dispatcher*, uint64_t> key_by_dispatcher_
141 RTC_GUARDED_BY(crit_);
142 // A list of dispatcher keys that we're interested in for the current
Taylor Brandstetter51366002023-03-14 23:45:49143 // select(), poll(), or WSAWaitForMultipleEvents() loop. Again, used to avoid
144 // the ABA problem (a socket being destroyed and a new one created with the
145 // same handle, erroneously receiving the events from the destroyed socket).
Taylor Brandstetter7b69a442020-08-20 23:43:13146 //
147 // Kept as a member variable just for efficiency.
148 std::vector<uint64_t> current_dispatcher_keys_;
Niels Möller8ce078d2020-05-18 08:17:41149 Signaler* signal_wakeup_; // Assigned in constructor only
Markus Handell3cb525b2020-07-16 14:16:09150 RecursiveCriticalSection crit_;
Henrik Kjellanderec78f1c2017-06-29 05:52:50151#if defined(WEBRTC_WIN)
Niels Möller611fba42020-05-13 12:42:22152 const WSAEVENT socket_ev_;
Henrik Kjellanderec78f1c2017-06-29 05:52:50153#endif
Niels Möller611fba42020-05-13 12:42:22154 bool fWait_;
Taylor Brandstetter7b69a442020-08-20 23:43:13155 // Are we currently in a select()/epoll()/WSAWaitForMultipleEvents loop?
156 // Used for a DCHECK, because we don't support reentrant waiting.
157 bool waiting_ = false;
Henrik Kjellanderec78f1c2017-06-29 05:52:50158};
159
Niels Möllerd0b88792021-08-12 08:32:30160class PhysicalSocket : public Socket, public sigslot::has_slots<> {
Henrik Kjellanderec78f1c2017-06-29 05:52:50161 public:
162 PhysicalSocket(PhysicalSocketServer* ss, SOCKET s = INVALID_SOCKET);
163 ~PhysicalSocket() override;
164
165 // Creates the underlying OS socket (same as the "socket" function).
166 virtual bool Create(int family, int type);
167
168 SocketAddress GetLocalAddress() const override;
169 SocketAddress GetRemoteAddress() const override;
170
171 int Bind(const SocketAddress& bind_addr) override;
172 int Connect(const SocketAddress& addr) override;
173
174 int GetError() const override;
175 void SetError(int error) override;
176
177 ConnState GetState() const override;
178
179 int GetOption(Option opt, int* value) override;
180 int SetOption(Option opt, int value) override;
181
182 int Send(const void* pv, size_t cb) override;
183 int SendTo(const void* buffer,
184 size_t length,
185 const SocketAddress& addr) override;
186
187 int Recv(void* buffer, size_t length, int64_t* timestamp) override;
Per K056782c2024-01-30 11:32:05188 // TODO(webrtc:15368): Deprecate and remove.
Henrik Kjellanderec78f1c2017-06-29 05:52:50189 int RecvFrom(void* buffer,
190 size_t length,
191 SocketAddress* out_addr,
192 int64_t* timestamp) override;
Per K056782c2024-01-30 11:32:05193 int RecvFrom(ReceiveBuffer& buffer) override;
Henrik Kjellanderec78f1c2017-06-29 05:52:50194
195 int Listen(int backlog) override;
Niels Möllerd0b88792021-08-12 08:32:30196 Socket* Accept(SocketAddress* out_addr) override;
Henrik Kjellanderec78f1c2017-06-29 05:52:50197
198 int Close() override;
199
200 SocketServer* socketserver() { return ss_; }
201
Artem Titov32740512023-01-26 11:54:49202 SOCKET GetSocketFD() const { return s_; }
203
Henrik Kjellanderec78f1c2017-06-29 05:52:50204 protected:
205 int DoConnect(const SocketAddress& connect_addr);
206
207 // Make virtual so ::accept can be overwritten in tests.
208 virtual SOCKET DoAccept(SOCKET socket, sockaddr* addr, socklen_t* addrlen);
209
210 // Make virtual so ::send can be overwritten in tests.
211 virtual int DoSend(SOCKET socket, const char* buf, int len, int flags);
212
213 // Make virtual so ::sendto can be overwritten in tests.
Yves Gerey665174f2018-06-19 13:03:05214 virtual int DoSendTo(SOCKET socket,
215 const char* buf,
216 int len,
217 int flags,
218 const struct sockaddr* dest_addr,
219 socklen_t addrlen);
Henrik Kjellanderec78f1c2017-06-29 05:52:50220
Per Kjellanderfdcfefa2022-11-08 11:48:52221 int DoReadFromSocket(void* buffer,
222 size_t length,
223 SocketAddress* out_addr,
Per K8df31c92024-03-11 09:21:48224 int64_t* timestamp,
225 EcnMarking* ecn);
Per Kjellanderfdcfefa2022-11-08 11:48:52226
Harald Alvestrand60362c12023-10-10 11:30:18227 void OnResolveResult(const webrtc::AsyncDnsResolverResult& resolver);
Henrik Kjellanderec78f1c2017-06-29 05:52:50228
229 void UpdateLastError();
230 void MaybeRemapSendError();
231
232 uint8_t enabled_events() const { return enabled_events_; }
233 virtual void SetEnabledEvents(uint8_t events);
234 virtual void EnableEvents(uint8_t events);
235 virtual void DisableEvents(uint8_t events);
236
Taylor Brandstetterecd6fc82020-02-06 01:26:37237 int TranslateOption(Option opt, int* slevel, int* sopt);
Henrik Kjellanderec78f1c2017-06-29 05:52:50238
239 PhysicalSocketServer* ss_;
240 SOCKET s_;
241 bool udp_;
Taylor Brandstetterecd6fc82020-02-06 01:26:37242 int family_ = 0;
Niels Möller6d176022021-02-09 13:44:48243 mutable webrtc::Mutex mutex_;
244 int error_ RTC_GUARDED_BY(mutex_);
Henrik Kjellanderec78f1c2017-06-29 05:52:50245 ConnState state_;
Harald Alvestrand60362c12023-10-10 11:30:18246 std::unique_ptr<webrtc::AsyncDnsResolverInterface> resolver_;
Per K8df31c92024-03-11 09:21:48247 uint8_t dscp_ = 0; // 6bit.
248 uint8_t ecn_ = 0; // 2bits.
Henrik Kjellanderec78f1c2017-06-29 05:52:50249
250#if !defined(NDEBUG)
251 std::string dbg_addr_;
252#endif
253
254 private:
255 uint8_t enabled_events_ = 0;
256};
257
258class SocketDispatcher : public Dispatcher, public PhysicalSocket {
259 public:
Yves Gerey665174f2018-06-19 13:03:05260 explicit SocketDispatcher(PhysicalSocketServer* ss);
261 SocketDispatcher(SOCKET s, PhysicalSocketServer* ss);
Henrik Kjellanderec78f1c2017-06-29 05:52:50262 ~SocketDispatcher() override;
263
264 bool Initialize();
265
266 virtual bool Create(int type);
267 bool Create(int family, int type) override;
268
269#if defined(WEBRTC_WIN)
270 WSAEVENT GetWSAEvent() override;
271 SOCKET GetSocket() override;
272 bool CheckSignalClose() override;
273#elif defined(WEBRTC_POSIX)
274 int GetDescriptor() override;
275 bool IsDescriptorClosed() override;
276#endif
277
278 uint32_t GetRequestedEvents() override;
Henrik Kjellanderec78f1c2017-06-29 05:52:50279 void OnEvent(uint32_t ff, int err) override;
280
281 int Close() override;
282
283#if defined(WEBRTC_USE_EPOLL)
284 protected:
285 void StartBatchedEventUpdates();
286 void FinishBatchedEventUpdates();
287
288 void SetEnabledEvents(uint8_t events) override;
289 void EnableEvents(uint8_t events) override;
290 void DisableEvents(uint8_t events) override;
291#endif
292
293 private:
294#if defined(WEBRTC_WIN)
295 static int next_id_;
296 int id_;
297 bool signal_close_;
298 int signal_err_;
Yves Gerey665174f2018-06-19 13:03:05299#endif // WEBRTC_WIN
Henrik Kjellanderec78f1c2017-06-29 05:52:50300#if defined(WEBRTC_USE_EPOLL)
301 void MaybeUpdateDispatcher(uint8_t old_events);
302
303 int saved_enabled_events_ = -1;
304#endif
305};
306
Yves Gerey665174f2018-06-19 13:03:05307} // namespace rtc
Henrik Kjellanderec78f1c2017-06-29 05:52:50308
Steve Anton10542f22019-01-11 17:11:00309#endif // RTC_BASE_PHYSICAL_SOCKET_SERVER_H_