| /* | |
| * Copyright 2004 The WebRTC Project Authors. All rights reserved. | |
| * | |
| * Use of this source code is governed by a BSD-style license | |
| * that can be found in the LICENSE file in the root of the source | |
| * tree. An additional intellectual property rights grant can be found | |
| * in the file PATENTS. All contributing project authors may | |
| * be found in the AUTHORS file in the root of the source tree. | |
| */ | |
| #ifndef RTC_BASE_FIREWALL_SOCKET_SERVER_H_ | |
| #define RTC_BASE_FIREWALL_SOCKET_SERVER_H_ | |
| #include <vector> | |
| #include "rtc_base/async_socket.h" | |
| #include "rtc_base/critical_section.h" | |
| #include "rtc_base/ip_address.h" | |
| #include "rtc_base/socket.h" | |
| #include "rtc_base/socket_address.h" | |
| #include "rtc_base/socket_server.h" | |
| namespace rtc { | |
| class FirewallManager; | |
| // This SocketServer shim simulates a rule-based firewall server. | |
| enum FirewallProtocol { FP_UDP, FP_TCP, FP_ANY }; | |
| enum FirewallDirection { FD_IN, FD_OUT, FD_ANY }; | |
| class FirewallSocketServer : public SocketServer { | |
| public: | |
| FirewallSocketServer(SocketServer* server, | |
| FirewallManager* manager = nullptr, | |
| bool should_delete_server = false); | |
| ~FirewallSocketServer() override; | |
| SocketServer* socketserver() const { return server_; } | |
| void set_socketserver(SocketServer* server) { | |
| if (server_ && should_delete_server_) { | |
| delete server_; | |
| server_ = nullptr; | |
| should_delete_server_ = false; | |
| } | |
| server_ = server; | |
| } | |
| // Settings to control whether CreateSocket or Socket::Listen succeed. | |
| void set_udp_sockets_enabled(bool enabled) { udp_sockets_enabled_ = enabled; } | |
| void set_tcp_sockets_enabled(bool enabled) { tcp_sockets_enabled_ = enabled; } | |
| bool tcp_listen_enabled() const { return tcp_listen_enabled_; } | |
| void set_tcp_listen_enabled(bool enabled) { tcp_listen_enabled_ = enabled; } | |
| // Rules govern the behavior of Connect/Accept/Send/Recv attempts. | |
| void AddRule(bool allow, | |
| FirewallProtocol p = FP_ANY, | |
| FirewallDirection d = FD_ANY, | |
| const SocketAddress& addr = SocketAddress()); | |
| void AddRule(bool allow, | |
| FirewallProtocol p, | |
| const SocketAddress& src, | |
| const SocketAddress& dst); | |
| void ClearRules(); | |
| bool Check(FirewallProtocol p, | |
| const SocketAddress& src, | |
| const SocketAddress& dst); | |
| // Set the IP addresses for which Bind will fail. By default this list is | |
| // empty. This can be used to simulate a real OS that refuses to bind to | |
| // addresses under various circumstances. | |
| // | |
| // No matter how many addresses are added (including INADDR_ANY), the server | |
| // will still allow creating outgoing TCP connections, since they don't | |
| // require explicitly binding a socket. | |
| void SetUnbindableIps(const std::vector<rtc::IPAddress>& unbindable_ips); | |
| bool IsBindableIp(const rtc::IPAddress& ip); | |
| Socket* CreateSocket(int family, int type) override; | |
| AsyncSocket* CreateAsyncSocket(int family, int type) override; | |
| void SetMessageQueue(Thread* queue) override; | |
| bool Wait(int cms, bool process_io) override; | |
| void WakeUp() override; | |
| Socket* WrapSocket(Socket* sock, int type); | |
| AsyncSocket* WrapSocket(AsyncSocket* sock, int type); | |
| private: | |
| SocketServer* server_; | |
| FirewallManager* manager_; | |
| CriticalSection crit_; | |
| struct Rule { | |
| bool allow; | |
| FirewallProtocol p; | |
| FirewallDirection d; | |
| SocketAddress src; | |
| SocketAddress dst; | |
| }; | |
| std::vector<Rule> rules_; | |
| std::vector<rtc::IPAddress> unbindable_ips_; | |
| bool should_delete_server_; | |
| bool udp_sockets_enabled_; | |
| bool tcp_sockets_enabled_; | |
| bool tcp_listen_enabled_; | |
| }; | |
| // FirewallManager allows you to manage firewalls in multiple threads together | |
| class FirewallManager { | |
| public: | |
| FirewallManager(); | |
| ~FirewallManager(); | |
| void AddServer(FirewallSocketServer* server); | |
| void RemoveServer(FirewallSocketServer* server); | |
| void AddRule(bool allow, | |
| FirewallProtocol p = FP_ANY, | |
| FirewallDirection d = FD_ANY, | |
| const SocketAddress& addr = SocketAddress()); | |
| void ClearRules(); | |
| private: | |
| CriticalSection crit_; | |
| std::vector<FirewallSocketServer*> servers_; | |
| }; | |
| } // namespace rtc | |
| #endif // RTC_BASE_FIREWALL_SOCKET_SERVER_H_ |