blob: 2f53d4d4fe029a2632f6800b3018ecb964f523ee [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"
Niels Möller8ce078d2020-05-18 10:17:41 +020027#include "rtc_base/thread_annotations.h"
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020028
29#if defined(WEBRTC_POSIX)
30typedef int SOCKET;
Yves Gerey665174f2018-06-19 15:03:05 +020031#endif // WEBRTC_POSIX
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020032
33namespace rtc {
34
35// Event constants for the Dispatcher class.
36enum DispatcherEvent {
Yves Gerey665174f2018-06-19 15:03:05 +020037 DE_READ = 0x0001,
38 DE_WRITE = 0x0002,
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020039 DE_CONNECT = 0x0004,
Yves Gerey665174f2018-06-19 15:03:05 +020040 DE_CLOSE = 0x0008,
41 DE_ACCEPT = 0x0010,
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020042};
43
44class Signaler;
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020045
46class Dispatcher {
47 public:
48 virtual ~Dispatcher() {}
49 virtual uint32_t GetRequestedEvents() = 0;
50 virtual void OnPreEvent(uint32_t ff) = 0;
51 virtual void OnEvent(uint32_t ff, int err) = 0;
52#if defined(WEBRTC_WIN)
53 virtual WSAEVENT GetWSAEvent() = 0;
54 virtual SOCKET GetSocket() = 0;
55 virtual bool CheckSignalClose() = 0;
56#elif defined(WEBRTC_POSIX)
57 virtual int GetDescriptor() = 0;
58 virtual bool IsDescriptorClosed() = 0;
59#endif
60};
61
62// A socket server that provides the real sockets of the underlying OS.
Mirko Bonadei35214fc2019-09-23 14:54:28 +020063class RTC_EXPORT PhysicalSocketServer : public SocketServer {
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020064 public:
65 PhysicalSocketServer();
66 ~PhysicalSocketServer() override;
67
68 // SocketFactory:
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020069 Socket* CreateSocket(int family, int type) override;
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020070 AsyncSocket* CreateAsyncSocket(int family, int type) override;
71
72 // Internal Factory for Accept (virtual so it can be overwritten in tests).
73 virtual AsyncSocket* WrapSocket(SOCKET s);
74
75 // SocketServer:
76 bool Wait(int cms, bool process_io) override;
77 void WakeUp() override;
78
79 void Add(Dispatcher* dispatcher);
80 void Remove(Dispatcher* dispatcher);
81 void Update(Dispatcher* dispatcher);
82
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020083 private:
84 typedef std::set<Dispatcher*> DispatcherSet;
85
Niels Möller8ce078d2020-05-18 10:17:41 +020086 void AddRemovePendingDispatchers() RTC_EXCLUSIVE_LOCKS_REQUIRED(crit_);
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020087
88#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)
92 void AddEpoll(Dispatcher* dispatcher);
93 void RemoveEpoll(Dispatcher* dispatcher);
94 void UpdateEpoll(Dispatcher* dispatcher);
95 bool WaitEpoll(int cms);
96 bool WaitPoll(int cms, Dispatcher* dispatcher);
97
Niels Möller611fba42020-05-13 14:42:22 +020098 const int epoll_fd_ = INVALID_SOCKET;
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020099 std::vector<struct epoll_event> epoll_events_;
100#endif // WEBRTC_USE_EPOLL
Niels Möller8ce078d2020-05-18 10:17:41 +0200101 DispatcherSet dispatchers_ RTC_GUARDED_BY(crit_);
102 DispatcherSet pending_add_dispatchers_ RTC_GUARDED_BY(crit_);
103 DispatcherSet pending_remove_dispatchers_ RTC_GUARDED_BY(crit_);
104 bool processing_dispatchers_ RTC_GUARDED_BY(crit_) = false;
105 Signaler* signal_wakeup_; // Assigned in constructor only
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200106 CriticalSection crit_;
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200107#if defined(WEBRTC_WIN)
Niels Möller611fba42020-05-13 14:42:22 +0200108 const WSAEVENT socket_ev_;
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200109#endif
Niels Möller611fba42020-05-13 14:42:22 +0200110 bool fWait_;
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200111};
112
113class PhysicalSocket : public AsyncSocket, public sigslot::has_slots<> {
114 public:
115 PhysicalSocket(PhysicalSocketServer* ss, SOCKET s = INVALID_SOCKET);
116 ~PhysicalSocket() override;
117
118 // Creates the underlying OS socket (same as the "socket" function).
119 virtual bool Create(int family, int type);
120
121 SocketAddress GetLocalAddress() const override;
122 SocketAddress GetRemoteAddress() const override;
123
124 int Bind(const SocketAddress& bind_addr) override;
125 int Connect(const SocketAddress& addr) override;
126
127 int GetError() const override;
128 void SetError(int error) override;
129
130 ConnState GetState() const override;
131
132 int GetOption(Option opt, int* value) override;
133 int SetOption(Option opt, int value) override;
134
135 int Send(const void* pv, size_t cb) override;
136 int SendTo(const void* buffer,
137 size_t length,
138 const SocketAddress& addr) override;
139
140 int Recv(void* buffer, size_t length, int64_t* timestamp) override;
141 int RecvFrom(void* buffer,
142 size_t length,
143 SocketAddress* out_addr,
144 int64_t* timestamp) override;
145
146 int Listen(int backlog) override;
147 AsyncSocket* Accept(SocketAddress* out_addr) override;
148
149 int Close() override;
150
151 SocketServer* socketserver() { return ss_; }
152
153 protected:
154 int DoConnect(const SocketAddress& connect_addr);
155
156 // Make virtual so ::accept can be overwritten in tests.
157 virtual SOCKET DoAccept(SOCKET socket, sockaddr* addr, socklen_t* addrlen);
158
159 // Make virtual so ::send can be overwritten in tests.
160 virtual int DoSend(SOCKET socket, const char* buf, int len, int flags);
161
162 // Make virtual so ::sendto can be overwritten in tests.
Yves Gerey665174f2018-06-19 15:03:05 +0200163 virtual int DoSendTo(SOCKET socket,
164 const char* buf,
165 int len,
166 int flags,
167 const struct sockaddr* dest_addr,
168 socklen_t addrlen);
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200169
170 void OnResolveResult(AsyncResolverInterface* resolver);
171
172 void UpdateLastError();
173 void MaybeRemapSendError();
174
175 uint8_t enabled_events() const { return enabled_events_; }
176 virtual void SetEnabledEvents(uint8_t events);
177 virtual void EnableEvents(uint8_t events);
178 virtual void DisableEvents(uint8_t events);
179
Taylor Brandstetterecd6fc82020-02-05 17:26:37 -0800180 int TranslateOption(Option opt, int* slevel, int* sopt);
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200181
182 PhysicalSocketServer* ss_;
183 SOCKET s_;
184 bool udp_;
Taylor Brandstetterecd6fc82020-02-05 17:26:37 -0800185 int family_ = 0;
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200186 CriticalSection crit_;
danilchap3c6abd22017-09-06 05:46:29 -0700187 int error_ RTC_GUARDED_BY(crit_);
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200188 ConnState state_;
189 AsyncResolver* resolver_;
190
191#if !defined(NDEBUG)
192 std::string dbg_addr_;
193#endif
194
195 private:
196 uint8_t enabled_events_ = 0;
197};
198
199class SocketDispatcher : public Dispatcher, public PhysicalSocket {
200 public:
Yves Gerey665174f2018-06-19 15:03:05 +0200201 explicit SocketDispatcher(PhysicalSocketServer* ss);
202 SocketDispatcher(SOCKET s, PhysicalSocketServer* ss);
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200203 ~SocketDispatcher() override;
204
205 bool Initialize();
206
207 virtual bool Create(int type);
208 bool Create(int family, int type) override;
209
210#if defined(WEBRTC_WIN)
211 WSAEVENT GetWSAEvent() override;
212 SOCKET GetSocket() override;
213 bool CheckSignalClose() override;
214#elif defined(WEBRTC_POSIX)
215 int GetDescriptor() override;
216 bool IsDescriptorClosed() override;
217#endif
218
219 uint32_t GetRequestedEvents() override;
220 void OnPreEvent(uint32_t ff) override;
221 void OnEvent(uint32_t ff, int err) override;
222
223 int Close() override;
224
225#if defined(WEBRTC_USE_EPOLL)
226 protected:
227 void StartBatchedEventUpdates();
228 void FinishBatchedEventUpdates();
229
230 void SetEnabledEvents(uint8_t events) override;
231 void EnableEvents(uint8_t events) override;
232 void DisableEvents(uint8_t events) override;
233#endif
234
235 private:
236#if defined(WEBRTC_WIN)
237 static int next_id_;
238 int id_;
239 bool signal_close_;
240 int signal_err_;
Yves Gerey665174f2018-06-19 15:03:05 +0200241#endif // WEBRTC_WIN
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200242#if defined(WEBRTC_USE_EPOLL)
243 void MaybeUpdateDispatcher(uint8_t old_events);
244
245 int saved_enabled_events_ = -1;
246#endif
247};
248
Yves Gerey665174f2018-06-19 15:03:05 +0200249} // namespace rtc
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200250
Steve Anton10542f22019-01-11 09:11:00 -0800251#endif // RTC_BASE_PHYSICAL_SOCKET_SERVER_H_