Clone of @ https://codereview.chromium.org/22452002/

which is LGTMed by @sergeyu and @juberti.

Adding TLS support to the TCP Client sockets. 
In case of WebRTC TLS socket will be created when application passes TURNS url. TurnPort will request for creating TLS sockets. 

In other instances TLS will be done using Pseudo-TLS, i.e. when TCPPort creates ssltcp, it's actually a pseudo-tls. 

TBR=vrk@chromium.org,jln@chromium.org,sergeyu@chromium.org,juberti@chromium.org

Review URL: https://codereview.chromium.org/22990002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@217145 0039d316-1c4b-4281-b951-d872f2087c98
parent 6dfcfabd
......@@ -88,10 +88,12 @@ P2PSocketHost* P2PSocketHost::Create(
case P2P_SOCKET_TCP_CLIENT:
case P2P_SOCKET_SSLTCP_CLIENT:
case P2P_SOCKET_TLS_CLIENT:
return new P2PSocketHostTcp(message_sender, id, type, url_context);
case P2P_SOCKET_STUN_TCP_CLIENT:
case P2P_SOCKET_STUN_SSLTCP_CLIENT:
case P2P_SOCKET_STUN_TLS_CLIENT:
return new P2PSocketHostStunTcp(message_sender, id, type, url_context);
}
......
......@@ -64,6 +64,7 @@ class CONTENT_EXPORT P2PSocketHost {
enum State {
STATE_UNINITIALIZED,
STATE_CONNECTING,
STATE_TLS_CONNECTING,
STATE_OPEN,
STATE_ERROR,
};
......
......@@ -12,7 +12,11 @@
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
#include "net/base/net_util.h"
#include "net/socket/client_socket_factory.h"
#include "net/socket/client_socket_handle.h"
#include "net/socket/ssl_client_socket.h"
#include "net/socket/tcp_client_socket.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_getter.h"
namespace {
......@@ -23,7 +27,12 @@ const int kReadBufferSize = 4096;
const int kPacketLengthOffset = 2;
const int kTurnChannelDataHeaderSize = 4;
bool IsSslClientSocket(content::P2PSocketType type) {
bool IsTlsClientSocket(content::P2PSocketType type) {
return (type == content::P2P_SOCKET_STUN_TLS_CLIENT ||
type == content::P2P_SOCKET_TLS_CLIENT);
}
bool IsPseudoTlsClientSocket(content::P2PSocketType type) {
return (type == content::P2P_SOCKET_SSLTCP_CLIENT ||
type == content::P2P_SOCKET_STUN_SSLTCP_CLIENT);
}
......@@ -82,9 +91,6 @@ bool P2PSocketHostTcpBase::Init(const net::IPEndPoint& local_address,
url_context_,
ssl_config,
dest_host_port_pair));
if (IsSslClientSocket(type_)) {
socket_.reset(new jingle_glue::FakeSSLClientSocket(socket_.release()));
}
int status = socket_->Connect(
base::Bind(&P2PSocketHostTcpBase::OnConnected,
......@@ -109,7 +115,7 @@ void P2PSocketHostTcpBase::OnError() {
socket_.reset();
if (state_ == STATE_UNINITIALIZED || state_ == STATE_CONNECTING ||
state_ == STATE_OPEN) {
state_ == STATE_TLS_CONNECTING || state_ == STATE_OPEN) {
message_sender_->Send(new P2PMsg_OnError(id_));
}
......@@ -125,19 +131,88 @@ void P2PSocketHostTcpBase::OnConnected(int result) {
return;
}
if (IsTlsClientSocket(type_)) {
state_ = STATE_TLS_CONNECTING;
StartTls();
} else {
if (IsPseudoTlsClientSocket(type_)) {
socket_.reset(new jingle_glue::FakeSSLClientSocket(socket_.release()));
}
// If we are not doing TLS, we are ready to send data now.
// In case of TLS, SignalConnect will be sent only after TLS handshake is
// successfull. So no buffering will be done at socket handlers if any
// packets sent before that by the application.
state_ = STATE_OPEN;
DoSendSocketCreateMsg();
DoRead();
}
}
void P2PSocketHostTcpBase::StartTls() {
DCHECK_EQ(state_, STATE_TLS_CONNECTING);
DCHECK(socket_.get());
scoped_ptr<net::ClientSocketHandle> socket_handle(
new net::ClientSocketHandle());
socket_handle->set_socket(socket_.release());
net::SSLClientSocketContext context;
context.cert_verifier = url_context_->GetURLRequestContext()->cert_verifier();
context.transport_security_state =
url_context_->GetURLRequestContext()->transport_security_state();
DCHECK(context.transport_security_state);
// Default ssl config.
const net::SSLConfig ssl_config;
net::HostPortPair dest_host_port_pair =
net::HostPortPair::FromIPEndPoint(remote_address_);
net::ClientSocketFactory* socket_factory =
net::ClientSocketFactory::GetDefaultFactory();
DCHECK(socket_factory);
socket_.reset(socket_factory->CreateSSLClientSocket(
socket_handle.release(), dest_host_port_pair, ssl_config, context));
int status = socket_->Connect(
base::Bind(&P2PSocketHostTcpBase::ProcessTlsConnectDone,
base::Unretained(this)));
if (status != net::ERR_IO_PENDING) {
ProcessTlsConnectDone(status);
}
}
void P2PSocketHostTcpBase::ProcessTlsConnectDone(int status) {
DCHECK_NE(status, net::ERR_IO_PENDING);
DCHECK_EQ(state_, STATE_TLS_CONNECTING);
if (status != net::OK) {
OnError();
return;
}
state_ = STATE_OPEN;
DoSendSocketCreateMsg();
DoRead();
}
void P2PSocketHostTcpBase::DoSendSocketCreateMsg() {
DCHECK(socket_.get());
net::IPEndPoint address;
result = socket_->GetLocalAddress(&address);
int result = socket_->GetLocalAddress(&address);
if (result < 0) {
LOG(ERROR) << "P2PSocket::Init(): unable to get local address: "
<< result;
LOG(ERROR) << "P2PSocketHostTcpBase::OnConnected: unable to get local"
<< " address: " << result;
OnError();
return;
}
VLOG(1) << "Local address: " << address.ToString();
state_ = STATE_OPEN;
// If we are not doing TLS, we are ready to send data now.
// In case of TLS SignalConnect will be sent only after TLS handshake is
// successfull. So no buffering will be done at socket handlers if any
// packets sent before that by the application.
message_sender_->Send(new P2PMsg_OnSocketCreated(id_, address));
DoRead();
}
void P2PSocketHostTcpBase::DoRead() {
......@@ -307,7 +382,9 @@ P2PSocketHostTcp::P2PSocketHostTcp(
IPC::Sender* message_sender, int id,
P2PSocketType type, net::URLRequestContextGetter* url_context)
: P2PSocketHostTcpBase(message_sender, id, type, url_context) {
DCHECK(type == P2P_SOCKET_TCP_CLIENT || type == P2P_SOCKET_SSLTCP_CLIENT);
DCHECK(type == P2P_SOCKET_TCP_CLIENT ||
type == P2P_SOCKET_SSLTCP_CLIENT ||
type == P2P_SOCKET_TLS_CLIENT);
}
P2PSocketHostTcp::~P2PSocketHostTcp() {
......@@ -345,7 +422,8 @@ P2PSocketHostStunTcp::P2PSocketHostStunTcp(
P2PSocketType type, net::URLRequestContextGetter* url_context)
: P2PSocketHostTcpBase(message_sender, id, type, url_context) {
DCHECK(type == P2P_SOCKET_STUN_TCP_CLIENT ||
type == P2P_SOCKET_STUN_SSLTCP_CLIENT);
type == P2P_SOCKET_STUN_SSLTCP_CLIENT ||
type == P2P_SOCKET_STUN_TLS_CLIENT);
}
P2PSocketHostStunTcp::~P2PSocketHostStunTcp() {
......
......@@ -59,6 +59,10 @@ class CONTENT_EXPORT P2PSocketHostTcpBase : public P2PSocketHost {
friend class P2PSocketHostTcpTestBase;
friend class P2PSocketHostTcpServerTest;
// SSL/TLS connection functions.
void StartTls();
void ProcessTlsConnectDone(int status);
void DidCompleteRead(int result);
void DoRead();
......@@ -70,6 +74,8 @@ class CONTENT_EXPORT P2PSocketHostTcpBase : public P2PSocketHost {
void OnRead(int result);
void OnWritten(int result);
void DoSendSocketCreateMsg();
net::IPEndPoint remote_address_;
scoped_ptr<net::StreamSocket> socket_;
......
......@@ -19,6 +19,8 @@ enum P2PSocketType {
P2P_SOCKET_STUN_TCP_CLIENT,
P2P_SOCKET_SSLTCP_CLIENT,
P2P_SOCKET_STUN_SSLTCP_CLIENT,
P2P_SOCKET_TLS_CLIENT,
P2P_SOCKET_STUN_TLS_CLIENT,
};
} // namespace content
......
......@@ -117,6 +117,7 @@ class P2PPortAllocatorFactory : public webrtc::PortAllocatorFactoryInterface {
relay_config.username = turn_configurations[i].username;
relay_config.password = turn_configurations[i].password;
relay_config.transport_type = turn_configurations[i].transport_type;
relay_config.secure = turn_configurations[i].secure;
config.relays.push_back(relay_config);
}
......
......@@ -23,7 +23,9 @@ bool IsTcpClientSocket(P2PSocketType type) {
return (type == P2P_SOCKET_STUN_TCP_CLIENT) ||
(type == P2P_SOCKET_TCP_CLIENT) ||
(type == P2P_SOCKET_STUN_SSLTCP_CLIENT) ||
(type == P2P_SOCKET_SSLTCP_CLIENT);
(type == P2P_SOCKET_SSLTCP_CLIENT) ||
(type == P2P_SOCKET_TLS_CLIENT) ||
(type == P2P_SOCKET_STUN_TLS_CLIENT);
}
// TODO(miu): This needs tuning. http://crbug.com/237960
......@@ -433,6 +435,9 @@ talk_base::AsyncPacketSocket* IpcPacketSocketFactory::CreateClientTcpSocket(
if (opts & talk_base::PacketSocketFactory::OPT_SSLTCP) {
type = (opts & talk_base::PacketSocketFactory::OPT_STUN) ?
P2P_SOCKET_STUN_SSLTCP_CLIENT : P2P_SOCKET_SSLTCP_CLIENT;
} else if (opts & talk_base::PacketSocketFactory::OPT_TLS) {
type = (opts & talk_base::PacketSocketFactory::OPT_STUN) ?
P2P_SOCKET_STUN_TLS_CLIENT : P2P_SOCKET_TLS_CLIENT;
} else {
type = (opts & talk_base::PacketSocketFactory::OPT_STUN) ?
P2P_SOCKET_STUN_TCP_CLIENT : P2P_SOCKET_TCP_CLIENT;
......
......@@ -385,7 +385,9 @@ void P2PPortAllocatorSession::AddConfig() {
}
relay_server.ports.push_back(cricket::ProtocolAddress(
relay_info.resolved_relay_address, protocol));
relay_info.resolved_relay_address,
protocol,
relay_info.config.secure));
relay_server.credentials = credentials;
port_config->AddRelay(relay_server);
}
......
......@@ -40,6 +40,7 @@ class P2PPortAllocator : public cricket::BasicPortAllocator {
std::string server_address;
int port;
std::string transport_type;
bool secure;
};
// STUN server address and port.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment