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