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/p2p/base/port.h"
36 #include "talk/p2p/client/basicportallocator.h"
39 class AsyncPacketSocket;
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 const talk_base::IPAddress& ip,
56 int min_port, int max_port,
57 const std::string& username, // ice username.
58 const std::string& password, // ice password.
59 const ProtocolAddress& server_address,
60 const RelayCredentials& credentials) {
61 return new TurnPort(thread, factory, network, ip, min_port, max_port,
62 username, password, server_address, credentials);
67 const ProtocolAddress& server_address() const { return server_address_; }
69 bool connected() const { return connected_; }
70 const RelayCredentials& credentials() const { return credentials_; }
72 virtual void PrepareAddress();
73 virtual Connection* CreateConnection(
74 const Candidate& c, PortInterface::CandidateOrigin origin);
75 virtual int SendTo(const void* data, size_t size,
76 const talk_base::SocketAddress& addr,
77 talk_base::DiffServCodePoint dscp,
79 virtual int SetOption(talk_base::Socket::Option opt, int value);
80 virtual int GetOption(talk_base::Socket::Option opt, int* value);
81 virtual int GetError();
82 virtual void OnReadPacket(talk_base::AsyncPacketSocket* socket,
83 const char* data, size_t size,
84 const talk_base::SocketAddress& remote_addr);
85 virtual void OnReadyToSend(talk_base::AsyncPacketSocket* socket);
87 void OnSocketConnect(talk_base::AsyncPacketSocket* socket);
88 void OnSocketClose(talk_base::AsyncPacketSocket* socket, int error);
91 const std::string& hash() const { return hash_; }
92 const std::string& nonce() const { return nonce_; }
94 // This signal is only for testing purpose.
95 sigslot::signal3<TurnPort*, const talk_base::SocketAddress&, int>
96 SignalCreatePermissionResult;
99 TurnPort(talk_base::Thread* thread,
100 talk_base::PacketSocketFactory* factory,
101 talk_base::Network* network,
102 const talk_base::IPAddress& ip,
103 int min_port, int max_port,
104 const std::string& username,
105 const std::string& password,
106 const ProtocolAddress& server_address,
107 const RelayCredentials& credentials);
110 enum { MSG_ERROR = MSG_FIRST_AVAILABLE };
112 typedef std::list<TurnEntry*> EntryList;
113 typedef std::map<talk_base::Socket::Option, int> SocketOptionsMap;
115 virtual void OnMessage(talk_base::Message* pmsg);
117 void set_nonce(const std::string& nonce) { nonce_ = nonce; }
118 void set_realm(const std::string& realm) {
119 if (realm != realm_) {
125 void ResolveTurnAddress(const talk_base::SocketAddress& address);
126 void OnResolveResult(talk_base::SignalThread* signal_thread);
128 void AddRequestAuthInfo(StunMessage* msg);
129 void OnSendStunPacket(const void* data, size_t size, StunRequest* request);
130 // Stun address from allocate success response.
131 // Currently used only for testing.
132 void OnStunAddress(const talk_base::SocketAddress& address);
133 void OnAllocateSuccess(const talk_base::SocketAddress& address);
134 void OnAllocateError();
135 void OnAllocateRequestTimeout();
137 void HandleDataIndication(const char* data, size_t size);
138 void HandleChannelData(int channel_id, const char* data, size_t size);
139 void DispatchPacket(const char* data, size_t size,
140 const talk_base::SocketAddress& remote_addr, ProtocolType proto);
142 bool ScheduleRefresh(int lifetime);
143 void SendRequest(StunRequest* request, int delay);
144 int Send(const void* data, size_t size, talk_base::DiffServCodePoint dscp);
146 bool UpdateNonce(StunMessage* response);
148 bool HasPermission(const talk_base::IPAddress& ipaddr) const;
149 TurnEntry* FindEntry(const talk_base::SocketAddress& address) const;
150 TurnEntry* FindEntry(int channel_id) const;
151 TurnEntry* CreateEntry(const talk_base::SocketAddress& address);
152 void DestroyEntry(const talk_base::SocketAddress& address);
153 void OnConnectionDestroyed(Connection* conn);
155 ProtocolAddress server_address_;
156 RelayCredentials credentials_;
158 talk_base::scoped_ptr<talk_base::AsyncPacketSocket> socket_;
159 SocketOptionsMap socket_options_;
160 talk_base::AsyncResolver* resolver_;
163 StunRequestManager request_manager_;
164 std::string realm_; // From 401/438 response message.
165 std::string nonce_; // From 401/438 response message.
166 std::string hash_; // Digest of username:realm:password
168 int next_channel_number_;
173 friend class TurnEntry;
174 friend class TurnAllocateRequest;
175 friend class TurnRefreshRequest;
176 friend class TurnCreatePermissionRequest;
177 friend class TurnChannelBindRequest;
180 } // namespace cricket
182 #endif // TALK_P2P_BASE_TURNPORT_H_