• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * libjingle
3  * Copyright 2012, Google Inc.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  *  1. Redistributions of source code must retain the above copyright notice,
9  *     this list of conditions and the following disclaimer.
10  *  2. Redistributions in binary form must reproduce the above copyright notice,
11  *     this list of conditions and the following disclaimer in the documentation
12  *     and/or other materials provided with the distribution.
13  *  3. The name of the author may not be used to endorse or promote products
14  *     derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19  * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 #ifndef TALK_P2P_BASE_TURNPORT_H_
29 #define TALK_P2P_BASE_TURNPORT_H_
30 
31 #include <stdio.h>
32 #include <list>
33 #include <set>
34 #include <string>
35 
36 #include "talk/p2p/base/port.h"
37 #include "talk/p2p/client/basicportallocator.h"
38 #include "webrtc/base/asyncpacketsocket.h"
39 
40 namespace rtc {
41 class AsyncResolver;
42 class SignalThread;
43 }
44 
45 namespace cricket {
46 
47 extern const char TURN_PORT_TYPE[];
48 class TurnAllocateRequest;
49 class TurnEntry;
50 
51 class TurnPort : public Port {
52  public:
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)53   static TurnPort* Create(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     return new TurnPort(thread, factory, network, socket,
63                         username, password, server_address,
64                         credentials, server_priority);
65   }
66 
Create(rtc::Thread * thread,rtc::PacketSocketFactory * factory,rtc::Network * network,const rtc::IPAddress & ip,int min_port,int max_port,const std::string & username,const std::string & password,const ProtocolAddress & server_address,const RelayCredentials & credentials,int server_priority)67   static TurnPort* Create(rtc::Thread* thread,
68                           rtc::PacketSocketFactory* factory,
69                           rtc::Network* network,
70                           const rtc::IPAddress& ip,
71                           int min_port, int max_port,
72                           const std::string& username,  // ice username.
73                           const std::string& password,  // ice password.
74                           const ProtocolAddress& server_address,
75                           const RelayCredentials& credentials,
76                           int server_priority) {
77     return new TurnPort(thread, factory, network, ip, min_port, max_port,
78                         username, password, server_address, credentials,
79                         server_priority);
80   }
81 
82   virtual ~TurnPort();
83 
server_address()84   const ProtocolAddress& server_address() const { return server_address_; }
85 
connected()86   bool connected() const { return connected_; }
credentials()87   const RelayCredentials& credentials() const { return credentials_; }
88 
89   virtual void PrepareAddress();
90   virtual Connection* CreateConnection(
91       const Candidate& c, PortInterface::CandidateOrigin origin);
92   virtual int SendTo(const void* data, size_t size,
93                      const rtc::SocketAddress& addr,
94                      const rtc::PacketOptions& options,
95                      bool payload);
96   virtual int SetOption(rtc::Socket::Option opt, int value);
97   virtual int GetOption(rtc::Socket::Option opt, int* value);
98   virtual int GetError();
99 
HandleIncomingPacket(rtc::AsyncPacketSocket * socket,const char * data,size_t size,const rtc::SocketAddress & remote_addr,const rtc::PacketTime & packet_time)100   virtual bool HandleIncomingPacket(
101       rtc::AsyncPacketSocket* socket, const char* data, size_t size,
102       const rtc::SocketAddress& remote_addr,
103       const rtc::PacketTime& packet_time) {
104     OnReadPacket(socket, data, size, remote_addr, packet_time);
105     return true;
106   }
107   virtual void OnReadPacket(rtc::AsyncPacketSocket* socket,
108                             const char* data, size_t size,
109                             const rtc::SocketAddress& remote_addr,
110                             const rtc::PacketTime& packet_time);
111 
112   virtual void OnReadyToSend(rtc::AsyncPacketSocket* socket);
113 
114   void OnSocketConnect(rtc::AsyncPacketSocket* socket);
115   void OnSocketClose(rtc::AsyncPacketSocket* socket, int error);
116 
117 
hash()118   const std::string& hash() const { return hash_; }
nonce()119   const std::string& nonce() const { return nonce_; }
120 
error()121   int error() const { return error_; }
122 
123   void OnAllocateMismatch();
124 
socket()125   rtc::AsyncPacketSocket* socket() const {
126     return socket_;
127   }
128 
129   // Signal with resolved server address.
130   // Parameters are port, server address and resolved server address.
131   // This signal will be sent only if server address is resolved successfully.
132   sigslot::signal3<TurnPort*,
133                    const rtc::SocketAddress&,
134                    const rtc::SocketAddress&> SignalResolvedServerAddress;
135 
136   // This signal is only for testing purpose.
137   sigslot::signal3<TurnPort*, const rtc::SocketAddress&, int>
138       SignalCreatePermissionResult;
139 
140  protected:
141   TurnPort(rtc::Thread* thread,
142            rtc::PacketSocketFactory* factory,
143            rtc::Network* network,
144            rtc::AsyncPacketSocket* socket,
145            const std::string& username,
146            const std::string& password,
147            const ProtocolAddress& server_address,
148            const RelayCredentials& credentials,
149            int server_priority);
150 
151   TurnPort(rtc::Thread* thread,
152            rtc::PacketSocketFactory* factory,
153            rtc::Network* network,
154            const rtc::IPAddress& ip,
155            int min_port, int max_port,
156            const std::string& username,
157            const std::string& password,
158            const ProtocolAddress& server_address,
159            const RelayCredentials& credentials,
160            int server_priority);
161 
162  private:
163   enum {
164     MSG_ERROR = MSG_FIRST_AVAILABLE,
165     MSG_ALLOCATE_MISMATCH
166   };
167 
168   typedef std::list<TurnEntry*> EntryList;
169   typedef std::map<rtc::Socket::Option, int> SocketOptionsMap;
170   typedef std::set<rtc::SocketAddress> AttemptedServerSet;
171 
172   virtual void OnMessage(rtc::Message* pmsg);
173 
174   bool CreateTurnClientSocket();
175 
set_nonce(const std::string & nonce)176   void set_nonce(const std::string& nonce) { nonce_ = nonce; }
set_realm(const std::string & realm)177   void set_realm(const std::string& realm) {
178     if (realm != realm_) {
179       realm_ = realm;
180       UpdateHash();
181     }
182   }
183 
184   bool SetAlternateServer(const rtc::SocketAddress& address);
185   void ResolveTurnAddress(const rtc::SocketAddress& address);
186   void OnResolveResult(rtc::AsyncResolverInterface* resolver);
187 
188   void AddRequestAuthInfo(StunMessage* msg);
189   void OnSendStunPacket(const void* data, size_t size, StunRequest* request);
190   // Stun address from allocate success response.
191   // Currently used only for testing.
192   void OnStunAddress(const rtc::SocketAddress& address);
193   void OnAllocateSuccess(const rtc::SocketAddress& address,
194                          const rtc::SocketAddress& stun_address);
195   void OnAllocateError();
196   void OnAllocateRequestTimeout();
197 
198   void HandleDataIndication(const char* data, size_t size,
199                             const rtc::PacketTime& packet_time);
200   void HandleChannelData(int channel_id, const char* data, size_t size,
201                          const rtc::PacketTime& packet_time);
202   void DispatchPacket(const char* data, size_t size,
203       const rtc::SocketAddress& remote_addr,
204       ProtocolType proto, const rtc::PacketTime& packet_time);
205 
206   bool ScheduleRefresh(int lifetime);
207   void SendRequest(StunRequest* request, int delay);
208   int Send(const void* data, size_t size,
209            const rtc::PacketOptions& options);
210   void UpdateHash();
211   bool UpdateNonce(StunMessage* response);
212 
213   bool HasPermission(const rtc::IPAddress& ipaddr) const;
214   TurnEntry* FindEntry(const rtc::SocketAddress& address) const;
215   TurnEntry* FindEntry(int channel_id) const;
216   TurnEntry* CreateEntry(const rtc::SocketAddress& address);
217   void DestroyEntry(const rtc::SocketAddress& address);
218   void OnConnectionDestroyed(Connection* conn);
219 
220   ProtocolAddress server_address_;
221   RelayCredentials credentials_;
222   AttemptedServerSet attempted_server_addresses_;
223 
224   rtc::AsyncPacketSocket* socket_;
225   SocketOptionsMap socket_options_;
226   rtc::AsyncResolverInterface* resolver_;
227   int error_;
228 
229   StunRequestManager request_manager_;
230   std::string realm_;       // From 401/438 response message.
231   std::string nonce_;       // From 401/438 response message.
232   std::string hash_;        // Digest of username:realm:password
233 
234   int next_channel_number_;
235   EntryList entries_;
236 
237   bool connected_;
238   // By default the value will be set to 0. This value will be used in
239   // calculating the candidate priority.
240   int server_priority_;
241 
242   // The number of retries made due to allocate mismatch error.
243   size_t allocate_mismatch_retries_;
244 
245   friend class TurnEntry;
246   friend class TurnAllocateRequest;
247   friend class TurnRefreshRequest;
248   friend class TurnCreatePermissionRequest;
249   friend class TurnChannelBindRequest;
250 };
251 
252 }  // namespace cricket
253 
254 #endif  // TALK_P2P_BASE_TURNPORT_H_
255