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(); |