summaryrefslogtreecommitdiffstats
path: root/content
diff options
context:
space:
mode:
Diffstat (limited to 'content')
-rw-r--r--content/browser/renderer_host/p2p/socket_host.h9
-rw-r--r--content/browser/renderer_host/p2p/socket_host_tcp.cc72
-rw-r--r--content/browser/renderer_host/p2p/socket_host_tcp.h3
-rw-r--r--content/browser/renderer_host/p2p/socket_host_tcp_unittest.cc13
-rw-r--r--content/browser/renderer_host/p2p/socket_host_udp.cc41
-rw-r--r--content/browser/renderer_host/p2p/socket_host_udp.h10
-rw-r--r--content/browser/renderer_host/p2p/socket_host_udp_unittest.cc11
-rw-r--r--content/common/p2p_messages.h3
-rw-r--r--content/renderer/p2p/ipc_socket_factory.cc45
-rw-r--r--content/renderer/p2p/socket_client.cc13
-rw-r--r--content/renderer/p2p/socket_client.h7
-rw-r--r--content/renderer/p2p/socket_dispatcher.cc8
-rw-r--r--content/renderer/p2p/socket_dispatcher.h1
13 files changed, 152 insertions, 84 deletions
diff --git a/content/browser/renderer_host/p2p/socket_host.h b/content/browser/renderer_host/p2p/socket_host.h
index 0abb74e..9fe985d 100644
--- a/content/browser/renderer_host/p2p/socket_host.h
+++ b/content/browser/renderer_host/p2p/socket_host.h
@@ -62,15 +62,6 @@ class CONTENT_EXPORT P2PSocketHost {
STATE_ERROR,
};
- // Maximum size of send buffers. Must be big enough to fit data for
- // one data burst. Send buffers size needs to be limited to prevent
- // from consuming too much memory with misbehaving renderer process.
- //
- // TODO(sergeyu): Consider implementing congestion notifications to
- // minimize buffering. This will require some fixes in libjingle,
- // see crbug.com/91495 .
- static const int kMaxSendBufferSize = 256 * 1024;
-
P2PSocketHost(IPC::Sender* message_sender, int id);
// Verifies that the packet |data| has a valid STUN header. In case
diff --git a/content/browser/renderer_host/p2p/socket_host_tcp.cc b/content/browser/renderer_host/p2p/socket_host_tcp.cc
index 2409280..be59f72 100644
--- a/content/browser/renderer_host/p2p/socket_host_tcp.cc
+++ b/content/browser/renderer_host/p2p/socket_host_tcp.cc
@@ -87,10 +87,6 @@ void P2PSocketHostTcp::OnConnected(int result) {
return;
}
- if (!socket_->SetSendBufferSize(kMaxSendBufferSize)) {
- LOG(WARNING) << "Failed to set send buffer size for TCP socket.";
- }
-
net::IPEndPoint address;
result = socket_->GetLocalAddress(&address);
if (result < 0) {
@@ -196,16 +192,8 @@ void P2PSocketHostTcp::Send(const net::IPEndPoint& to,
return;
}
- if (write_buffer_) {
- // Silently drop packet if we haven't finished sending previous
- // packet.
- VLOG(1) << "Dropping TCP packet.";
- return;
- }
-
if (!(to == remote_address_)) {
- // Renderer should use this socket only to send data to
- // |remote_address_|.
+ // Renderer should use this socket only to send data to |remote_address_|.
NOTREACHED();
OnError();
return;
@@ -223,51 +211,51 @@ void P2PSocketHostTcp::Send(const net::IPEndPoint& to,
}
int size = kPacketHeaderSize + data.size();
- write_buffer_ = new net::DrainableIOBuffer(new net::IOBuffer(size), size);
- *reinterpret_cast<uint16*>(write_buffer_->data()) =
- base::HostToNet16(data.size());
- memcpy(write_buffer_->data() + kPacketHeaderSize, &data[0], data.size());
+ scoped_refptr<net::DrainableIOBuffer> buffer =
+ new net::DrainableIOBuffer(new net::IOBuffer(size), size);
+ *reinterpret_cast<uint16*>(buffer->data()) = base::HostToNet16(data.size());
+ memcpy(buffer->data() + kPacketHeaderSize, &data[0], data.size());
+ if (write_buffer_) {
+ write_queue_.push(buffer);
+ return;
+ }
+
+ write_buffer_ = buffer;
DoWrite();
}
void P2PSocketHostTcp::DoWrite() {
- while (true) {
+ while (write_buffer_ && state_ == STATE_OPEN) {
int result = socket_->Write(write_buffer_, write_buffer_->BytesRemaining(),
base::Bind(&P2PSocketHostTcp::OnWritten,
base::Unretained(this)));
- if (result >= 0) {
- write_buffer_->DidConsume(result);
- if (write_buffer_->BytesRemaining() == 0) {
- write_buffer_ = NULL;
- break;
- }
- } else {
- if (result != net::ERR_IO_PENDING) {
- LOG(ERROR) << "Error when sending data in TCP socket: " << result;
- OnError();
- }
- break;
- }
+ HandleWriteResult(result);
}
}
void P2PSocketHostTcp::OnWritten(int result) {
- DCHECK(write_buffer_);
DCHECK_NE(result, net::ERR_IO_PENDING);
+ HandleWriteResult(result);
+ DoWrite();
+}
- if (result < 0) {
- DCHECK(result != net::ERR_IO_PENDING);
+void P2PSocketHostTcp::HandleWriteResult(int result) {
+ DCHECK(write_buffer_);
+ if (result >= 0) {
+ write_buffer_->DidConsume(result);
+ if (write_buffer_->BytesRemaining() == 0) {
+ message_sender_->Send(new P2PMsg_OnSendComplete(id_));
+ if (write_queue_.empty()) {
+ write_buffer_ = NULL;
+ } else {
+ write_buffer_ = write_queue_.front();
+ write_queue_.pop();
+ }
+ }
+ } else if (result != net::ERR_IO_PENDING) {
LOG(ERROR) << "Error when sending data in TCP socket: " << result;
OnError();
- return;
- }
-
- write_buffer_->DidConsume(result);
- if (write_buffer_->BytesRemaining() == 0) {
- write_buffer_ = NULL;
- } else {
- DoWrite();
}
}
diff --git a/content/browser/renderer_host/p2p/socket_host_tcp.h b/content/browser/renderer_host/p2p/socket_host_tcp.h
index 48cc7f9..0b129cc 100644
--- a/content/browser/renderer_host/p2p/socket_host_tcp.h
+++ b/content/browser/renderer_host/p2p/socket_host_tcp.h
@@ -51,6 +51,7 @@ class CONTENT_EXPORT P2PSocketHostTcp : public P2PSocketHost {
void OnPacket(std::vector<char>& data);
void DoWrite();
+ void HandleWriteResult(int result);
// Callbacks for Connect(), Read() and Write().
void OnConnected(int result);
@@ -61,6 +62,8 @@ class CONTENT_EXPORT P2PSocketHostTcp : public P2PSocketHost {
scoped_ptr<net::StreamSocket> socket_;
scoped_refptr<net::GrowableIOBuffer> read_buffer_;
+
+ std::queue<scoped_refptr<net::DrainableIOBuffer> > write_queue_;
scoped_refptr<net::DrainableIOBuffer> write_buffer_;
bool connected_;
diff --git a/content/browser/renderer_host/p2p/socket_host_tcp_unittest.cc b/content/browser/renderer_host/p2p/socket_host_tcp_unittest.cc
index 86e1d97..af4950c 100644
--- a/content/browser/renderer_host/p2p/socket_host_tcp_unittest.cc
+++ b/content/browser/renderer_host/p2p/socket_host_tcp_unittest.cc
@@ -62,6 +62,11 @@ class P2PSocketHostTcpTest : public testing::Test {
// Verify that we can send STUN message and that they are formatted
// properly.
TEST_F(P2PSocketHostTcpTest, SendStunNoAuth) {
+ EXPECT_CALL(sender_, Send(
+ MatchMessage(static_cast<uint32>(P2PMsg_OnSendComplete::ID))))
+ .Times(3)
+ .WillRepeatedly(DoAll(DeleteArg<0>(), Return(true)));
+
std::vector<char> packet1;
CreateStunRequest(&packet1);
socket_host_->Send(dest_, packet1);
@@ -88,6 +93,11 @@ TEST_F(P2PSocketHostTcpTest, SendStunNoAuth) {
// Verify that we can receive STUN messages from the socket, and that
// the messages are parsed properly.
TEST_F(P2PSocketHostTcpTest, ReceiveStun) {
+ EXPECT_CALL(sender_, Send(
+ MatchMessage(static_cast<uint32>(P2PMsg_OnSendComplete::ID))))
+ .Times(3)
+ .WillRepeatedly(DoAll(DeleteArg<0>(), Return(true)));
+
std::vector<char> packet1;
CreateStunRequest(&packet1);
socket_host_->Send(dest_, packet1);
@@ -152,6 +162,9 @@ TEST_F(P2PSocketHostTcpTest, SendAfterStunRequest) {
received_data.append(IntToSize(request_packet.size()));
received_data.append(request_packet.begin(), request_packet.end());
+ EXPECT_CALL(sender_, Send(
+ MatchMessage(static_cast<uint32>(P2PMsg_OnSendComplete::ID))))
+ .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
EXPECT_CALL(sender_, Send(MatchPacketMessage(request_packet)))
.WillOnce(DoAll(DeleteArg<0>(), Return(true)));
socket_->AppendInputData(&received_data[0], received_data.size());
diff --git a/content/browser/renderer_host/p2p/socket_host_udp.cc b/content/browser/renderer_host/p2p/socket_host_udp.cc
index b84ee68..6a9a93d 100644
--- a/content/browser/renderer_host/p2p/socket_host_udp.cc
+++ b/content/browser/renderer_host/p2p/socket_host_udp.cc
@@ -42,7 +42,6 @@ P2PSocketHostUdp::PendingPacket::~PendingPacket() {
P2PSocketHostUdp::P2PSocketHostUdp(IPC::Sender* message_sender, int id)
: P2PSocketHost(message_sender, id),
socket_(new net::UDPServerSocket(NULL, net::NetLog::Source())),
- send_queue_bytes_(0),
send_pending_(false) {
}
@@ -102,18 +101,18 @@ void P2PSocketHostUdp::DoRead() {
base::Unretained(this)));
if (result == net::ERR_IO_PENDING)
return;
- DidCompleteRead(result);
+ HandleReadResult(result);
} while (state_ == STATE_OPEN);
}
void P2PSocketHostUdp::OnRecv(int result) {
- DidCompleteRead(result);
+ HandleReadResult(result);
if (state_ == STATE_OPEN) {
DoRead();
}
}
-void P2PSocketHostUdp::DidCompleteRead(int result) {
+void P2PSocketHostUdp::HandleReadResult(int result) {
DCHECK_EQ(state_, STATE_OPEN);
if (result > 0) {
@@ -159,13 +158,7 @@ void P2PSocketHostUdp::Send(const net::IPEndPoint& to,
}
if (send_pending_) {
- if (send_queue_bytes_ + static_cast<int>(data.size()) >
- kMaxSendBufferSize) {
- LOG(WARNING) << "Send buffer is full. Dropping a packet.";
- return;
- }
send_queue_.push_back(PendingPacket(to, data));
- send_queue_bytes_ += data.size();
} else {
PendingPacket packet(to, data);
DoSend(packet);
@@ -188,12 +181,8 @@ void P2PSocketHostUdp::DoSend(const PendingPacket& packet) {
if (result == net::ERR_IO_PENDING) {
send_pending_ = true;
- } else if (IsTransientError(result)) {
- LOG(INFO) << "sendto() has failed twice returning a "
- " transient error. Dropping the packet.";
- } else if (result < 0) {
- LOG(ERROR) << "Error when sending data in UDP socket: " << result;
- OnError();
+ } else {
+ HandleSendResult(result);
}
}
@@ -203,19 +192,27 @@ void P2PSocketHostUdp::OnSend(int result) {
send_pending_ = false;
- if (result < 0 && !IsTransientError(result)) {
- OnError();
- return;
- }
+ HandleSendResult(result);
// Send next packets if we have them waiting in the buffer.
- while (!send_queue_.empty() && !send_pending_) {
+ while (state_ == STATE_OPEN && !send_queue_.empty() && !send_pending_) {
DoSend(send_queue_.front());
- send_queue_bytes_ -= send_queue_.front().size;
send_queue_.pop_front();
}
}
+void P2PSocketHostUdp::HandleSendResult(int result) {
+ if (result > 0) {
+ message_sender_->Send(new P2PMsg_OnSendComplete(id_));
+ } else if (IsTransientError(result)) {
+ LOG(INFO) << "sendto() has failed twice returning a "
+ " transient error. Dropping the packet.";
+ } else if (result < 0) {
+ LOG(ERROR) << "Error when sending data in UDP socket: " << result;
+ OnError();
+ }
+}
+
P2PSocketHost* P2PSocketHostUdp::AcceptIncomingTcpConnection(
const net::IPEndPoint& remote_address, int id) {
NOTREACHED();
diff --git a/content/browser/renderer_host/p2p/socket_host_udp.h b/content/browser/renderer_host/p2p/socket_host_udp.h
index 710f743..2b83c97 100644
--- a/content/browser/renderer_host/p2p/socket_host_udp.h
+++ b/content/browser/renderer_host/p2p/socket_host_udp.h
@@ -48,20 +48,20 @@ class CONTENT_EXPORT P2PSocketHostUdp : public P2PSocketHost {
};
void OnError();
- void DoRead();
- void DoSend(const PendingPacket& packet);
- void DidCompleteRead(int result);
- // Callbacks for RecvFrom() and SendTo().
+ void DoRead();
void OnRecv(int result);
+ void HandleReadResult(int result);
+
+ void DoSend(const PendingPacket& packet);
void OnSend(int result);
+ void HandleSendResult(int result);
scoped_ptr<net::DatagramServerSocket> socket_;
scoped_refptr<net::IOBuffer> recv_buffer_;
net::IPEndPoint recv_address_;
std::deque<PendingPacket> send_queue_;
- int send_queue_bytes_;
bool send_pending_;
// Set of peer for which we have received STUN binding request or
diff --git a/content/browser/renderer_host/p2p/socket_host_udp_unittest.cc b/content/browser/renderer_host/p2p/socket_host_udp_unittest.cc
index 5a5f15a..d7a3bec 100644
--- a/content/browser/renderer_host/p2p/socket_host_udp_unittest.cc
+++ b/content/browser/renderer_host/p2p/socket_host_udp_unittest.cc
@@ -164,6 +164,11 @@ class P2PSocketHostUdpTest : public testing::Test {
// Verify that we can send STUN messages before we receive anything
// from the other side.
TEST_F(P2PSocketHostUdpTest, SendStunNoAuth) {
+ EXPECT_CALL(sender_, Send(
+ MatchMessage(static_cast<uint32>(P2PMsg_OnSendComplete::ID))))
+ .Times(3)
+ .WillRepeatedly(DoAll(DeleteArg<0>(), Return(true)));
+
std::vector<char> packet1;
CreateStunRequest(&packet1);
socket_host_->Send(dest1_, packet1);
@@ -208,6 +213,9 @@ TEST_F(P2PSocketHostUdpTest, SendAfterStunRequest) {
socket_->ReceivePacket(dest1_, request_packet);
// Now we should be able to send any data to |dest1_|.
+ EXPECT_CALL(sender_, Send(
+ MatchMessage(static_cast<uint32>(P2PMsg_OnSendComplete::ID))))
+ .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
std::vector<char> packet;
CreateRandomPacket(&packet);
socket_host_->Send(dest1_, packet);
@@ -228,6 +236,9 @@ TEST_F(P2PSocketHostUdpTest, SendAfterStunResponse) {
socket_->ReceivePacket(dest1_, request_packet);
// Now we should be able to send any data to |dest1_|.
+ EXPECT_CALL(sender_, Send(
+ MatchMessage(static_cast<uint32>(P2PMsg_OnSendComplete::ID))))
+ .WillOnce(DoAll(DeleteArg<0>(), Return(true)));
std::vector<char> packet;
CreateRandomPacket(&packet);
socket_host_->Send(dest1_, packet);
diff --git a/content/common/p2p_messages.h b/content/common/p2p_messages.h
index 59f6a8f..6b13831 100644
--- a/content/common/p2p_messages.h
+++ b/content/common/p2p_messages.h
@@ -35,6 +35,9 @@ IPC_MESSAGE_CONTROL2(P2PMsg_OnSocketCreated,
int /* socket_id */,
net::IPEndPoint /* socket_address */)
+IPC_MESSAGE_CONTROL1(P2PMsg_OnSendComplete,
+ int /* socket_id */)
+
IPC_MESSAGE_CONTROL1(P2PMsg_OnError,
int /* socket_id */)
diff --git a/content/renderer/p2p/ipc_socket_factory.cc b/content/renderer/p2p/ipc_socket_factory.cc
index ea53678..defe31f 100644
--- a/content/renderer/p2p/ipc_socket_factory.cc
+++ b/content/renderer/p2p/ipc_socket_factory.cc
@@ -16,6 +16,10 @@ namespace content {
namespace {
+// TODO(sergeyu): Try adjusting these parameters to achieve optimal performance.
+const int kMaxPendingPackets = 8;
+const int kWritableSignalThreshold = 0;
+
// IpcPacketSocket implements talk_base::AsyncPacketSocket interface
// using P2PSocketClient that works over IPC-channel. It must be used
// on the thread it was created.
@@ -47,6 +51,7 @@ class IpcPacketSocket : public talk_base::AsyncPacketSocket,
virtual void OnOpen(const net::IPEndPoint& address) OVERRIDE;
virtual void OnIncomingTcpConnection(const net::IPEndPoint& address,
P2PSocketClient* client) OVERRIDE;
+ virtual void OnSendComplete() OVERRIDE;
virtual void OnError() OVERRIDE;
virtual void OnDataReceived(const net::IPEndPoint& address,
const std::vector<char>& data) OVERRIDE;
@@ -83,6 +88,14 @@ class IpcPacketSocket : public talk_base::AsyncPacketSocket,
// Current state of the object.
InternalState state_;
+ // Number which have been sent to the browser, but for which we haven't
+ // received response.
+ int send_packets_pending_;
+
+ // Set to true once EWOULDBLOCK was returned from Send(). Indicates that the
+ // caller expects SignalWritable notification.
+ bool writable_signal_expected_;
+
// Current error code. Valid when state_ == IS_ERROR.
int error_;
@@ -93,6 +106,8 @@ IpcPacketSocket::IpcPacketSocket()
: type_(P2P_SOCKET_UDP),
message_loop_(MessageLoop::current()),
state_(IS_UNINITIALIZED),
+ send_packets_pending_(0),
+ writable_signal_expected_(false),
error_(0) {
}
@@ -180,15 +195,22 @@ int IpcPacketSocket::SendTo(const void *data, size_t data_size,
break;
}
+ if (send_packets_pending_ > kMaxPendingPackets) {
+ writable_signal_expected_ = true;
+ error_ = EWOULDBLOCK;
+ return -1;
+ }
+
const char* data_char = reinterpret_cast<const char*>(data);
std::vector<char> data_vector(data_char, data_char + data_size);
net::IPEndPoint address_chrome;
if (!jingle_glue::SocketAddressToIPEndPoint(address, &address_chrome)) {
- // Just drop the packet if we failed to convert the address.
- return 0;
+ NOTREACHED();
+ return -1;
}
+ ++send_packets_pending_;
client_->Send(address_chrome, data_vector);
// Fake successful send. The caller ignores result anyway.
@@ -238,9 +260,6 @@ int IpcPacketSocket::GetOption(talk_base::Socket::Option opt, int* value) {
int IpcPacketSocket::SetOption(talk_base::Socket::Option opt, int value) {
// We don't support socket options for IPC sockets.
- //
- // TODO(sergeyu): Make sure we set proper socket options on the
- // browser side.
return -1;
}
@@ -287,6 +306,22 @@ void IpcPacketSocket::OnIncomingTcpConnection(
SignalNewConnection(this, socket.release());
}
+void IpcPacketSocket::OnSendComplete() {
+ DCHECK_EQ(MessageLoop::current(), message_loop_);
+
+ --send_packets_pending_;
+ DCHECK_GE(send_packets_pending_, 0);
+
+ if (writable_signal_expected_ &&
+ send_packets_pending_ <= kWritableSignalThreshold) {
+ // TODO(sergeyu): Uncomment this line once SignalWritable is added in
+ // talk_base::AsyncPacketSocket.
+ //
+ // SignalWritable(this);
+ writable_signal_expected_ = false;
+ }
+}
+
void IpcPacketSocket::OnError() {
DCHECK_EQ(MessageLoop::current(), message_loop_);
state_ = IS_ERROR;
diff --git a/content/renderer/p2p/socket_client.cc b/content/renderer/p2p/socket_client.cc
index e6f5a0f..ed3f211 100644
--- a/content/renderer/p2p/socket_client.cc
+++ b/content/renderer/p2p/socket_client.cc
@@ -134,6 +134,19 @@ void P2PSocketClient::DeliverOnIncomingTcpConnection(
}
}
+void P2PSocketClient::OnSendComplete() {
+ DCHECK(ipc_message_loop_->BelongsToCurrentThread());
+
+ delegate_message_loop_->PostTask(
+ FROM_HERE, base::Bind(&P2PSocketClient::DeliverOnSendComplete, this));
+}
+
+void P2PSocketClient::DeliverOnSendComplete() {
+ DCHECK(delegate_message_loop_->BelongsToCurrentThread());
+ if (delegate_)
+ delegate_->OnSendComplete();
+}
+
void P2PSocketClient::OnError() {
DCHECK(ipc_message_loop_->BelongsToCurrentThread());
state_ = STATE_ERROR;
diff --git a/content/renderer/p2p/socket_client.h b/content/renderer/p2p/socket_client.h
index d74107f..fd8537e 100644
--- a/content/renderer/p2p/socket_client.h
+++ b/content/renderer/p2p/socket_client.h
@@ -27,7 +27,8 @@ class P2PSocketDispatcher;
// thread which is specified in Init().
class P2PSocketClient : public base::RefCountedThreadSafe<P2PSocketClient> {
public:
- // Delegate is called on the the same thread on the delegate thread.
+ // Delegate is called on the the same thread on which P2PSocketCLient is
+ // created.
class Delegate {
public:
virtual ~Delegate() { }
@@ -35,6 +36,7 @@ class P2PSocketClient : public base::RefCountedThreadSafe<P2PSocketClient> {
virtual void OnOpen(const net::IPEndPoint& address) = 0;
virtual void OnIncomingTcpConnection(const net::IPEndPoint& address,
P2PSocketClient* client) = 0;
+ virtual void OnSendComplete() = 0;
virtual void OnError() = 0;
virtual void OnDataReceived(const net::IPEndPoint& address,
const std::vector<char>& data) = 0;
@@ -80,6 +82,8 @@ class P2PSocketClient : public base::RefCountedThreadSafe<P2PSocketClient> {
// Message handlers that run on IPC thread.
void OnSocketCreated(const net::IPEndPoint& address);
void OnIncomingTcpConnection(const net::IPEndPoint& address);
+ void OnSendComplete(int packet_id);
+ void OnSendComplete();
void OnError();
void OnDataReceived(const net::IPEndPoint& address,
const std::vector<char>& data);
@@ -89,6 +93,7 @@ class P2PSocketClient : public base::RefCountedThreadSafe<P2PSocketClient> {
void DeliverOnIncomingTcpConnection(
const net::IPEndPoint& address,
scoped_refptr<P2PSocketClient> new_client);
+ void DeliverOnSendComplete();
void DeliverOnError();
void DeliverOnDataReceived(const net::IPEndPoint& address,
const std::vector<char>& data);
diff --git a/content/renderer/p2p/socket_dispatcher.cc b/content/renderer/p2p/socket_dispatcher.cc
index c999e62..7fe71ee 100644
--- a/content/renderer/p2p/socket_dispatcher.cc
+++ b/content/renderer/p2p/socket_dispatcher.cc
@@ -63,6 +63,7 @@ bool P2PSocketDispatcher::OnMessageReceived(const IPC::Message& message) {
IPC_MESSAGE_HANDLER(P2PMsg_GetHostAddressResult, OnGetHostAddressResult)
IPC_MESSAGE_HANDLER(P2PMsg_OnSocketCreated, OnSocketCreated)
IPC_MESSAGE_HANDLER(P2PMsg_OnIncomingTcpConnection, OnIncomingTcpConnection)
+ IPC_MESSAGE_HANDLER(P2PMsg_OnSendComplete, OnSendComplete)
IPC_MESSAGE_HANDLER(P2PMsg_OnError, OnError)
IPC_MESSAGE_HANDLER(P2PMsg_OnDataReceived, OnDataReceived)
IPC_MESSAGE_UNHANDLED(handled = false)
@@ -152,6 +153,13 @@ void P2PSocketDispatcher::OnIncomingTcpConnection(
}
}
+void P2PSocketDispatcher::OnSendComplete(int socket_id) {
+ P2PSocketClient* client = GetClient(socket_id);
+ if (client) {
+ client->OnSendComplete();
+ }
+}
+
void P2PSocketDispatcher::OnError(int socket_id) {
P2PSocketClient* client = GetClient(socket_id);
if (client) {
diff --git a/content/renderer/p2p/socket_dispatcher.h b/content/renderer/p2p/socket_dispatcher.h
index e17a8c1..cbd8f2a 100644
--- a/content/renderer/p2p/socket_dispatcher.h
+++ b/content/renderer/p2p/socket_dispatcher.h
@@ -102,6 +102,7 @@ class CONTENT_EXPORT P2PSocketDispatcher
const net::IPAddressNumber& address);
void OnSocketCreated(int socket_id, const net::IPEndPoint& address);
void OnIncomingTcpConnection(int socket_id, const net::IPEndPoint& address);
+ void OnSendComplete(int socket_id);
void OnError(int socket_id);
void OnDataReceived(int socket_id, const net::IPEndPoint& address,
const std::vector<char>& data);