| Index: content/browser/renderer_host/p2p/socket_host_tcp.cc
|
| ===================================================================
|
| --- content/browser/renderer_host/p2p/socket_host_tcp.cc (revision 217133)
|
| +++ content/browser/renderer_host/p2p/socket_host_tcp.cc (working copy)
|
| @@ -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 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 @@
|
| 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 @@
|
| 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 @@
|
| 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 @@
|
| 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 @@
|
| 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() {
|
|
|