3 * Copyright 2012, Google Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
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.
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.
28 #ifndef TALK_P2P_BASE_TURNPORT_H_
29 #define TALK_P2P_BASE_TURNPORT_H_
35 #include "talk/base/asyncpacketsocket.h"
36 #include "talk/p2p/base/port.h"
37 #include "talk/p2p/client/basicportallocator.h"
46 extern const char TURN_PORT_TYPE[];
47 class TurnAllocateRequest;
50 class TurnPort : public Port {
52 static TurnPort* Create(talk_base::Thread* thread,
53 talk_base::PacketSocketFactory* factory,
54 talk_base::Network* network,
55 talk_base::AsyncPacketSocket* socket,
56 const std::string& username, // ice username.
57 const std::string& password, // ice password.
58 const ProtocolAddress& server_address,
59 const RelayCredentials& credentials) {
60 return new TurnPort(thread, factory, network, socket, username, password,
61 server_address, credentials);
64 static TurnPort* Create(talk_base::Thread* thread,
65 talk_base::PacketSocketFactory* factory,
66 talk_base::Network* network,
67 const talk_base::IPAddress& ip,
68 int min_port, int max_port,
69 const std::string& username, // ice username.
70 const std::string& password, // ice password.
71 const ProtocolAddress& server_address,
72 const RelayCredentials& credentials) {
73 return new TurnPort(thread, factory, network, ip, min_port, max_port,
74 username, password, server_address, credentials);
79 const ProtocolAddress& server_address() const { return server_address_; }
81 bool connected() const { return connected_; }
82 const RelayCredentials& credentials() const { return credentials_; }
84 virtual void PrepareAddress();
85 virtual Connection* CreateConnection(
86 const Candidate& c, PortInterface::CandidateOrigin origin);
87 virtual int SendTo(const void* data, size_t size,
88 const talk_base::SocketAddress& addr,
89 const talk_base::PacketOptions& options,
91 virtual int SetOption(talk_base::Socket::Option opt, int value);
92 virtual int GetOption(talk_base::Socket::Option opt, int* value);
93 virtual int GetError();
95 virtual bool HandleIncomingPacket(
96 talk_base::AsyncPacketSocket* socket, const char* data, size_t size,
97 const talk_base::SocketAddress& remote_addr,
98 const talk_base::PacketTime& packet_time) {
99 OnReadPacket(socket, data, size, remote_addr, packet_time);
102 virtual void OnReadPacket(talk_base::AsyncPacketSocket* socket,
103 const char* data, size_t size,
104 const talk_base::SocketAddress& remote_addr,
105 const talk_base::PacketTime& packet_time);
107 virtual void OnReadyToSend(talk_base::AsyncPacketSocket* socket);
109 void OnSocketConnect(talk_base::AsyncPacketSocket* socket);
110 void OnSocketClose(talk_base::AsyncPacketSocket* socket, int error);
113 const std::string& hash() const { return hash_; }
114 const std::string& nonce() const { return nonce_; }
116 // Signal with resolved server address.
117 // Parameters are port, server address and resolved server address.
118 // This signal will be sent only if server address is resolved successfully.
119 sigslot::signal3<TurnPort*,
120 const talk_base::SocketAddress&,
121 const talk_base::SocketAddress&> SignalResolvedServerAddress;
123 // This signal is only for testing purpose.
124 sigslot::signal3<TurnPort*, const talk_base::SocketAddress&, int>
125 SignalCreatePermissionResult;
128 TurnPort(talk_base::Thread* thread,
129 talk_base::PacketSocketFactory* factory,
130 talk_base::Network* network,
131 talk_base::AsyncPacketSocket* socket,
132 const std::string& username,
133 const std::string& password,
134 const ProtocolAddress& server_address,
135 const RelayCredentials& credentials);
137 TurnPort(talk_base::Thread* thread,
138 talk_base::PacketSocketFactory* factory,
139 talk_base::Network* network,
140 const talk_base::IPAddress& ip,
141 int min_port, int max_port,
142 const std::string& username,
143 const std::string& password,
144 const ProtocolAddress& server_address,
145 const RelayCredentials& credentials);
148 enum { MSG_ERROR = MSG_FIRST_AVAILABLE };
150 typedef std::list<TurnEntry*> EntryList;
151 typedef std::map<talk_base::Socket::Option, int> SocketOptionsMap;
153 virtual void OnMessage(talk_base::Message* pmsg);
155 void set_nonce(const std::string& nonce) { nonce_ = nonce; }
156 void set_realm(const std::string& realm) {
157 if (realm != realm_) {
163 void ResolveTurnAddress(const talk_base::SocketAddress& address);
164 void OnResolveResult(talk_base::AsyncResolverInterface* resolver);
166 void AddRequestAuthInfo(StunMessage* msg);
167 void OnSendStunPacket(const void* data, size_t size, StunRequest* request);
168 // Stun address from allocate success response.
169 // Currently used only for testing.
170 void OnStunAddress(const talk_base::SocketAddress& address);
171 void OnAllocateSuccess(const talk_base::SocketAddress& address,
172 const talk_base::SocketAddress& stun_address);
173 void OnAllocateError();
174 void OnAllocateRequestTimeout();
176 void HandleDataIndication(const char* data, size_t size,
177 const talk_base::PacketTime& packet_time);
178 void HandleChannelData(int channel_id, const char* data, size_t size,
179 const talk_base::PacketTime& packet_time);
180 void DispatchPacket(const char* data, size_t size,
181 const talk_base::SocketAddress& remote_addr,
182 ProtocolType proto, const talk_base::PacketTime& packet_time);
184 bool ScheduleRefresh(int lifetime);
185 void SendRequest(StunRequest* request, int delay);
186 int Send(const void* data, size_t size,
187 const talk_base::PacketOptions& options);
189 bool UpdateNonce(StunMessage* response);
191 bool HasPermission(const talk_base::IPAddress& ipaddr) const;
192 TurnEntry* FindEntry(const talk_base::SocketAddress& address) const;
193 TurnEntry* FindEntry(int channel_id) const;
194 TurnEntry* CreateEntry(const talk_base::SocketAddress& address);
195 void DestroyEntry(const talk_base::SocketAddress& address);
196 void OnConnectionDestroyed(Connection* conn);
198 ProtocolAddress server_address_;
199 RelayCredentials credentials_;
201 talk_base::AsyncPacketSocket* socket_;
202 SocketOptionsMap socket_options_;
203 talk_base::AsyncResolverInterface* resolver_;
206 StunRequestManager request_manager_;
207 std::string realm_; // From 401/438 response message.
208 std::string nonce_; // From 401/438 response message.
209 std::string hash_; // Digest of username:realm:password
211 int next_channel_number_;
216 friend class TurnEntry;
217 friend class TurnAllocateRequest;
218 friend class TurnRefreshRequest;
219 friend class TurnCreatePermissionRequest;
220 friend class TurnChannelBindRequest;
223 } // namespace cricket
225 #endif // TALK_P2P_BASE_TURNPORT_H_