blob: 64a431112434ae66b65f930165cdcbf1739d165b [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>
Yves Gerey3e707812018-11-28 16:47:49 +010015
16#include "rtc_base/asyncsocket.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020017#include "rtc_base/criticalsection.h"
Yves Gerey3e707812018-11-28 16:47:49 +010018#include "rtc_base/ipaddress.h"
19#include "rtc_base/socket.h"
20#include "rtc_base/socketaddress.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020021#include "rtc_base/socketserver.h"
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000022
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020023namespace rtc {
24
25class FirewallManager;
26
27// This SocketServer shim simulates a rule-based firewall server.
28
29enum FirewallProtocol { FP_UDP, FP_TCP, FP_ANY };
30enum FirewallDirection { FD_IN, FD_OUT, FD_ANY };
31
32class FirewallSocketServer : public SocketServer {
33 public:
34 FirewallSocketServer(SocketServer* server,
35 FirewallManager* manager = nullptr,
36 bool should_delete_server = false);
37 ~FirewallSocketServer() override;
38
39 SocketServer* socketserver() const { return server_; }
40 void set_socketserver(SocketServer* server) {
41 if (server_ && should_delete_server_) {
42 delete server_;
43 server_ = nullptr;
44 should_delete_server_ = false;
45 }
46 server_ = server;
47 }
48
49 // Settings to control whether CreateSocket or Socket::Listen succeed.
50 void set_udp_sockets_enabled(bool enabled) { udp_sockets_enabled_ = enabled; }
51 void set_tcp_sockets_enabled(bool enabled) { tcp_sockets_enabled_ = enabled; }
52 bool tcp_listen_enabled() const { return tcp_listen_enabled_; }
53 void set_tcp_listen_enabled(bool enabled) { tcp_listen_enabled_ = enabled; }
54
55 // Rules govern the behavior of Connect/Accept/Send/Recv attempts.
Yves Gerey665174f2018-06-19 15:03:05 +020056 void AddRule(bool allow,
57 FirewallProtocol p = FP_ANY,
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020058 FirewallDirection d = FD_ANY,
59 const SocketAddress& addr = SocketAddress());
Yves Gerey665174f2018-06-19 15:03:05 +020060 void AddRule(bool allow,
61 FirewallProtocol p,
62 const SocketAddress& src,
63 const SocketAddress& dst);
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020064 void ClearRules();
65
66 bool Check(FirewallProtocol p,
Yves Gerey665174f2018-06-19 15:03:05 +020067 const SocketAddress& src,
68 const SocketAddress& dst);
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020069
70 // Set the IP addresses for which Bind will fail. By default this list is
71 // empty. This can be used to simulate a real OS that refuses to bind to
72 // addresses under various circumstances.
73 //
74 // No matter how many addresses are added (including INADDR_ANY), the server
75 // will still allow creating outgoing TCP connections, since they don't
76 // require explicitly binding a socket.
77 void SetUnbindableIps(const std::vector<rtc::IPAddress>& unbindable_ips);
78 bool IsBindableIp(const rtc::IPAddress& ip);
79
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020080 Socket* CreateSocket(int family, int type) override;
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020081 AsyncSocket* CreateAsyncSocket(int family, int type) override;
82
83 void SetMessageQueue(MessageQueue* queue) override;
84 bool Wait(int cms, bool process_io) override;
85 void WakeUp() override;
86
Yves Gerey665174f2018-06-19 15:03:05 +020087 Socket* WrapSocket(Socket* sock, int type);
88 AsyncSocket* WrapSocket(AsyncSocket* sock, int type);
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020089
90 private:
Yves Gerey665174f2018-06-19 15:03:05 +020091 SocketServer* server_;
92 FirewallManager* manager_;
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020093 CriticalSection crit_;
94 struct Rule {
95 bool allow;
96 FirewallProtocol p;
97 FirewallDirection d;
98 SocketAddress src;
99 SocketAddress dst;
100 };
101 std::vector<Rule> rules_;
102 std::vector<rtc::IPAddress> unbindable_ips_;
103 bool should_delete_server_;
104 bool udp_sockets_enabled_;
105 bool tcp_sockets_enabled_;
106 bool tcp_listen_enabled_;
107};
108
109// FirewallManager allows you to manage firewalls in multiple threads together
110
111class FirewallManager {
112 public:
113 FirewallManager();
114 ~FirewallManager();
115
Yves Gerey665174f2018-06-19 15:03:05 +0200116 void AddServer(FirewallSocketServer* server);
117 void RemoveServer(FirewallSocketServer* server);
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200118
Yves Gerey665174f2018-06-19 15:03:05 +0200119 void AddRule(bool allow,
120 FirewallProtocol p = FP_ANY,
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200121 FirewallDirection d = FD_ANY,
122 const SocketAddress& addr = SocketAddress());
123 void ClearRules();
124
125 private:
126 CriticalSection crit_;
Yves Gerey665174f2018-06-19 15:03:05 +0200127 std::vector<FirewallSocketServer*> servers_;
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200128};
129
130} // namespace rtc
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000131
Mirko Bonadei92ea95e2017-09-15 06:47:31 +0200132#endif // RTC_BASE_FIREWALLSOCKETSERVER_H_