blob: e21e53b8ecb47e6c8daa9115a2c9b5e55ff4a54e [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>
21#include <set>
22#include <vector>
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000023
Steve Anton10542f22019-01-11 09:11:00 -080024#include "rtc_base/critical_section.h"
25#include "rtc_base/net_helpers.h"
26#include "rtc_base/socket_server.h"
Mirko Bonadei35214fc2019-09-23 14:54:28 +020027#include "rtc_base/system/rtc_export.h"
Niels Möller8ce078d2020-05-18 10:17:41 +020028#include "rtc_base/thread_annotations.h"
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020029
30#if defined(WEBRTC_POSIX)
31typedef int SOCKET;
Yves Gerey665174f2018-06-19 15:03:05 +020032#endif // WEBRTC_POSIX
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020033
34namespace rtc {
35
36// Event constants for the Dispatcher class.
37enum DispatcherEvent {
Yves Gerey665174f2018-06-19 15:03:05 +020038 DE_READ = 0x0001,
39 DE_WRITE = 0x0002,
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020040 DE_CONNECT = 0x0004,
Yves Gerey665174f2018-06-19 15:03:05 +020041 DE_CLOSE = 0x0008,
42 DE_ACCEPT = 0x0010,
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020043};
44
45class Signaler;
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020046
47class Dispatcher {
48 public:
49 virtual ~Dispatcher() {}
50 virtual uint32_t GetRequestedEvents() = 0;
51 virtual void OnPreEvent(uint32_t ff) = 0;
52 virtual void OnEvent(uint32_t ff, int err) = 0;
53#if defined(WEBRTC_WIN)
54 virtual WSAEVENT GetWSAEvent() = 0;
55 virtual SOCKET GetSocket() = 0;
56 virtual bool CheckSignalClose() = 0;
57#elif defined(WEBRTC_POSIX)
58 virtual int GetDescriptor() = 0;
59 virtual bool IsDescriptorClosed() = 0;
60#endif
61};
62
63// A socket server that provides the real sockets of the underlying OS.
Mirko Bonadei35214fc2019-09-23 14:54:28 +020064class RTC_EXPORT PhysicalSocketServer : public SocketServer {
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020065 public:
66 PhysicalSocketServer();
67 ~PhysicalSocketServer() override;
68
69 // SocketFactory:
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020070 Socket* CreateSocket(int family, int type) override;
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020071 AsyncSocket* CreateAsyncSocket(int family, int type) override;
72
73 // Internal Factory for Accept (virtual so it can be overwritten in tests).
74 virtual AsyncSocket* WrapSocket(SOCKET s);
75
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 typedef std::set<Dispatcher*> DispatcherSet;
89
Niels Möller8ce078d2020-05-18 10:17:41 +020090 void AddRemovePendingDispatchers() RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_);
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020091
92#if defined(WEBRTC_POSIX)
93 bool WaitSelect(int cms, bool process_io);
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020094#endif // WEBRTC_POSIX
95#if defined(WEBRTC_USE_EPOLL)
96 void AddEpoll(Dispatcher* dispatcher);
97 void RemoveEpoll(Dispatcher* dispatcher);
98 void UpdateEpoll(Dispatcher* dispatcher);
99 bool WaitEpoll(int cms);
100 bool WaitPoll(int cms, Dispatcher* dispatcher);
101
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
Niels Möller8ce078d2020-05-18 10:17:41 +0200109 DispatcherSet dispatchers_ RTC_GUARDED_BY(crit_);
110 DispatcherSet pending_add_dispatchers_ RTC_GUARDED_BY(crit_);
111 DispatcherSet pending_remove_dispatchers_ RTC_GUARDED_BY(crit_);
112 bool processing_dispatchers_ RTC_GUARDED_BY(crit_) = false;
113 Signaler* signal_wakeup_; // Assigned in constructor only
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200114 CriticalSection crit_;
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200115#if defined(WEBRTC_WIN)
Niels Möller611fba42020-05-13 14:42:22 +0200116 const WSAEVENT socket_ev_;
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200117#endif
Niels Möller611fba42020-05-13 14:42:22 +0200118 bool fWait_;
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200119};
120
121class PhysicalSocket : public AsyncSocket, public sigslot::has_slots<> {
122 public:
123 PhysicalSocket(PhysicalSocketServer* ss, SOCKET s = INVALID_SOCKET);
124 ~PhysicalSocket() override;
125
126 // Creates the underlying OS socket (same as the "socket" function).
127 virtual bool Create(int family, int type);
128
129 SocketAddress GetLocalAddress() const override;
130 SocketAddress GetRemoteAddress() const override;
131
132 int Bind(const SocketAddress& bind_addr) override;
133 int Connect(const SocketAddress& addr) override;
134
135 int GetError() const override;
136 void SetError(int error) override;
137
138 ConnState GetState() const override;
139
140 int GetOption(Option opt, int* value) override;
141 int SetOption(Option opt, int value) override;
142
143 int Send(const void* pv, size_t cb) override;
144 int SendTo(const void* buffer,
145 size_t length,
146 const SocketAddress& addr) override;
147
148 int Recv(void* buffer, size_t length, int64_t* timestamp) override;
149 int RecvFrom(void* buffer,
150 size_t length,
151 SocketAddress* out_addr,
152 int64_t* timestamp) override;
153
154 int Listen(int backlog) override;
155 AsyncSocket* Accept(SocketAddress* out_addr) override;
156
157 int Close() override;
158
159 SocketServer* socketserver() { return ss_; }
160
161 protected:
162 int DoConnect(const SocketAddress& connect_addr);
163
164 // Make virtual so ::accept can be overwritten in tests.
165 virtual SOCKET DoAccept(SOCKET socket, sockaddr* addr, socklen_t* addrlen);
166
167 // Make virtual so ::send can be overwritten in tests.
168 virtual int DoSend(SOCKET socket, const char* buf, int len, int flags);
169
170 // Make virtual so ::sendto can be overwritten in tests.
Yves Gerey665174f2018-06-19 15:03:05 +0200171 virtual int DoSendTo(SOCKET socket,
172 const char* buf,
173 int len,
174 int flags,
175 const struct sockaddr* dest_addr,
176 socklen_t addrlen);
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200177
178 void OnResolveResult(AsyncResolverInterface* resolver);
179
180 void UpdateLastError();
181 void MaybeRemapSendError();
182
183 uint8_t enabled_events() const { return enabled_events_; }
184 virtual void SetEnabledEvents(uint8_t events);
185 virtual void EnableEvents(uint8_t events);
186 virtual void DisableEvents(uint8_t events);
187
Taylor Brandstetterecd6fc82020-02-05 17:26:37 -0800188 int TranslateOption(Option opt, int* slevel, int* sopt);
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200189
190 PhysicalSocketServer* ss_;
191 SOCKET s_;
192 bool udp_;
Taylor Brandstetterecd6fc82020-02-05 17:26:37 -0800193 int family_ = 0;
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200194 CriticalSection crit_;
danilchap3c6abd22017-09-06 05:46:29 -0700195 int error_ RTC_GUARDED_BY(crit_);
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200196 ConnState state_;
197 AsyncResolver* resolver_;
198
199#if !defined(NDEBUG)
200 std::string dbg_addr_;
201#endif
202
203 private:
204 uint8_t enabled_events_ = 0;
205};
206
207class SocketDispatcher : public Dispatcher, public PhysicalSocket {
208 public:
Yves Gerey665174f2018-06-19 15:03:05 +0200209 explicit SocketDispatcher(PhysicalSocketServer* ss);
210 SocketDispatcher(SOCKET s, PhysicalSocketServer* ss);
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200211 ~SocketDispatcher() override;
212
213 bool Initialize();
214
215 virtual bool Create(int type);
216 bool Create(int family, int type) override;
217
218#if defined(WEBRTC_WIN)
219 WSAEVENT GetWSAEvent() override;
220 SOCKET GetSocket() override;
221 bool CheckSignalClose() override;
222#elif defined(WEBRTC_POSIX)
223 int GetDescriptor() override;
224 bool IsDescriptorClosed() override;
225#endif
226
227 uint32_t GetRequestedEvents() override;
228 void OnPreEvent(uint32_t ff) override;
229 void OnEvent(uint32_t ff, int err) override;
230
231 int Close() override;
232
233#if defined(WEBRTC_USE_EPOLL)
234 protected:
235 void StartBatchedEventUpdates();
236 void FinishBatchedEventUpdates();
237
238 void SetEnabledEvents(uint8_t events) override;
239 void EnableEvents(uint8_t events) override;
240 void DisableEvents(uint8_t events) override;
241#endif
242
243 private:
244#if defined(WEBRTC_WIN)
245 static int next_id_;
246 int id_;
247 bool signal_close_;
248 int signal_err_;
Yves Gerey665174f2018-06-19 15:03:05 +0200249#endif // WEBRTC_WIN
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200250#if defined(WEBRTC_USE_EPOLL)
251 void MaybeUpdateDispatcher(uint8_t old_events);
252
253 int saved_enabled_events_ = -1;
254#endif
255};
256
Yves Gerey665174f2018-06-19 15:03:05 +0200257} // namespace rtc
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200258
Steve Anton10542f22019-01-11 09:11:00 -0800259#endif // RTC_BASE_PHYSICAL_SOCKET_SERVER_H_