blob: 63f9e1ac6c363f85c3863501e6f73953060e2684 [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
Steve Anton10542f22019-01-11 09:11:00 -080011#ifndef RTC_BASE_FIREWALL_SOCKET_SERVER_H_
12#define RTC_BASE_FIREWALL_SOCKET_SERVER_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
Steve Anton10542f22019-01-11 09:11:00 -080016#include "rtc_base/ip_address.h"
Yves Gerey3e707812018-11-28 16:47:49 +010017#include "rtc_base/socket.h"
Steve Anton10542f22019-01-11 09:11:00 -080018#include "rtc_base/socket_address.h"
19#include "rtc_base/socket_server.h"
Markus Handell18523c32020-07-08 17:55:58 +020020#include "rtc_base/synchronization/mutex.h"
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000021
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020022namespace rtc {
23
24class FirewallManager;
25
26// This SocketServer shim simulates a rule-based firewall server.
27
28enum FirewallProtocol { FP_UDP, FP_TCP, FP_ANY };
29enum FirewallDirection { FD_IN, FD_OUT, FD_ANY };
30
31class FirewallSocketServer : public SocketServer {
32 public:
33 FirewallSocketServer(SocketServer* server,
34 FirewallManager* manager = nullptr,
35 bool should_delete_server = false);
36 ~FirewallSocketServer() override;
37
38 SocketServer* socketserver() const { return server_; }
39 void set_socketserver(SocketServer* server) {
40 if (server_ && should_delete_server_) {
41 delete server_;
42 server_ = nullptr;
43 should_delete_server_ = false;
44 }
45 server_ = server;
46 }
47
48 // Settings to control whether CreateSocket or Socket::Listen succeed.
49 void set_udp_sockets_enabled(bool enabled) { udp_sockets_enabled_ = enabled; }
50 void set_tcp_sockets_enabled(bool enabled) { tcp_sockets_enabled_ = enabled; }
51 bool tcp_listen_enabled() const { return tcp_listen_enabled_; }
52 void set_tcp_listen_enabled(bool enabled) { tcp_listen_enabled_ = enabled; }
53
54 // Rules govern the behavior of Connect/Accept/Send/Recv attempts.
Yves Gerey665174f2018-06-19 15:03:05 +020055 void AddRule(bool allow,
56 FirewallProtocol p = FP_ANY,
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020057 FirewallDirection d = FD_ANY,
58 const SocketAddress& addr = SocketAddress());
Yves Gerey665174f2018-06-19 15:03:05 +020059 void AddRule(bool allow,
60 FirewallProtocol p,
61 const SocketAddress& src,
62 const SocketAddress& dst);
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020063 void ClearRules();
64
65 bool Check(FirewallProtocol p,
Yves Gerey665174f2018-06-19 15:03:05 +020066 const SocketAddress& src,
67 const SocketAddress& dst);
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020068
69 // Set the IP addresses for which Bind will fail. By default this list is
70 // empty. This can be used to simulate a real OS that refuses to bind to
71 // addresses under various circumstances.
72 //
73 // No matter how many addresses are added (including INADDR_ANY), the server
74 // will still allow creating outgoing TCP connections, since they don't
75 // require explicitly binding a socket.
76 void SetUnbindableIps(const std::vector<rtc::IPAddress>& unbindable_ips);
77 bool IsBindableIp(const rtc::IPAddress& ip);
78
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020079 Socket* CreateSocket(int family, int type) override;
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020080
Sebastian Jansson290de822020-01-09 14:20:23 +010081 void SetMessageQueue(Thread* queue) override;
Markus Handell9a21c492022-08-25 11:40:13 +000082 bool Wait(webrtc::TimeDelta max_wait_duration, bool process_io) override;
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020083 void WakeUp() override;
84
Yves Gerey665174f2018-06-19 15:03:05 +020085 Socket* WrapSocket(Socket* sock, int type);
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020086
87 private:
Yves Gerey665174f2018-06-19 15:03:05 +020088 SocketServer* server_;
89 FirewallManager* manager_;
Markus Handell18523c32020-07-08 17:55:58 +020090 webrtc::Mutex mutex_;
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +020091 struct Rule {
92 bool allow;
93 FirewallProtocol p;
94 FirewallDirection d;
95 SocketAddress src;
96 SocketAddress dst;
97 };
98 std::vector<Rule> rules_;
99 std::vector<rtc::IPAddress> unbindable_ips_;
100 bool should_delete_server_;
101 bool udp_sockets_enabled_;
102 bool tcp_sockets_enabled_;
103 bool tcp_listen_enabled_;
104};
105
106// FirewallManager allows you to manage firewalls in multiple threads together
107
108class FirewallManager {
109 public:
110 FirewallManager();
111 ~FirewallManager();
112
Yves Gerey665174f2018-06-19 15:03:05 +0200113 void AddServer(FirewallSocketServer* server);
114 void RemoveServer(FirewallSocketServer* server);
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200115
Yves Gerey665174f2018-06-19 15:03:05 +0200116 void AddRule(bool allow,
117 FirewallProtocol p = FP_ANY,
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200118 FirewallDirection d = FD_ANY,
119 const SocketAddress& addr = SocketAddress());
120 void ClearRules();
121
122 private:
Markus Handell18523c32020-07-08 17:55:58 +0200123 webrtc::Mutex mutex_;
Yves Gerey665174f2018-06-19 15:03:05 +0200124 std::vector<FirewallSocketServer*> servers_;
Henrik Kjellanderec78f1c2017-06-29 07:52:50 +0200125};
126
127} // namespace rtc
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000128
Steve Anton10542f22019-01-11 09:11:00 -0800129#endif // RTC_BASE_FIREWALL_SOCKET_SERVER_H_