blob: 6345aea16e54043bc1da1f3f5fef139f7bcfa017 [file] [log] [blame]
/*
* libjingle
* Copyright 2012, Google Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef WEBRTC_P2P_BASE_TURNPORT_H_
#define WEBRTC_P2P_BASE_TURNPORT_H_
#include <stdio.h>
#include <list>
#include <set>
#include <string>
#include "webrtc/p2p/base/port.h"
#include "webrtc/p2p/client/basicportallocator.h"
#include "webrtc/base/asyncpacketsocket.h"
namespace rtc {
class AsyncResolver;
class SignalThread;
}
namespace cricket {
extern const char TURN_PORT_TYPE[];
class TurnAllocateRequest;
class TurnEntry;
class TurnPort : public Port {
public:
static TurnPort* Create(rtc::Thread* thread,
rtc::PacketSocketFactory* factory,
rtc::Network* network,
rtc::AsyncPacketSocket* socket,
const std::string& username, // ice username.
const std::string& password, // ice password.
const ProtocolAddress& server_address,
const RelayCredentials& credentials,
int server_priority) {
return new TurnPort(thread, factory, network, socket,
username, password, server_address,
credentials, server_priority);
}
static TurnPort* Create(rtc::Thread* thread,
rtc::PacketSocketFactory* factory,
rtc::Network* network,
const rtc::IPAddress& ip,
int min_port, int max_port,
const std::string& username, // ice username.
const std::string& password, // ice password.
const ProtocolAddress& server_address,
const RelayCredentials& credentials,
int server_priority) {
return new TurnPort(thread, factory, network, ip, min_port, max_port,
username, password, server_address, credentials,
server_priority);
}
virtual ~TurnPort();
const ProtocolAddress& server_address() const { return server_address_; }
bool connected() const { return connected_; }
const RelayCredentials& credentials() const { return credentials_; }
virtual void PrepareAddress();
virtual Connection* CreateConnection(
const Candidate& c, PortInterface::CandidateOrigin origin);
virtual int SendTo(const void* data, size_t size,
const rtc::SocketAddress& addr,
const rtc::PacketOptions& options,
bool payload);
virtual int SetOption(rtc::Socket::Option opt, int value);
virtual int GetOption(rtc::Socket::Option opt, int* value);
virtual int GetError();
virtual bool HandleIncomingPacket(
rtc::AsyncPacketSocket* socket, const char* data, size_t size,
const rtc::SocketAddress& remote_addr,
const rtc::PacketTime& packet_time) {
OnReadPacket(socket, data, size, remote_addr, packet_time);
return true;
}
virtual void OnReadPacket(rtc::AsyncPacketSocket* socket,
const char* data, size_t size,
const rtc::SocketAddress& remote_addr,
const rtc::PacketTime& packet_time);
virtual void OnReadyToSend(rtc::AsyncPacketSocket* socket);
void OnSocketConnect(rtc::AsyncPacketSocket* socket);
void OnSocketClose(rtc::AsyncPacketSocket* socket, int error);
const std::string& hash() const { return hash_; }
const std::string& nonce() const { return nonce_; }
int error() const { return error_; }
void OnAllocateMismatch();
rtc::AsyncPacketSocket* socket() const {
return socket_;
}
// Signal with resolved server address.
// Parameters are port, server address and resolved server address.
// This signal will be sent only if server address is resolved successfully.
sigslot::signal3<TurnPort*,
const rtc::SocketAddress&,
const rtc::SocketAddress&> SignalResolvedServerAddress;
// This signal is only for testing purpose.
sigslot::signal3<TurnPort*, const rtc::SocketAddress&, int>
SignalCreatePermissionResult;
protected:
TurnPort(rtc::Thread* thread,
rtc::PacketSocketFactory* factory,
rtc::Network* network,
rtc::AsyncPacketSocket* socket,
const std::string& username,
const std::string& password,
const ProtocolAddress& server_address,
const RelayCredentials& credentials,
int server_priority);
TurnPort(rtc::Thread* thread,
rtc::PacketSocketFactory* factory,
rtc::Network* network,
const rtc::IPAddress& ip,
int min_port, int max_port,
const std::string& username,
const std::string& password,
const ProtocolAddress& server_address,
const RelayCredentials& credentials,
int server_priority);
private:
enum {
MSG_ERROR = MSG_FIRST_AVAILABLE,
MSG_ALLOCATE_MISMATCH
};
typedef std::list<TurnEntry*> EntryList;
typedef std::map<rtc::Socket::Option, int> SocketOptionsMap;
typedef std::set<rtc::SocketAddress> AttemptedServerSet;
virtual void OnMessage(rtc::Message* pmsg);
bool CreateTurnClientSocket();
void set_nonce(const std::string& nonce) { nonce_ = nonce; }
void set_realm(const std::string& realm) {
if (realm != realm_) {
realm_ = realm;
UpdateHash();
}
}
bool SetAlternateServer(const rtc::SocketAddress& address);
void ResolveTurnAddress(const rtc::SocketAddress& address);
void OnResolveResult(rtc::AsyncResolverInterface* resolver);
void AddRequestAuthInfo(StunMessage* msg);
void OnSendStunPacket(const void* data, size_t size, StunRequest* request);
// Stun address from allocate success response.
// Currently used only for testing.
void OnStunAddress(const rtc::SocketAddress& address);
void OnAllocateSuccess(const rtc::SocketAddress& address,
const rtc::SocketAddress& stun_address);
void OnAllocateError();
void OnAllocateRequestTimeout();
void HandleDataIndication(const char* data, size_t size,
const rtc::PacketTime& packet_time);
void HandleChannelData(int channel_id, const char* data, size_t size,
const rtc::PacketTime& packet_time);
void DispatchPacket(const char* data, size_t size,
const rtc::SocketAddress& remote_addr,
ProtocolType proto, const rtc::PacketTime& packet_time);
bool ScheduleRefresh(int lifetime);
void SendRequest(StunRequest* request, int delay);
int Send(const void* data, size_t size,
const rtc::PacketOptions& options);
void UpdateHash();
bool UpdateNonce(StunMessage* response);
bool HasPermission(const rtc::IPAddress& ipaddr) const;
TurnEntry* FindEntry(const rtc::SocketAddress& address) const;
TurnEntry* FindEntry(int channel_id) const;
TurnEntry* CreateEntry(const rtc::SocketAddress& address);
void DestroyEntry(const rtc::SocketAddress& address);
void OnConnectionDestroyed(Connection* conn);
ProtocolAddress server_address_;
RelayCredentials credentials_;
AttemptedServerSet attempted_server_addresses_;
rtc::AsyncPacketSocket* socket_;
SocketOptionsMap socket_options_;
rtc::AsyncResolverInterface* resolver_;
int error_;
StunRequestManager request_manager_;
std::string realm_; // From 401/438 response message.
std::string nonce_; // From 401/438 response message.
std::string hash_; // Digest of username:realm:password
int next_channel_number_;
EntryList entries_;
bool connected_;
// By default the value will be set to 0. This value will be used in
// calculating the candidate priority.
int server_priority_;
// The number of retries made due to allocate mismatch error.
size_t allocate_mismatch_retries_;
friend class TurnEntry;
friend class TurnAllocateRequest;
friend class TurnRefreshRequest;
friend class TurnCreatePermissionRequest;
friend class TurnChannelBindRequest;
};
} // namespace cricket
#endif // WEBRTC_P2P_BASE_TURNPORT_H_