xref: /aosp_15_r20/external/webrtc/rtc_base/firewall_socket_server.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
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 #include "rtc_base/firewall_socket_server.h"
12*d9f75844SAndroid Build Coastguard Worker 
13*d9f75844SAndroid Build Coastguard Worker #include <errno.h>
14*d9f75844SAndroid Build Coastguard Worker #include <stddef.h>
15*d9f75844SAndroid Build Coastguard Worker #include <stdint.h>
16*d9f75844SAndroid Build Coastguard Worker 
17*d9f75844SAndroid Build Coastguard Worker #include <string>
18*d9f75844SAndroid Build Coastguard Worker 
19*d9f75844SAndroid Build Coastguard Worker #include "absl/algorithm/container.h"
20*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/async_socket.h"
21*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/checks.h"
22*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/logging.h"
23*d9f75844SAndroid Build Coastguard Worker 
24*d9f75844SAndroid Build Coastguard Worker namespace rtc {
25*d9f75844SAndroid Build Coastguard Worker 
26*d9f75844SAndroid Build Coastguard Worker class FirewallSocket : public AsyncSocketAdapter {
27*d9f75844SAndroid Build Coastguard Worker  public:
FirewallSocket(FirewallSocketServer * server,Socket * socket,int type)28*d9f75844SAndroid Build Coastguard Worker   FirewallSocket(FirewallSocketServer* server, Socket* socket, int type)
29*d9f75844SAndroid Build Coastguard Worker       : AsyncSocketAdapter(socket), server_(server), type_(type) {}
30*d9f75844SAndroid Build Coastguard Worker 
Bind(const SocketAddress & addr)31*d9f75844SAndroid Build Coastguard Worker   int Bind(const SocketAddress& addr) override {
32*d9f75844SAndroid Build Coastguard Worker     if (!server_->IsBindableIp(addr.ipaddr())) {
33*d9f75844SAndroid Build Coastguard Worker       SetError(EINVAL);
34*d9f75844SAndroid Build Coastguard Worker       return SOCKET_ERROR;
35*d9f75844SAndroid Build Coastguard Worker     }
36*d9f75844SAndroid Build Coastguard Worker     return AsyncSocketAdapter::Bind(addr);
37*d9f75844SAndroid Build Coastguard Worker   }
38*d9f75844SAndroid Build Coastguard Worker 
Connect(const SocketAddress & addr)39*d9f75844SAndroid Build Coastguard Worker   int Connect(const SocketAddress& addr) override {
40*d9f75844SAndroid Build Coastguard Worker     if (type_ == SOCK_STREAM) {
41*d9f75844SAndroid Build Coastguard Worker       if (!server_->Check(FP_TCP, GetLocalAddress(), addr)) {
42*d9f75844SAndroid Build Coastguard Worker         RTC_LOG(LS_VERBOSE) << "FirewallSocket outbound TCP connection from "
43*d9f75844SAndroid Build Coastguard Worker                             << GetLocalAddress().ToSensitiveString() << " to "
44*d9f75844SAndroid Build Coastguard Worker                             << addr.ToSensitiveString() << " denied";
45*d9f75844SAndroid Build Coastguard Worker         // TODO: Handle this asynchronously.
46*d9f75844SAndroid Build Coastguard Worker         SetError(EHOSTUNREACH);
47*d9f75844SAndroid Build Coastguard Worker         return SOCKET_ERROR;
48*d9f75844SAndroid Build Coastguard Worker       }
49*d9f75844SAndroid Build Coastguard Worker     }
50*d9f75844SAndroid Build Coastguard Worker     return AsyncSocketAdapter::Connect(addr);
51*d9f75844SAndroid Build Coastguard Worker   }
Send(const void * pv,size_t cb)52*d9f75844SAndroid Build Coastguard Worker   int Send(const void* pv, size_t cb) override {
53*d9f75844SAndroid Build Coastguard Worker     return SendTo(pv, cb, GetRemoteAddress());
54*d9f75844SAndroid Build Coastguard Worker   }
SendTo(const void * pv,size_t cb,const SocketAddress & addr)55*d9f75844SAndroid Build Coastguard Worker   int SendTo(const void* pv, size_t cb, const SocketAddress& addr) override {
56*d9f75844SAndroid Build Coastguard Worker     RTC_DCHECK(type_ == SOCK_DGRAM || type_ == SOCK_STREAM);
57*d9f75844SAndroid Build Coastguard Worker     FirewallProtocol protocol = (type_ == SOCK_DGRAM) ? FP_UDP : FP_TCP;
58*d9f75844SAndroid Build Coastguard Worker     if (!server_->Check(protocol, GetLocalAddress(), addr)) {
59*d9f75844SAndroid Build Coastguard Worker       RTC_LOG(LS_VERBOSE) << "FirewallSocket outbound packet with type "
60*d9f75844SAndroid Build Coastguard Worker                           << type_ << " from "
61*d9f75844SAndroid Build Coastguard Worker                           << GetLocalAddress().ToSensitiveString() << " to "
62*d9f75844SAndroid Build Coastguard Worker                           << addr.ToSensitiveString() << " dropped";
63*d9f75844SAndroid Build Coastguard Worker       return static_cast<int>(cb);
64*d9f75844SAndroid Build Coastguard Worker     }
65*d9f75844SAndroid Build Coastguard Worker     return AsyncSocketAdapter::SendTo(pv, cb, addr);
66*d9f75844SAndroid Build Coastguard Worker   }
Recv(void * pv,size_t cb,int64_t * timestamp)67*d9f75844SAndroid Build Coastguard Worker   int Recv(void* pv, size_t cb, int64_t* timestamp) override {
68*d9f75844SAndroid Build Coastguard Worker     SocketAddress addr;
69*d9f75844SAndroid Build Coastguard Worker     return RecvFrom(pv, cb, &addr, timestamp);
70*d9f75844SAndroid Build Coastguard Worker   }
RecvFrom(void * pv,size_t cb,SocketAddress * paddr,int64_t * timestamp)71*d9f75844SAndroid Build Coastguard Worker   int RecvFrom(void* pv,
72*d9f75844SAndroid Build Coastguard Worker                size_t cb,
73*d9f75844SAndroid Build Coastguard Worker                SocketAddress* paddr,
74*d9f75844SAndroid Build Coastguard Worker                int64_t* timestamp) override {
75*d9f75844SAndroid Build Coastguard Worker     if (type_ == SOCK_DGRAM) {
76*d9f75844SAndroid Build Coastguard Worker       while (true) {
77*d9f75844SAndroid Build Coastguard Worker         int res = AsyncSocketAdapter::RecvFrom(pv, cb, paddr, timestamp);
78*d9f75844SAndroid Build Coastguard Worker         if (res <= 0)
79*d9f75844SAndroid Build Coastguard Worker           return res;
80*d9f75844SAndroid Build Coastguard Worker         if (server_->Check(FP_UDP, *paddr, GetLocalAddress()))
81*d9f75844SAndroid Build Coastguard Worker           return res;
82*d9f75844SAndroid Build Coastguard Worker         RTC_LOG(LS_VERBOSE)
83*d9f75844SAndroid Build Coastguard Worker             << "FirewallSocket inbound UDP packet from "
84*d9f75844SAndroid Build Coastguard Worker             << paddr->ToSensitiveString() << " to "
85*d9f75844SAndroid Build Coastguard Worker             << GetLocalAddress().ToSensitiveString() << " dropped";
86*d9f75844SAndroid Build Coastguard Worker       }
87*d9f75844SAndroid Build Coastguard Worker     }
88*d9f75844SAndroid Build Coastguard Worker     return AsyncSocketAdapter::RecvFrom(pv, cb, paddr, timestamp);
89*d9f75844SAndroid Build Coastguard Worker   }
90*d9f75844SAndroid Build Coastguard Worker 
Listen(int backlog)91*d9f75844SAndroid Build Coastguard Worker   int Listen(int backlog) override {
92*d9f75844SAndroid Build Coastguard Worker     if (!server_->tcp_listen_enabled()) {
93*d9f75844SAndroid Build Coastguard Worker       RTC_LOG(LS_VERBOSE) << "FirewallSocket listen attempt denied";
94*d9f75844SAndroid Build Coastguard Worker       return -1;
95*d9f75844SAndroid Build Coastguard Worker     }
96*d9f75844SAndroid Build Coastguard Worker 
97*d9f75844SAndroid Build Coastguard Worker     return AsyncSocketAdapter::Listen(backlog);
98*d9f75844SAndroid Build Coastguard Worker   }
Accept(SocketAddress * paddr)99*d9f75844SAndroid Build Coastguard Worker   Socket* Accept(SocketAddress* paddr) override {
100*d9f75844SAndroid Build Coastguard Worker     SocketAddress addr;
101*d9f75844SAndroid Build Coastguard Worker     while (Socket* sock = AsyncSocketAdapter::Accept(&addr)) {
102*d9f75844SAndroid Build Coastguard Worker       if (server_->Check(FP_TCP, addr, GetLocalAddress())) {
103*d9f75844SAndroid Build Coastguard Worker         if (paddr)
104*d9f75844SAndroid Build Coastguard Worker           *paddr = addr;
105*d9f75844SAndroid Build Coastguard Worker         return sock;
106*d9f75844SAndroid Build Coastguard Worker       }
107*d9f75844SAndroid Build Coastguard Worker       sock->Close();
108*d9f75844SAndroid Build Coastguard Worker       delete sock;
109*d9f75844SAndroid Build Coastguard Worker       RTC_LOG(LS_VERBOSE) << "FirewallSocket inbound TCP connection from "
110*d9f75844SAndroid Build Coastguard Worker                           << addr.ToSensitiveString() << " to "
111*d9f75844SAndroid Build Coastguard Worker                           << GetLocalAddress().ToSensitiveString() << " denied";
112*d9f75844SAndroid Build Coastguard Worker     }
113*d9f75844SAndroid Build Coastguard Worker     return 0;
114*d9f75844SAndroid Build Coastguard Worker   }
115*d9f75844SAndroid Build Coastguard Worker 
116*d9f75844SAndroid Build Coastguard Worker  private:
117*d9f75844SAndroid Build Coastguard Worker   FirewallSocketServer* server_;
118*d9f75844SAndroid Build Coastguard Worker   int type_;
119*d9f75844SAndroid Build Coastguard Worker };
120*d9f75844SAndroid Build Coastguard Worker 
FirewallSocketServer(SocketServer * server,FirewallManager * manager,bool should_delete_server)121*d9f75844SAndroid Build Coastguard Worker FirewallSocketServer::FirewallSocketServer(SocketServer* server,
122*d9f75844SAndroid Build Coastguard Worker                                            FirewallManager* manager,
123*d9f75844SAndroid Build Coastguard Worker                                            bool should_delete_server)
124*d9f75844SAndroid Build Coastguard Worker     : server_(server),
125*d9f75844SAndroid Build Coastguard Worker       manager_(manager),
126*d9f75844SAndroid Build Coastguard Worker       should_delete_server_(should_delete_server),
127*d9f75844SAndroid Build Coastguard Worker       udp_sockets_enabled_(true),
128*d9f75844SAndroid Build Coastguard Worker       tcp_sockets_enabled_(true),
129*d9f75844SAndroid Build Coastguard Worker       tcp_listen_enabled_(true) {
130*d9f75844SAndroid Build Coastguard Worker   if (manager_)
131*d9f75844SAndroid Build Coastguard Worker     manager_->AddServer(this);
132*d9f75844SAndroid Build Coastguard Worker }
133*d9f75844SAndroid Build Coastguard Worker 
~FirewallSocketServer()134*d9f75844SAndroid Build Coastguard Worker FirewallSocketServer::~FirewallSocketServer() {
135*d9f75844SAndroid Build Coastguard Worker   if (manager_)
136*d9f75844SAndroid Build Coastguard Worker     manager_->RemoveServer(this);
137*d9f75844SAndroid Build Coastguard Worker 
138*d9f75844SAndroid Build Coastguard Worker   if (server_ && should_delete_server_) {
139*d9f75844SAndroid Build Coastguard Worker     delete server_;
140*d9f75844SAndroid Build Coastguard Worker     server_ = nullptr;
141*d9f75844SAndroid Build Coastguard Worker   }
142*d9f75844SAndroid Build Coastguard Worker }
143*d9f75844SAndroid Build Coastguard Worker 
AddRule(bool allow,FirewallProtocol p,FirewallDirection d,const SocketAddress & addr)144*d9f75844SAndroid Build Coastguard Worker void FirewallSocketServer::AddRule(bool allow,
145*d9f75844SAndroid Build Coastguard Worker                                    FirewallProtocol p,
146*d9f75844SAndroid Build Coastguard Worker                                    FirewallDirection d,
147*d9f75844SAndroid Build Coastguard Worker                                    const SocketAddress& addr) {
148*d9f75844SAndroid Build Coastguard Worker   SocketAddress any;
149*d9f75844SAndroid Build Coastguard Worker   if (d == FD_IN || d == FD_ANY) {
150*d9f75844SAndroid Build Coastguard Worker     AddRule(allow, p, any, addr);
151*d9f75844SAndroid Build Coastguard Worker   }
152*d9f75844SAndroid Build Coastguard Worker   if (d == FD_OUT || d == FD_ANY) {
153*d9f75844SAndroid Build Coastguard Worker     AddRule(allow, p, addr, any);
154*d9f75844SAndroid Build Coastguard Worker   }
155*d9f75844SAndroid Build Coastguard Worker }
156*d9f75844SAndroid Build Coastguard Worker 
AddRule(bool allow,FirewallProtocol p,const SocketAddress & src,const SocketAddress & dst)157*d9f75844SAndroid Build Coastguard Worker void FirewallSocketServer::AddRule(bool allow,
158*d9f75844SAndroid Build Coastguard Worker                                    FirewallProtocol p,
159*d9f75844SAndroid Build Coastguard Worker                                    const SocketAddress& src,
160*d9f75844SAndroid Build Coastguard Worker                                    const SocketAddress& dst) {
161*d9f75844SAndroid Build Coastguard Worker   Rule r;
162*d9f75844SAndroid Build Coastguard Worker   r.allow = allow;
163*d9f75844SAndroid Build Coastguard Worker   r.p = p;
164*d9f75844SAndroid Build Coastguard Worker   r.src = src;
165*d9f75844SAndroid Build Coastguard Worker   r.dst = dst;
166*d9f75844SAndroid Build Coastguard Worker   webrtc::MutexLock scope(&mutex_);
167*d9f75844SAndroid Build Coastguard Worker   rules_.push_back(r);
168*d9f75844SAndroid Build Coastguard Worker }
169*d9f75844SAndroid Build Coastguard Worker 
ClearRules()170*d9f75844SAndroid Build Coastguard Worker void FirewallSocketServer::ClearRules() {
171*d9f75844SAndroid Build Coastguard Worker   webrtc::MutexLock scope(&mutex_);
172*d9f75844SAndroid Build Coastguard Worker   rules_.clear();
173*d9f75844SAndroid Build Coastguard Worker }
174*d9f75844SAndroid Build Coastguard Worker 
Check(FirewallProtocol p,const SocketAddress & src,const SocketAddress & dst)175*d9f75844SAndroid Build Coastguard Worker bool FirewallSocketServer::Check(FirewallProtocol p,
176*d9f75844SAndroid Build Coastguard Worker                                  const SocketAddress& src,
177*d9f75844SAndroid Build Coastguard Worker                                  const SocketAddress& dst) {
178*d9f75844SAndroid Build Coastguard Worker   webrtc::MutexLock scope(&mutex_);
179*d9f75844SAndroid Build Coastguard Worker   for (size_t i = 0; i < rules_.size(); ++i) {
180*d9f75844SAndroid Build Coastguard Worker     const Rule& r = rules_[i];
181*d9f75844SAndroid Build Coastguard Worker     if ((r.p != p) && (r.p != FP_ANY))
182*d9f75844SAndroid Build Coastguard Worker       continue;
183*d9f75844SAndroid Build Coastguard Worker     if ((r.src.ipaddr() != src.ipaddr()) && !r.src.IsNil())
184*d9f75844SAndroid Build Coastguard Worker       continue;
185*d9f75844SAndroid Build Coastguard Worker     if ((r.src.port() != src.port()) && (r.src.port() != 0))
186*d9f75844SAndroid Build Coastguard Worker       continue;
187*d9f75844SAndroid Build Coastguard Worker     if ((r.dst.ipaddr() != dst.ipaddr()) && !r.dst.IsNil())
188*d9f75844SAndroid Build Coastguard Worker       continue;
189*d9f75844SAndroid Build Coastguard Worker     if ((r.dst.port() != dst.port()) && (r.dst.port() != 0))
190*d9f75844SAndroid Build Coastguard Worker       continue;
191*d9f75844SAndroid Build Coastguard Worker     return r.allow;
192*d9f75844SAndroid Build Coastguard Worker   }
193*d9f75844SAndroid Build Coastguard Worker   return true;
194*d9f75844SAndroid Build Coastguard Worker }
195*d9f75844SAndroid Build Coastguard Worker 
SetUnbindableIps(const std::vector<rtc::IPAddress> & unbindable_ips)196*d9f75844SAndroid Build Coastguard Worker void FirewallSocketServer::SetUnbindableIps(
197*d9f75844SAndroid Build Coastguard Worker     const std::vector<rtc::IPAddress>& unbindable_ips) {
198*d9f75844SAndroid Build Coastguard Worker   unbindable_ips_ = unbindable_ips;
199*d9f75844SAndroid Build Coastguard Worker }
200*d9f75844SAndroid Build Coastguard Worker 
IsBindableIp(const rtc::IPAddress & ip)201*d9f75844SAndroid Build Coastguard Worker bool FirewallSocketServer::IsBindableIp(const rtc::IPAddress& ip) {
202*d9f75844SAndroid Build Coastguard Worker   return !absl::c_linear_search(unbindable_ips_, ip);
203*d9f75844SAndroid Build Coastguard Worker }
204*d9f75844SAndroid Build Coastguard Worker 
CreateSocket(int family,int type)205*d9f75844SAndroid Build Coastguard Worker Socket* FirewallSocketServer::CreateSocket(int family, int type) {
206*d9f75844SAndroid Build Coastguard Worker   return WrapSocket(server_->CreateSocket(family, type), type);
207*d9f75844SAndroid Build Coastguard Worker }
208*d9f75844SAndroid Build Coastguard Worker 
SetMessageQueue(Thread * queue)209*d9f75844SAndroid Build Coastguard Worker void FirewallSocketServer::SetMessageQueue(Thread* queue) {
210*d9f75844SAndroid Build Coastguard Worker   server_->SetMessageQueue(queue);
211*d9f75844SAndroid Build Coastguard Worker }
212*d9f75844SAndroid Build Coastguard Worker 
Wait(webrtc::TimeDelta max_wait_duration,bool process_io)213*d9f75844SAndroid Build Coastguard Worker bool FirewallSocketServer::Wait(webrtc::TimeDelta max_wait_duration,
214*d9f75844SAndroid Build Coastguard Worker                                 bool process_io) {
215*d9f75844SAndroid Build Coastguard Worker   return server_->Wait(max_wait_duration, process_io);
216*d9f75844SAndroid Build Coastguard Worker }
217*d9f75844SAndroid Build Coastguard Worker 
WakeUp()218*d9f75844SAndroid Build Coastguard Worker void FirewallSocketServer::WakeUp() {
219*d9f75844SAndroid Build Coastguard Worker   return server_->WakeUp();
220*d9f75844SAndroid Build Coastguard Worker }
221*d9f75844SAndroid Build Coastguard Worker 
WrapSocket(Socket * sock,int type)222*d9f75844SAndroid Build Coastguard Worker Socket* FirewallSocketServer::WrapSocket(Socket* sock, int type) {
223*d9f75844SAndroid Build Coastguard Worker   if (!sock || (type == SOCK_STREAM && !tcp_sockets_enabled_) ||
224*d9f75844SAndroid Build Coastguard Worker       (type == SOCK_DGRAM && !udp_sockets_enabled_)) {
225*d9f75844SAndroid Build Coastguard Worker     RTC_LOG(LS_VERBOSE) << "FirewallSocketServer socket creation denied";
226*d9f75844SAndroid Build Coastguard Worker     delete sock;
227*d9f75844SAndroid Build Coastguard Worker     return nullptr;
228*d9f75844SAndroid Build Coastguard Worker   }
229*d9f75844SAndroid Build Coastguard Worker   return new FirewallSocket(this, sock, type);
230*d9f75844SAndroid Build Coastguard Worker }
231*d9f75844SAndroid Build Coastguard Worker 
FirewallManager()232*d9f75844SAndroid Build Coastguard Worker FirewallManager::FirewallManager() {}
233*d9f75844SAndroid Build Coastguard Worker 
~FirewallManager()234*d9f75844SAndroid Build Coastguard Worker FirewallManager::~FirewallManager() {
235*d9f75844SAndroid Build Coastguard Worker   RTC_DCHECK(servers_.empty());
236*d9f75844SAndroid Build Coastguard Worker }
237*d9f75844SAndroid Build Coastguard Worker 
AddServer(FirewallSocketServer * server)238*d9f75844SAndroid Build Coastguard Worker void FirewallManager::AddServer(FirewallSocketServer* server) {
239*d9f75844SAndroid Build Coastguard Worker   webrtc::MutexLock scope(&mutex_);
240*d9f75844SAndroid Build Coastguard Worker   servers_.push_back(server);
241*d9f75844SAndroid Build Coastguard Worker }
242*d9f75844SAndroid Build Coastguard Worker 
RemoveServer(FirewallSocketServer * server)243*d9f75844SAndroid Build Coastguard Worker void FirewallManager::RemoveServer(FirewallSocketServer* server) {
244*d9f75844SAndroid Build Coastguard Worker   webrtc::MutexLock scope(&mutex_);
245*d9f75844SAndroid Build Coastguard Worker   servers_.erase(std::remove(servers_.begin(), servers_.end(), server),
246*d9f75844SAndroid Build Coastguard Worker                  servers_.end());
247*d9f75844SAndroid Build Coastguard Worker }
248*d9f75844SAndroid Build Coastguard Worker 
AddRule(bool allow,FirewallProtocol p,FirewallDirection d,const SocketAddress & addr)249*d9f75844SAndroid Build Coastguard Worker void FirewallManager::AddRule(bool allow,
250*d9f75844SAndroid Build Coastguard Worker                               FirewallProtocol p,
251*d9f75844SAndroid Build Coastguard Worker                               FirewallDirection d,
252*d9f75844SAndroid Build Coastguard Worker                               const SocketAddress& addr) {
253*d9f75844SAndroid Build Coastguard Worker   webrtc::MutexLock scope(&mutex_);
254*d9f75844SAndroid Build Coastguard Worker   for (std::vector<FirewallSocketServer*>::const_iterator it = servers_.begin();
255*d9f75844SAndroid Build Coastguard Worker        it != servers_.end(); ++it) {
256*d9f75844SAndroid Build Coastguard Worker     (*it)->AddRule(allow, p, d, addr);
257*d9f75844SAndroid Build Coastguard Worker   }
258*d9f75844SAndroid Build Coastguard Worker }
259*d9f75844SAndroid Build Coastguard Worker 
ClearRules()260*d9f75844SAndroid Build Coastguard Worker void FirewallManager::ClearRules() {
261*d9f75844SAndroid Build Coastguard Worker   webrtc::MutexLock scope(&mutex_);
262*d9f75844SAndroid Build Coastguard Worker   for (std::vector<FirewallSocketServer*>::const_iterator it = servers_.begin();
263*d9f75844SAndroid Build Coastguard Worker        it != servers_.end(); ++it) {
264*d9f75844SAndroid Build Coastguard Worker     (*it)->ClearRules();
265*d9f75844SAndroid Build Coastguard Worker   }
266*d9f75844SAndroid Build Coastguard Worker }
267*d9f75844SAndroid Build Coastguard Worker 
268*d9f75844SAndroid Build Coastguard Worker }  // namespace rtc
269