• 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 P2P_BASE_STUN_PORT_H_
12 #define P2P_BASE_STUN_PORT_H_
13 
14 #include <map>
15 #include <memory>
16 #include <string>
17 
18 #include "absl/memory/memory.h"
19 #include "p2p/base/port.h"
20 #include "p2p/base/stun_request.h"
21 #include "rtc_base/async_packet_socket.h"
22 
23 // TODO(mallinath) - Rename stunport.cc|h to udpport.cc|h.
24 
25 namespace cricket {
26 
27 // Lifetime chosen for STUN ports on low-cost networks.
28 static const int INFINITE_LIFETIME = -1;
29 // Lifetime for STUN ports on high-cost networks: 2 minutes
30 static const int HIGH_COST_PORT_KEEPALIVE_LIFETIME = 2 * 60 * 1000;
31 
32 // Communicates using the address on the outside of a NAT.
33 class UDPPort : public Port {
34  public:
Create(rtc::Thread * thread,rtc::PacketSocketFactory * factory,rtc::Network * network,rtc::AsyncPacketSocket * socket,const std::string & username,const std::string & password,const std::string & origin,bool emit_local_for_anyaddress,absl::optional<int> stun_keepalive_interval)35   static std::unique_ptr<UDPPort> Create(
36       rtc::Thread* thread,
37       rtc::PacketSocketFactory* factory,
38       rtc::Network* network,
39       rtc::AsyncPacketSocket* socket,
40       const std::string& username,
41       const std::string& password,
42       const std::string& origin,
43       bool emit_local_for_anyaddress,
44       absl::optional<int> stun_keepalive_interval) {
45     // Using `new` to access a non-public constructor.
46     auto port = absl::WrapUnique(new UDPPort(thread, factory, network, socket,
47                                              username, password, origin,
48                                              emit_local_for_anyaddress));
49     port->set_stun_keepalive_delay(stun_keepalive_interval);
50     if (!port->Init()) {
51       return nullptr;
52     }
53     return port;
54   }
55 
Create(rtc::Thread * thread,rtc::PacketSocketFactory * factory,rtc::Network * network,uint16_t min_port,uint16_t max_port,const std::string & username,const std::string & password,const std::string & origin,bool emit_local_for_anyaddress,absl::optional<int> stun_keepalive_interval)56   static std::unique_ptr<UDPPort> Create(
57       rtc::Thread* thread,
58       rtc::PacketSocketFactory* factory,
59       rtc::Network* network,
60       uint16_t min_port,
61       uint16_t max_port,
62       const std::string& username,
63       const std::string& password,
64       const std::string& origin,
65       bool emit_local_for_anyaddress,
66       absl::optional<int> stun_keepalive_interval) {
67     // Using `new` to access a non-public constructor.
68     auto port = absl::WrapUnique(
69         new UDPPort(thread, factory, network, min_port, max_port, username,
70                     password, origin, emit_local_for_anyaddress));
71     port->set_stun_keepalive_delay(stun_keepalive_interval);
72     if (!port->Init()) {
73       return nullptr;
74     }
75     return port;
76   }
77 
78   ~UDPPort() override;
79 
GetLocalAddress()80   rtc::SocketAddress GetLocalAddress() const {
81     return socket_->GetLocalAddress();
82   }
83 
server_addresses()84   const ServerAddresses& server_addresses() const { return server_addresses_; }
set_server_addresses(const ServerAddresses & addresses)85   void set_server_addresses(const ServerAddresses& addresses) {
86     server_addresses_ = addresses;
87   }
88 
89   void PrepareAddress() override;
90 
91   Connection* CreateConnection(const Candidate& address,
92                                CandidateOrigin origin) override;
93   int SetOption(rtc::Socket::Option opt, int value) override;
94   int GetOption(rtc::Socket::Option opt, int* value) override;
95   int GetError() override;
96 
97   bool HandleIncomingPacket(rtc::AsyncPacketSocket* socket,
98                             const char* data,
99                             size_t size,
100                             const rtc::SocketAddress& remote_addr,
101                             int64_t packet_time_us) override;
102 
103   bool SupportsProtocol(const std::string& protocol) const override;
104   ProtocolType GetProtocol() const override;
105 
106   void GetStunStats(absl::optional<StunStats>* stats) override;
107 
108   void set_stun_keepalive_delay(const absl::optional<int>& delay);
stun_keepalive_delay()109   int stun_keepalive_delay() const { return stun_keepalive_delay_; }
110 
111   // Visible for testing.
stun_keepalive_lifetime()112   int stun_keepalive_lifetime() const { return stun_keepalive_lifetime_; }
set_stun_keepalive_lifetime(int lifetime)113   void set_stun_keepalive_lifetime(int lifetime) {
114     stun_keepalive_lifetime_ = lifetime;
115   }
116   // Returns true if there is a pending request with type |msg_type|.
HasPendingRequest(int msg_type)117   bool HasPendingRequest(int msg_type) {
118     return requests_.HasRequest(msg_type);
119   }
120 
121  protected:
122   UDPPort(rtc::Thread* thread,
123           rtc::PacketSocketFactory* factory,
124           rtc::Network* network,
125           uint16_t min_port,
126           uint16_t max_port,
127           const std::string& username,
128           const std::string& password,
129           const std::string& origin,
130           bool emit_local_for_anyaddress);
131 
132   UDPPort(rtc::Thread* thread,
133           rtc::PacketSocketFactory* factory,
134           rtc::Network* network,
135           rtc::AsyncPacketSocket* socket,
136           const std::string& username,
137           const std::string& password,
138           const std::string& origin,
139           bool emit_local_for_anyaddress);
140 
141   bool Init();
142 
143   int SendTo(const void* data,
144              size_t size,
145              const rtc::SocketAddress& addr,
146              const rtc::PacketOptions& options,
147              bool payload) override;
148 
149   void UpdateNetworkCost() override;
150 
151   rtc::DiffServCodePoint StunDscpValue() const override;
152 
153   void OnLocalAddressReady(rtc::AsyncPacketSocket* socket,
154                            const rtc::SocketAddress& address);
155 
156   void PostAddAddress(bool is_final) override;
157 
158   void OnReadPacket(rtc::AsyncPacketSocket* socket,
159                     const char* data,
160                     size_t size,
161                     const rtc::SocketAddress& remote_addr,
162                     const int64_t& packet_time_us);
163 
164   void OnSentPacket(rtc::AsyncPacketSocket* socket,
165                     const rtc::SentPacket& sent_packet) override;
166 
167   void OnReadyToSend(rtc::AsyncPacketSocket* socket);
168 
169   // This method will send STUN binding request if STUN server address is set.
170   void MaybePrepareStunCandidate();
171 
172   void SendStunBindingRequests();
173 
174   // Helper function which will set |addr|'s IP to the default local address if
175   // |addr| is the "any" address and |emit_local_for_anyaddress_| is true. When
176   // returning false, it indicates that the operation has failed and the
177   // address shouldn't be used by any candidate.
178   bool MaybeSetDefaultLocalAddress(rtc::SocketAddress* addr) const;
179 
180  private:
181   // A helper class which can be called repeatedly to resolve multiple
182   // addresses, as opposed to rtc::AsyncResolverInterface, which can only
183   // resolve one address per instance.
184   class AddressResolver : public sigslot::has_slots<> {
185    public:
186     explicit AddressResolver(rtc::PacketSocketFactory* factory);
187     ~AddressResolver() override;
188 
189     void Resolve(const rtc::SocketAddress& address);
190     bool GetResolvedAddress(const rtc::SocketAddress& input,
191                             int family,
192                             rtc::SocketAddress* output) const;
193 
194     // The signal is sent when resolving the specified address is finished. The
195     // first argument is the input address, the second argument is the error
196     // or 0 if it succeeded.
197     sigslot::signal2<const rtc::SocketAddress&, int> SignalDone;
198 
199    private:
200     typedef std::map<rtc::SocketAddress, rtc::AsyncResolverInterface*>
201         ResolverMap;
202 
203     void OnResolveResult(rtc::AsyncResolverInterface* resolver);
204 
205     rtc::PacketSocketFactory* socket_factory_;
206     ResolverMap resolvers_;
207   };
208 
209   // DNS resolution of the STUN server.
210   void ResolveStunAddress(const rtc::SocketAddress& stun_addr);
211   void OnResolveResult(const rtc::SocketAddress& input, int error);
212 
213   void SendStunBindingRequest(const rtc::SocketAddress& stun_addr);
214 
215   // Below methods handles binding request responses.
216   void OnStunBindingRequestSucceeded(
217       int rtt_ms,
218       const rtc::SocketAddress& stun_server_addr,
219       const rtc::SocketAddress& stun_reflected_addr);
220   void OnStunBindingOrResolveRequestFailed(
221       const rtc::SocketAddress& stun_server_addr,
222       int error_code,
223       const std::string& reason);
224 
225   // Sends STUN requests to the server.
226   void OnSendPacket(const void* data, size_t size, StunRequest* req);
227 
228   // TODO(mallinaht) - Move this up to cricket::Port when SignalAddressReady is
229   // changed to SignalPortReady.
230   void MaybeSetPortCompleteOrError();
231 
232   bool HasCandidateWithAddress(const rtc::SocketAddress& addr) const;
233 
234   // If this is a low-cost network, it will keep on sending STUN binding
235   // requests indefinitely to keep the NAT binding alive. Otherwise, stop
236   // sending STUN binding requests after HIGH_COST_PORT_KEEPALIVE_LIFETIME.
GetStunKeepaliveLifetime()237   int GetStunKeepaliveLifetime() {
238     return (network_cost() >= rtc::kNetworkCostHigh)
239                ? HIGH_COST_PORT_KEEPALIVE_LIFETIME
240                : INFINITE_LIFETIME;
241   }
242 
243   ServerAddresses server_addresses_;
244   ServerAddresses bind_request_succeeded_servers_;
245   ServerAddresses bind_request_failed_servers_;
246   StunRequestManager requests_;
247   rtc::AsyncPacketSocket* socket_;
248   int error_;
249   int send_error_count_ = 0;
250   std::unique_ptr<AddressResolver> resolver_;
251   bool ready_;
252   int stun_keepalive_delay_;
253   int stun_keepalive_lifetime_ = INFINITE_LIFETIME;
254   rtc::DiffServCodePoint dscp_;
255 
256   StunStats stats_;
257 
258   // This is true by default and false when
259   // PORTALLOCATOR_DISABLE_DEFAULT_LOCAL_CANDIDATE is specified.
260   bool emit_local_for_anyaddress_;
261 
262   friend class StunBindingRequest;
263 };
264 
265 class StunPort : public UDPPort {
266  public:
267   static std::unique_ptr<StunPort> Create(
268       rtc::Thread* thread,
269       rtc::PacketSocketFactory* factory,
270       rtc::Network* network,
271       uint16_t min_port,
272       uint16_t max_port,
273       const std::string& username,
274       const std::string& password,
275       const ServerAddresses& servers,
276       const std::string& origin,
277       absl::optional<int> stun_keepalive_interval);
278 
279   void PrepareAddress() override;
280 
281  protected:
282   StunPort(rtc::Thread* thread,
283            rtc::PacketSocketFactory* factory,
284            rtc::Network* network,
285            uint16_t min_port,
286            uint16_t max_port,
287            const std::string& username,
288            const std::string& password,
289            const ServerAddresses& servers,
290            const std::string& origin);
291 };
292 
293 }  // namespace cricket
294 
295 #endif  // P2P_BASE_STUN_PORT_H_
296