• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright 2012 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_TURN_PORT_H_
12 #define P2P_BASE_TURN_PORT_H_
13 
14 #include <stdio.h>
15 
16 #include <list>
17 #include <map>
18 #include <memory>
19 #include <set>
20 #include <string>
21 #include <vector>
22 
23 #include "absl/memory/memory.h"
24 #include "p2p/base/port.h"
25 #include "p2p/client/basic_port_allocator.h"
26 #include "rtc_base/async_invoker.h"
27 #include "rtc_base/async_packet_socket.h"
28 #include "rtc_base/ssl_certificate.h"
29 
30 namespace webrtc {
31 class TurnCustomizer;
32 }
33 
34 namespace cricket {
35 
36 extern const int STUN_ATTR_TURN_LOGGING_ID;
37 extern const char TURN_PORT_TYPE[];
38 class TurnAllocateRequest;
39 class TurnEntry;
40 
41 class TurnPort : public Port {
42  public:
43   enum PortState {
44     STATE_CONNECTING,    // Initial state, cannot send any packets.
45     STATE_CONNECTED,     // Socket connected, ready to send stun requests.
46     STATE_READY,         // Received allocate success, can send any packets.
47     STATE_RECEIVEONLY,   // Had REFRESH_REQUEST error, cannot send any packets.
48     STATE_DISCONNECTED,  // TCP connection died, cannot send/receive any
49                          // packets.
50   };
51   // Create a TURN port using the shared UDP socket, |socket|.
Create(rtc::Thread * thread,rtc::PacketSocketFactory * factory,rtc::Network * network,rtc::AsyncPacketSocket * socket,const std::string & username,const std::string & password,const ProtocolAddress & server_address,const RelayCredentials & credentials,int server_priority,const std::string & origin,webrtc::TurnCustomizer * customizer)52   static std::unique_ptr<TurnPort> Create(
53       rtc::Thread* thread,
54       rtc::PacketSocketFactory* factory,
55       rtc::Network* network,
56       rtc::AsyncPacketSocket* socket,
57       const std::string& username,  // ice username.
58       const std::string& password,  // ice password.
59       const ProtocolAddress& server_address,
60       const RelayCredentials& credentials,
61       int server_priority,
62       const std::string& origin,
63       webrtc::TurnCustomizer* customizer) {
64     // Using `new` to access a non-public constructor.
65     return absl::WrapUnique(new TurnPort(
66         thread, factory, network, socket, username, password, server_address,
67         credentials, server_priority, origin, customizer));
68   }
69   // TODO(steveanton): Remove once downstream clients have moved to |Create|.
CreateUnique(rtc::Thread * thread,rtc::PacketSocketFactory * factory,rtc::Network * network,rtc::AsyncPacketSocket * socket,const std::string & username,const std::string & password,const ProtocolAddress & server_address,const RelayCredentials & credentials,int server_priority,const std::string & origin,webrtc::TurnCustomizer * customizer)70   static std::unique_ptr<TurnPort> CreateUnique(
71       rtc::Thread* thread,
72       rtc::PacketSocketFactory* factory,
73       rtc::Network* network,
74       rtc::AsyncPacketSocket* socket,
75       const std::string& username,  // ice username.
76       const std::string& password,  // ice password.
77       const ProtocolAddress& server_address,
78       const RelayCredentials& credentials,
79       int server_priority,
80       const std::string& origin,
81       webrtc::TurnCustomizer* customizer) {
82     return Create(thread, factory, network, socket, username, password,
83                   server_address, credentials, server_priority, origin,
84                   customizer);
85   }
86 
87   // Create a TURN port that will use a new socket, bound to |network| and
88   // using a port in the range between |min_port| and |max_port|.
89   static std::unique_ptr<TurnPort> Create(
90       rtc::Thread* thread,
91       rtc::PacketSocketFactory* factory,
92       rtc::Network* network,
93       uint16_t min_port,
94       uint16_t max_port,
95       const std::string& username,  // ice username.
96       const std::string& password,  // ice password.
97       const ProtocolAddress& server_address,
98       const RelayCredentials& credentials,
99       int server_priority,
100       const std::string& origin,
101       const std::vector<std::string>& tls_alpn_protocols,
102       const std::vector<std::string>& tls_elliptic_curves,
103       webrtc::TurnCustomizer* customizer,
104       rtc::SSLCertificateVerifier* tls_cert_verifier = nullptr) {
105     // Using `new` to access a non-public constructor.
106     return absl::WrapUnique(
107         new TurnPort(thread, factory, network, min_port, max_port, username,
108                      password, server_address, credentials, server_priority,
109                      origin, tls_alpn_protocols, tls_elliptic_curves,
110                      customizer, tls_cert_verifier));
111   }
112   // TODO(steveanton): Remove once downstream clients have moved to |Create|.
113   static std::unique_ptr<TurnPort> CreateUnique(
114       rtc::Thread* thread,
115       rtc::PacketSocketFactory* factory,
116       rtc::Network* network,
117       uint16_t min_port,
118       uint16_t max_port,
119       const std::string& username,  // ice username.
120       const std::string& password,  // ice password.
121       const ProtocolAddress& server_address,
122       const RelayCredentials& credentials,
123       int server_priority,
124       const std::string& origin,
125       const std::vector<std::string>& tls_alpn_protocols,
126       const std::vector<std::string>& tls_elliptic_curves,
127       webrtc::TurnCustomizer* customizer,
128       rtc::SSLCertificateVerifier* tls_cert_verifier = nullptr) {
129     return Create(thread, factory, network, min_port, max_port, username,
130                   password, server_address, credentials, server_priority,
131                   origin, tls_alpn_protocols, tls_elliptic_curves, customizer,
132                   tls_cert_verifier);
133   }
134 
135   ~TurnPort() override;
136 
server_address()137   const ProtocolAddress& server_address() const { return server_address_; }
138   // Returns an empty address if the local address has not been assigned.
139   rtc::SocketAddress GetLocalAddress() const;
140 
ready()141   bool ready() const { return state_ == STATE_READY; }
connected()142   bool connected() const {
143     return state_ == STATE_READY || state_ == STATE_CONNECTED;
144   }
credentials()145   const RelayCredentials& credentials() const { return credentials_; }
146 
147   ProtocolType GetProtocol() const override;
148 
149   virtual TlsCertPolicy GetTlsCertPolicy() const;
150   virtual void SetTlsCertPolicy(TlsCertPolicy tls_cert_policy);
151 
152   void SetTurnLoggingId(const std::string& turn_logging_id);
153 
154   virtual std::vector<std::string> GetTlsAlpnProtocols() const;
155   virtual std::vector<std::string> GetTlsEllipticCurves() const;
156 
157   // Release a TURN allocation by sending a refresh with lifetime 0.
158   // Sets state to STATE_RECEIVEONLY.
159   void Release();
160 
161   void PrepareAddress() override;
162   Connection* CreateConnection(const Candidate& c,
163                                PortInterface::CandidateOrigin origin) override;
164   int SendTo(const void* data,
165              size_t size,
166              const rtc::SocketAddress& addr,
167              const rtc::PacketOptions& options,
168              bool payload) override;
169   int SetOption(rtc::Socket::Option opt, int value) override;
170   int GetOption(rtc::Socket::Option opt, int* value) override;
171   int GetError() override;
172 
173   bool HandleIncomingPacket(rtc::AsyncPacketSocket* socket,
174                             const char* data,
175                             size_t size,
176                             const rtc::SocketAddress& remote_addr,
177                             int64_t packet_time_us) override;
178   bool CanHandleIncomingPacketsFrom(
179       const rtc::SocketAddress& addr) const override;
180   virtual void OnReadPacket(rtc::AsyncPacketSocket* socket,
181                             const char* data,
182                             size_t size,
183                             const rtc::SocketAddress& remote_addr,
184                             const int64_t& packet_time_us);
185 
186   void OnSentPacket(rtc::AsyncPacketSocket* socket,
187                     const rtc::SentPacket& sent_packet) override;
188   virtual void OnReadyToSend(rtc::AsyncPacketSocket* socket);
189   bool SupportsProtocol(const std::string& protocol) const override;
190 
191   void OnSocketConnect(rtc::AsyncPacketSocket* socket);
192   void OnSocketClose(rtc::AsyncPacketSocket* socket, int error);
193 
hash()194   const std::string& hash() const { return hash_; }
nonce()195   const std::string& nonce() const { return nonce_; }
196 
error()197   int error() const { return error_; }
198 
199   void OnAllocateMismatch();
200 
socket()201   rtc::AsyncPacketSocket* socket() const { return socket_; }
202 
203   // For testing only.
invoker()204   rtc::AsyncInvoker* invoker() { return &invoker_; }
205 
206   // Signal with resolved server address.
207   // Parameters are port, server address and resolved server address.
208   // This signal will be sent only if server address is resolved successfully.
209   sigslot::
210       signal3<TurnPort*, const rtc::SocketAddress&, const rtc::SocketAddress&>
211           SignalResolvedServerAddress;
212 
213   // Signal when TurnPort is closed,
214   // e.g remote socket closed (TCP)
215   //  or receiveing a REFRESH response with lifetime 0.
216   sigslot::signal1<TurnPort*> SignalTurnPortClosed;
217 
218   // All public methods/signals below are for testing only.
219   sigslot::signal2<TurnPort*, int> SignalTurnRefreshResult;
220   sigslot::signal3<TurnPort*, const rtc::SocketAddress&, int>
221       SignalCreatePermissionResult;
FlushRequests(int msg_type)222   void FlushRequests(int msg_type) { request_manager_.Flush(msg_type); }
HasRequests()223   bool HasRequests() { return !request_manager_.empty(); }
set_credentials(const RelayCredentials & credentials)224   void set_credentials(const RelayCredentials& credentials) {
225     credentials_ = credentials;
226   }
227   // Finds the turn entry with |address| and sets its channel id.
228   // Returns true if the entry is found.
229   bool SetEntryChannelId(const rtc::SocketAddress& address, int channel_id);
230   // Visible for testing.
231   // Shuts down the turn port, usually because of some fatal errors.
232   void Close();
233 
234   void HandleConnectionDestroyed(Connection* conn) override;
235 
236  protected:
237   TurnPort(rtc::Thread* thread,
238            rtc::PacketSocketFactory* factory,
239            rtc::Network* network,
240            rtc::AsyncPacketSocket* socket,
241            const std::string& username,
242            const std::string& password,
243            const ProtocolAddress& server_address,
244            const RelayCredentials& credentials,
245            int server_priority,
246            const std::string& origin,
247            webrtc::TurnCustomizer* customizer);
248 
249   TurnPort(rtc::Thread* thread,
250            rtc::PacketSocketFactory* factory,
251            rtc::Network* network,
252            uint16_t min_port,
253            uint16_t max_port,
254            const std::string& username,
255            const std::string& password,
256            const ProtocolAddress& server_address,
257            const RelayCredentials& credentials,
258            int server_priority,
259            const std::string& origin,
260            const std::vector<std::string>& tls_alpn_protocols,
261            const std::vector<std::string>& tls_elliptic_curves,
262            webrtc::TurnCustomizer* customizer,
263            rtc::SSLCertificateVerifier* tls_cert_verifier = nullptr);
264 
265   // NOTE: This method needs to be accessible for StacPort
266   // return true if entry was created (i.e channel_number consumed).
267   bool CreateOrRefreshEntry(const rtc::SocketAddress& addr, int channel_number);
268 
269   bool CreateOrRefreshEntry(const rtc::SocketAddress& addr,
270                             int channel_number,
271                             const std::string& remote_ufrag);
272 
273   rtc::DiffServCodePoint StunDscpValue() const override;
274 
275  private:
276   enum {
277     MSG_ALLOCATE_ERROR = MSG_FIRST_AVAILABLE,
278     MSG_ALLOCATE_MISMATCH,
279     MSG_TRY_ALTERNATE_SERVER,
280     MSG_REFRESH_ERROR,
281     MSG_ALLOCATION_RELEASED
282   };
283 
284   typedef std::list<TurnEntry*> EntryList;
285   typedef std::map<rtc::Socket::Option, int> SocketOptionsMap;
286   typedef std::set<rtc::SocketAddress> AttemptedServerSet;
287 
288   void OnMessage(rtc::Message* pmsg) override;
289 
290   bool CreateTurnClientSocket();
291 
set_nonce(const std::string & nonce)292   void set_nonce(const std::string& nonce) { nonce_ = nonce; }
set_realm(const std::string & realm)293   void set_realm(const std::string& realm) {
294     if (realm != realm_) {
295       realm_ = realm;
296       UpdateHash();
297     }
298   }
299 
300   void OnRefreshError();
301   void HandleRefreshError();
302   bool SetAlternateServer(const rtc::SocketAddress& address);
303   void ResolveTurnAddress(const rtc::SocketAddress& address);
304   void OnResolveResult(rtc::AsyncResolverInterface* resolver);
305 
306   void AddRequestAuthInfo(StunMessage* msg);
307   void OnSendStunPacket(const void* data, size_t size, StunRequest* request);
308   // Stun address from allocate success response.
309   // Currently used only for testing.
310   void OnStunAddress(const rtc::SocketAddress& address);
311   void OnAllocateSuccess(const rtc::SocketAddress& address,
312                          const rtc::SocketAddress& stun_address);
313   void OnAllocateError(int error_code, const std::string& reason);
314   void OnAllocateRequestTimeout();
315 
316   void HandleDataIndication(const char* data,
317                             size_t size,
318                             int64_t packet_time_us);
319   void HandleChannelData(int channel_id,
320                          const char* data,
321                          size_t size,
322                          int64_t packet_time_us);
323   void DispatchPacket(const char* data,
324                       size_t size,
325                       const rtc::SocketAddress& remote_addr,
326                       ProtocolType proto,
327                       int64_t packet_time_us);
328 
329   bool ScheduleRefresh(uint32_t lifetime);
330   void SendRequest(StunRequest* request, int delay);
331   int Send(const void* data, size_t size, const rtc::PacketOptions& options);
332   void UpdateHash();
333   bool UpdateNonce(StunMessage* response);
334   void ResetNonce();
335 
336   bool HasPermission(const rtc::IPAddress& ipaddr) const;
337   TurnEntry* FindEntry(const rtc::SocketAddress& address) const;
338   TurnEntry* FindEntry(int channel_id) const;
339   bool EntryExists(TurnEntry* e);
340   void DestroyEntry(TurnEntry* entry);
341   // Destroys the entry only if |timestamp| matches the destruction timestamp
342   // in |entry|.
343   void DestroyEntryIfNotCancelled(TurnEntry* entry, int64_t timestamp);
344   void ScheduleEntryDestruction(TurnEntry* entry);
345 
346   // Marks the connection with remote address |address| failed and
347   // pruned (a.k.a. write-timed-out). Returns true if a connection is found.
348   bool FailAndPruneConnection(const rtc::SocketAddress& address);
349 
350   // Reconstruct the URL of the server which the candidate is gathered from.
351   std::string ReconstructedServerUrl(bool use_hostname);
352 
353   void MaybeAddTurnLoggingId(StunMessage* message);
354 
355   void TurnCustomizerMaybeModifyOutgoingStunMessage(StunMessage* message);
356   bool TurnCustomizerAllowChannelData(const void* data,
357                                       size_t size,
358                                       bool payload);
359 
360   ProtocolAddress server_address_;
361   TlsCertPolicy tls_cert_policy_ = TlsCertPolicy::TLS_CERT_POLICY_SECURE;
362   std::vector<std::string> tls_alpn_protocols_;
363   std::vector<std::string> tls_elliptic_curves_;
364   rtc::SSLCertificateVerifier* tls_cert_verifier_;
365   RelayCredentials credentials_;
366   AttemptedServerSet attempted_server_addresses_;
367 
368   rtc::AsyncPacketSocket* socket_;
369   SocketOptionsMap socket_options_;
370   rtc::AsyncResolverInterface* resolver_;
371   int error_;
372   rtc::DiffServCodePoint stun_dscp_value_;
373 
374   StunRequestManager request_manager_;
375   std::string realm_;  // From 401/438 response message.
376   std::string nonce_;  // From 401/438 response message.
377   std::string hash_;   // Digest of username:realm:password
378 
379   int next_channel_number_;
380   EntryList entries_;
381 
382   PortState state_;
383   // By default the value will be set to 0. This value will be used in
384   // calculating the candidate priority.
385   int server_priority_;
386 
387   // The number of retries made due to allocate mismatch error.
388   size_t allocate_mismatch_retries_;
389 
390   rtc::AsyncInvoker invoker_;
391 
392   // Optional TurnCustomizer that can modify outgoing messages. Once set, this
393   // must outlive the TurnPort's lifetime.
394   webrtc::TurnCustomizer* turn_customizer_ = nullptr;
395 
396   // Optional TurnLoggingId.
397   // An identifier set by application that is added to TURN_ALLOCATE_REQUEST
398   // and can be used to match client/backend logs.
399   // TODO(jonaso): This should really be initialized in constructor,
400   // but that is currently so terrible. Fix once constructor is changed
401   // to be more easy to work with.
402   std::string turn_logging_id_;
403 
404   friend class TurnEntry;
405   friend class TurnAllocateRequest;
406   friend class TurnRefreshRequest;
407   friend class TurnCreatePermissionRequest;
408   friend class TurnChannelBindRequest;
409 };
410 
411 }  // namespace cricket
412 
413 #endif  // P2P_BASE_TURN_PORT_H_
414