Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(169)

Side by Side Diff: webrtc/base/firewallsocketserver.cc

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

Powered by Google App Engine
This is Rietveld 408576698