blob: 0e96823ff66629489cd9e984b6bfbbd567dead5b [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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#ifndef RTC_BASE_FIREWALLSOCKETSERVER_H_
12#define RTC_BASE_FIREWALLSOCKETSERVER_H_
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000013
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020014#include <vector>
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020015#include "rtc_base/criticalsection.h"
16#include "rtc_base/socketserver.h"
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000017
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020018namespace rtc {
19
20class FirewallManager;
21
22// This SocketServer shim simulates a rule-based firewall server.
23
24enum FirewallProtocol { FP_UDP, FP_TCP, FP_ANY };
25enum FirewallDirection { FD_IN, FD_OUT, FD_ANY };
26
27class FirewallSocketServer : public SocketServer {
28 public:
29 FirewallSocketServer(SocketServer* server,
30 FirewallManager* manager = nullptr,
31 bool should_delete_server = false);
32 ~FirewallSocketServer() override;
33
34 SocketServer* socketserver() const { return server_; }
35 void set_socketserver(SocketServer* server) {
36 if (server_ && should_delete_server_) {
37 delete server_;
38 server_ = nullptr;
39 should_delete_server_ = false;
40 }
41 server_ = server;
42 }
43
44 // Settings to control whether CreateSocket or Socket::Listen succeed.
45 void set_udp_sockets_enabled(bool enabled) { udp_sockets_enabled_ = enabled; }
46 void set_tcp_sockets_enabled(bool enabled) { tcp_sockets_enabled_ = enabled; }
47 bool tcp_listen_enabled() const { return tcp_listen_enabled_; }
48 void set_tcp_listen_enabled(bool enabled) { tcp_listen_enabled_ = enabled; }
49
50 // Rules govern the behavior of Connect/Accept/Send/Recv attempts.
Yves Gerey665174f2018-06-19 15:03:05 +020051 void AddRule(bool allow,
52 FirewallProtocol p = FP_ANY,
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020053 FirewallDirection d = FD_ANY,
54 const SocketAddress& addr = SocketAddress());
Yves Gerey665174f2018-06-19 15:03:05 +020055 void AddRule(bool allow,
56 FirewallProtocol p,
57 const SocketAddress& src,
58 const SocketAddress& dst);
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020059 void ClearRules();
60
61 bool Check(FirewallProtocol p,
Yves Gerey665174f2018-06-19 15:03:05 +020062 const SocketAddress& src,
63 const SocketAddress& dst);
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020064
65 // Set the IP addresses for which Bind will fail. By default this list is
66 // empty. This can be used to simulate a real OS that refuses to bind to
67 // addresses under various circumstances.
68 //
69 // No matter how many addresses are added (including INADDR_ANY), the server
70 // will still allow creating outgoing TCP connections, since they don't
71 // require explicitly binding a socket.
72 void SetUnbindableIps(const std::vector<rtc::IPAddress>& unbindable_ips);
73 bool IsBindableIp(const rtc::IPAddress& ip);
74
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020075 Socket* CreateSocket(int family, int type) override;
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020076 AsyncSocket* CreateAsyncSocket(int family, int type) override;
77
78 void SetMessageQueue(MessageQueue* queue) override;
79 bool Wait(int cms, bool process_io) override;
80 void WakeUp() override;
81
Yves Gerey665174f2018-06-19 15:03:05 +020082 Socket* WrapSocket(Socket* sock, int type);
83 AsyncSocket* WrapSocket(AsyncSocket* sock, int type);
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020084
85 private:
Yves Gerey665174f2018-06-19 15:03:05 +020086 SocketServer* server_;
87 FirewallManager* manager_;
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020088 CriticalSection crit_;
89 struct Rule {
90 bool allow;
91 FirewallProtocol p;
92 FirewallDirection d;
93 SocketAddress src;
94 SocketAddress dst;
95 };
96 std::vector<Rule> rules_;
97 std::vector<rtc::IPAddress> unbindable_ips_;
98 bool should_delete_server_;
99 bool udp_sockets_enabled_;
100 bool tcp_sockets_enabled_;
101 bool tcp_listen_enabled_;
102};
103
104// FirewallManager allows you to manage firewalls in multiple threads together
105
106class FirewallManager {
107 public:
108 FirewallManager();
109 ~FirewallManager();
110
Yves Gerey665174f2018-06-19 15:03:05 +0200111 void AddServer(FirewallSocketServer* server);
112 void RemoveServer(FirewallSocketServer* server);
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200113
Yves Gerey665174f2018-06-19 15:03:05 +0200114 void AddRule(bool allow,
115 FirewallProtocol p = FP_ANY,
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200116 FirewallDirection d = FD_ANY,
117 const SocketAddress& addr = SocketAddress());
118 void ClearRules();
119
120 private:
121 CriticalSection crit_;
Yves Gerey665174f2018-06-19 15:03:05 +0200122 std::vector<FirewallSocketServer*> servers_;
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200123};
124
125} // namespace rtc
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000126
Mirko Bonadei92ea95e2017-09-15 06:47:31 +0200127#endif // RTC_BASE_FIREWALLSOCKETSERVER_H_