Chromium Code Reviews| Index: content/browser/renderer_host/p2p/socket_host_tcp.cc |
| =================================================================== |
| --- content/browser/renderer_host/p2p/socket_host_tcp.cc (revision 205587) |
| +++ content/browser/renderer_host/p2p/socket_host_tcp.cc (working copy) |
| @@ -5,6 +5,7 @@ |
| #include "content/browser/renderer_host/p2p/socket_host_tcp.h" |
| #include "base/sys_byteorder.h" |
| +#include "content/browser/renderer_host/p2p/ssltcp_helper.h" |
| #include "content/common/p2p_messages.h" |
| #include "ipc/ipc_sender.h" |
| #include "net/base/io_buffer.h" |
| @@ -19,16 +20,18 @@ |
| const int kReadBufferSize = 4096; |
| const int kPacketLengthOffset = 2; |
| const int kTurnChannelDataHeaderSize = 4; |
| - |
| } // namespace |
| namespace content { |
| P2PSocketHostTcpBase::P2PSocketHostTcpBase(IPC::Sender* message_sender, |
| - int id) |
| + int id, bool ssl) |
|
Sergey Ulanov
2013/06/18 20:01:26
nit: one argument per line please.
|
| : P2PSocketHost(message_sender, id), |
| write_pending_(false), |
| connected_(false) { |
| + if (ssl) { |
| + ssltcp_helper_.reset(new SsltcpHelper()); |
| + } |
| } |
| P2PSocketHostTcpBase::~P2PSocketHostTcpBase() { |
| @@ -43,6 +46,10 @@ |
| DCHECK(socket); |
| DCHECK_EQ(state_, STATE_UNINITIALIZED); |
| + if (ssltcp_helper_.get()) { |
|
Sergey Ulanov
2013/06/18 20:01:26
nit: don't need .get() here and in Init().
|
| + // Init ssltcp helper to server mode. |
|
Sergey Ulanov
2013/06/18 20:01:26
You wouldn't need this comment if you used an enum
|
| + ssltcp_helper_->Init(false); |
| + } |
| remote_address_ = remote_address; |
| socket_.reset(socket); |
| state_ = STATE_OPEN; |
| @@ -51,9 +58,13 @@ |
| } |
| bool P2PSocketHostTcpBase::Init(const net::IPEndPoint& local_address, |
| - const net::IPEndPoint& remote_address) { |
| + const net::IPEndPoint& remote_address) { |
| DCHECK_EQ(state_, STATE_UNINITIALIZED); |
| + if (ssltcp_helper_.get()) { |
| + // Init ssltcp helper to client mode. |
| + ssltcp_helper_->Init(true); |
| + } |
| remote_address_ = remote_address; |
| state_ = STATE_CONNECTING; |
| scoped_ptr<net::TCPClientSocket> tcp_socket(new net::TCPClientSocket( |
| @@ -85,6 +96,31 @@ |
| state_ = STATE_ERROR; |
| } |
| +int P2PSocketHostTcpBase::MaybeHandleSslHello(char** cur, int* cur_len, |
| + int* consumed) { |
| + if (static_cast<size_t>(*cur_len) < |
| + ssltcp_helper_->remote_hello_message_size()) { |
| + return 0; |
| + } |
| + if (!ssltcp_helper_->IsHelloMessage(*cur)) { |
| + LOG(ERROR) << "Expect a SSL HELLO message."; |
| + OnError(); |
| + return 0; |
| + } |
| + *cur_len -= ssltcp_helper_->remote_hello_message_size(); |
| + *consumed += ssltcp_helper_->remote_hello_message_size(); |
| + *cur += ssltcp_helper_->remote_hello_message_size(); |
| + ssltcp_helper_->set_hello_received(true); |
| + |
| + if (!ssltcp_helper_->IsClient()) { |
| + // Response with a server hello message. |
| + DoSend(remote_address_, ssltcp_helper_->server_hello_message()); |
| + ssltcp_helper_->set_hello_sent(true); |
| + } |
| + |
| + return *consumed; |
| +} |
| + |
| void P2PSocketHostTcpBase::OnConnected(int result) { |
| DCHECK_EQ(state_, STATE_CONNECTING); |
| DCHECK_NE(result, net::ERR_IO_PENDING); |
| @@ -172,6 +208,12 @@ |
| return; |
| } |
| + if (ssltcp_helper_.get() && ssltcp_helper_->IsClient() && |
| + !ssltcp_helper_->hello_sent()) { |
| + DoSend(remote_address_, ssltcp_helper_->client_hello_message()); |
| + ssltcp_helper_->set_hello_sent(true); |
| + } |
| + |
| if (!connected_) { |
| P2PSocketHost::StunMessageType type; |
| bool stun = GetStunPacketType(&*data.begin(), data.size(), &type); |
| @@ -272,8 +314,9 @@ |
| } |
| } |
| -P2PSocketHostTcp::P2PSocketHostTcp(IPC::Sender* message_sender, int id) |
| - : P2PSocketHostTcpBase(message_sender, id) { |
| +P2PSocketHostTcp::P2PSocketHostTcp(IPC::Sender* message_sender, int id, |
| + bool ssl) |
| + : P2PSocketHostTcpBase(message_sender, id, ssl) { |
| } |
| P2PSocketHostTcp::~P2PSocketHostTcp() { |
| @@ -288,6 +331,12 @@ |
| int consumed = kPacketHeaderSize; |
| char* cur = input + consumed; |
| + |
| + // Handle ssltcp hello message. |
| + if (ssltcp_helper_.get() && !ssltcp_helper_->hello_received()) { |
| + return MaybeHandleSslHello(&cur, &packet_size, &consumed); |
|
Sergey Ulanov
2013/06/18 20:01:26
I think this should be handled in DidCompleteRead(
|
| + } |
| + |
| std::vector<char> data(cur, cur + packet_size); |
| OnPacket(data); |
| consumed += packet_size; |
| @@ -307,27 +356,33 @@ |
| // P2PSocketHostStunTcp |
| P2PSocketHostStunTcp::P2PSocketHostStunTcp(IPC::Sender* message_sender, |
| - int id) |
| - : P2PSocketHostTcpBase(message_sender, id) { |
| + int id, bool ssl) |
| + : P2PSocketHostTcpBase(message_sender, id, ssl) { |
| } |
| P2PSocketHostStunTcp::~P2PSocketHostStunTcp() { |
| } |
| int P2PSocketHostStunTcp::ProcessInput(char* input, int input_len) { |
| - if (input_len < kPacketHeaderSize + kPacketLengthOffset) |
| - return 0; |
| - |
| + int consumed = 0; |
| + char* cur = input; |
| + int cur_len = input_len; |
| int pad_bytes; |
| - int packet_size = GetExpectedPacketSize( |
| - input, input_len, &pad_bytes); |
| - if (input_len < packet_size + pad_bytes) |
| - return 0; |
| + // Handle ssltcp hello message if not received yet. |
| + if (ssltcp_helper_.get() && !ssltcp_helper_->hello_received()) { |
| + return MaybeHandleSslHello(&cur, &cur_len, &consumed); |
| + } |
| + if (cur_len < kPacketHeaderSize + kPacketLengthOffset) |
| + return consumed; |
| + |
| + int packet_size = GetExpectedPacketSize(cur, cur_len, &pad_bytes); |
| + |
| + if (cur_len < packet_size + pad_bytes) |
| + return consumed; |
| + |
| // We have a complete packet. Read through it. |
| - int consumed = 0; |
| - char* cur = input; |
| std::vector<char> data(cur, cur + packet_size); |
| OnPacket(data); |
| consumed += packet_size; |
| @@ -349,6 +404,11 @@ |
| size_t expected_len = GetExpectedPacketSize( |
| &data[0], data.size(), &pad_bytes); |
| + if (ssltcp_helper_.get() && !ssltcp_helper_->hello_sent()) { |
| + expected_len = ssltcp_helper_->hello_message_size(); |
|
Sergey Ulanov
2013/06/18 20:01:26
Why do we need this here? P2PSocketHostTcpBase::Se
|
| + pad_bytes = 0; |
| + } |
| + |
| // Accepts only complete STUN/TURN packets. |
| if (data.size() != expected_len) { |
| NOTREACHED(); |