Added support for an Origin header in STUN messages.
For WebRTC there are instances where it may be desirable to provide information to the STUN/TURN server about the website that initiated a peer connection. This modification allows an origin string to be included in the MediaConstraints object provided by the browser, which is then passed as a STUN header in communications with the server. A separate change will be submitted to the Chromium project that uses and is dependent on this change, implementing IETF draft http://tools.ietf.org/html/draft-johnston-tram-stun-origin-02 Originally a patch from skobalt@gmail.com. (https://webrtc-codereview.appspot.com/12839005/edit) R=juberti@webrtc.org Review URL: https://webrtc-codereview.appspot.com/41409004 git-svn-id: http://webrtc.googlecode.com/svn/trunk@8035 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
parent
2693a54614
commit
0ba1533fdb
2
AUTHORS
2
AUTHORS
@ -9,6 +9,7 @@ Christophe Dumez <ch.dumez@samsung.com>
|
||||
Colin Plumb
|
||||
Eric Rescorla, RTFM Inc.
|
||||
Giji Gangadharan <giji.g@samsung.com>
|
||||
Graham Yoakum <gyoakum@skobalt.com>
|
||||
James H. Brown <jbrown@burgoyne.com>
|
||||
Jie Mao <maojie0924@gmail.com>
|
||||
Luke Weber
|
||||
@ -21,6 +22,7 @@ Rafael Lopez Diez <rafalopezdiez@gmail.com>
|
||||
Ralph Giles <giles@ghostscript.com>
|
||||
Robert Nagy
|
||||
Ron Rivest
|
||||
Ryan Yoakum <ryoakum@skobalt.com>
|
||||
Sarah Thompson <sarah@telergy.com>
|
||||
Saul Kravitz <Saul.Kravitz@celera.com>
|
||||
Silviu Caragea <silviu.cpp@gmail.com>
|
||||
|
@ -598,7 +598,8 @@ class TestPortAllocatorSession : public cricket::PortAllocatorSession {
|
||||
ports_[i] = cricket::UDPPort::Create(
|
||||
rtc::Thread::Current(), &socket_factory_,
|
||||
&network_, address_.ipaddr(), GetPort(index), GetPort(index),
|
||||
GetUsername(index), GetPassword(index));
|
||||
GetUsername(index), GetPassword(index),
|
||||
std::string());
|
||||
AddPort(ports_[i]);
|
||||
}
|
||||
running_ = true;
|
||||
|
@ -262,7 +262,7 @@ class Port : public PortInterface, public rtc::MessageHandler,
|
||||
|
||||
// Debugging description of this port
|
||||
virtual std::string ToString() const;
|
||||
rtc::IPAddress& ip() { return ip_; }
|
||||
const rtc::IPAddress& ip() const { return ip_; }
|
||||
uint16 min_port() { return min_port_; }
|
||||
uint16 max_port() { return max_port_; }
|
||||
|
||||
|
@ -207,7 +207,7 @@ class TestChannel : public sigslot::has_slots<> {
|
||||
// Takes ownership of |p1| (but not |p2|).
|
||||
TestChannel(Port* p1, Port* p2)
|
||||
: ice_mode_(ICEMODE_FULL), src_(p1), dst_(p2), complete_count_(0),
|
||||
conn_(NULL), remote_request_(), nominated_(false) {
|
||||
conn_(NULL), remote_request_(), nominated_(false) {
|
||||
src_->SignalPortComplete.connect(
|
||||
this, &TestChannel::OnPortComplete);
|
||||
src_->SignalUnknownAddress.connect(this, &TestChannel::OnUnknownAddress);
|
||||
@ -413,7 +413,8 @@ class PortTest : public testing::Test, public sigslot::has_slots<> {
|
||||
UDPPort* CreateUdpPort(const SocketAddress& addr,
|
||||
PacketSocketFactory* socket_factory) {
|
||||
UDPPort* port = UDPPort::Create(main_, socket_factory, &network_,
|
||||
addr.ipaddr(), 0, 0, username_, password_);
|
||||
addr.ipaddr(), 0, 0, username_, password_,
|
||||
std::string());
|
||||
port->SetIceProtocolType(ice_protocol_);
|
||||
return port;
|
||||
}
|
||||
@ -436,7 +437,8 @@ class PortTest : public testing::Test, public sigslot::has_slots<> {
|
||||
stun_servers.insert(kStunAddr);
|
||||
StunPort* port = StunPort::Create(main_, factory, &network_,
|
||||
addr.ipaddr(), 0, 0,
|
||||
username_, password_, stun_servers);
|
||||
username_, password_, stun_servers,
|
||||
std::string());
|
||||
port->SetIceProtocolType(ice_protocol_);
|
||||
return port;
|
||||
}
|
||||
@ -461,8 +463,9 @@ class PortTest : public testing::Test, public sigslot::has_slots<> {
|
||||
TurnPort* port = TurnPort::Create(main_, socket_factory, &network_,
|
||||
addr.ipaddr(), 0, 0,
|
||||
username_, password_, ProtocolAddress(
|
||||
server_addr, PROTO_UDP),
|
||||
kRelayCredentials, 0);
|
||||
server_addr, PROTO_UDP),
|
||||
kRelayCredentials, 0,
|
||||
std::string());
|
||||
port->SetIceProtocolType(ice_protocol_);
|
||||
return port;
|
||||
}
|
||||
|
@ -167,6 +167,10 @@ class PortAllocator : public sigslot::has_slots<> {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Gets/Sets the Origin value used for WebRTC STUN requests.
|
||||
const std::string& origin() const { return origin_; }
|
||||
void set_origin(const std::string& origin) { origin_ = origin; }
|
||||
|
||||
protected:
|
||||
virtual PortAllocatorSession* CreateSessionInternal(
|
||||
const std::string& content_name,
|
||||
@ -185,6 +189,7 @@ class PortAllocator : public sigslot::has_slots<> {
|
||||
SessionMuxerMap muxers_;
|
||||
bool allow_tcp_listen_;
|
||||
uint32 candidate_filter_;
|
||||
std::string origin_;
|
||||
};
|
||||
|
||||
} // namespace cricket
|
||||
|
@ -387,6 +387,7 @@ StunAttributeValueType StunMessage::GetAttributeValueType(int type) const {
|
||||
case STUN_ATTR_SOFTWARE: return STUN_VALUE_BYTE_STRING;
|
||||
case STUN_ATTR_ALTERNATE_SERVER: return STUN_VALUE_ADDRESS;
|
||||
case STUN_ATTR_FINGERPRINT: return STUN_VALUE_UINT32;
|
||||
case STUN_ATTR_ORIGIN: return STUN_VALUE_BYTE_STRING;
|
||||
case STUN_ATTR_RETRANSMIT_COUNT: return STUN_VALUE_UINT32;
|
||||
default: return STUN_VALUE_UNKNOWN;
|
||||
}
|
||||
|
@ -48,6 +48,7 @@ enum StunAttributeType {
|
||||
STUN_ATTR_SOFTWARE = 0x8022, // ByteString
|
||||
STUN_ATTR_ALTERNATE_SERVER = 0x8023, // Address
|
||||
STUN_ATTR_FINGERPRINT = 0x8028, // UInt32
|
||||
STUN_ATTR_ORIGIN = 0x802F, // ByteString
|
||||
STUN_ATTR_RETRANSMIT_COUNT = 0xFF00 // UInt32
|
||||
};
|
||||
|
||||
|
@ -191,6 +191,20 @@ static const unsigned char kStunMessageWithErrorAttribute[] = {
|
||||
0x69, 0x7a, 0x65, 0x64
|
||||
};
|
||||
|
||||
static const unsigned char kStunMessageWithOriginAttribute[] = {
|
||||
0x00, 0x01, 0x00, 0x18, // message header (binding request), length 24
|
||||
0x21, 0x12, 0xA4, 0x42, // magic cookie
|
||||
0x29, 0x1f, 0xcd, 0x7c, // transaction id
|
||||
0xba, 0x58, 0xab, 0xd7,
|
||||
0xf2, 0x41, 0x01, 0x00,
|
||||
0x80, 0x2f, 0x00, 0x12, // origin attribute (length 18)
|
||||
0x68, 0x74, 0x74, 0x70, // http://example.com
|
||||
0x3A, 0x2F, 0x2F, 0x65,
|
||||
0x78, 0x61, 0x6d, 0x70,
|
||||
0x6c, 0x65, 0x2e, 0x63,
|
||||
0x6f, 0x6d, 0x00, 0x00,
|
||||
};
|
||||
|
||||
// Sample messages with an invalid length Field
|
||||
|
||||
// The actual length in bytes of the invalid messages (including STUN header)
|
||||
@ -472,6 +486,7 @@ const in_addr kIPv4TestAddress1 = { { 0x0ac, 0x017, 0x044, 0x0e6 } };
|
||||
const char kTestUserName1[] = "abcdefgh";
|
||||
const char kTestUserName2[] = "abc";
|
||||
const char kTestErrorReason[] = "Unauthorized";
|
||||
const char kTestOrigin[] = "http://example.com";
|
||||
const int kTestErrorClass = 4;
|
||||
const int kTestErrorNumber = 1;
|
||||
const int kTestErrorCode = 401;
|
||||
@ -1020,6 +1035,16 @@ TEST_F(StunTest, ReadMessageWithAnUnknownAttribute) {
|
||||
EXPECT_EQ(kTestUserName2, username->GetString());
|
||||
}
|
||||
|
||||
TEST_F(StunTest, ReadMessageWithOriginAttribute) {
|
||||
StunMessage msg;
|
||||
size_t size = ReadStunMessage(&msg, kStunMessageWithOriginAttribute);
|
||||
CheckStunHeader(msg, STUN_BINDING_REQUEST, size);
|
||||
const StunByteStringAttribute* origin =
|
||||
msg.GetByteString(STUN_ATTR_ORIGIN);
|
||||
ASSERT_TRUE(origin != NULL);
|
||||
EXPECT_EQ(kTestOrigin, origin->GetString());
|
||||
}
|
||||
|
||||
TEST_F(StunTest, WriteMessageWithAnErrorCodeAttribute) {
|
||||
StunMessage msg;
|
||||
size_t size = sizeof(kStunMessageWithErrorAttribute);
|
||||
@ -1066,6 +1091,25 @@ TEST_F(StunTest, WriteMessageWithAUInt16ListAttribute) {
|
||||
memcmp(out.Data(), kStunMessageWithUInt16ListAttribute, size - 2));
|
||||
}
|
||||
|
||||
TEST_F(StunTest, WriteMessageWithOriginAttribute) {
|
||||
StunMessage msg;
|
||||
size_t size = sizeof(kStunMessageWithOriginAttribute);
|
||||
|
||||
msg.SetType(STUN_BINDING_REQUEST);
|
||||
msg.SetTransactionID(
|
||||
std::string(reinterpret_cast<const char*>(kTestTransactionId1),
|
||||
kStunTransactionIdLength));
|
||||
StunByteStringAttribute* origin =
|
||||
new StunByteStringAttribute(STUN_ATTR_ORIGIN, kTestOrigin);
|
||||
EXPECT_TRUE(msg.AddAttribute(origin));
|
||||
|
||||
rtc::ByteBuffer out;
|
||||
EXPECT_TRUE(msg.Write(&out));
|
||||
ASSERT_EQ(size, out.Length());
|
||||
// Check everything up to the padding
|
||||
ASSERT_EQ(0, memcmp(out.Data(), kStunMessageWithOriginAttribute, size - 2));
|
||||
}
|
||||
|
||||
// Test that we fail to read messages with invalid lengths.
|
||||
void CheckFailureToRead(const unsigned char* testcase, size_t length) {
|
||||
StunMessage msg;
|
||||
|
@ -163,7 +163,8 @@ UDPPort::UDPPort(rtc::Thread* thread,
|
||||
rtc::Network* network,
|
||||
rtc::AsyncPacketSocket* socket,
|
||||
const std::string& username,
|
||||
const std::string& password)
|
||||
const std::string& password,
|
||||
const std::string& origin)
|
||||
: Port(thread, factory, network, socket->GetLocalAddress().ipaddr(),
|
||||
username, password),
|
||||
requests_(thread),
|
||||
@ -171,6 +172,7 @@ UDPPort::UDPPort(rtc::Thread* thread,
|
||||
error_(0),
|
||||
ready_(false),
|
||||
stun_keepalive_delay_(KEEPALIVE_DELAY) {
|
||||
requests_.set_origin(origin);
|
||||
}
|
||||
|
||||
UDPPort::UDPPort(rtc::Thread* thread,
|
||||
@ -180,7 +182,8 @@ UDPPort::UDPPort(rtc::Thread* thread,
|
||||
uint16 min_port,
|
||||
uint16 max_port,
|
||||
const std::string& username,
|
||||
const std::string& password)
|
||||
const std::string& password,
|
||||
const std::string& origin)
|
||||
: Port(thread, LOCAL_PORT_TYPE, factory, network, ip, min_port, max_port,
|
||||
username, password),
|
||||
requests_(thread),
|
||||
@ -188,6 +191,7 @@ UDPPort::UDPPort(rtc::Thread* thread,
|
||||
error_(0),
|
||||
ready_(false),
|
||||
stun_keepalive_delay_(KEEPALIVE_DELAY) {
|
||||
requests_.set_origin(origin);
|
||||
}
|
||||
|
||||
bool UDPPort::Init() {
|
||||
|
@ -33,9 +33,10 @@ class UDPPort : public Port {
|
||||
rtc::Network* network,
|
||||
rtc::AsyncPacketSocket* socket,
|
||||
const std::string& username,
|
||||
const std::string& password) {
|
||||
UDPPort* port =
|
||||
new UDPPort(thread, factory, network, socket, username, password);
|
||||
const std::string& password,
|
||||
const std::string& origin) {
|
||||
UDPPort* port = new UDPPort(thread, factory, network, socket,
|
||||
username, password, origin);
|
||||
if (!port->Init()) {
|
||||
delete port;
|
||||
port = NULL;
|
||||
@ -50,15 +51,18 @@ class UDPPort : public Port {
|
||||
uint16 min_port,
|
||||
uint16 max_port,
|
||||
const std::string& username,
|
||||
const std::string& password) {
|
||||
UDPPort* port = new UDPPort(thread, factory, network, ip, min_port,
|
||||
max_port, username, password);
|
||||
const std::string& password,
|
||||
const std::string& origin) {
|
||||
UDPPort* port = new UDPPort(thread, factory, network,
|
||||
ip, min_port, max_port,
|
||||
username, password, origin);
|
||||
if (!port->Init()) {
|
||||
delete port;
|
||||
port = NULL;
|
||||
}
|
||||
return port;
|
||||
}
|
||||
|
||||
virtual ~UDPPort();
|
||||
|
||||
rtc::SocketAddress GetLocalAddress() const {
|
||||
@ -105,14 +109,16 @@ class UDPPort : public Port {
|
||||
uint16 min_port,
|
||||
uint16 max_port,
|
||||
const std::string& username,
|
||||
const std::string& password);
|
||||
const std::string& password,
|
||||
const std::string& origin);
|
||||
|
||||
UDPPort(rtc::Thread* thread,
|
||||
rtc::PacketSocketFactory* factory,
|
||||
rtc::Network* network,
|
||||
rtc::AsyncPacketSocket* socket,
|
||||
const std::string& username,
|
||||
const std::string& password);
|
||||
const std::string& password,
|
||||
const std::string& origin);
|
||||
|
||||
bool Init();
|
||||
|
||||
@ -208,9 +214,12 @@ class StunPort : public UDPPort {
|
||||
uint16 min_port, uint16 max_port,
|
||||
const std::string& username,
|
||||
const std::string& password,
|
||||
const ServerAddresses& servers) {
|
||||
StunPort* port = new StunPort(thread, factory, network, ip, min_port,
|
||||
max_port, username, password, servers);
|
||||
const ServerAddresses& servers,
|
||||
const std::string& origin) {
|
||||
StunPort* port = new StunPort(thread, factory, network,
|
||||
ip, min_port, max_port,
|
||||
username, password, servers,
|
||||
origin);
|
||||
if (!port->Init()) {
|
||||
delete port;
|
||||
port = NULL;
|
||||
@ -233,9 +242,10 @@ class StunPort : public UDPPort {
|
||||
uint16 max_port,
|
||||
const std::string& username,
|
||||
const std::string& password,
|
||||
const ServerAddresses& servers)
|
||||
const ServerAddresses& servers,
|
||||
const std::string& origin)
|
||||
: UDPPort(thread, factory, network, ip, min_port, max_port, username,
|
||||
password) {
|
||||
password, origin) {
|
||||
// UDPPort will set these to local udp, updating these to STUN.
|
||||
set_type(STUN_PORT_TYPE);
|
||||
set_server_addresses(servers);
|
||||
|
@ -65,7 +65,7 @@ class StunPortTest : public testing::Test,
|
||||
stun_port_.reset(cricket::StunPort::Create(
|
||||
rtc::Thread::Current(), &socket_factory_, &network_,
|
||||
kLocalAddr.ipaddr(), 0, 0, rtc::CreateRandomString(16),
|
||||
rtc::CreateRandomString(22), stun_servers));
|
||||
rtc::CreateRandomString(22), stun_servers, std::string()));
|
||||
stun_port_->set_stun_keepalive_delay(stun_keepalive_delay_);
|
||||
stun_port_->SignalPortComplete.connect(this,
|
||||
&StunPortTest::OnPortComplete);
|
||||
@ -81,7 +81,8 @@ class StunPortTest : public testing::Test,
|
||||
stun_port_.reset(cricket::UDPPort::Create(
|
||||
rtc::Thread::Current(), &socket_factory_,
|
||||
&network_, socket_.get(),
|
||||
rtc::CreateRandomString(16), rtc::CreateRandomString(22)));
|
||||
rtc::CreateRandomString(16), rtc::CreateRandomString(22),
|
||||
std::string()));
|
||||
ASSERT_TRUE(stun_port_ != NULL);
|
||||
ServerAddresses stun_servers;
|
||||
stun_servers.insert(server_addr);
|
||||
|
@ -41,6 +41,7 @@ void StunRequestManager::Send(StunRequest* request) {
|
||||
void StunRequestManager::SendDelayed(StunRequest* request, int delay) {
|
||||
request->set_manager(this);
|
||||
ASSERT(requests_.find(request->id()) == requests_.end());
|
||||
request->set_origin(origin_);
|
||||
request->Construct();
|
||||
requests_[request->id()] = request;
|
||||
thread_->PostDelayed(delay, request, MSG_STUN_SEND, NULL);
|
||||
@ -138,6 +139,10 @@ StunRequest::~StunRequest() {
|
||||
|
||||
void StunRequest::Construct() {
|
||||
if (msg_->type() == 0) {
|
||||
if (!origin_.empty()) {
|
||||
msg_->AddAttribute(new StunByteStringAttribute(STUN_ATTR_ORIGIN,
|
||||
origin_));
|
||||
}
|
||||
Prepare(msg_);
|
||||
ASSERT(msg_->type() != 0);
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ class StunRequest;
|
||||
// Manages a set of STUN requests, sending and resending until we receive a
|
||||
// response or determine that the request has timed out.
|
||||
class StunRequestManager {
|
||||
public:
|
||||
public:
|
||||
StunRequestManager(rtc::Thread* thread);
|
||||
~StunRequestManager();
|
||||
|
||||
@ -46,14 +46,18 @@ public:
|
||||
|
||||
bool empty() { return requests_.empty(); }
|
||||
|
||||
// Set the Origin header for outgoing stun messages.
|
||||
void set_origin(const std::string& origin) { origin_ = origin; }
|
||||
|
||||
// Raised when there are bytes to be sent.
|
||||
sigslot::signal3<const void*, size_t, StunRequest*> SignalSendPacket;
|
||||
|
||||
private:
|
||||
private:
|
||||
typedef std::map<std::string, StunRequest*> RequestMap;
|
||||
|
||||
rtc::Thread* thread_;
|
||||
RequestMap requests_;
|
||||
std::string origin_;
|
||||
|
||||
friend class StunRequest;
|
||||
};
|
||||
@ -61,7 +65,7 @@ private:
|
||||
// Represents an individual request to be sent. The STUN message can either be
|
||||
// constructed beforehand or built on demand.
|
||||
class StunRequest : public rtc::MessageHandler {
|
||||
public:
|
||||
public:
|
||||
StunRequest();
|
||||
StunRequest(StunMessage* request);
|
||||
virtual ~StunRequest();
|
||||
@ -75,6 +79,10 @@ public:
|
||||
// Returns the transaction ID of this request.
|
||||
const std::string& id() { return msg_->transaction_id(); }
|
||||
|
||||
// the origin value
|
||||
const std::string& origin() const { return origin_; }
|
||||
void set_origin(const std::string& origin) { origin_ = origin; }
|
||||
|
||||
// Returns the STUN type of the request message.
|
||||
int type();
|
||||
|
||||
@ -84,9 +92,10 @@ public:
|
||||
// Time elapsed since last send (in ms)
|
||||
uint32 Elapsed() const;
|
||||
|
||||
protected:
|
||||
protected:
|
||||
int count_;
|
||||
bool timeout_;
|
||||
std::string origin_;
|
||||
|
||||
// Fills in a request object to be sent. Note that request's transaction ID
|
||||
// will already be set and cannot be changed.
|
||||
@ -98,7 +107,7 @@ protected:
|
||||
virtual void OnTimeout() {}
|
||||
virtual int GetNextDelay();
|
||||
|
||||
private:
|
||||
private:
|
||||
void set_manager(StunRequestManager* manager);
|
||||
|
||||
// Handles messages for sending and timeout.
|
||||
|
@ -87,6 +87,19 @@ class TestTurnServer : public TurnAuthInterface {
|
||||
}
|
||||
}
|
||||
|
||||
// Finds the first allocation in the server allocation map with a source
|
||||
// ip and port matching the socket address provided.
|
||||
TurnServerAllocation* FindAllocation(const rtc::SocketAddress& src) {
|
||||
const TurnServer::AllocationMap& map = server_.allocations();
|
||||
for (TurnServer::AllocationMap::const_iterator it = map.begin();
|
||||
it != map.end(); ++it) {
|
||||
if (src == it->first.src()) {
|
||||
return it->second;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
private:
|
||||
// For this test server, succeed if the password is the same as the username.
|
||||
// Obviously, do not use this in a production environment.
|
||||
|
@ -164,7 +164,8 @@ TurnPort::TurnPort(rtc::Thread* thread,
|
||||
const std::string& password,
|
||||
const ProtocolAddress& server_address,
|
||||
const RelayCredentials& credentials,
|
||||
int server_priority)
|
||||
int server_priority,
|
||||
const std::string& origin)
|
||||
: Port(thread, factory, network, socket->GetLocalAddress().ipaddr(),
|
||||
username, password),
|
||||
server_address_(server_address),
|
||||
@ -178,6 +179,7 @@ TurnPort::TurnPort(rtc::Thread* thread,
|
||||
server_priority_(server_priority),
|
||||
allocate_mismatch_retries_(0) {
|
||||
request_manager_.SignalSendPacket.connect(this, &TurnPort::OnSendStunPacket);
|
||||
request_manager_.set_origin(origin);
|
||||
}
|
||||
|
||||
TurnPort::TurnPort(rtc::Thread* thread,
|
||||
@ -190,7 +192,8 @@ TurnPort::TurnPort(rtc::Thread* thread,
|
||||
const std::string& password,
|
||||
const ProtocolAddress& server_address,
|
||||
const RelayCredentials& credentials,
|
||||
int server_priority)
|
||||
int server_priority,
|
||||
const std::string& origin)
|
||||
: Port(thread, RELAY_PORT_TYPE, factory, network, ip, min_port, max_port,
|
||||
username, password),
|
||||
server_address_(server_address),
|
||||
@ -204,6 +207,7 @@ TurnPort::TurnPort(rtc::Thread* thread,
|
||||
server_priority_(server_priority),
|
||||
allocate_mismatch_retries_(0) {
|
||||
request_manager_.SignalSendPacket.connect(this, &TurnPort::OnSendStunPacket);
|
||||
request_manager_.set_origin(origin);
|
||||
}
|
||||
|
||||
TurnPort::~TurnPort() {
|
||||
@ -219,6 +223,10 @@ TurnPort::~TurnPort() {
|
||||
}
|
||||
}
|
||||
|
||||
rtc::SocketAddress TurnPort::GetLocalAddress() const {
|
||||
return socket_ ? socket_->GetLocalAddress() : rtc::SocketAddress();
|
||||
}
|
||||
|
||||
void TurnPort::PrepareAddress() {
|
||||
if (credentials_.username.empty() ||
|
||||
credentials_.password.empty()) {
|
||||
|
@ -41,9 +41,10 @@ class TurnPort : public Port {
|
||||
const std::string& password, // ice password.
|
||||
const ProtocolAddress& server_address,
|
||||
const RelayCredentials& credentials,
|
||||
int server_priority) {
|
||||
int server_priority,
|
||||
const std::string& origin) {
|
||||
return new TurnPort(thread, factory, network, socket, username, password,
|
||||
server_address, credentials, server_priority);
|
||||
server_address, credentials, server_priority, origin);
|
||||
}
|
||||
|
||||
static TurnPort* Create(rtc::Thread* thread,
|
||||
@ -56,15 +57,18 @@ class TurnPort : public Port {
|
||||
const std::string& password, // ice password.
|
||||
const ProtocolAddress& server_address,
|
||||
const RelayCredentials& credentials,
|
||||
int server_priority) {
|
||||
int server_priority,
|
||||
const std::string& origin) {
|
||||
return new TurnPort(thread, factory, network, ip, min_port, max_port,
|
||||
username, password, server_address, credentials,
|
||||
server_priority);
|
||||
server_priority, origin);
|
||||
}
|
||||
|
||||
virtual ~TurnPort();
|
||||
|
||||
const ProtocolAddress& server_address() const { return server_address_; }
|
||||
// Returns an empty address if the local address has not been assigned.
|
||||
rtc::SocketAddress GetLocalAddress() const;
|
||||
|
||||
bool connected() const { return connected_; }
|
||||
const RelayCredentials& credentials() const { return credentials_; }
|
||||
@ -129,7 +133,8 @@ class TurnPort : public Port {
|
||||
const std::string& password,
|
||||
const ProtocolAddress& server_address,
|
||||
const RelayCredentials& credentials,
|
||||
int server_priority);
|
||||
int server_priority,
|
||||
const std::string& origin);
|
||||
|
||||
TurnPort(rtc::Thread* thread,
|
||||
rtc::PacketSocketFactory* factory,
|
||||
@ -141,7 +146,8 @@ class TurnPort : public Port {
|
||||
const std::string& password,
|
||||
const ProtocolAddress& server_address,
|
||||
const RelayCredentials& credentials,
|
||||
int server_priority);
|
||||
int server_priority,
|
||||
const std::string& origin);
|
||||
|
||||
private:
|
||||
enum {
|
||||
|
@ -60,6 +60,7 @@ static const char kIcePwd1[] = "TESTICEPWD00000000000001";
|
||||
static const char kIcePwd2[] = "TESTICEPWD00000000000002";
|
||||
static const char kTurnUsername[] = "test";
|
||||
static const char kTurnPassword[] = "test";
|
||||
static const char kTestOrigin[] = "http://example.com";
|
||||
static const unsigned int kTimeout = 1000;
|
||||
|
||||
static const cricket::ProtocolAddress kTurnUdpProtoAddr(
|
||||
@ -193,7 +194,30 @@ class TurnPortTest : public testing::Test,
|
||||
turn_port_.reset(TurnPort::Create(main_, &socket_factory_, &network_,
|
||||
local_address.ipaddr(), 0, 0,
|
||||
kIceUfrag1, kIcePwd1,
|
||||
server_address, credentials, 0));
|
||||
server_address, credentials, 0,
|
||||
std::string()));
|
||||
// Set ICE protocol type to ICEPROTO_RFC5245, as port by default will be
|
||||
// in Hybrid mode. Protocol type is necessary to send correct type STUN ping
|
||||
// messages.
|
||||
// This TURN port will be the controlling.
|
||||
turn_port_->SetIceProtocolType(cricket::ICEPROTO_RFC5245);
|
||||
turn_port_->SetIceRole(cricket::ICEROLE_CONTROLLING);
|
||||
ConnectSignals();
|
||||
}
|
||||
|
||||
// Should be identical to CreateTurnPort but specifies an origin value
|
||||
// when creating the instance of TurnPort.
|
||||
void CreateTurnPortWithOrigin(const rtc::SocketAddress& local_address,
|
||||
const std::string& username,
|
||||
const std::string& password,
|
||||
const cricket::ProtocolAddress& server_address,
|
||||
const std::string& origin) {
|
||||
cricket::RelayCredentials credentials(username, password);
|
||||
turn_port_.reset(TurnPort::Create(main_, &socket_factory_, &network_,
|
||||
local_address.ipaddr(), 0, 0,
|
||||
kIceUfrag1, kIcePwd1,
|
||||
server_address, credentials, 0,
|
||||
origin));
|
||||
// Set ICE protocol type to ICEPROTO_RFC5245, as port by default will be
|
||||
// in Hybrid mode. Protocol type is necessary to send correct type STUN ping
|
||||
// messages.
|
||||
@ -219,7 +243,7 @@ class TurnPortTest : public testing::Test,
|
||||
cricket::RelayCredentials credentials(username, password);
|
||||
turn_port_.reset(cricket::TurnPort::Create(
|
||||
main_, &socket_factory_, &network_, socket_.get(),
|
||||
kIceUfrag1, kIcePwd1, server_address, credentials, 0));
|
||||
kIceUfrag1, kIcePwd1, server_address, credentials, 0, std::string()));
|
||||
// Set ICE protocol type to ICEPROTO_RFC5245, as port by default will be
|
||||
// in Hybrid mode. Protocol type is necessary to send correct type STUN ping
|
||||
// messages.
|
||||
@ -242,7 +266,8 @@ class TurnPortTest : public testing::Test,
|
||||
void CreateUdpPort() {
|
||||
udp_port_.reset(UDPPort::Create(main_, &socket_factory_, &network_,
|
||||
kLocalAddr2.ipaddr(), 0, 0,
|
||||
kIceUfrag2, kIcePwd2));
|
||||
kIceUfrag2, kIcePwd2,
|
||||
std::string()));
|
||||
// Set protocol type to RFC5245, as turn port is also in same mode.
|
||||
// UDP port will be controlled.
|
||||
udp_port_->SetIceProtocolType(cricket::ICEPROTO_RFC5245);
|
||||
@ -685,6 +710,17 @@ TEST_F(TurnPortTest, TestTurnLocalIPv6AddressServerIPv6ExtenalIPv4) {
|
||||
EXPECT_NE(0, turn_port_->Candidates()[0].address().port());
|
||||
}
|
||||
|
||||
TEST_F(TurnPortTest, TestOriginHeader) {
|
||||
CreateTurnPortWithOrigin(kLocalAddr1, kTurnUsername, kTurnPassword,
|
||||
kTurnUdpProtoAddr, kTestOrigin);
|
||||
turn_port_->PrepareAddress();
|
||||
EXPECT_TRUE_WAIT(turn_ready_, kTimeout);
|
||||
ASSERT_GT(turn_server_.server()->allocations().size(), 0U);
|
||||
SocketAddress local_address = turn_port_->GetLocalAddress();
|
||||
ASSERT_TRUE(turn_server_.FindAllocation(local_address) != NULL);
|
||||
EXPECT_EQ(kTestOrigin, turn_server_.FindAllocation(local_address)->origin());
|
||||
}
|
||||
|
||||
// This test verifies any FD's are not leaked after TurnPort is destroyed.
|
||||
// https://code.google.com/p/webrtc/issues/detail?id=2651
|
||||
#if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID)
|
||||
|
@ -45,88 +45,15 @@ inline bool IsTurnChannelData(uint16 msg_type) {
|
||||
return ((msg_type & 0xC000) == 0x4000);
|
||||
}
|
||||
|
||||
// IDs used for posted messages for TurnServer::Allocation.
|
||||
// IDs used for posted messages for TurnServerAllocation.
|
||||
enum {
|
||||
MSG_ALLOCATION_TIMEOUT,
|
||||
};
|
||||
|
||||
// Encapsulates a TURN allocation.
|
||||
// The object is created when an allocation request is received, and then
|
||||
// handles TURN messages (via HandleTurnMessage) and channel data messages
|
||||
// (via HandleChannelData) for this allocation when received by the server.
|
||||
// The object self-deletes and informs the server if its lifetime timer expires.
|
||||
class TurnServer::Allocation : public rtc::MessageHandler,
|
||||
public sigslot::has_slots<> {
|
||||
public:
|
||||
Allocation(TurnServer* server_,
|
||||
rtc::Thread* thread, const Connection& conn,
|
||||
rtc::AsyncPacketSocket* server_socket,
|
||||
const std::string& key);
|
||||
virtual ~Allocation();
|
||||
|
||||
Connection* conn() { return &conn_; }
|
||||
const std::string& key() const { return key_; }
|
||||
const std::string& transaction_id() const { return transaction_id_; }
|
||||
const std::string& username() const { return username_; }
|
||||
const std::string& last_nonce() const { return last_nonce_; }
|
||||
void set_last_nonce(const std::string& nonce) { last_nonce_ = nonce; }
|
||||
|
||||
std::string ToString() const;
|
||||
|
||||
void HandleTurnMessage(const TurnMessage* msg);
|
||||
void HandleChannelData(const char* data, size_t size);
|
||||
|
||||
sigslot::signal1<Allocation*> SignalDestroyed;
|
||||
|
||||
private:
|
||||
typedef std::list<Permission*> PermissionList;
|
||||
typedef std::list<Channel*> ChannelList;
|
||||
|
||||
void HandleAllocateRequest(const TurnMessage* msg);
|
||||
void HandleRefreshRequest(const TurnMessage* msg);
|
||||
void HandleSendIndication(const TurnMessage* msg);
|
||||
void HandleCreatePermissionRequest(const TurnMessage* msg);
|
||||
void HandleChannelBindRequest(const TurnMessage* msg);
|
||||
|
||||
void OnExternalPacket(rtc::AsyncPacketSocket* socket,
|
||||
const char* data, size_t size,
|
||||
const rtc::SocketAddress& addr,
|
||||
const rtc::PacketTime& packet_time);
|
||||
|
||||
static int ComputeLifetime(const TurnMessage* msg);
|
||||
bool HasPermission(const rtc::IPAddress& addr);
|
||||
void AddPermission(const rtc::IPAddress& addr);
|
||||
Permission* FindPermission(const rtc::IPAddress& addr) const;
|
||||
Channel* FindChannel(int channel_id) const;
|
||||
Channel* FindChannel(const rtc::SocketAddress& addr) const;
|
||||
|
||||
void SendResponse(TurnMessage* msg);
|
||||
void SendBadRequestResponse(const TurnMessage* req);
|
||||
void SendErrorResponse(const TurnMessage* req, int code,
|
||||
const std::string& reason);
|
||||
void SendExternal(const void* data, size_t size,
|
||||
const rtc::SocketAddress& peer);
|
||||
|
||||
void OnPermissionDestroyed(Permission* perm);
|
||||
void OnChannelDestroyed(Channel* channel);
|
||||
virtual void OnMessage(rtc::Message* msg);
|
||||
|
||||
TurnServer* server_;
|
||||
rtc::Thread* thread_;
|
||||
Connection conn_;
|
||||
rtc::scoped_ptr<rtc::AsyncPacketSocket> external_socket_;
|
||||
std::string key_;
|
||||
std::string transaction_id_;
|
||||
std::string username_;
|
||||
std::string last_nonce_;
|
||||
PermissionList perms_;
|
||||
ChannelList channels_;
|
||||
};
|
||||
|
||||
// Encapsulates a TURN permission.
|
||||
// The object is created when a create permission request is received by an
|
||||
// allocation, and self-deletes when its lifetime timer expires.
|
||||
class TurnServer::Permission : public rtc::MessageHandler {
|
||||
class TurnServerAllocation::Permission : public rtc::MessageHandler {
|
||||
public:
|
||||
Permission(rtc::Thread* thread, const rtc::IPAddress& peer);
|
||||
~Permission();
|
||||
@ -146,7 +73,7 @@ class TurnServer::Permission : public rtc::MessageHandler {
|
||||
// Encapsulates a TURN channel binding.
|
||||
// The object is created when a channel bind request is received by an
|
||||
// allocation, and self-deletes when its lifetime timer expires.
|
||||
class TurnServer::Channel : public rtc::MessageHandler {
|
||||
class TurnServerAllocation::Channel : public rtc::MessageHandler {
|
||||
public:
|
||||
Channel(rtc::Thread* thread, int id,
|
||||
const rtc::SocketAddress& peer);
|
||||
@ -187,6 +114,7 @@ static bool InitErrorResponse(const StunMessage* req, int code,
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
TurnServer::TurnServer(rtc::Thread* thread)
|
||||
: thread_(thread),
|
||||
nonce_key_(rtc::CreateRandomString(kNonceKeySize)),
|
||||
@ -271,21 +199,21 @@ void TurnServer::OnInternalPacket(rtc::AsyncPacketSocket* socket,
|
||||
}
|
||||
InternalSocketMap::iterator iter = server_sockets_.find(socket);
|
||||
ASSERT(iter != server_sockets_.end());
|
||||
Connection conn(addr, iter->second, socket);
|
||||
TurnServerConnection conn(addr, iter->second, socket);
|
||||
uint16 msg_type = rtc::GetBE16(data);
|
||||
if (!IsTurnChannelData(msg_type)) {
|
||||
// This is a STUN message.
|
||||
HandleStunMessage(&conn, data, size);
|
||||
} else {
|
||||
// This is a channel message; let the allocation handle it.
|
||||
Allocation* allocation = FindAllocation(&conn);
|
||||
TurnServerAllocation* allocation = FindAllocation(&conn);
|
||||
if (allocation) {
|
||||
allocation->HandleChannelData(data, size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TurnServer::HandleStunMessage(Connection* conn, const char* data,
|
||||
void TurnServer::HandleStunMessage(TurnServerConnection* conn, const char* data,
|
||||
size_t size) {
|
||||
TurnMessage msg;
|
||||
rtc::ByteBuffer buf(data, size);
|
||||
@ -311,7 +239,7 @@ void TurnServer::HandleStunMessage(Connection* conn, const char* data,
|
||||
|
||||
// Look up the key that we'll use to validate the M-I. If we have an
|
||||
// existing allocation, the key will already be cached.
|
||||
Allocation* allocation = FindAllocation(conn);
|
||||
TurnServerAllocation* allocation = FindAllocation(conn);
|
||||
std::string key;
|
||||
if (!allocation) {
|
||||
GetKey(&msg, &key);
|
||||
@ -359,7 +287,7 @@ bool TurnServer::GetKey(const StunMessage* msg, std::string* key) {
|
||||
return (auth_hook_ != NULL && auth_hook_->GetKey(username, realm_, key));
|
||||
}
|
||||
|
||||
bool TurnServer::CheckAuthorization(Connection* conn,
|
||||
bool TurnServer::CheckAuthorization(TurnServerConnection* conn,
|
||||
const StunMessage* msg,
|
||||
const char* data, size_t size,
|
||||
const std::string& key) {
|
||||
@ -404,7 +332,7 @@ bool TurnServer::CheckAuthorization(Connection* conn,
|
||||
}
|
||||
|
||||
// Fail if one-time-use nonce feature is enabled.
|
||||
Allocation* allocation = FindAllocation(conn);
|
||||
TurnServerAllocation* allocation = FindAllocation(conn);
|
||||
if (enable_otu_nonce_ && allocation &&
|
||||
allocation->last_nonce() == nonce_attr->GetString()) {
|
||||
SendErrorResponseWithRealmAndNonce(conn, msg, STUN_ERROR_STALE_NONCE,
|
||||
@ -419,7 +347,7 @@ bool TurnServer::CheckAuthorization(Connection* conn,
|
||||
return true;
|
||||
}
|
||||
|
||||
void TurnServer::HandleBindingRequest(Connection* conn,
|
||||
void TurnServer::HandleBindingRequest(TurnServerConnection* conn,
|
||||
const StunMessage* req) {
|
||||
StunMessage response;
|
||||
InitResponse(req, &response);
|
||||
@ -433,7 +361,7 @@ void TurnServer::HandleBindingRequest(Connection* conn,
|
||||
SendStun(conn, &response);
|
||||
}
|
||||
|
||||
void TurnServer::HandleAllocateRequest(Connection* conn,
|
||||
void TurnServer::HandleAllocateRequest(TurnServerConnection* conn,
|
||||
const TurnMessage* msg,
|
||||
const std::string& key) {
|
||||
// Check the parameters in the request.
|
||||
@ -455,7 +383,7 @@ void TurnServer::HandleAllocateRequest(Connection* conn,
|
||||
|
||||
// Create the allocation and let it send the success response.
|
||||
// If the actual socket allocation fails, send an internal error.
|
||||
Allocation* alloc = CreateAllocation(conn, proto, key);
|
||||
TurnServerAllocation* alloc = CreateAllocation(conn, proto, key);
|
||||
if (alloc) {
|
||||
alloc->HandleTurnMessage(msg);
|
||||
} else {
|
||||
@ -499,14 +427,14 @@ bool TurnServer::ValidateNonce(const std::string& nonce) const {
|
||||
return rtc::TimeSince(then) < kNonceTimeout;
|
||||
}
|
||||
|
||||
TurnServer::Allocation* TurnServer::FindAllocation(Connection* conn) {
|
||||
TurnServerAllocation* TurnServer::FindAllocation(TurnServerConnection* conn) {
|
||||
AllocationMap::const_iterator it = allocations_.find(*conn);
|
||||
return (it != allocations_.end()) ? it->second : NULL;
|
||||
}
|
||||
|
||||
TurnServer::Allocation* TurnServer::CreateAllocation(Connection* conn,
|
||||
int proto,
|
||||
const std::string& key) {
|
||||
TurnServerAllocation* TurnServer::CreateAllocation(TurnServerConnection* conn,
|
||||
int proto,
|
||||
const std::string& key) {
|
||||
rtc::AsyncPacketSocket* external_socket = (external_socket_factory_) ?
|
||||
external_socket_factory_->CreateUdpSocket(external_addr_, 0, 0) : NULL;
|
||||
if (!external_socket) {
|
||||
@ -514,14 +442,14 @@ TurnServer::Allocation* TurnServer::CreateAllocation(Connection* conn,
|
||||
}
|
||||
|
||||
// The Allocation takes ownership of the socket.
|
||||
Allocation* allocation = new Allocation(this,
|
||||
TurnServerAllocation* allocation = new TurnServerAllocation(this,
|
||||
thread_, *conn, external_socket, key);
|
||||
allocation->SignalDestroyed.connect(this, &TurnServer::OnAllocationDestroyed);
|
||||
allocations_[*conn] = allocation;
|
||||
return allocation;
|
||||
}
|
||||
|
||||
void TurnServer::SendErrorResponse(Connection* conn,
|
||||
void TurnServer::SendErrorResponse(TurnServerConnection* conn,
|
||||
const StunMessage* req,
|
||||
int code, const std::string& reason) {
|
||||
TurnMessage resp;
|
||||
@ -532,7 +460,7 @@ void TurnServer::SendErrorResponse(Connection* conn,
|
||||
}
|
||||
|
||||
void TurnServer::SendErrorResponseWithRealmAndNonce(
|
||||
Connection* conn, const StunMessage* msg,
|
||||
TurnServerConnection* conn, const StunMessage* msg,
|
||||
int code, const std::string& reason) {
|
||||
TurnMessage resp;
|
||||
InitErrorResponse(msg, code, reason, &resp);
|
||||
@ -544,7 +472,7 @@ void TurnServer::SendErrorResponseWithRealmAndNonce(
|
||||
}
|
||||
|
||||
void TurnServer::SendErrorResponseWithAlternateServer(
|
||||
Connection* conn, const StunMessage* msg,
|
||||
TurnServerConnection* conn, const StunMessage* msg,
|
||||
const rtc::SocketAddress& addr) {
|
||||
TurnMessage resp;
|
||||
InitErrorResponse(msg, STUN_ERROR_TRY_ALTERNATE,
|
||||
@ -554,7 +482,7 @@ void TurnServer::SendErrorResponseWithAlternateServer(
|
||||
SendStun(conn, &resp);
|
||||
}
|
||||
|
||||
void TurnServer::SendStun(Connection* conn, StunMessage* msg) {
|
||||
void TurnServer::SendStun(TurnServerConnection* conn, StunMessage* msg) {
|
||||
rtc::ByteBuffer buf;
|
||||
// Add a SOFTWARE attribute if one is set.
|
||||
if (!software_.empty()) {
|
||||
@ -565,13 +493,13 @@ void TurnServer::SendStun(Connection* conn, StunMessage* msg) {
|
||||
Send(conn, buf);
|
||||
}
|
||||
|
||||
void TurnServer::Send(Connection* conn,
|
||||
void TurnServer::Send(TurnServerConnection* conn,
|
||||
const rtc::ByteBuffer& buf) {
|
||||
rtc::PacketOptions options;
|
||||
conn->socket()->SendTo(buf.Data(), buf.Length(), conn->src(), options);
|
||||
}
|
||||
|
||||
void TurnServer::OnAllocationDestroyed(Allocation* allocation) {
|
||||
void TurnServer::OnAllocationDestroyed(TurnServerAllocation* allocation) {
|
||||
// Removing the internal socket if the connection is not udp.
|
||||
rtc::AsyncPacketSocket* socket = allocation->conn()->socket();
|
||||
InternalSocketMap::iterator iter = server_sockets_.find(socket);
|
||||
@ -598,24 +526,24 @@ void TurnServer::DestroyInternalSocket(rtc::AsyncPacketSocket* socket) {
|
||||
}
|
||||
}
|
||||
|
||||
TurnServer::Connection::Connection(const rtc::SocketAddress& src,
|
||||
ProtocolType proto,
|
||||
rtc::AsyncPacketSocket* socket)
|
||||
TurnServerConnection::TurnServerConnection(const rtc::SocketAddress& src,
|
||||
ProtocolType proto,
|
||||
rtc::AsyncPacketSocket* socket)
|
||||
: src_(src),
|
||||
dst_(socket->GetRemoteAddress()),
|
||||
proto_(proto),
|
||||
socket_(socket) {
|
||||
}
|
||||
|
||||
bool TurnServer::Connection::operator==(const Connection& c) const {
|
||||
bool TurnServerConnection::operator==(const TurnServerConnection& c) const {
|
||||
return src_ == c.src_ && dst_ == c.dst_ && proto_ == c.proto_;
|
||||
}
|
||||
|
||||
bool TurnServer::Connection::operator<(const Connection& c) const {
|
||||
bool TurnServerConnection::operator<(const TurnServerConnection& c) const {
|
||||
return src_ < c.src_ || dst_ < c.dst_ || proto_ < c.proto_;
|
||||
}
|
||||
|
||||
std::string TurnServer::Connection::ToString() const {
|
||||
std::string TurnServerConnection::ToString() const {
|
||||
const char* const kProtos[] = {
|
||||
"unknown", "udp", "tcp", "ssltcp"
|
||||
};
|
||||
@ -624,21 +552,21 @@ std::string TurnServer::Connection::ToString() const {
|
||||
return ost.str();
|
||||
}
|
||||
|
||||
TurnServer::Allocation::Allocation(TurnServer* server,
|
||||
rtc::Thread* thread,
|
||||
const Connection& conn,
|
||||
rtc::AsyncPacketSocket* socket,
|
||||
const std::string& key)
|
||||
TurnServerAllocation::TurnServerAllocation(TurnServer* server,
|
||||
rtc::Thread* thread,
|
||||
const TurnServerConnection& conn,
|
||||
rtc::AsyncPacketSocket* socket,
|
||||
const std::string& key)
|
||||
: server_(server),
|
||||
thread_(thread),
|
||||
conn_(conn),
|
||||
external_socket_(socket),
|
||||
key_(key) {
|
||||
external_socket_->SignalReadPacket.connect(
|
||||
this, &TurnServer::Allocation::OnExternalPacket);
|
||||
this, &TurnServerAllocation::OnExternalPacket);
|
||||
}
|
||||
|
||||
TurnServer::Allocation::~Allocation() {
|
||||
TurnServerAllocation::~TurnServerAllocation() {
|
||||
for (ChannelList::iterator it = channels_.begin();
|
||||
it != channels_.end(); ++it) {
|
||||
delete *it;
|
||||
@ -651,13 +579,13 @@ TurnServer::Allocation::~Allocation() {
|
||||
LOG_J(LS_INFO, this) << "Allocation destroyed";
|
||||
}
|
||||
|
||||
std::string TurnServer::Allocation::ToString() const {
|
||||
std::string TurnServerAllocation::ToString() const {
|
||||
std::ostringstream ost;
|
||||
ost << "Alloc[" << conn_.ToString() << "]";
|
||||
return ost.str();
|
||||
}
|
||||
|
||||
void TurnServer::Allocation::HandleTurnMessage(const TurnMessage* msg) {
|
||||
void TurnServerAllocation::HandleTurnMessage(const TurnMessage* msg) {
|
||||
ASSERT(msg != NULL);
|
||||
switch (msg->type()) {
|
||||
case STUN_ALLOCATE_REQUEST:
|
||||
@ -682,13 +610,18 @@ void TurnServer::Allocation::HandleTurnMessage(const TurnMessage* msg) {
|
||||
}
|
||||
}
|
||||
|
||||
void TurnServer::Allocation::HandleAllocateRequest(const TurnMessage* msg) {
|
||||
void TurnServerAllocation::HandleAllocateRequest(const TurnMessage* msg) {
|
||||
// Copy the important info from the allocate request.
|
||||
transaction_id_ = msg->transaction_id();
|
||||
const StunByteStringAttribute* username_attr =
|
||||
msg->GetByteString(STUN_ATTR_USERNAME);
|
||||
ASSERT(username_attr != NULL);
|
||||
username_ = username_attr->GetString();
|
||||
const StunByteStringAttribute* origin_attr =
|
||||
msg->GetByteString(STUN_ATTR_ORIGIN);
|
||||
if (origin_attr) {
|
||||
origin_ = origin_attr->GetString();
|
||||
}
|
||||
|
||||
// Figure out the lifetime and start the allocation timer.
|
||||
int lifetime_secs = ComputeLifetime(msg);
|
||||
@ -714,7 +647,7 @@ void TurnServer::Allocation::HandleAllocateRequest(const TurnMessage* msg) {
|
||||
SendResponse(&response);
|
||||
}
|
||||
|
||||
void TurnServer::Allocation::HandleRefreshRequest(const TurnMessage* msg) {
|
||||
void TurnServerAllocation::HandleRefreshRequest(const TurnMessage* msg) {
|
||||
// Figure out the new lifetime.
|
||||
int lifetime_secs = ComputeLifetime(msg);
|
||||
|
||||
@ -735,7 +668,7 @@ void TurnServer::Allocation::HandleRefreshRequest(const TurnMessage* msg) {
|
||||
SendResponse(&response);
|
||||
}
|
||||
|
||||
void TurnServer::Allocation::HandleSendIndication(const TurnMessage* msg) {
|
||||
void TurnServerAllocation::HandleSendIndication(const TurnMessage* msg) {
|
||||
// Check mandatory attributes.
|
||||
const StunByteStringAttribute* data_attr = msg->GetByteString(STUN_ATTR_DATA);
|
||||
const StunAddressAttribute* peer_attr =
|
||||
@ -755,7 +688,7 @@ void TurnServer::Allocation::HandleSendIndication(const TurnMessage* msg) {
|
||||
}
|
||||
}
|
||||
|
||||
void TurnServer::Allocation::HandleCreatePermissionRequest(
|
||||
void TurnServerAllocation::HandleCreatePermissionRequest(
|
||||
const TurnMessage* msg) {
|
||||
// Check mandatory attributes.
|
||||
const StunAddressAttribute* peer_attr =
|
||||
@ -777,7 +710,7 @@ void TurnServer::Allocation::HandleCreatePermissionRequest(
|
||||
SendResponse(&response);
|
||||
}
|
||||
|
||||
void TurnServer::Allocation::HandleChannelBindRequest(const TurnMessage* msg) {
|
||||
void TurnServerAllocation::HandleChannelBindRequest(const TurnMessage* msg) {
|
||||
// Check mandatory attributes.
|
||||
const StunUInt32Attribute* channel_attr =
|
||||
msg->GetUInt32(STUN_ATTR_CHANNEL_NUMBER);
|
||||
@ -808,7 +741,7 @@ void TurnServer::Allocation::HandleChannelBindRequest(const TurnMessage* msg) {
|
||||
if (!channel1) {
|
||||
channel1 = new Channel(thread_, channel_id, peer_attr->GetAddress());
|
||||
channel1->SignalDestroyed.connect(this,
|
||||
&TurnServer::Allocation::OnChannelDestroyed);
|
||||
&TurnServerAllocation::OnChannelDestroyed);
|
||||
channels_.push_back(channel1);
|
||||
} else {
|
||||
channel1->Refresh();
|
||||
@ -826,7 +759,7 @@ void TurnServer::Allocation::HandleChannelBindRequest(const TurnMessage* msg) {
|
||||
SendResponse(&response);
|
||||
}
|
||||
|
||||
void TurnServer::Allocation::HandleChannelData(const char* data, size_t size) {
|
||||
void TurnServerAllocation::HandleChannelData(const char* data, size_t size) {
|
||||
// Extract the channel number from the data.
|
||||
uint16 channel_id = rtc::GetBE16(data);
|
||||
Channel* channel = FindChannel(channel_id);
|
||||
@ -840,7 +773,7 @@ void TurnServer::Allocation::HandleChannelData(const char* data, size_t size) {
|
||||
}
|
||||
}
|
||||
|
||||
void TurnServer::Allocation::OnExternalPacket(
|
||||
void TurnServerAllocation::OnExternalPacket(
|
||||
rtc::AsyncPacketSocket* socket,
|
||||
const char* data, size_t size,
|
||||
const rtc::SocketAddress& addr,
|
||||
@ -871,7 +804,7 @@ void TurnServer::Allocation::OnExternalPacket(
|
||||
}
|
||||
}
|
||||
|
||||
int TurnServer::Allocation::ComputeLifetime(const TurnMessage* msg) {
|
||||
int TurnServerAllocation::ComputeLifetime(const TurnMessage* msg) {
|
||||
// Return the smaller of our default lifetime and the requested lifetime.
|
||||
uint32 lifetime = kDefaultAllocationTimeout / 1000; // convert to seconds
|
||||
const StunUInt32Attribute* lifetime_attr = msg->GetUInt32(STUN_ATTR_LIFETIME);
|
||||
@ -881,23 +814,23 @@ int TurnServer::Allocation::ComputeLifetime(const TurnMessage* msg) {
|
||||
return lifetime;
|
||||
}
|
||||
|
||||
bool TurnServer::Allocation::HasPermission(const rtc::IPAddress& addr) {
|
||||
bool TurnServerAllocation::HasPermission(const rtc::IPAddress& addr) {
|
||||
return (FindPermission(addr) != NULL);
|
||||
}
|
||||
|
||||
void TurnServer::Allocation::AddPermission(const rtc::IPAddress& addr) {
|
||||
void TurnServerAllocation::AddPermission(const rtc::IPAddress& addr) {
|
||||
Permission* perm = FindPermission(addr);
|
||||
if (!perm) {
|
||||
perm = new Permission(thread_, addr);
|
||||
perm->SignalDestroyed.connect(
|
||||
this, &TurnServer::Allocation::OnPermissionDestroyed);
|
||||
this, &TurnServerAllocation::OnPermissionDestroyed);
|
||||
perms_.push_back(perm);
|
||||
} else {
|
||||
perm->Refresh();
|
||||
}
|
||||
}
|
||||
|
||||
TurnServer::Permission* TurnServer::Allocation::FindPermission(
|
||||
TurnServerAllocation::Permission* TurnServerAllocation::FindPermission(
|
||||
const rtc::IPAddress& addr) const {
|
||||
for (PermissionList::const_iterator it = perms_.begin();
|
||||
it != perms_.end(); ++it) {
|
||||
@ -907,7 +840,8 @@ TurnServer::Permission* TurnServer::Allocation::FindPermission(
|
||||
return NULL;
|
||||
}
|
||||
|
||||
TurnServer::Channel* TurnServer::Allocation::FindChannel(int channel_id) const {
|
||||
TurnServerAllocation::Channel* TurnServerAllocation::FindChannel(
|
||||
int channel_id) const {
|
||||
for (ChannelList::const_iterator it = channels_.begin();
|
||||
it != channels_.end(); ++it) {
|
||||
if ((*it)->id() == channel_id)
|
||||
@ -916,7 +850,7 @@ TurnServer::Channel* TurnServer::Allocation::FindChannel(int channel_id) const {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
TurnServer::Channel* TurnServer::Allocation::FindChannel(
|
||||
TurnServerAllocation::Channel* TurnServerAllocation::FindChannel(
|
||||
const rtc::SocketAddress& addr) const {
|
||||
for (ChannelList::const_iterator it = channels_.begin();
|
||||
it != channels_.end(); ++it) {
|
||||
@ -926,83 +860,83 @@ TurnServer::Channel* TurnServer::Allocation::FindChannel(
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void TurnServer::Allocation::SendResponse(TurnMessage* msg) {
|
||||
void TurnServerAllocation::SendResponse(TurnMessage* msg) {
|
||||
// Success responses always have M-I.
|
||||
msg->AddMessageIntegrity(key_);
|
||||
server_->SendStun(&conn_, msg);
|
||||
}
|
||||
|
||||
void TurnServer::Allocation::SendBadRequestResponse(const TurnMessage* req) {
|
||||
void TurnServerAllocation::SendBadRequestResponse(const TurnMessage* req) {
|
||||
SendErrorResponse(req, STUN_ERROR_BAD_REQUEST, STUN_ERROR_REASON_BAD_REQUEST);
|
||||
}
|
||||
|
||||
void TurnServer::Allocation::SendErrorResponse(const TurnMessage* req, int code,
|
||||
void TurnServerAllocation::SendErrorResponse(const TurnMessage* req, int code,
|
||||
const std::string& reason) {
|
||||
server_->SendErrorResponse(&conn_, req, code, reason);
|
||||
}
|
||||
|
||||
void TurnServer::Allocation::SendExternal(const void* data, size_t size,
|
||||
void TurnServerAllocation::SendExternal(const void* data, size_t size,
|
||||
const rtc::SocketAddress& peer) {
|
||||
rtc::PacketOptions options;
|
||||
external_socket_->SendTo(data, size, peer, options);
|
||||
}
|
||||
|
||||
void TurnServer::Allocation::OnMessage(rtc::Message* msg) {
|
||||
void TurnServerAllocation::OnMessage(rtc::Message* msg) {
|
||||
ASSERT(msg->message_id == MSG_ALLOCATION_TIMEOUT);
|
||||
SignalDestroyed(this);
|
||||
delete this;
|
||||
}
|
||||
|
||||
void TurnServer::Allocation::OnPermissionDestroyed(Permission* perm) {
|
||||
void TurnServerAllocation::OnPermissionDestroyed(Permission* perm) {
|
||||
PermissionList::iterator it = std::find(perms_.begin(), perms_.end(), perm);
|
||||
ASSERT(it != perms_.end());
|
||||
perms_.erase(it);
|
||||
}
|
||||
|
||||
void TurnServer::Allocation::OnChannelDestroyed(Channel* channel) {
|
||||
void TurnServerAllocation::OnChannelDestroyed(Channel* channel) {
|
||||
ChannelList::iterator it =
|
||||
std::find(channels_.begin(), channels_.end(), channel);
|
||||
ASSERT(it != channels_.end());
|
||||
channels_.erase(it);
|
||||
}
|
||||
|
||||
TurnServer::Permission::Permission(rtc::Thread* thread,
|
||||
TurnServerAllocation::Permission::Permission(rtc::Thread* thread,
|
||||
const rtc::IPAddress& peer)
|
||||
: thread_(thread), peer_(peer) {
|
||||
Refresh();
|
||||
}
|
||||
|
||||
TurnServer::Permission::~Permission() {
|
||||
TurnServerAllocation::Permission::~Permission() {
|
||||
thread_->Clear(this, MSG_ALLOCATION_TIMEOUT);
|
||||
}
|
||||
|
||||
void TurnServer::Permission::Refresh() {
|
||||
void TurnServerAllocation::Permission::Refresh() {
|
||||
thread_->Clear(this, MSG_ALLOCATION_TIMEOUT);
|
||||
thread_->PostDelayed(kPermissionTimeout, this, MSG_ALLOCATION_TIMEOUT);
|
||||
}
|
||||
|
||||
void TurnServer::Permission::OnMessage(rtc::Message* msg) {
|
||||
void TurnServerAllocation::Permission::OnMessage(rtc::Message* msg) {
|
||||
ASSERT(msg->message_id == MSG_ALLOCATION_TIMEOUT);
|
||||
SignalDestroyed(this);
|
||||
delete this;
|
||||
}
|
||||
|
||||
TurnServer::Channel::Channel(rtc::Thread* thread, int id,
|
||||
TurnServerAllocation::Channel::Channel(rtc::Thread* thread, int id,
|
||||
const rtc::SocketAddress& peer)
|
||||
: thread_(thread), id_(id), peer_(peer) {
|
||||
Refresh();
|
||||
}
|
||||
|
||||
TurnServer::Channel::~Channel() {
|
||||
TurnServerAllocation::Channel::~Channel() {
|
||||
thread_->Clear(this, MSG_ALLOCATION_TIMEOUT);
|
||||
}
|
||||
|
||||
void TurnServer::Channel::Refresh() {
|
||||
void TurnServerAllocation::Channel::Refresh() {
|
||||
thread_->Clear(this, MSG_ALLOCATION_TIMEOUT);
|
||||
thread_->PostDelayed(kChannelTimeout, this, MSG_ALLOCATION_TIMEOUT);
|
||||
}
|
||||
|
||||
void TurnServer::Channel::OnMessage(rtc::Message* msg) {
|
||||
void TurnServerAllocation::Channel::OnMessage(rtc::Message* msg) {
|
||||
ASSERT(msg->message_id == MSG_ALLOCATION_TIMEOUT);
|
||||
SignalDestroyed(this);
|
||||
delete this;
|
||||
|
@ -32,10 +32,109 @@ namespace cricket {
|
||||
|
||||
class StunMessage;
|
||||
class TurnMessage;
|
||||
class TurnServer;
|
||||
|
||||
// The default server port for TURN, as specified in RFC5766.
|
||||
const int TURN_SERVER_PORT = 3478;
|
||||
|
||||
// Encapsulates the client's connection to the server.
|
||||
class TurnServerConnection {
|
||||
public:
|
||||
TurnServerConnection() : proto_(PROTO_UDP), socket_(NULL) {}
|
||||
TurnServerConnection(const rtc::SocketAddress& src,
|
||||
ProtocolType proto,
|
||||
rtc::AsyncPacketSocket* socket);
|
||||
const rtc::SocketAddress& src() const { return src_; }
|
||||
rtc::AsyncPacketSocket* socket() { return socket_; }
|
||||
bool operator==(const TurnServerConnection& t) const;
|
||||
bool operator<(const TurnServerConnection& t) const;
|
||||
std::string ToString() const;
|
||||
|
||||
private:
|
||||
rtc::SocketAddress src_;
|
||||
rtc::SocketAddress dst_;
|
||||
cricket::ProtocolType proto_;
|
||||
rtc::AsyncPacketSocket* socket_;
|
||||
};
|
||||
|
||||
// Encapsulates a TURN allocation.
|
||||
// The object is created when an allocation request is received, and then
|
||||
// handles TURN messages (via HandleTurnMessage) and channel data messages
|
||||
// (via HandleChannelData) for this allocation when received by the server.
|
||||
// The object self-deletes and informs the server if its lifetime timer expires.
|
||||
class TurnServerAllocation : public rtc::MessageHandler,
|
||||
public sigslot::has_slots<> {
|
||||
public:
|
||||
TurnServerAllocation(TurnServer* server_,
|
||||
rtc::Thread* thread,
|
||||
const TurnServerConnection& conn,
|
||||
rtc::AsyncPacketSocket* server_socket,
|
||||
const std::string& key);
|
||||
virtual ~TurnServerAllocation();
|
||||
|
||||
TurnServerConnection* conn() { return &conn_; }
|
||||
const std::string& key() const { return key_; }
|
||||
const std::string& transaction_id() const { return transaction_id_; }
|
||||
const std::string& username() const { return username_; }
|
||||
const std::string& origin() const { return origin_; }
|
||||
const std::string& last_nonce() const { return last_nonce_; }
|
||||
void set_last_nonce(const std::string& nonce) { last_nonce_ = nonce; }
|
||||
|
||||
std::string ToString() const;
|
||||
|
||||
void HandleTurnMessage(const TurnMessage* msg);
|
||||
void HandleChannelData(const char* data, size_t size);
|
||||
|
||||
sigslot::signal1<TurnServerAllocation*> SignalDestroyed;
|
||||
|
||||
private:
|
||||
class Channel;
|
||||
class Permission;
|
||||
typedef std::list<Permission*> PermissionList;
|
||||
typedef std::list<Channel*> ChannelList;
|
||||
|
||||
void HandleAllocateRequest(const TurnMessage* msg);
|
||||
void HandleRefreshRequest(const TurnMessage* msg);
|
||||
void HandleSendIndication(const TurnMessage* msg);
|
||||
void HandleCreatePermissionRequest(const TurnMessage* msg);
|
||||
void HandleChannelBindRequest(const TurnMessage* msg);
|
||||
|
||||
void OnExternalPacket(rtc::AsyncPacketSocket* socket,
|
||||
const char* data, size_t size,
|
||||
const rtc::SocketAddress& addr,
|
||||
const rtc::PacketTime& packet_time);
|
||||
|
||||
static int ComputeLifetime(const TurnMessage* msg);
|
||||
bool HasPermission(const rtc::IPAddress& addr);
|
||||
void AddPermission(const rtc::IPAddress& addr);
|
||||
Permission* FindPermission(const rtc::IPAddress& addr) const;
|
||||
Channel* FindChannel(int channel_id) const;
|
||||
Channel* FindChannel(const rtc::SocketAddress& addr) const;
|
||||
|
||||
void SendResponse(TurnMessage* msg);
|
||||
void SendBadRequestResponse(const TurnMessage* req);
|
||||
void SendErrorResponse(const TurnMessage* req, int code,
|
||||
const std::string& reason);
|
||||
void SendExternal(const void* data, size_t size,
|
||||
const rtc::SocketAddress& peer);
|
||||
|
||||
void OnPermissionDestroyed(Permission* perm);
|
||||
void OnChannelDestroyed(Channel* channel);
|
||||
virtual void OnMessage(rtc::Message* msg);
|
||||
|
||||
TurnServer* server_;
|
||||
rtc::Thread* thread_;
|
||||
TurnServerConnection conn_;
|
||||
rtc::scoped_ptr<rtc::AsyncPacketSocket> external_socket_;
|
||||
std::string key_;
|
||||
std::string transaction_id_;
|
||||
std::string username_;
|
||||
std::string origin_;
|
||||
std::string last_nonce_;
|
||||
PermissionList perms_;
|
||||
ChannelList channels_;
|
||||
};
|
||||
|
||||
// An interface through which the MD5 credential hash can be retrieved.
|
||||
class TurnAuthInterface {
|
||||
public:
|
||||
@ -60,6 +159,8 @@ class TurnRedirectInterface {
|
||||
// Not yet wired up: TCP support.
|
||||
class TurnServer : public sigslot::has_slots<> {
|
||||
public:
|
||||
typedef std::map<TurnServerConnection, TurnServerAllocation*> AllocationMap;
|
||||
|
||||
explicit TurnServer(rtc::Thread* thread);
|
||||
~TurnServer();
|
||||
|
||||
@ -71,6 +172,8 @@ class TurnServer : public sigslot::has_slots<> {
|
||||
const std::string& software() const { return software_; }
|
||||
void set_software(const std::string& software) { software_ = software; }
|
||||
|
||||
const AllocationMap& allocations() const { return allocations_; }
|
||||
|
||||
// Sets the authentication callback; does not take ownership.
|
||||
void set_auth_hook(TurnAuthInterface* auth_hook) { auth_hook_ = auth_hook; }
|
||||
|
||||
@ -93,30 +196,6 @@ class TurnServer : public sigslot::has_slots<> {
|
||||
const rtc::SocketAddress& address);
|
||||
|
||||
private:
|
||||
// Encapsulates the client's connection to the server.
|
||||
class Connection {
|
||||
public:
|
||||
Connection() : proto_(PROTO_UDP), socket_(NULL) {}
|
||||
Connection(const rtc::SocketAddress& src,
|
||||
ProtocolType proto,
|
||||
rtc::AsyncPacketSocket* socket);
|
||||
const rtc::SocketAddress& src() const { return src_; }
|
||||
rtc::AsyncPacketSocket* socket() { return socket_; }
|
||||
bool operator==(const Connection& t) const;
|
||||
bool operator<(const Connection& t) const;
|
||||
std::string ToString() const;
|
||||
|
||||
private:
|
||||
rtc::SocketAddress src_;
|
||||
rtc::SocketAddress dst_;
|
||||
cricket::ProtocolType proto_;
|
||||
rtc::AsyncPacketSocket* socket_;
|
||||
};
|
||||
class Allocation;
|
||||
class Permission;
|
||||
class Channel;
|
||||
typedef std::map<Connection, Allocation*> AllocationMap;
|
||||
|
||||
void OnInternalPacket(rtc::AsyncPacketSocket* socket, const char* data,
|
||||
size_t size, const rtc::SocketAddress& address,
|
||||
const rtc::PacketTime& packet_time);
|
||||
@ -127,38 +206,39 @@ class TurnServer : public sigslot::has_slots<> {
|
||||
void AcceptConnection(rtc::AsyncSocket* server_socket);
|
||||
void OnInternalSocketClose(rtc::AsyncPacketSocket* socket, int err);
|
||||
|
||||
void HandleStunMessage(Connection* conn, const char* data, size_t size);
|
||||
void HandleBindingRequest(Connection* conn, const StunMessage* msg);
|
||||
void HandleAllocateRequest(Connection* conn, const TurnMessage* msg,
|
||||
void HandleStunMessage(
|
||||
TurnServerConnection* conn, const char* data, size_t size);
|
||||
void HandleBindingRequest(TurnServerConnection* conn, const StunMessage* msg);
|
||||
void HandleAllocateRequest(TurnServerConnection* conn, const TurnMessage* msg,
|
||||
const std::string& key);
|
||||
|
||||
bool GetKey(const StunMessage* msg, std::string* key);
|
||||
bool CheckAuthorization(Connection* conn, const StunMessage* msg,
|
||||
bool CheckAuthorization(TurnServerConnection* conn, const StunMessage* msg,
|
||||
const char* data, size_t size,
|
||||
const std::string& key);
|
||||
std::string GenerateNonce() const;
|
||||
bool ValidateNonce(const std::string& nonce) const;
|
||||
|
||||
Allocation* FindAllocation(Connection* conn);
|
||||
Allocation* CreateAllocation(Connection* conn, int proto,
|
||||
const std::string& key);
|
||||
TurnServerAllocation* FindAllocation(TurnServerConnection* conn);
|
||||
TurnServerAllocation* CreateAllocation(
|
||||
TurnServerConnection* conn, int proto, const std::string& key);
|
||||
|
||||
void SendErrorResponse(Connection* conn, const StunMessage* req,
|
||||
void SendErrorResponse(TurnServerConnection* conn, const StunMessage* req,
|
||||
int code, const std::string& reason);
|
||||
|
||||
void SendErrorResponseWithRealmAndNonce(Connection* conn,
|
||||
void SendErrorResponseWithRealmAndNonce(TurnServerConnection* conn,
|
||||
const StunMessage* req,
|
||||
int code,
|
||||
const std::string& reason);
|
||||
|
||||
void SendErrorResponseWithAlternateServer(Connection* conn,
|
||||
void SendErrorResponseWithAlternateServer(TurnServerConnection* conn,
|
||||
const StunMessage* req,
|
||||
const rtc::SocketAddress& addr);
|
||||
|
||||
void SendStun(Connection* conn, StunMessage* msg);
|
||||
void Send(Connection* conn, const rtc::ByteBuffer& buf);
|
||||
void SendStun(TurnServerConnection* conn, StunMessage* msg);
|
||||
void Send(TurnServerConnection* conn, const rtc::ByteBuffer& buf);
|
||||
|
||||
void OnAllocationDestroyed(Allocation* allocation);
|
||||
void OnAllocationDestroyed(TurnServerAllocation* allocation);
|
||||
void DestroyInternalSocket(rtc::AsyncPacketSocket* socket);
|
||||
|
||||
typedef std::map<rtc::AsyncPacketSocket*,
|
||||
@ -183,6 +263,8 @@ class TurnServer : public sigslot::has_slots<> {
|
||||
rtc::SocketAddress external_addr_;
|
||||
|
||||
AllocationMap allocations_;
|
||||
|
||||
friend class TurnServerAllocation;
|
||||
};
|
||||
|
||||
} // namespace cricket
|
||||
|
@ -889,14 +889,16 @@ void AllocationSequence::CreateUDPPorts() {
|
||||
port = UDPPort::Create(session_->network_thread(),
|
||||
session_->socket_factory(), network_,
|
||||
udp_socket_.get(),
|
||||
session_->username(), session_->password());
|
||||
session_->username(), session_->password(),
|
||||
session_->allocator()->origin());
|
||||
} else {
|
||||
port = UDPPort::Create(session_->network_thread(),
|
||||
session_->socket_factory(),
|
||||
network_, ip_,
|
||||
session_->allocator()->min_port(),
|
||||
session_->allocator()->max_port(),
|
||||
session_->username(), session_->password());
|
||||
session_->username(), session_->password(),
|
||||
session_->allocator()->origin());
|
||||
}
|
||||
|
||||
if (port) {
|
||||
@ -973,7 +975,8 @@ void AllocationSequence::CreateStunPorts() {
|
||||
session_->allocator()->min_port(),
|
||||
session_->allocator()->max_port(),
|
||||
session_->username(), session_->password(),
|
||||
config_->StunServers());
|
||||
config_->StunServers(),
|
||||
session_->allocator()->origin());
|
||||
if (port) {
|
||||
session_->AddAllocatedPort(port, this, true);
|
||||
// Since StunPort is not created using shared socket, |port| will not be
|
||||
@ -1055,8 +1058,8 @@ void AllocationSequence::CreateTurnPort(const RelayServerConfig& config) {
|
||||
session_->socket_factory(),
|
||||
network_, udp_socket_.get(),
|
||||
session_->username(), session_->password(),
|
||||
*relay_port, config.credentials, config.priority);
|
||||
|
||||
*relay_port, config.credentials, config.priority,
|
||||
session_->allocator()->origin());
|
||||
turn_ports_.push_back(port);
|
||||
// Listen to the port destroyed signal, to allow AllocationSequence to
|
||||
// remove entrt from it's map.
|
||||
@ -1069,7 +1072,8 @@ void AllocationSequence::CreateTurnPort(const RelayServerConfig& config) {
|
||||
session_->allocator()->max_port(),
|
||||
session_->username(),
|
||||
session_->password(),
|
||||
*relay_port, config.credentials, config.priority);
|
||||
*relay_port, config.credentials, config.priority,
|
||||
session_->allocator()->origin());
|
||||
}
|
||||
ASSERT(port != NULL);
|
||||
session_->AddAllocatedPort(port, this, true);
|
||||
|
@ -371,7 +371,8 @@ StunPort* ConnectivityChecker::CreateStunPort(
|
||||
0,
|
||||
username,
|
||||
password,
|
||||
config->stun_servers);
|
||||
config->stun_servers,
|
||||
std::string());
|
||||
}
|
||||
|
||||
RelayPort* ConnectivityChecker::CreateRelayPort(
|
||||
|
@ -75,7 +75,7 @@ class FakeStunPort : public StunPort {
|
||||
const std::string& username, const std::string& password,
|
||||
const ServerAddresses& server_addr)
|
||||
: StunPort(thread, factory, network, ip, min_port, max_port,
|
||||
username, password, server_addr) {
|
||||
username, password, server_addr, std::string()) {
|
||||
}
|
||||
|
||||
// Just set external address and signal that we are done.
|
||||
|
@ -56,7 +56,8 @@ class FakePortAllocatorSession : public PortAllocatorSession {
|
||||
0,
|
||||
0,
|
||||
username(),
|
||||
password()));
|
||||
password(),
|
||||
std::string()));
|
||||
AddPort(port_.get());
|
||||
}
|
||||
++port_config_count_;
|
||||
|
Loading…
x
Reference in New Issue
Block a user