turnport.h revision 55674ffb32307c6f3efaab442340d3c5c075073b
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
24namespace rtc {
25class AsyncResolver;
26class SignalThread;
27}
28
29namespace cricket {
30
31extern const char TURN_PORT_TYPE[];
32class TurnAllocateRequest;
33class TurnEntry;
34
35class 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  };
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
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
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
80  bool ready() const { return state_ == STATE_READY; }
81  bool connected() const {
82    return state_ == STATE_READY || state_ == STATE_CONNECTED;
83  }
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
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);
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
121  const std::string& hash() const { return hash_; }
122  const std::string& nonce() const { return nonce_; }
123
124  int error() const { return error_; }
125
126  void OnAllocateMismatch();
127
128  rtc::AsyncPacketSocket* socket() const {
129    return socket_;
130  }
131
132  // For testing only.
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;
146  void FlushRequests(int msg_type) { request_manager_.Flush(msg_type); }
147  bool HasRequests() { return !request_manager_.empty(); }
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
196  void set_nonce(const std::string& nonce) { nonce_ = nonce; }
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