1 /* 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 11 #ifndef RTC_BASE_PHYSICAL_SOCKET_SERVER_H_ 12 #define RTC_BASE_PHYSICAL_SOCKET_SERVER_H_ 13 14 #if defined(WEBRTC_POSIX) && defined(WEBRTC_LINUX) && !defined(WEBRTC_BSD) 15 #include <sys/epoll.h> 16 #define WEBRTC_USE_EPOLL 1 17 #endif 18 19 #include <memory> 20 #include <set> 21 #include <vector> 22 23 #include "rtc_base/critical_section.h" 24 #include "rtc_base/net_helpers.h" 25 #include "rtc_base/socket_server.h" 26 #include "rtc_base/system/rtc_export.h" 27 28 #if defined(WEBRTC_POSIX) 29 typedef int SOCKET; 30 #endif // WEBRTC_POSIX 31 32 namespace rtc { 33 34 // Event constants for the Dispatcher class. 35 enum DispatcherEvent { 36 DE_READ = 0x0001, 37 DE_WRITE = 0x0002, 38 DE_CONNECT = 0x0004, 39 DE_CLOSE = 0x0008, 40 DE_ACCEPT = 0x0010, 41 }; 42 43 class Signaler; 44 #if defined(WEBRTC_POSIX) 45 class PosixSignalDispatcher; 46 #endif 47 48 class Dispatcher { 49 public: ~Dispatcher()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. 65 class RTC_EXPORT PhysicalSocketServer : public SocketServer { 66 public: 67 PhysicalSocketServer(); 68 ~PhysicalSocketServer() override; 69 70 // SocketFactory: 71 Socket* CreateSocket(int family, int type) override; 72 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 135 class 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 socketserver()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. 185 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); 191 192 void OnResolveResult(AsyncResolverInterface* resolver); 193 194 void UpdateLastError(); 195 void MaybeRemapSendError(); 196 enabled_events()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 int TranslateOption(Option opt, int* slevel, int* sopt); 203 204 PhysicalSocketServer* ss_; 205 SOCKET s_; 206 bool udp_; 207 int family_ = 0; 208 CriticalSection crit_; 209 int error_ RTC_GUARDED_BY(crit_); 210 ConnState state_; 211 AsyncResolver* resolver_; 212 213 #if !defined(NDEBUG) 214 std::string dbg_addr_; 215 #endif 216 217 private: 218 uint8_t enabled_events_ = 0; 219 }; 220 221 class SocketDispatcher : public Dispatcher, public PhysicalSocket { 222 public: 223 explicit SocketDispatcher(PhysicalSocketServer* ss); 224 SocketDispatcher(SOCKET s, PhysicalSocketServer* ss); 225 ~SocketDispatcher() override; 226 227 bool Initialize(); 228 229 virtual bool Create(int type); 230 bool Create(int family, int type) override; 231 232 #if defined(WEBRTC_WIN) 233 WSAEVENT GetWSAEvent() override; 234 SOCKET GetSocket() override; 235 bool CheckSignalClose() override; 236 #elif defined(WEBRTC_POSIX) 237 int GetDescriptor() override; 238 bool IsDescriptorClosed() override; 239 #endif 240 241 uint32_t GetRequestedEvents() override; 242 void OnPreEvent(uint32_t ff) override; 243 void OnEvent(uint32_t ff, int err) override; 244 245 int Close() override; 246 247 #if defined(WEBRTC_USE_EPOLL) 248 protected: 249 void StartBatchedEventUpdates(); 250 void FinishBatchedEventUpdates(); 251 252 void SetEnabledEvents(uint8_t events) override; 253 void EnableEvents(uint8_t events) override; 254 void DisableEvents(uint8_t events) override; 255 #endif 256 257 private: 258 #if defined(WEBRTC_WIN) 259 static int next_id_; 260 int id_; 261 bool signal_close_; 262 int signal_err_; 263 #endif // WEBRTC_WIN 264 #if defined(WEBRTC_USE_EPOLL) 265 void MaybeUpdateDispatcher(uint8_t old_events); 266 267 int saved_enabled_events_ = -1; 268 #endif 269 }; 270 271 } // namespace rtc 272 273 #endif // RTC_BASE_PHYSICAL_SOCKET_SERVER_H_ 274