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