|  | /* | 
|  | *  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/ip_address.h" | 
|  | #include "rtc_base/socket.h" | 
|  | #include "rtc_base/socket_address.h" | 
|  | #include "rtc_base/socket_server.h" | 
|  | #include "rtc_base/synchronization/mutex.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; | 
|  |  | 
|  | void SetMessageQueue(Thread* queue) override; | 
|  | bool Wait(int cms, bool process_io) override; | 
|  | void WakeUp() override; | 
|  |  | 
|  | Socket* WrapSocket(Socket* sock, int type); | 
|  |  | 
|  | private: | 
|  | SocketServer* server_; | 
|  | FirewallManager* manager_; | 
|  | webrtc::Mutex mutex_; | 
|  | 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: | 
|  | webrtc::Mutex mutex_; | 
|  | std::vector<FirewallSocketServer*> servers_; | 
|  | }; | 
|  |  | 
|  | }  // namespace rtc | 
|  |  | 
|  | #endif  // RTC_BASE_FIREWALL_SOCKET_SERVER_H_ |