blob: a01229d593ca12be5e358dcdf7096b941204c68d [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
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020014#if defined(WEBRTC_POSIX) && defined(WEBRTC_LINUX)
15#include <sys/epoll.h>
16#define WEBRTC_USE_EPOLL 1
17#endif
jbauchde4db112017-05-31 13:09:18 -070018
Markus Handellb7c63ab2020-05-26 18:09:55 +020019#include <array>
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020020#include <memory>
Taylor Brandstetter7b69a442020-08-20 23:43:13 +000021#include <unordered_map>
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020022#include <vector>
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000023
Mirko Bonadeie5f4c6b2021-01-15 10:41:01 +010024#include "rtc_base/async_resolver.h"
25#include "rtc_base/async_resolver_interface.h"
Markus Handell3cb525b2020-07-16 16:16:09 +020026#include "rtc_base/deprecated/recursive_critical_section.h"
Steve Anton10542f22019-01-11 09:11:00 -080027#include "rtc_base/socket_server.h"
Niels Möller6d176022021-02-09 14:44:48 +010028#include "rtc_base/synchronization/mutex.h"
Mirko Bonadei35214fc2019-09-23 14:54:28 +020029#include "rtc_base/system/rtc_export.h"
Niels Möller8ce078d2020-05-18 10:17:41 +020030#include "rtc_base/thread_annotations.h"
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020031
32#if defined(WEBRTC_POSIX)
33typedef int SOCKET;
Yves Gerey665174f2018-06-19 15:03:05 +020034#endif // WEBRTC_POSIX
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020035
36namespace rtc {
37
38// Event constants for the Dispatcher class.
39enum DispatcherEvent {
Yves Gerey665174f2018-06-19 15:03:05 +020040 DE_READ = 0x0001,
41 DE_WRITE = 0x0002,
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020042 DE_CONNECT = 0x0004,
Yves Gerey665174f2018-06-19 15:03:05 +020043 DE_CLOSE = 0x0008,
44 DE_ACCEPT = 0x0010,
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020045};
46
47class Signaler;
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020048
49class Dispatcher {
50 public:
51 virtual ~Dispatcher() {}
52 virtual uint32_t GetRequestedEvents() = 0;
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020053 virtual void OnEvent(uint32_t ff, int err) = 0;
54#if defined(WEBRTC_WIN)
55 virtual WSAEVENT GetWSAEvent() = 0;
56 virtual SOCKET GetSocket() = 0;
57 virtual bool CheckSignalClose() = 0;
58#elif defined(WEBRTC_POSIX)
59 virtual int GetDescriptor() = 0;
60 virtual bool IsDescriptorClosed() = 0;
61#endif
62};
63
64// A socket server that provides the real sockets of the underlying OS.
Mirko Bonadei35214fc2019-09-23 14:54:28 +020065class RTC_EXPORT PhysicalSocketServer : public SocketServer {
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020066 public:
67 PhysicalSocketServer();
68 ~PhysicalSocketServer() override;
69
70 // SocketFactory:
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020071 Socket* CreateSocket(int family, int type) override;
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020072
73 // Internal Factory for Accept (virtual so it can be overwritten in tests).
Niels Möllerd0b88792021-08-12 10:32:30 +020074 virtual Socket* WrapSocket(SOCKET s);
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020075
76 // SocketServer:
77 bool Wait(int cms, bool process_io) override;
78 void WakeUp() override;
79
80 void Add(Dispatcher* dispatcher);
81 void Remove(Dispatcher* dispatcher);
82 void Update(Dispatcher* dispatcher);
83
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020084 private:
Markus Handellb7c63ab2020-05-26 18:09:55 +020085 // The number of events to process with one call to "epoll_wait".
86 static constexpr size_t kNumEpollEvents = 128;
87
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020088#if defined(WEBRTC_POSIX)
89 bool WaitSelect(int cms, bool process_io);
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020090#endif // WEBRTC_POSIX
91#if defined(WEBRTC_USE_EPOLL)
Taylor Brandstetter7b69a442020-08-20 23:43:13 +000092 void AddEpoll(Dispatcher* dispatcher, uint64_t key);
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020093 void RemoveEpoll(Dispatcher* dispatcher);
Taylor Brandstetter7b69a442020-08-20 23:43:13 +000094 void UpdateEpoll(Dispatcher* dispatcher, uint64_t key);
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020095 bool WaitEpoll(int cms);
96 bool WaitPoll(int cms, Dispatcher* dispatcher);
97
Markus Handellb7c63ab2020-05-26 18:09:55 +020098 // This array is accessed in isolation by a thread calling into Wait().
99 // It's useless to use a SequenceChecker to guard it because a socket
100 // server can outlive the thread it's bound to, forcing the Wait call
101 // to have to reset the sequence checker on Wait calls.
102 std::array<epoll_event, kNumEpollEvents> epoll_events_;
Niels Möller611fba42020-05-13 14:42:22 +0200103 const int epoll_fd_ = INVALID_SOCKET;
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200104#endif // WEBRTC_USE_EPOLL
Taylor Brandstetter7b69a442020-08-20 23:43:13 +0000105 // uint64_t keys are used to uniquely identify a dispatcher in order to avoid
106 // the ABA problem during the epoll loop (a dispatcher being destroyed and
107 // replaced by one with the same address).
108 uint64_t next_dispatcher_key_ RTC_GUARDED_BY(crit_) = 0;
109 std::unordered_map<uint64_t, Dispatcher*> dispatcher_by_key_
110 RTC_GUARDED_BY(crit_);
111 // Reverse lookup necessary for removals/updates.
112 std::unordered_map<Dispatcher*, uint64_t> key_by_dispatcher_
113 RTC_GUARDED_BY(crit_);
114 // A list of dispatcher keys that we're interested in for the current
115 // select() or WSAWaitForMultipleEvents() loop. Again, used to avoid the ABA
116 // problem (a socket being destroyed and a new one created with the same
117 // handle, erroneously receiving the events from the destroyed socket).
118 //
119 // Kept as a member variable just for efficiency.
120 std::vector<uint64_t> current_dispatcher_keys_;
Niels Möller8ce078d2020-05-18 10:17:41 +0200121 Signaler* signal_wakeup_; // Assigned in constructor only
Markus Handell3cb525b2020-07-16 16:16:09 +0200122 RecursiveCriticalSection crit_;
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200123#if defined(WEBRTC_WIN)
Niels Möller611fba42020-05-13 14:42:22 +0200124 const WSAEVENT socket_ev_;
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200125#endif
Niels Möller611fba42020-05-13 14:42:22 +0200126 bool fWait_;
Taylor Brandstetter7b69a442020-08-20 23:43:13 +0000127 // Are we currently in a select()/epoll()/WSAWaitForMultipleEvents loop?
128 // Used for a DCHECK, because we don't support reentrant waiting.
129 bool waiting_ = false;
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200130};
131
Niels Möllerd0b88792021-08-12 10:32:30 +0200132class PhysicalSocket : public Socket, public sigslot::has_slots<> {
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200133 public:
134 PhysicalSocket(PhysicalSocketServer* ss, SOCKET s = INVALID_SOCKET);
135 ~PhysicalSocket() override;
136
137 // Creates the underlying OS socket (same as the "socket" function).
138 virtual bool Create(int family, int type);
139
140 SocketAddress GetLocalAddress() const override;
141 SocketAddress GetRemoteAddress() const override;
142
143 int Bind(const SocketAddress& bind_addr) override;
144 int Connect(const SocketAddress& addr) override;
145
146 int GetError() const override;
147 void SetError(int error) override;
148
149 ConnState GetState() const override;
150
151 int GetOption(Option opt, int* value) override;
152 int SetOption(Option opt, int value) override;
153
154 int Send(const void* pv, size_t cb) override;
155 int SendTo(const void* buffer,
156 size_t length,
157 const SocketAddress& addr) override;
158
159 int Recv(void* buffer, size_t length, int64_t* timestamp) override;
160 int RecvFrom(void* buffer,
161 size_t length,
162 SocketAddress* out_addr,
163 int64_t* timestamp) override;
164
165 int Listen(int backlog) override;
Niels Möllerd0b88792021-08-12 10:32:30 +0200166 Socket* Accept(SocketAddress* out_addr) override;
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200167
168 int Close() override;
169
170 SocketServer* socketserver() { return ss_; }
171
172 protected:
173 int DoConnect(const SocketAddress& connect_addr);
174
175 // Make virtual so ::accept can be overwritten in tests.
176 virtual SOCKET DoAccept(SOCKET socket, sockaddr* addr, socklen_t* addrlen);
177
178 // Make virtual so ::send can be overwritten in tests.
179 virtual int DoSend(SOCKET socket, const char* buf, int len, int flags);
180
181 // Make virtual so ::sendto can be overwritten in tests.
Yves Gerey665174f2018-06-19 15:03:05 +0200182 virtual int DoSendTo(SOCKET socket,
183 const char* buf,
184 int len,
185 int flags,
186 const struct sockaddr* dest_addr,
187 socklen_t addrlen);
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200188
189 void OnResolveResult(AsyncResolverInterface* resolver);
190
191 void UpdateLastError();
192 void MaybeRemapSendError();
193
194 uint8_t enabled_events() const { return enabled_events_; }
195 virtual void SetEnabledEvents(uint8_t events);
196 virtual void EnableEvents(uint8_t events);
197 virtual void DisableEvents(uint8_t events);
198
Taylor Brandstetterecd6fc82020-02-05 17:26:37 -0800199 int TranslateOption(Option opt, int* slevel, int* sopt);
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200200
201 PhysicalSocketServer* ss_;
202 SOCKET s_;
203 bool udp_;
Taylor Brandstetterecd6fc82020-02-05 17:26:37 -0800204 int family_ = 0;
Niels Möller6d176022021-02-09 14:44:48 +0100205 mutable webrtc::Mutex mutex_;
206 int error_ RTC_GUARDED_BY(mutex_);
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200207 ConnState state_;
208 AsyncResolver* resolver_;
209
210#if !defined(NDEBUG)
211 std::string dbg_addr_;
212#endif
213
214 private:
215 uint8_t enabled_events_ = 0;
216};
217
218class SocketDispatcher : public Dispatcher, public PhysicalSocket {
219 public:
Yves Gerey665174f2018-06-19 15:03:05 +0200220 explicit SocketDispatcher(PhysicalSocketServer* ss);
221 SocketDispatcher(SOCKET s, PhysicalSocketServer* ss);
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200222 ~SocketDispatcher() override;
223
224 bool Initialize();
225
226 virtual bool Create(int type);
227 bool Create(int family, int type) override;
228
229#if defined(WEBRTC_WIN)
230 WSAEVENT GetWSAEvent() override;
231 SOCKET GetSocket() override;
232 bool CheckSignalClose() override;
233#elif defined(WEBRTC_POSIX)
234 int GetDescriptor() override;
235 bool IsDescriptorClosed() override;
236#endif
237
238 uint32_t GetRequestedEvents() override;
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200239 void OnEvent(uint32_t ff, int err) override;
240
241 int Close() override;
242
243#if defined(WEBRTC_USE_EPOLL)
244 protected:
245 void StartBatchedEventUpdates();
246 void FinishBatchedEventUpdates();
247
248 void SetEnabledEvents(uint8_t events) override;
249 void EnableEvents(uint8_t events) override;
250 void DisableEvents(uint8_t events) override;
251#endif
252
253 private:
254#if defined(WEBRTC_WIN)
255 static int next_id_;
256 int id_;
257 bool signal_close_;
258 int signal_err_;
Yves Gerey665174f2018-06-19 15:03:05 +0200259#endif // WEBRTC_WIN
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200260#if defined(WEBRTC_USE_EPOLL)
261 void MaybeUpdateDispatcher(uint8_t old_events);
262
263 int saved_enabled_events_ = -1;
264#endif
265};
266
Yves Gerey665174f2018-06-19 15:03:05 +0200267} // namespace rtc
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200268
Steve Anton10542f22019-01-11 09:11:00 -0800269#endif // RTC_BASE_PHYSICAL_SOCKET_SERVER_H_