Index: content/browser/renderer_host/p2p/socket_host_tcp.cc |
=================================================================== |
--- content/browser/renderer_host/p2p/socket_host_tcp.cc (revision 215641) |
+++ 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); |
} |
@@ -49,6 +58,10 @@ |
} |
} |
+bool P2PSocketHostTcpBase::IsOpen() const { |
+ return (state_ == STATE_OPEN) || (state_ == STATE_TLS_OPEN); |
+} |
+ |
bool P2PSocketHostTcpBase::InitAccepted(const net::IPEndPoint& remote_address, |
net::StreamSocket* socket) { |
DCHECK(socket); |
@@ -82,9 +95,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 +119,8 @@ |
socket_.reset(); |
if (state_ == STATE_UNINITIALIZED || state_ == STATE_CONNECTING || |
- state_ == STATE_OPEN) { |
+ state_ == STATE_OPEN || state_ == STATE_TLS_CONNECTING || |
+ state_ == STATE_TLS_OPEN) { |
message_sender_->Send(new P2PMsg_OnError(id_)); |
} |
@@ -125,21 +136,99 @@ |
return; |
} |
+ state_ = STATE_OPEN; |
+ |
+ if (IsTlsClientSocket(type_)) { |
+ return StartTls(); |
+ } else if (IsPseudoTlsClientSocket(type_)) { |
+ socket_.reset(new jingle_glue::FakeSSLClientSocket(socket_.release())); |
+ } |
+ |
net::IPEndPoint address; |
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 going 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::StartTls() { |
+ if (state_ != STATE_OPEN) { |
+ LOG(DFATAL) << "StartTls() called in wrong state"; |
+ return; |
+ } |
+ |
+ 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::ProcessSSLConnectDone, |
+ base::Unretained(this))); |
+ if (status != net::ERR_IO_PENDING) { |
+ base::MessageLoop* message_loop = base::MessageLoop::current(); |
+ CHECK(message_loop); |
+ message_loop->PostTask( |
+ FROM_HERE, |
+ base::Bind(&P2PSocketHostTcpBase::ProcessSSLConnectDone, |
+ base::Unretained(this), status)); |
+ } |
+ return; |
+} |
+ |
+void P2PSocketHostTcpBase::ProcessSSLConnectDone(int status) { |
juberti2
2013/08/07 06:04:21
This code looks very similar to the code that is u
Mallinath (Gone from Chromium)
2013/08/07 23:48:19
Done.
|
+ DCHECK_NE(status, net::ERR_IO_PENDING); |
+ DCHECK_EQ(state_, STATE_TLS_CONNECTING); |
+ if (status != net::OK) { |
+ OnError(); |
+ return; |
+ } |
+ |
+ net::IPEndPoint address; |
+ status = socket_->GetLocalAddress(&address); |
+ if (status < 0) { |
+ LOG(ERROR) << "P2PSocketHostTcpBase::ProcessSSLConnectDone: unable to get" |
+ << " local address: " << status; |
+ OnError(); |
+ return; |
+ } |
+ |
+ state_ = STATE_TLS_OPEN; |
+ |
+ message_sender_->Send(new P2PMsg_OnSocketCreated(id_, address)); |
+ DoRead(); |
+} |
+ |
void P2PSocketHostTcpBase::DoRead() { |
int result; |
do { |
@@ -164,7 +253,7 @@ |
void P2PSocketHostTcpBase::OnRead(int result) { |
DidCompleteRead(result); |
- if (state_ == STATE_OPEN) { |
+ if (IsOpen()) { |
DoRead(); |
} |
} |