blob: e85b2b0f1ed89fd995e8be202467f0f2b19f0354 [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
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020019#include <memory>
20#include <set>
21#include <vector>
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000022
Steve Anton10542f22019-01-11 09:11:00 -080023#include "rtc_base/critical_section.h"
24#include "rtc_base/net_helpers.h"
25#include "rtc_base/socket_server.h"
Mirko Bonadei35214fc2019-09-23 14:54:28 +020026#include "rtc_base/system/rtc_export.h"
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020027
28#if defined(WEBRTC_POSIX)
29typedef int SOCKET;
Yves Gerey665174f2018-06-19 15:03:05 +020030#endif // WEBRTC_POSIX
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020031
32namespace rtc {
33
34// Event constants for the Dispatcher class.
35enum DispatcherEvent {
Yves Gerey665174f2018-06-19 15:03:05 +020036 DE_READ = 0x0001,
37 DE_WRITE = 0x0002,
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020038 DE_CONNECT = 0x0004,
Yves Gerey665174f2018-06-19 15:03:05 +020039 DE_CLOSE = 0x0008,
40 DE_ACCEPT = 0x0010,
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020041};
42
43class Signaler;
44#if defined(WEBRTC_POSIX)
45class PosixSignalDispatcher;
46#endif
47
48class Dispatcher {
49 public:
50 virtual ~Dispatcher() {}
51 virtual uint32_t GetRequestedEvents() = 0;
52 virtual void OnPreEvent(uint32_t ff) = 0;
53 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 AsyncSocket* CreateAsyncSocket(int family, int type) override;
73
74 // Internal Factory for Accept (virtual so it can be overwritten in tests).
75 virtual AsyncSocket* WrapSocket(SOCKET s);
76
77 // SocketServer:
78 bool Wait(int cms, bool process_io) override;
79 void WakeUp() override;
80
81 void Add(Dispatcher* dispatcher);
82 void Remove(Dispatcher* dispatcher);
83 void Update(Dispatcher* dispatcher);
84
85#if defined(WEBRTC_POSIX)
86 // Sets the function to be executed in response to the specified POSIX signal.
87 // The function is executed from inside Wait() using the "self-pipe trick"--
88 // regardless of which thread receives the signal--and hence can safely
89 // manipulate user-level data structures.
90 // "handler" may be SIG_IGN, SIG_DFL, or a user-specified function, just like
91 // with signal(2).
92 // Only one PhysicalSocketServer should have user-level signal handlers.
93 // Dispatching signals on multiple PhysicalSocketServers is not reliable.
94 // The signal mask is not modified. It is the caller's responsibily to
95 // maintain it as desired.
96 virtual bool SetPosixSignalHandler(int signum, void (*handler)(int));
97
98 protected:
99 Dispatcher* signal_dispatcher();
100#endif
101
102 private:
103 typedef std::set<Dispatcher*> DispatcherSet;
104
105 void AddRemovePendingDispatchers();
106
107#if defined(WEBRTC_POSIX)
108 bool WaitSelect(int cms, bool process_io);
109 static bool InstallSignal(int signum, void (*handler)(int));
110
111 std::unique_ptr<PosixSignalDispatcher> signal_dispatcher_;
112#endif // WEBRTC_POSIX
113#if defined(WEBRTC_USE_EPOLL)
114 void AddEpoll(Dispatcher* dispatcher);
115 void RemoveEpoll(Dispatcher* dispatcher);
116 void UpdateEpoll(Dispatcher* dispatcher);
117 bool WaitEpoll(int cms);
118 bool WaitPoll(int cms, Dispatcher* dispatcher);
119
120 int epoll_fd_ = INVALID_SOCKET;
121 std::vector<struct epoll_event> epoll_events_;
122#endif // WEBRTC_USE_EPOLL
123 DispatcherSet dispatchers_;
124 DispatcherSet pending_add_dispatchers_;
125 DispatcherSet pending_remove_dispatchers_;
126 bool processing_dispatchers_ = false;
127 Signaler* signal_wakeup_;
128 CriticalSection crit_;
129 bool fWait_;
130#if defined(WEBRTC_WIN)
131 WSAEVENT socket_ev_;
132#endif
133};
134
135class PhysicalSocket : public AsyncSocket, public sigslot::has_slots<> {
136 public:
137 PhysicalSocket(PhysicalSocketServer* ss, SOCKET s = INVALID_SOCKET);
138 ~PhysicalSocket() override;
139
140 // Creates the underlying OS socket (same as the "socket" function).
141 virtual bool Create(int family, int type);
142
143 SocketAddress GetLocalAddress() const override;
144 SocketAddress GetRemoteAddress() const override;
145
146 int Bind(const SocketAddress& bind_addr) override;
147 int Connect(const SocketAddress& addr) override;
148
149 int GetError() const override;
150 void SetError(int error) override;
151
152 ConnState GetState() const override;
153
154 int GetOption(Option opt, int* value) override;
155 int SetOption(Option opt, int value) override;
156
157 int Send(const void* pv, size_t cb) override;
158 int SendTo(const void* buffer,
159 size_t length,
160 const SocketAddress& addr) override;
161
162 int Recv(void* buffer, size_t length, int64_t* timestamp) override;
163 int RecvFrom(void* buffer,
164 size_t length,
165 SocketAddress* out_addr,
166 int64_t* timestamp) override;
167
168 int Listen(int backlog) override;
169 AsyncSocket* Accept(SocketAddress* out_addr) override;
170
171 int Close() override;
172
173 SocketServer* socketserver() { return ss_; }
174
175 protected:
176 int DoConnect(const SocketAddress& connect_addr);
177
178 // Make virtual so ::accept can be overwritten in tests.
179 virtual SOCKET DoAccept(SOCKET socket, sockaddr* addr, socklen_t* addrlen);
180
181 // Make virtual so ::send can be overwritten in tests.
182 virtual int DoSend(SOCKET socket, const char* buf, int len, int flags);
183
184 // Make virtual so ::sendto can be overwritten in tests.
Yves Gerey665174f2018-06-19 15:03:05 +0200185 virtual int DoSendTo(SOCKET socket,
186 const char* buf,
187 int len,
188 int flags,
189 const struct sockaddr* dest_addr,
190 socklen_t addrlen);
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200191
192 void OnResolveResult(AsyncResolverInterface* resolver);
193
194 void UpdateLastError();
195 void MaybeRemapSendError();
196
197 uint8_t enabled_events() const { return enabled_events_; }
198 virtual void SetEnabledEvents(uint8_t events);
199 virtual void EnableEvents(uint8_t events);
200 virtual void DisableEvents(uint8_t events);
201
202 static int TranslateOption(Option opt, int* slevel, int* sopt);
203
204 PhysicalSocketServer* ss_;
205 SOCKET s_;
206 bool udp_;
207 CriticalSection crit_;
danilchap3c6abd22017-09-06 05:46:29 -0700208 int error_ RTC_GUARDED_BY(crit_);
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200209 ConnState state_;
210 AsyncResolver* resolver_;
211
212#if !defined(NDEBUG)
213 std::string dbg_addr_;
214#endif
215
216 private:
217 uint8_t enabled_events_ = 0;
218};
219
220class SocketDispatcher : public Dispatcher, public PhysicalSocket {
221 public:
Yves Gerey665174f2018-06-19 15:03:05 +0200222 explicit SocketDispatcher(PhysicalSocketServer* ss);
223 SocketDispatcher(SOCKET s, PhysicalSocketServer* ss);
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200224 ~SocketDispatcher() override;
225
226 bool Initialize();
227
228 virtual bool Create(int type);
229 bool Create(int family, int type) override;
230
231#if defined(WEBRTC_WIN)
232 WSAEVENT GetWSAEvent() override;
233 SOCKET GetSocket() override;
234 bool CheckSignalClose() override;
235#elif defined(WEBRTC_POSIX)
236 int GetDescriptor() override;
237 bool IsDescriptorClosed() override;
238#endif
239
240 uint32_t GetRequestedEvents() override;
241 void OnPreEvent(uint32_t ff) override;
242 void OnEvent(uint32_t ff, int err) override;
243
244 int Close() override;
245
246#if defined(WEBRTC_USE_EPOLL)
247 protected:
248 void StartBatchedEventUpdates();
249 void FinishBatchedEventUpdates();
250
251 void SetEnabledEvents(uint8_t events) override;
252 void EnableEvents(uint8_t events) override;
253 void DisableEvents(uint8_t events) override;
254#endif
255
256 private:
257#if defined(WEBRTC_WIN)
258 static int next_id_;
259 int id_;
260 bool signal_close_;
261 int signal_err_;
Yves Gerey665174f2018-06-19 15:03:05 +0200262#endif // WEBRTC_WIN
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200263#if defined(WEBRTC_USE_EPOLL)
264 void MaybeUpdateDispatcher(uint8_t old_events);
265
266 int saved_enabled_events_ = -1;
267#endif
268};
269
Yves Gerey665174f2018-06-19 15:03:05 +0200270} // namespace rtc
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200271
Steve Anton10542f22019-01-11 09:11:00 -0800272#endif // RTC_BASE_PHYSICAL_SOCKET_SERVER_H_