• 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 WEBRTC_P2P_BASE_TURNPORT_H_
12 #define WEBRTC_P2P_BASE_TURNPORT_H_
13 
14 #include <stdio.h>
15 #include <list>
16 #include <set>
17 #include <string>
18 
19 #include "webrtc/base/asyncinvoker.h"
20 #include "webrtc/base/asyncpacketsocket.h"
21 #include "webrtc/p2p/base/port.h"
22 #include "webrtc/p2p/client/basicportallocator.h"
23 
24 namespace rtc {
25 class AsyncResolver;
26 class SignalThread;
27 }
28 
29 namespace cricket {
30 
31 extern const char TURN_PORT_TYPE[];
32 class TurnAllocateRequest;
33 class TurnEntry;
34 
35 class TurnPort : public Port {
36  public:
37   enum PortState {
38     STATE_CONNECTING,    // Initial state, cannot send any packets.
39     STATE_CONNECTED,     // Socket connected, ready to send stun requests.
40     STATE_READY,         // Received allocate success, can send any packets.
41     STATE_DISCONNECTED,  // TCP connection died, cannot send any packets.
42   };
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)43   static TurnPort* Create(rtc::Thread* thread,
44                           rtc::PacketSocketFactory* factory,
45                           rtc::Network* network,
46                           rtc::AsyncPacketSocket* socket,
47                           const std::string& username,  // ice username.
48                           const std::string& password,  // ice password.
49                           const ProtocolAddress& server_address,
50                           const RelayCredentials& credentials,
51                           int server_priority,
52                           const std::string& origin) {
53     return new TurnPort(thread, factory, network, socket, username, password,
54                         server_address, credentials, server_priority, origin);
55   }
56 
Create(rtc::Thread * thread,rtc::PacketSocketFactory * factory,rtc::Network * network,const rtc::IPAddress & ip,uint16_t min_port,uint16_t max_port,const std::string & username,const std::string & password,const ProtocolAddress & server_address,const RelayCredentials & credentials,int server_priority,const std::string & origin)57   static TurnPort* Create(rtc::Thread* thread,
58                           rtc::PacketSocketFactory* factory,
59                           rtc::Network* network,
60                           const rtc::IPAddress& ip,
61                           uint16_t min_port,
62                           uint16_t max_port,
63                           const std::string& username,  // ice username.
64                           const std::string& password,  // ice password.
65                           const ProtocolAddress& server_address,
66                           const RelayCredentials& credentials,
67                           int server_priority,
68                           const std::string& origin) {
69     return new TurnPort(thread, factory, network, ip, min_port, max_port,
70                         username, password, server_address, credentials,
71                         server_priority, origin);
72   }
73 
74   virtual ~TurnPort();
75 
server_address()76   const ProtocolAddress& server_address() const { return server_address_; }
77   // Returns an empty address if the local address has not been assigned.
78   rtc::SocketAddress GetLocalAddress() const;
79 
ready()80   bool ready() const { return state_ == STATE_READY; }
connected()81   bool connected() const {
82     return state_ == STATE_READY || state_ == STATE_CONNECTED;
83   }
credentials()84   const RelayCredentials& credentials() const { return credentials_; }
85 
86   virtual void PrepareAddress();
87   virtual Connection* CreateConnection(
88       const Candidate& c, PortInterface::CandidateOrigin origin);
89   virtual int SendTo(const void* data, size_t size,
90                      const rtc::SocketAddress& addr,
91                      const rtc::PacketOptions& options,
92                      bool payload);
93   virtual int SetOption(rtc::Socket::Option opt, int value);
94   virtual int GetOption(rtc::Socket::Option opt, int* value);
95   virtual int GetError();
96 
HandleIncomingPacket(rtc::AsyncPacketSocket * socket,const char * data,size_t size,const rtc::SocketAddress & remote_addr,const rtc::PacketTime & packet_time)97   virtual bool HandleIncomingPacket(
98       rtc::AsyncPacketSocket* socket, const char* data, size_t size,
99       const rtc::SocketAddress& remote_addr,
100       const rtc::PacketTime& packet_time) {
101     OnReadPacket(socket, data, size, remote_addr, packet_time);
102     return true;
103   }
104   virtual void OnReadPacket(rtc::AsyncPacketSocket* socket,
105                             const char* data, size_t size,
106                             const rtc::SocketAddress& remote_addr,
107                             const rtc::PacketTime& packet_time);
108 
109   virtual void OnSentPacket(rtc::AsyncPacketSocket* socket,
110                             const rtc::SentPacket& sent_packet);
111   virtual void OnReadyToSend(rtc::AsyncPacketSocket* socket);
SupportsProtocol(const std::string & protocol)112   virtual bool SupportsProtocol(const std::string& protocol) const {
113     // Turn port only connects to UDP candidates.
114     return protocol == UDP_PROTOCOL_NAME;
115   }
116 
117   void OnSocketConnect(rtc::AsyncPacketSocket* socket);
118   void OnSocketClose(rtc::AsyncPacketSocket* socket, int error);
119 
120 
hash()121   const std::string& hash() const { return hash_; }
nonce()122   const std::string& nonce() const { return nonce_; }
123 
error()124   int error() const { return error_; }
125 
126   void OnAllocateMismatch();
127 
socket()128   rtc::AsyncPacketSocket* socket() const {
129     return socket_;
130   }
131 
132   // For testing only.
invoker()133   rtc::AsyncInvoker* invoker() { return &invoker_; }
134 
135   // Signal with resolved server address.
136   // Parameters are port, server address and resolved server address.
137   // This signal will be sent only if server address is resolved successfully.
138   sigslot::signal3<TurnPort*,
139                    const rtc::SocketAddress&,
140                    const rtc::SocketAddress&> SignalResolvedServerAddress;
141 
142   // All public methods/signals below are for testing only.
143   sigslot::signal2<TurnPort*, int> SignalTurnRefreshResult;
144   sigslot::signal3<TurnPort*, const rtc::SocketAddress&, int>
145       SignalCreatePermissionResult;
FlushRequests(int msg_type)146   void FlushRequests(int msg_type) { request_manager_.Flush(msg_type); }
HasRequests()147   bool HasRequests() { return !request_manager_.empty(); }
set_credentials(RelayCredentials & credentials)148   void set_credentials(RelayCredentials& credentials) {
149     credentials_ = credentials;
150   }
151   // Finds the turn entry with |address| and sets its channel id.
152   // Returns true if the entry is found.
153   bool SetEntryChannelId(const rtc::SocketAddress& address, int channel_id);
154 
155  protected:
156   TurnPort(rtc::Thread* thread,
157            rtc::PacketSocketFactory* factory,
158            rtc::Network* network,
159            rtc::AsyncPacketSocket* socket,
160            const std::string& username,
161            const std::string& password,
162            const ProtocolAddress& server_address,
163            const RelayCredentials& credentials,
164            int server_priority,
165            const std::string& origin);
166 
167   TurnPort(rtc::Thread* thread,
168            rtc::PacketSocketFactory* factory,
169            rtc::Network* network,
170            const rtc::IPAddress& ip,
171            uint16_t min_port,
172            uint16_t max_port,
173            const std::string& username,
174            const std::string& password,
175            const ProtocolAddress& server_address,
176            const RelayCredentials& credentials,
177            int server_priority,
178            const std::string& origin);
179 
180  private:
181   enum {
182     MSG_ALLOCATE_ERROR = MSG_FIRST_AVAILABLE,
183     MSG_ALLOCATE_MISMATCH,
184     MSG_TRY_ALTERNATE_SERVER,
185     MSG_REFRESH_ERROR
186   };
187 
188   typedef std::list<TurnEntry*> EntryList;
189   typedef std::map<rtc::Socket::Option, int> SocketOptionsMap;
190   typedef std::set<rtc::SocketAddress> AttemptedServerSet;
191 
192   virtual void OnMessage(rtc::Message* pmsg);
193 
194   bool CreateTurnClientSocket();
195 
set_nonce(const std::string & nonce)196   void set_nonce(const std::string& nonce) { nonce_ = nonce; }
set_realm(const std::string & realm)197   void set_realm(const std::string& realm) {
198     if (realm != realm_) {
199       realm_ = realm;
200       UpdateHash();
201     }
202   }
203 
204   // Shuts down the turn port, usually because of some fatal errors.
205   void Close();
206   void OnTurnRefreshError();
207   bool SetAlternateServer(const rtc::SocketAddress& address);
208   void ResolveTurnAddress(const rtc::SocketAddress& address);
209   void OnResolveResult(rtc::AsyncResolverInterface* resolver);
210 
211   void AddRequestAuthInfo(StunMessage* msg);
212   void OnSendStunPacket(const void* data, size_t size, StunRequest* request);
213   // Stun address from allocate success response.
214   // Currently used only for testing.
215   void OnStunAddress(const rtc::SocketAddress& address);
216   void OnAllocateSuccess(const rtc::SocketAddress& address,
217                          const rtc::SocketAddress& stun_address);
218   void OnAllocateError();
219   void OnAllocateRequestTimeout();
220 
221   void HandleDataIndication(const char* data, size_t size,
222                             const rtc::PacketTime& packet_time);
223   void HandleChannelData(int channel_id, const char* data, size_t size,
224                          const rtc::PacketTime& packet_time);
225   void DispatchPacket(const char* data, size_t size,
226       const rtc::SocketAddress& remote_addr,
227       ProtocolType proto, const rtc::PacketTime& packet_time);
228 
229   bool ScheduleRefresh(int lifetime);
230   void SendRequest(StunRequest* request, int delay);
231   int Send(const void* data, size_t size,
232            const rtc::PacketOptions& options);
233   void UpdateHash();
234   bool UpdateNonce(StunMessage* response);
235 
236   bool HasPermission(const rtc::IPAddress& ipaddr) const;
237   TurnEntry* FindEntry(const rtc::SocketAddress& address) const;
238   TurnEntry* FindEntry(int channel_id) const;
239   bool EntryExists(TurnEntry* e);
240   void CreateOrRefreshEntry(const rtc::SocketAddress& address);
241   void DestroyEntry(TurnEntry* entry);
242   // Destroys the entry only if |timestamp| matches the destruction timestamp
243   // in |entry|.
244   void DestroyEntryIfNotCancelled(TurnEntry* entry, uint32_t timestamp);
245   void ScheduleEntryDestruction(TurnEntry* entry);
246   void CancelEntryDestruction(TurnEntry* entry);
247   void OnConnectionDestroyed(Connection* conn);
248 
249   // Destroys the connection with remote address |address|. Returns true if
250   // a connection is found and destroyed.
251   bool DestroyConnection(const rtc::SocketAddress& address);
252 
253   ProtocolAddress server_address_;
254   RelayCredentials credentials_;
255   AttemptedServerSet attempted_server_addresses_;
256 
257   rtc::AsyncPacketSocket* socket_;
258   SocketOptionsMap socket_options_;
259   rtc::AsyncResolverInterface* resolver_;
260   int error_;
261 
262   StunRequestManager request_manager_;
263   std::string realm_;       // From 401/438 response message.
264   std::string nonce_;       // From 401/438 response message.
265   std::string hash_;        // Digest of username:realm:password
266 
267   int next_channel_number_;
268   EntryList entries_;
269 
270   PortState state_;
271   // By default the value will be set to 0. This value will be used in
272   // calculating the candidate priority.
273   int server_priority_;
274 
275   // The number of retries made due to allocate mismatch error.
276   size_t allocate_mismatch_retries_;
277 
278   rtc::AsyncInvoker invoker_;
279 
280   friend class TurnEntry;
281   friend class TurnAllocateRequest;
282   friend class TurnRefreshRequest;
283   friend class TurnCreatePermissionRequest;
284   friend class TurnChannelBindRequest;
285 };
286 
287 }  // namespace cricket
288 
289 #endif  // WEBRTC_P2P_BASE_TURNPORT_H_
290