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