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_TURNSERVER_H_
29 #define TALK_P2P_BASE_TURNSERVER_H_
36 #include "talk/p2p/base/portinterface.h"
37 #include "webrtc/base/asyncpacketsocket.h"
38 #include "webrtc/base/messagequeue.h"
39 #include "webrtc/base/sigslot.h"
40 #include "webrtc/base/socketaddress.h"
44 class PacketSocketFactory;
53 // The default server port for TURN, as specified in RFC5766.
54 const int TURN_SERVER_PORT = 3478;
56 // An interface through which the MD5 credential hash can be retrieved.
57 class TurnAuthInterface {
59 // Gets HA1 for the specified user and realm.
60 // HA1 = MD5(A1) = MD5(username:realm:password).
61 // Return true if the given username and realm are valid, or false if not.
62 virtual bool GetKey(const std::string& username, const std::string& realm,
63 std::string* key) = 0;
66 // An interface enables Turn Server to control redirection behavior.
67 class TurnRedirectInterface {
69 virtual bool ShouldRedirect(const rtc::SocketAddress& address,
70 rtc::SocketAddress* out) = 0;
71 virtual ~TurnRedirectInterface() {}
74 // The core TURN server class. Give it a socket to listen on via
75 // AddInternalServerSocket, and a factory to create external sockets via
76 // SetExternalSocketFactory, and it's ready to go.
77 // Not yet wired up: TCP support.
78 class TurnServer : public sigslot::has_slots<> {
80 explicit TurnServer(rtc::Thread* thread);
83 // Gets/sets the realm value to use for the server.
84 const std::string& realm() const { return realm_; }
85 void set_realm(const std::string& realm) { realm_ = realm; }
87 // Gets/sets the value for the SOFTWARE attribute for TURN messages.
88 const std::string& software() const { return software_; }
89 void set_software(const std::string& software) { software_ = software; }
91 // Sets the authentication callback; does not take ownership.
92 void set_auth_hook(TurnAuthInterface* auth_hook) { auth_hook_ = auth_hook; }
94 void set_redirect_hook(TurnRedirectInterface* redirect_hook) {
95 redirect_hook_ = redirect_hook;
98 void set_enable_otu_nonce(bool enable) { enable_otu_nonce_ = enable; }
100 // Starts listening for packets from internal clients.
101 void AddInternalSocket(rtc::AsyncPacketSocket* socket,
103 // Starts listening for the connections on this socket. When someone tries
104 // to connect, the connection will be accepted and a new internal socket
106 void AddInternalServerSocket(rtc::AsyncSocket* socket,
108 // Specifies the factory to use for creating external sockets.
109 void SetExternalSocketFactory(rtc::PacketSocketFactory* factory,
110 const rtc::SocketAddress& address);
113 // Encapsulates the client's connection to the server.
116 Connection() : proto_(PROTO_UDP), socket_(NULL) {}
117 Connection(const rtc::SocketAddress& src,
119 rtc::AsyncPacketSocket* socket);
120 const rtc::SocketAddress& src() const { return src_; }
121 rtc::AsyncPacketSocket* socket() { return socket_; }
122 bool operator==(const Connection& t) const;
123 bool operator<(const Connection& t) const;
124 std::string ToString() const;
127 rtc::SocketAddress src_;
128 rtc::SocketAddress dst_;
129 cricket::ProtocolType proto_;
130 rtc::AsyncPacketSocket* socket_;
135 typedef std::map<Connection, Allocation*> AllocationMap;
137 void OnInternalPacket(rtc::AsyncPacketSocket* socket, const char* data,
138 size_t size, const rtc::SocketAddress& address,
139 const rtc::PacketTime& packet_time);
141 void OnNewInternalConnection(rtc::AsyncSocket* socket);
143 // Accept connections on this server socket.
144 void AcceptConnection(rtc::AsyncSocket* server_socket);
145 void OnInternalSocketClose(rtc::AsyncPacketSocket* socket, int err);
147 void HandleStunMessage(Connection* conn, const char* data, size_t size);
148 void HandleBindingRequest(Connection* conn, const StunMessage* msg);
149 void HandleAllocateRequest(Connection* conn, const TurnMessage* msg,
150 const std::string& key);
152 bool GetKey(const StunMessage* msg, std::string* key);
153 bool CheckAuthorization(Connection* conn, const StunMessage* msg,
154 const char* data, size_t size,
155 const std::string& key);
156 std::string GenerateNonce() const;
157 bool ValidateNonce(const std::string& nonce) const;
159 Allocation* FindAllocation(Connection* conn);
160 Allocation* CreateAllocation(Connection* conn, int proto,
161 const std::string& key);
163 void SendErrorResponse(Connection* conn, const StunMessage* req,
164 int code, const std::string& reason);
166 void SendErrorResponseWithRealmAndNonce(Connection* conn,
167 const StunMessage* req,
169 const std::string& reason);
171 void SendErrorResponseWithAlternateServer(Connection* conn,
172 const StunMessage* req,
173 const rtc::SocketAddress& addr);
175 void SendStun(Connection* conn, StunMessage* msg);
176 void Send(Connection* conn, const rtc::ByteBuffer& buf);
178 void OnAllocationDestroyed(Allocation* allocation);
179 void DestroyInternalSocket(rtc::AsyncPacketSocket* socket);
181 typedef std::map<rtc::AsyncPacketSocket*,
182 ProtocolType> InternalSocketMap;
183 typedef std::map<rtc::AsyncSocket*,
184 ProtocolType> ServerSocketMap;
186 rtc::Thread* thread_;
187 std::string nonce_key_;
189 std::string software_;
190 TurnAuthInterface* auth_hook_;
191 TurnRedirectInterface* redirect_hook_;
192 // otu - one-time-use. Server will respond with 438 if it's
193 // sees the same nonce in next transaction.
194 bool enable_otu_nonce_;
196 InternalSocketMap server_sockets_;
197 ServerSocketMap server_listen_sockets_;
198 rtc::scoped_ptr<rtc::PacketSocketFactory>
199 external_socket_factory_;
200 rtc::SocketAddress external_addr_;
202 AllocationMap allocations_;
205 } // namespace cricket
207 #endif // TALK_P2P_BASE_TURNSERVER_H_