blob: 52546e09a3d8efb162833c57dae8383f97dec367 [file] [log] [blame]
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001/*
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/p2p/base/port.h"
20#include "webrtc/p2p/client/basicportallocator.h"
21#include "webrtc/base/asyncpacketsocket.h"
22
23namespace rtc {
24class AsyncResolver;
25class SignalThread;
26}
27
28namespace cricket {
29
30extern const char TURN_PORT_TYPE[];
31class TurnAllocateRequest;
32class TurnEntry;
33
34class TurnPort : public Port {
35 public:
honghaizb19eba32015-08-03 10:23:31 -070036 enum PortState {
37 STATE_CONNECTING, // Initial state, cannot send any packets.
38 STATE_CONNECTED, // Socket connected, ready to send stun requests.
39 STATE_READY, // Received allocate success, can send any packets.
40 STATE_DISCONNECTED, // TCP connection died, cannot send any packets.
41 };
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000042 static TurnPort* Create(rtc::Thread* thread,
43 rtc::PacketSocketFactory* factory,
44 rtc::Network* network,
45 rtc::AsyncPacketSocket* socket,
46 const std::string& username, // ice username.
47 const std::string& password, // ice password.
48 const ProtocolAddress& server_address,
49 const RelayCredentials& credentials,
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +000050 int server_priority,
51 const std::string& origin) {
pkasting@chromium.org332331f2014-11-06 20:19:22 +000052 return new TurnPort(thread, factory, network, socket, username, password,
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +000053 server_address, credentials, server_priority, origin);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000054 }
55
56 static TurnPort* Create(rtc::Thread* thread,
57 rtc::PacketSocketFactory* factory,
58 rtc::Network* network,
59 const rtc::IPAddress& ip,
pkasting@chromium.org332331f2014-11-06 20:19:22 +000060 uint16 min_port,
61 uint16 max_port,
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000062 const std::string& username, // ice username.
63 const std::string& password, // ice password.
64 const ProtocolAddress& server_address,
65 const RelayCredentials& credentials,
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +000066 int server_priority,
67 const std::string& origin) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000068 return new TurnPort(thread, factory, network, ip, min_port, max_port,
69 username, password, server_address, credentials,
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +000070 server_priority, origin);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000071 }
72
73 virtual ~TurnPort();
74
75 const ProtocolAddress& server_address() const { return server_address_; }
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +000076 // Returns an empty address if the local address has not been assigned.
77 rtc::SocketAddress GetLocalAddress() const;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000078
honghaizb19eba32015-08-03 10:23:31 -070079 bool ready() const { return state_ == STATE_READY; }
80 bool connected() const {
81 return state_ == STATE_READY || state_ == STATE_CONNECTED;
82 }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000083 const RelayCredentials& credentials() const { return credentials_; }
84
85 virtual void PrepareAddress();
86 virtual Connection* CreateConnection(
87 const Candidate& c, PortInterface::CandidateOrigin origin);
88 virtual int SendTo(const void* data, size_t size,
89 const rtc::SocketAddress& addr,
90 const rtc::PacketOptions& options,
91 bool payload);
92 virtual int SetOption(rtc::Socket::Option opt, int value);
93 virtual int GetOption(rtc::Socket::Option opt, int* value);
94 virtual int GetError();
95
96 virtual bool HandleIncomingPacket(
97 rtc::AsyncPacketSocket* socket, const char* data, size_t size,
98 const rtc::SocketAddress& remote_addr,
99 const rtc::PacketTime& packet_time) {
100 OnReadPacket(socket, data, size, remote_addr, packet_time);
101 return true;
102 }
103 virtual void OnReadPacket(rtc::AsyncPacketSocket* socket,
104 const char* data, size_t size,
105 const rtc::SocketAddress& remote_addr,
106 const rtc::PacketTime& packet_time);
107
108 virtual void OnReadyToSend(rtc::AsyncPacketSocket* socket);
109
110 void OnSocketConnect(rtc::AsyncPacketSocket* socket);
111 void OnSocketClose(rtc::AsyncPacketSocket* socket, int error);
112
113
114 const std::string& hash() const { return hash_; }
115 const std::string& nonce() const { return nonce_; }
116
117 int error() const { return error_; }
118
119 void OnAllocateMismatch();
120
121 rtc::AsyncPacketSocket* socket() const {
122 return socket_;
123 }
124
125 // Signal with resolved server address.
126 // Parameters are port, server address and resolved server address.
127 // This signal will be sent only if server address is resolved successfully.
128 sigslot::signal3<TurnPort*,
129 const rtc::SocketAddress&,
130 const rtc::SocketAddress&> SignalResolvedServerAddress;
131
132 // This signal is only for testing purpose.
133 sigslot::signal3<TurnPort*, const rtc::SocketAddress&, int>
134 SignalCreatePermissionResult;
135
136 protected:
137 TurnPort(rtc::Thread* thread,
138 rtc::PacketSocketFactory* factory,
139 rtc::Network* network,
140 rtc::AsyncPacketSocket* socket,
141 const std::string& username,
142 const std::string& password,
143 const ProtocolAddress& server_address,
144 const RelayCredentials& credentials,
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +0000145 int server_priority,
146 const std::string& origin);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000147
148 TurnPort(rtc::Thread* thread,
149 rtc::PacketSocketFactory* factory,
150 rtc::Network* network,
151 const rtc::IPAddress& ip,
pkasting@chromium.org332331f2014-11-06 20:19:22 +0000152 uint16 min_port,
153 uint16 max_port,
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000154 const std::string& username,
155 const std::string& password,
156 const ProtocolAddress& server_address,
157 const RelayCredentials& credentials,
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +0000158 int server_priority,
159 const std::string& origin);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000160
161 private:
162 enum {
163 MSG_ERROR = MSG_FIRST_AVAILABLE,
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +0000164 MSG_ALLOCATE_MISMATCH,
165 MSG_TRY_ALTERNATE_SERVER
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000166 };
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
176 void set_nonce(const std::string& nonce) { nonce_ = nonce; }
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
honghaizb19eba32015-08-03 10:23:31 -0700237 PortState state_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000238 // 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 // WEBRTC_P2P_BASE_TURNPORT_H_