1*d9f75844SAndroid Build Coastguard Worker /* 2*d9f75844SAndroid Build Coastguard Worker * Copyright 2004 The WebRTC Project Authors. All rights reserved. 3*d9f75844SAndroid Build Coastguard Worker * 4*d9f75844SAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license 5*d9f75844SAndroid Build Coastguard Worker * that can be found in the LICENSE file in the root of the source 6*d9f75844SAndroid Build Coastguard Worker * tree. An additional intellectual property rights grant can be found 7*d9f75844SAndroid Build Coastguard Worker * in the file PATENTS. All contributing project authors may 8*d9f75844SAndroid Build Coastguard Worker * be found in the AUTHORS file in the root of the source tree. 9*d9f75844SAndroid Build Coastguard Worker */ 10*d9f75844SAndroid Build Coastguard Worker 11*d9f75844SAndroid Build Coastguard Worker #ifndef RTC_BASE_PHYSICAL_SOCKET_SERVER_H_ 12*d9f75844SAndroid Build Coastguard Worker #define RTC_BASE_PHYSICAL_SOCKET_SERVER_H_ 13*d9f75844SAndroid Build Coastguard Worker 14*d9f75844SAndroid Build Coastguard Worker #include "api/units/time_delta.h" 15*d9f75844SAndroid Build Coastguard Worker #if defined(WEBRTC_POSIX) && defined(WEBRTC_LINUX) 16*d9f75844SAndroid Build Coastguard Worker #include <sys/epoll.h> 17*d9f75844SAndroid Build Coastguard Worker #define WEBRTC_USE_EPOLL 1 18*d9f75844SAndroid Build Coastguard Worker #endif 19*d9f75844SAndroid Build Coastguard Worker 20*d9f75844SAndroid Build Coastguard Worker #include <array> 21*d9f75844SAndroid Build Coastguard Worker #include <memory> 22*d9f75844SAndroid Build Coastguard Worker #include <unordered_map> 23*d9f75844SAndroid Build Coastguard Worker #include <vector> 24*d9f75844SAndroid Build Coastguard Worker 25*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/async_resolver.h" 26*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/async_resolver_interface.h" 27*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/deprecated/recursive_critical_section.h" 28*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/socket_server.h" 29*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/synchronization/mutex.h" 30*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/system/rtc_export.h" 31*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/thread_annotations.h" 32*d9f75844SAndroid Build Coastguard Worker 33*d9f75844SAndroid Build Coastguard Worker #if defined(WEBRTC_POSIX) 34*d9f75844SAndroid Build Coastguard Worker typedef int SOCKET; 35*d9f75844SAndroid Build Coastguard Worker #endif // WEBRTC_POSIX 36*d9f75844SAndroid Build Coastguard Worker 37*d9f75844SAndroid Build Coastguard Worker namespace rtc { 38*d9f75844SAndroid Build Coastguard Worker 39*d9f75844SAndroid Build Coastguard Worker // Event constants for the Dispatcher class. 40*d9f75844SAndroid Build Coastguard Worker enum DispatcherEvent { 41*d9f75844SAndroid Build Coastguard Worker DE_READ = 0x0001, 42*d9f75844SAndroid Build Coastguard Worker DE_WRITE = 0x0002, 43*d9f75844SAndroid Build Coastguard Worker DE_CONNECT = 0x0004, 44*d9f75844SAndroid Build Coastguard Worker DE_CLOSE = 0x0008, 45*d9f75844SAndroid Build Coastguard Worker DE_ACCEPT = 0x0010, 46*d9f75844SAndroid Build Coastguard Worker }; 47*d9f75844SAndroid Build Coastguard Worker 48*d9f75844SAndroid Build Coastguard Worker class Signaler; 49*d9f75844SAndroid Build Coastguard Worker 50*d9f75844SAndroid Build Coastguard Worker class Dispatcher { 51*d9f75844SAndroid Build Coastguard Worker public: ~Dispatcher()52*d9f75844SAndroid Build Coastguard Worker virtual ~Dispatcher() {} 53*d9f75844SAndroid Build Coastguard Worker virtual uint32_t GetRequestedEvents() = 0; 54*d9f75844SAndroid Build Coastguard Worker virtual void OnEvent(uint32_t ff, int err) = 0; 55*d9f75844SAndroid Build Coastguard Worker #if defined(WEBRTC_WIN) 56*d9f75844SAndroid Build Coastguard Worker virtual WSAEVENT GetWSAEvent() = 0; 57*d9f75844SAndroid Build Coastguard Worker virtual SOCKET GetSocket() = 0; 58*d9f75844SAndroid Build Coastguard Worker virtual bool CheckSignalClose() = 0; 59*d9f75844SAndroid Build Coastguard Worker #elif defined(WEBRTC_POSIX) 60*d9f75844SAndroid Build Coastguard Worker virtual int GetDescriptor() = 0; 61*d9f75844SAndroid Build Coastguard Worker virtual bool IsDescriptorClosed() = 0; 62*d9f75844SAndroid Build Coastguard Worker #endif 63*d9f75844SAndroid Build Coastguard Worker }; 64*d9f75844SAndroid Build Coastguard Worker 65*d9f75844SAndroid Build Coastguard Worker // A socket server that provides the real sockets of the underlying OS. 66*d9f75844SAndroid Build Coastguard Worker class RTC_EXPORT PhysicalSocketServer : public SocketServer { 67*d9f75844SAndroid Build Coastguard Worker public: 68*d9f75844SAndroid Build Coastguard Worker PhysicalSocketServer(); 69*d9f75844SAndroid Build Coastguard Worker ~PhysicalSocketServer() override; 70*d9f75844SAndroid Build Coastguard Worker 71*d9f75844SAndroid Build Coastguard Worker // SocketFactory: 72*d9f75844SAndroid Build Coastguard Worker Socket* CreateSocket(int family, int type) override; 73*d9f75844SAndroid Build Coastguard Worker 74*d9f75844SAndroid Build Coastguard Worker // Internal Factory for Accept (virtual so it can be overwritten in tests). 75*d9f75844SAndroid Build Coastguard Worker virtual Socket* WrapSocket(SOCKET s); 76*d9f75844SAndroid Build Coastguard Worker 77*d9f75844SAndroid Build Coastguard Worker // SocketServer: 78*d9f75844SAndroid Build Coastguard Worker bool Wait(webrtc::TimeDelta max_wait_duration, bool process_io) override; 79*d9f75844SAndroid Build Coastguard Worker void WakeUp() override; 80*d9f75844SAndroid Build Coastguard Worker 81*d9f75844SAndroid Build Coastguard Worker void Add(Dispatcher* dispatcher); 82*d9f75844SAndroid Build Coastguard Worker void Remove(Dispatcher* dispatcher); 83*d9f75844SAndroid Build Coastguard Worker void Update(Dispatcher* dispatcher); 84*d9f75844SAndroid Build Coastguard Worker 85*d9f75844SAndroid Build Coastguard Worker private: 86*d9f75844SAndroid Build Coastguard Worker // The number of events to process with one call to "epoll_wait". 87*d9f75844SAndroid Build Coastguard Worker static constexpr size_t kNumEpollEvents = 128; 88*d9f75844SAndroid Build Coastguard Worker // A local historical definition of "foreverness", in milliseconds. 89*d9f75844SAndroid Build Coastguard Worker static constexpr int kForeverMs = -1; 90*d9f75844SAndroid Build Coastguard Worker 91*d9f75844SAndroid Build Coastguard Worker static int ToCmsWait(webrtc::TimeDelta max_wait_duration); 92*d9f75844SAndroid Build Coastguard Worker #if defined(WEBRTC_POSIX) 93*d9f75844SAndroid Build Coastguard Worker bool WaitSelect(int cmsWait, bool process_io); 94*d9f75844SAndroid Build Coastguard Worker #endif // WEBRTC_POSIX 95*d9f75844SAndroid Build Coastguard Worker #if defined(WEBRTC_USE_EPOLL) 96*d9f75844SAndroid Build Coastguard Worker void AddEpoll(Dispatcher* dispatcher, uint64_t key); 97*d9f75844SAndroid Build Coastguard Worker void RemoveEpoll(Dispatcher* dispatcher); 98*d9f75844SAndroid Build Coastguard Worker void UpdateEpoll(Dispatcher* dispatcher, uint64_t key); 99*d9f75844SAndroid Build Coastguard Worker bool WaitEpoll(int cmsWait); 100*d9f75844SAndroid Build Coastguard Worker bool WaitPoll(int cmsWait, Dispatcher* dispatcher); 101*d9f75844SAndroid Build Coastguard Worker 102*d9f75844SAndroid Build Coastguard Worker // This array is accessed in isolation by a thread calling into Wait(). 103*d9f75844SAndroid Build Coastguard Worker // It's useless to use a SequenceChecker to guard it because a socket 104*d9f75844SAndroid Build Coastguard Worker // server can outlive the thread it's bound to, forcing the Wait call 105*d9f75844SAndroid Build Coastguard Worker // to have to reset the sequence checker on Wait calls. 106*d9f75844SAndroid Build Coastguard Worker std::array<epoll_event, kNumEpollEvents> epoll_events_; 107*d9f75844SAndroid Build Coastguard Worker const int epoll_fd_ = INVALID_SOCKET; 108*d9f75844SAndroid Build Coastguard Worker #endif // WEBRTC_USE_EPOLL 109*d9f75844SAndroid Build Coastguard Worker // uint64_t keys are used to uniquely identify a dispatcher in order to avoid 110*d9f75844SAndroid Build Coastguard Worker // the ABA problem during the epoll loop (a dispatcher being destroyed and 111*d9f75844SAndroid Build Coastguard Worker // replaced by one with the same address). 112*d9f75844SAndroid Build Coastguard Worker uint64_t next_dispatcher_key_ RTC_GUARDED_BY(crit_) = 0; 113*d9f75844SAndroid Build Coastguard Worker std::unordered_map<uint64_t, Dispatcher*> dispatcher_by_key_ 114*d9f75844SAndroid Build Coastguard Worker RTC_GUARDED_BY(crit_); 115*d9f75844SAndroid Build Coastguard Worker // Reverse lookup necessary for removals/updates. 116*d9f75844SAndroid Build Coastguard Worker std::unordered_map<Dispatcher*, uint64_t> key_by_dispatcher_ 117*d9f75844SAndroid Build Coastguard Worker RTC_GUARDED_BY(crit_); 118*d9f75844SAndroid Build Coastguard Worker // A list of dispatcher keys that we're interested in for the current 119*d9f75844SAndroid Build Coastguard Worker // select() or WSAWaitForMultipleEvents() loop. Again, used to avoid the ABA 120*d9f75844SAndroid Build Coastguard Worker // problem (a socket being destroyed and a new one created with the same 121*d9f75844SAndroid Build Coastguard Worker // handle, erroneously receiving the events from the destroyed socket). 122*d9f75844SAndroid Build Coastguard Worker // 123*d9f75844SAndroid Build Coastguard Worker // Kept as a member variable just for efficiency. 124*d9f75844SAndroid Build Coastguard Worker std::vector<uint64_t> current_dispatcher_keys_; 125*d9f75844SAndroid Build Coastguard Worker Signaler* signal_wakeup_; // Assigned in constructor only 126*d9f75844SAndroid Build Coastguard Worker RecursiveCriticalSection crit_; 127*d9f75844SAndroid Build Coastguard Worker #if defined(WEBRTC_WIN) 128*d9f75844SAndroid Build Coastguard Worker const WSAEVENT socket_ev_; 129*d9f75844SAndroid Build Coastguard Worker #endif 130*d9f75844SAndroid Build Coastguard Worker bool fWait_; 131*d9f75844SAndroid Build Coastguard Worker // Are we currently in a select()/epoll()/WSAWaitForMultipleEvents loop? 132*d9f75844SAndroid Build Coastguard Worker // Used for a DCHECK, because we don't support reentrant waiting. 133*d9f75844SAndroid Build Coastguard Worker bool waiting_ = false; 134*d9f75844SAndroid Build Coastguard Worker }; 135*d9f75844SAndroid Build Coastguard Worker 136*d9f75844SAndroid Build Coastguard Worker class PhysicalSocket : public Socket, public sigslot::has_slots<> { 137*d9f75844SAndroid Build Coastguard Worker public: 138*d9f75844SAndroid Build Coastguard Worker PhysicalSocket(PhysicalSocketServer* ss, SOCKET s = INVALID_SOCKET); 139*d9f75844SAndroid Build Coastguard Worker ~PhysicalSocket() override; 140*d9f75844SAndroid Build Coastguard Worker 141*d9f75844SAndroid Build Coastguard Worker // Creates the underlying OS socket (same as the "socket" function). 142*d9f75844SAndroid Build Coastguard Worker virtual bool Create(int family, int type); 143*d9f75844SAndroid Build Coastguard Worker 144*d9f75844SAndroid Build Coastguard Worker SocketAddress GetLocalAddress() const override; 145*d9f75844SAndroid Build Coastguard Worker SocketAddress GetRemoteAddress() const override; 146*d9f75844SAndroid Build Coastguard Worker 147*d9f75844SAndroid Build Coastguard Worker int Bind(const SocketAddress& bind_addr) override; 148*d9f75844SAndroid Build Coastguard Worker int Connect(const SocketAddress& addr) override; 149*d9f75844SAndroid Build Coastguard Worker 150*d9f75844SAndroid Build Coastguard Worker int GetError() const override; 151*d9f75844SAndroid Build Coastguard Worker void SetError(int error) override; 152*d9f75844SAndroid Build Coastguard Worker 153*d9f75844SAndroid Build Coastguard Worker ConnState GetState() const override; 154*d9f75844SAndroid Build Coastguard Worker 155*d9f75844SAndroid Build Coastguard Worker int GetOption(Option opt, int* value) override; 156*d9f75844SAndroid Build Coastguard Worker int SetOption(Option opt, int value) override; 157*d9f75844SAndroid Build Coastguard Worker 158*d9f75844SAndroid Build Coastguard Worker int Send(const void* pv, size_t cb) override; 159*d9f75844SAndroid Build Coastguard Worker int SendTo(const void* buffer, 160*d9f75844SAndroid Build Coastguard Worker size_t length, 161*d9f75844SAndroid Build Coastguard Worker const SocketAddress& addr) override; 162*d9f75844SAndroid Build Coastguard Worker 163*d9f75844SAndroid Build Coastguard Worker int Recv(void* buffer, size_t length, int64_t* timestamp) override; 164*d9f75844SAndroid Build Coastguard Worker int RecvFrom(void* buffer, 165*d9f75844SAndroid Build Coastguard Worker size_t length, 166*d9f75844SAndroid Build Coastguard Worker SocketAddress* out_addr, 167*d9f75844SAndroid Build Coastguard Worker int64_t* timestamp) override; 168*d9f75844SAndroid Build Coastguard Worker 169*d9f75844SAndroid Build Coastguard Worker int Listen(int backlog) override; 170*d9f75844SAndroid Build Coastguard Worker Socket* Accept(SocketAddress* out_addr) override; 171*d9f75844SAndroid Build Coastguard Worker 172*d9f75844SAndroid Build Coastguard Worker int Close() override; 173*d9f75844SAndroid Build Coastguard Worker socketserver()174*d9f75844SAndroid Build Coastguard Worker SocketServer* socketserver() { return ss_; } 175*d9f75844SAndroid Build Coastguard Worker 176*d9f75844SAndroid Build Coastguard Worker protected: 177*d9f75844SAndroid Build Coastguard Worker int DoConnect(const SocketAddress& connect_addr); 178*d9f75844SAndroid Build Coastguard Worker 179*d9f75844SAndroid Build Coastguard Worker // Make virtual so ::accept can be overwritten in tests. 180*d9f75844SAndroid Build Coastguard Worker virtual SOCKET DoAccept(SOCKET socket, sockaddr* addr, socklen_t* addrlen); 181*d9f75844SAndroid Build Coastguard Worker 182*d9f75844SAndroid Build Coastguard Worker // Make virtual so ::send can be overwritten in tests. 183*d9f75844SAndroid Build Coastguard Worker virtual int DoSend(SOCKET socket, const char* buf, int len, int flags); 184*d9f75844SAndroid Build Coastguard Worker 185*d9f75844SAndroid Build Coastguard Worker // Make virtual so ::sendto can be overwritten in tests. 186*d9f75844SAndroid Build Coastguard Worker virtual int DoSendTo(SOCKET socket, 187*d9f75844SAndroid Build Coastguard Worker const char* buf, 188*d9f75844SAndroid Build Coastguard Worker int len, 189*d9f75844SAndroid Build Coastguard Worker int flags, 190*d9f75844SAndroid Build Coastguard Worker const struct sockaddr* dest_addr, 191*d9f75844SAndroid Build Coastguard Worker socklen_t addrlen); 192*d9f75844SAndroid Build Coastguard Worker 193*d9f75844SAndroid Build Coastguard Worker int DoReadFromSocket(void* buffer, 194*d9f75844SAndroid Build Coastguard Worker size_t length, 195*d9f75844SAndroid Build Coastguard Worker SocketAddress* out_addr, 196*d9f75844SAndroid Build Coastguard Worker int64_t* timestamp); 197*d9f75844SAndroid Build Coastguard Worker 198*d9f75844SAndroid Build Coastguard Worker void OnResolveResult(AsyncResolverInterface* resolver); 199*d9f75844SAndroid Build Coastguard Worker 200*d9f75844SAndroid Build Coastguard Worker void UpdateLastError(); 201*d9f75844SAndroid Build Coastguard Worker void MaybeRemapSendError(); 202*d9f75844SAndroid Build Coastguard Worker enabled_events()203*d9f75844SAndroid Build Coastguard Worker uint8_t enabled_events() const { return enabled_events_; } 204*d9f75844SAndroid Build Coastguard Worker virtual void SetEnabledEvents(uint8_t events); 205*d9f75844SAndroid Build Coastguard Worker virtual void EnableEvents(uint8_t events); 206*d9f75844SAndroid Build Coastguard Worker virtual void DisableEvents(uint8_t events); 207*d9f75844SAndroid Build Coastguard Worker 208*d9f75844SAndroid Build Coastguard Worker int TranslateOption(Option opt, int* slevel, int* sopt); 209*d9f75844SAndroid Build Coastguard Worker 210*d9f75844SAndroid Build Coastguard Worker PhysicalSocketServer* ss_; 211*d9f75844SAndroid Build Coastguard Worker SOCKET s_; 212*d9f75844SAndroid Build Coastguard Worker bool udp_; 213*d9f75844SAndroid Build Coastguard Worker int family_ = 0; 214*d9f75844SAndroid Build Coastguard Worker mutable webrtc::Mutex mutex_; 215*d9f75844SAndroid Build Coastguard Worker int error_ RTC_GUARDED_BY(mutex_); 216*d9f75844SAndroid Build Coastguard Worker ConnState state_; 217*d9f75844SAndroid Build Coastguard Worker AsyncResolver* resolver_; 218*d9f75844SAndroid Build Coastguard Worker 219*d9f75844SAndroid Build Coastguard Worker #if !defined(NDEBUG) 220*d9f75844SAndroid Build Coastguard Worker std::string dbg_addr_; 221*d9f75844SAndroid Build Coastguard Worker #endif 222*d9f75844SAndroid Build Coastguard Worker 223*d9f75844SAndroid Build Coastguard Worker private: 224*d9f75844SAndroid Build Coastguard Worker const bool read_scm_timestamp_experiment_; 225*d9f75844SAndroid Build Coastguard Worker uint8_t enabled_events_ = 0; 226*d9f75844SAndroid Build Coastguard Worker }; 227*d9f75844SAndroid Build Coastguard Worker 228*d9f75844SAndroid Build Coastguard Worker class SocketDispatcher : public Dispatcher, public PhysicalSocket { 229*d9f75844SAndroid Build Coastguard Worker public: 230*d9f75844SAndroid Build Coastguard Worker explicit SocketDispatcher(PhysicalSocketServer* ss); 231*d9f75844SAndroid Build Coastguard Worker SocketDispatcher(SOCKET s, PhysicalSocketServer* ss); 232*d9f75844SAndroid Build Coastguard Worker ~SocketDispatcher() override; 233*d9f75844SAndroid Build Coastguard Worker 234*d9f75844SAndroid Build Coastguard Worker bool Initialize(); 235*d9f75844SAndroid Build Coastguard Worker 236*d9f75844SAndroid Build Coastguard Worker virtual bool Create(int type); 237*d9f75844SAndroid Build Coastguard Worker bool Create(int family, int type) override; 238*d9f75844SAndroid Build Coastguard Worker 239*d9f75844SAndroid Build Coastguard Worker #if defined(WEBRTC_WIN) 240*d9f75844SAndroid Build Coastguard Worker WSAEVENT GetWSAEvent() override; 241*d9f75844SAndroid Build Coastguard Worker SOCKET GetSocket() override; 242*d9f75844SAndroid Build Coastguard Worker bool CheckSignalClose() override; 243*d9f75844SAndroid Build Coastguard Worker #elif defined(WEBRTC_POSIX) 244*d9f75844SAndroid Build Coastguard Worker int GetDescriptor() override; 245*d9f75844SAndroid Build Coastguard Worker bool IsDescriptorClosed() override; 246*d9f75844SAndroid Build Coastguard Worker #endif 247*d9f75844SAndroid Build Coastguard Worker 248*d9f75844SAndroid Build Coastguard Worker uint32_t GetRequestedEvents() override; 249*d9f75844SAndroid Build Coastguard Worker void OnEvent(uint32_t ff, int err) override; 250*d9f75844SAndroid Build Coastguard Worker 251*d9f75844SAndroid Build Coastguard Worker int Close() override; 252*d9f75844SAndroid Build Coastguard Worker 253*d9f75844SAndroid Build Coastguard Worker #if defined(WEBRTC_USE_EPOLL) 254*d9f75844SAndroid Build Coastguard Worker protected: 255*d9f75844SAndroid Build Coastguard Worker void StartBatchedEventUpdates(); 256*d9f75844SAndroid Build Coastguard Worker void FinishBatchedEventUpdates(); 257*d9f75844SAndroid Build Coastguard Worker 258*d9f75844SAndroid Build Coastguard Worker void SetEnabledEvents(uint8_t events) override; 259*d9f75844SAndroid Build Coastguard Worker void EnableEvents(uint8_t events) override; 260*d9f75844SAndroid Build Coastguard Worker void DisableEvents(uint8_t events) override; 261*d9f75844SAndroid Build Coastguard Worker #endif 262*d9f75844SAndroid Build Coastguard Worker 263*d9f75844SAndroid Build Coastguard Worker private: 264*d9f75844SAndroid Build Coastguard Worker #if defined(WEBRTC_WIN) 265*d9f75844SAndroid Build Coastguard Worker static int next_id_; 266*d9f75844SAndroid Build Coastguard Worker int id_; 267*d9f75844SAndroid Build Coastguard Worker bool signal_close_; 268*d9f75844SAndroid Build Coastguard Worker int signal_err_; 269*d9f75844SAndroid Build Coastguard Worker #endif // WEBRTC_WIN 270*d9f75844SAndroid Build Coastguard Worker #if defined(WEBRTC_USE_EPOLL) 271*d9f75844SAndroid Build Coastguard Worker void MaybeUpdateDispatcher(uint8_t old_events); 272*d9f75844SAndroid Build Coastguard Worker 273*d9f75844SAndroid Build Coastguard Worker int saved_enabled_events_ = -1; 274*d9f75844SAndroid Build Coastguard Worker #endif 275*d9f75844SAndroid Build Coastguard Worker }; 276*d9f75844SAndroid Build Coastguard Worker 277*d9f75844SAndroid Build Coastguard Worker } // namespace rtc 278*d9f75844SAndroid Build Coastguard Worker 279*d9f75844SAndroid Build Coastguard Worker #endif // RTC_BASE_PHYSICAL_SOCKET_SERVER_H_ 280