• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
11 #ifndef RTC_BASE_FIREWALL_SOCKET_SERVER_H_
12 #define RTC_BASE_FIREWALL_SOCKET_SERVER_H_
13 
14 #include <vector>
15 
16 #include "rtc_base/async_socket.h"
17 #include "rtc_base/ip_address.h"
18 #include "rtc_base/socket.h"
19 #include "rtc_base/socket_address.h"
20 #include "rtc_base/socket_server.h"
21 #include "rtc_base/synchronization/mutex.h"
22 
23 namespace rtc {
24 
25 class FirewallManager;
26 
27 // This SocketServer shim simulates a rule-based firewall server.
28 
29 enum FirewallProtocol { FP_UDP, FP_TCP, FP_ANY };
30 enum FirewallDirection { FD_IN, FD_OUT, FD_ANY };
31 
32 class FirewallSocketServer : public SocketServer {
33  public:
34   FirewallSocketServer(SocketServer* server,
35                        FirewallManager* manager = nullptr,
36                        bool should_delete_server = false);
37   ~FirewallSocketServer() override;
38 
socketserver()39   SocketServer* socketserver() const { return server_; }
set_socketserver(SocketServer * 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.
set_udp_sockets_enabled(bool enabled)50   void set_udp_sockets_enabled(bool enabled) { udp_sockets_enabled_ = enabled; }
set_tcp_sockets_enabled(bool enabled)51   void set_tcp_sockets_enabled(bool enabled) { tcp_sockets_enabled_ = enabled; }
tcp_listen_enabled()52   bool tcp_listen_enabled() const { return tcp_listen_enabled_; }
set_tcp_listen_enabled(bool 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.
56   void AddRule(bool allow,
57                FirewallProtocol p = FP_ANY,
58                FirewallDirection d = FD_ANY,
59                const SocketAddress& addr = SocketAddress());
60   void AddRule(bool allow,
61                FirewallProtocol p,
62                const SocketAddress& src,
63                const SocketAddress& dst);
64   void ClearRules();
65 
66   bool Check(FirewallProtocol p,
67              const SocketAddress& src,
68              const SocketAddress& dst);
69 
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 
80   Socket* CreateSocket(int family, int type) override;
81   AsyncSocket* CreateAsyncSocket(int family, int type) override;
82 
83   void SetMessageQueue(Thread* queue) override;
84   bool Wait(int cms, bool process_io) override;
85   void WakeUp() override;
86 
87   Socket* WrapSocket(Socket* sock, int type);
88   AsyncSocket* WrapSocket(AsyncSocket* sock, int type);
89 
90  private:
91   SocketServer* server_;
92   FirewallManager* manager_;
93   webrtc::Mutex mutex_;
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 
111 class FirewallManager {
112  public:
113   FirewallManager();
114   ~FirewallManager();
115 
116   void AddServer(FirewallSocketServer* server);
117   void RemoveServer(FirewallSocketServer* server);
118 
119   void AddRule(bool allow,
120                FirewallProtocol p = FP_ANY,
121                FirewallDirection d = FD_ANY,
122                const SocketAddress& addr = SocketAddress());
123   void ClearRules();
124 
125  private:
126   webrtc::Mutex mutex_;
127   std::vector<FirewallSocketServer*> servers_;
128 };
129 
130 }  // namespace rtc
131 
132 #endif  // RTC_BASE_FIREWALL_SOCKET_SERVER_H_
133