summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--jingle/glue/channel_socket_adapter.cc25
-rw-r--r--jingle/glue/channel_socket_adapter_unittest.cc2
-rw-r--r--remoting/protocol/jingle_session.cc105
-rw-r--r--remoting/protocol/jingle_session.h34
4 files changed, 70 insertions, 96 deletions
diff --git a/jingle/glue/channel_socket_adapter.cc b/jingle/glue/channel_socket_adapter.cc
index 1cdcf01..1141baf 100644
--- a/jingle/glue/channel_socket_adapter.cc
+++ b/jingle/glue/channel_socket_adapter.cc
@@ -64,16 +64,23 @@ int TransportChannelSocketAdapter::Write(
return closed_error_code_;
}
- int result = channel_->SendPacket(buffer->data(), buffer_size);
- if (result < 0) {
- result = net::MapSystemError(channel_->GetError());
- if (result == net::ERR_IO_PENDING) {
- write_pending_ = true;
- write_callback_ = callback;
- write_buffer_ = buffer;
- write_buffer_size_ = buffer_size;
- }
+ int result;
+ if (channel_->writable()) {
+ result = channel_->SendPacket(buffer->data(), buffer_size);
+ if (result < 0)
+ result = net::MapSystemError(channel_->GetError());
+ } else {
+ // Channel is not writable yet.
+ result = net::ERR_IO_PENDING;
}
+
+ if (result == net::ERR_IO_PENDING) {
+ write_pending_ = true;
+ write_callback_ = callback;
+ write_buffer_ = buffer;
+ write_buffer_size_ = buffer_size;
+ }
+
return result;
}
diff --git a/jingle/glue/channel_socket_adapter_unittest.cc b/jingle/glue/channel_socket_adapter_unittest.cc
index 60e60b6..fa4315d 100644
--- a/jingle/glue/channel_socket_adapter_unittest.cc
+++ b/jingle/glue/channel_socket_adapter_unittest.cc
@@ -31,6 +31,8 @@ class MockTransportChannel : public cricket::TransportChannel {
public:
MockTransportChannel()
: cricket::TransportChannel("", "") {
+ set_writable(true);
+ set_readable(true);
}
MOCK_METHOD2(SendPacket, int(const char *data, size_t len));
diff --git a/remoting/protocol/jingle_session.cc b/remoting/protocol/jingle_session.cc
index 78cfbae..1e6f390 100644
--- a/remoting/protocol/jingle_session.cc
+++ b/remoting/protocol/jingle_session.cc
@@ -7,6 +7,7 @@
#include "base/message_loop.h"
#include "crypto/rsa_private_key.h"
#include "jingle/glue/channel_socket_adapter.h"
+#include "jingle/glue/pseudotcp_adapter.h"
#include "jingle/glue/stream_socket_adapter.h"
#include "net/base/cert_status_flags.h"
#include "net/base/cert_verifier.h"
@@ -23,11 +24,8 @@
#include "remoting/protocol/socket_wrapper.h"
#include "third_party/libjingle/source/talk/base/thread.h"
#include "third_party/libjingle/source/talk/p2p/base/session.h"
-#include "third_party/libjingle/source/talk/session/tunnel/pseudotcpchannel.h"
using cricket::BaseSession;
-using cricket::PseudoTcp;
-using cricket::PseudoTcpChannel;
namespace remoting {
@@ -42,12 +40,6 @@ const char kVideoChannelName[] = "video";
const char kVideoRtpChannelName[] = "videortp";
const char kVideoRtcpChannelName[] = "videortcp";
-// Settings to apply to PseudoTcp channels for Control, Input and Video.
-// Disable Nagle's algorithm, to reduce latency for small messages.
-// Reduce the ACK Delay to 10ms, to balance throughput/latency with overhead.
-const int kEnableNoDelay = true;
-const int kDelayedAckTimeoutMs = 10;
-
// Helper method to create a SSL client socket.
net::SSLClientSocket* CreateSSLClientSocket(
net::ClientSocket* socket, scoped_refptr<net::X509Certificate> cert,
@@ -96,11 +88,11 @@ JingleSession::JingleSession(
closed_(false),
closing_(false),
cricket_session_(NULL),
- event_channel_(NULL),
- video_channel_(NULL),
ssl_connections_(0),
ALLOW_THIS_IN_INITIALIZER_LIST(connect_callback_(
- NewCallback(this, &JingleSession::OnSSLConnect))) {
+ this, &JingleSession::OnConnect)),
+ ALLOW_THIS_IN_INITIALIZER_LIST(ssl_connect_callback_(
+ this, &JingleSession::OnSSLConnect)) {
// TODO(hclam): Need a better way to clone a key.
if (key) {
std::vector<uint8> key_bytes;
@@ -132,39 +124,21 @@ void JingleSession::CloseInternal(int result, bool failed) {
if (!closed_ && !closing_) {
closing_ = true;
+ if (control_channel_.get())
+ control_channel_->Close(result);
if (control_ssl_socket_.get())
control_ssl_socket_->Disconnect();
- if (control_channel_adapter_.get())
- control_channel_adapter_->Close(result);
-
- if (control_channel_) {
- control_channel_->OnSessionTerminate(cricket_session_);
- control_channel_ = NULL;
- }
-
+ if (event_channel_.get())
+ event_channel_->Close(result);
if (event_ssl_socket_.get())
event_ssl_socket_->Disconnect();
- if (event_channel_adapter_.get())
- event_channel_adapter_->Close(result);
-
- if (event_channel_) {
- event_channel_->OnSessionTerminate(cricket_session_);
- event_channel_ = NULL;
- }
-
+ if (video_channel_.get())
+ video_channel_->Close(result);
if (video_ssl_socket_.get())
video_ssl_socket_->Disconnect();
- if (video_channel_adapter_.get())
- video_channel_adapter_->Close(result);
-
- if (video_channel_) {
- video_channel_->OnSessionTerminate(cricket_session_);
- video_channel_ = NULL;
- }
-
if (video_rtp_channel_.get())
video_rtp_channel_->Close(result);
if (video_rtcp_channel_.get())
@@ -370,32 +344,17 @@ void JingleSession::OnInitiate() {
cricket_session_->CreateChannel(content_name, kVideoRtcpChannelName)));
// Create control channel.
- control_channel_ = new PseudoTcpChannel(
- jingle_session_manager_->jingle_thread(), cricket_session_);
- control_channel_->Connect(content_name, kControlChannelName);
- control_channel_->SetOption(PseudoTcp::OPT_NODELAY, kEnableNoDelay);
- control_channel_->SetOption(PseudoTcp::OPT_ACKDELAY, kDelayedAckTimeoutMs);
- control_channel_adapter_.reset(new jingle_glue::StreamSocketAdapter(
- control_channel_->GetStream()));
+ control_channel_.reset(new jingle_glue::TransportChannelSocketAdapter(
+ cricket_session_->CreateChannel(content_name, kControlChannelName)));
// Create event channel.
- event_channel_ = new PseudoTcpChannel(
- jingle_session_manager_->jingle_thread(), cricket_session_);
- event_channel_->Connect(content_name, kEventChannelName);
- event_channel_->SetOption(PseudoTcp::OPT_NODELAY, kEnableNoDelay);
- event_channel_->SetOption(PseudoTcp::OPT_ACKDELAY, kDelayedAckTimeoutMs);
- event_channel_adapter_.reset(new jingle_glue::StreamSocketAdapter(
- event_channel_->GetStream()));
+ event_channel_.reset(new jingle_glue::TransportChannelSocketAdapter(
+ cricket_session_->CreateChannel(content_name, kEventChannelName)));
// Create video channel.
// TODO(sergeyu): Remove video channel when we are ready to switch to RTP.
- video_channel_ = new PseudoTcpChannel(
- jingle_session_manager_->jingle_thread(), cricket_session_);
- video_channel_->Connect(content_name, kVideoChannelName);
- video_channel_->SetOption(PseudoTcp::OPT_NODELAY, kEnableNoDelay);
- video_channel_->SetOption(PseudoTcp::OPT_ACKDELAY, kDelayedAckTimeoutMs);
- video_channel_adapter_.reset(new jingle_glue::StreamSocketAdapter(
- video_channel_->GetStream()));
+ video_channel_.reset(new jingle_glue::TransportChannelSocketAdapter(
+ cricket_session_->CreateChannel(content_name, kVideoChannelName)));
if (!cricket_session_->initiator())
jingle_session_manager_->AcceptConnection(this, cricket_session_);
@@ -407,15 +366,18 @@ void JingleSession::OnInitiate() {
}
bool JingleSession::EstablishSSLConnection(
- net::ClientSocket* adapter, scoped_ptr<SocketWrapper>* ssl_socket) {
+ net::Socket* channel, scoped_ptr<SocketWrapper>* ssl_socket) {
+ jingle_glue::PseudoTcpAdapter* pseudotcp =
+ new jingle_glue::PseudoTcpAdapter(channel);
+ pseudotcp->Connect(&connect_callback_);
+
if (cricket_session_->initiator()) {
// Create client SSL socket.
- net::SSLClientSocket* socket = CreateSSLClientSocket(adapter,
- server_cert_,
- cert_verifier_.get());
+ net::SSLClientSocket* socket = CreateSSLClientSocket(
+ pseudotcp, server_cert_, cert_verifier_.get());
ssl_socket->reset(new SocketWrapper(socket));
- int ret = socket->Connect(connect_callback_.get());
+ int ret = socket->Connect(&ssl_connect_callback_);
if (ret == net::ERR_IO_PENDING) {
return true;
} else if (ret != net::OK) {
@@ -427,10 +389,10 @@ bool JingleSession::EstablishSSLConnection(
// Create server SSL socket.
net::SSLConfig ssl_config;
net::SSLServerSocket* socket = net::CreateSSLServerSocket(
- adapter, server_cert_, key_.get(), ssl_config);
+ pseudotcp, server_cert_, key_.get(), ssl_config);
ssl_socket->reset(new SocketWrapper(socket));
- int ret = socket->Accept(connect_callback_.get());
+ int ret = socket->Accept(&ssl_connect_callback_);
if (ret == net::ERR_IO_PENDING) {
return true;
} else if (ret != net::OK) {
@@ -440,7 +402,7 @@ bool JingleSession::EstablishSSLConnection(
}
}
// Reach here if net::OK is received.
- connect_callback_->Run(net::OK);
+ ssl_connect_callback_.Run(net::OK);
return true;
}
@@ -473,14 +435,14 @@ void JingleSession::OnAccept() {
set_config(config);
}
- bool ret = EstablishSSLConnection(control_channel_adapter_.release(),
+ bool ret = EstablishSSLConnection(control_channel_.release(),
&control_ssl_socket_);
if (ret) {
- ret = EstablishSSLConnection(event_channel_adapter_.release(),
+ ret = EstablishSSLConnection(event_channel_.release(),
&event_ssl_socket_);
}
if (ret) {
- ret = EstablishSSLConnection(video_channel_adapter_.release(),
+ ret = EstablishSSLConnection(video_channel_.release(),
&video_ssl_socket_);
}
@@ -494,6 +456,13 @@ void JingleSession::OnTerminate() {
CloseInternal(net::ERR_CONNECTION_ABORTED, false);
}
+void JingleSession::OnConnect(int result) {
+ if (result != net::OK) {
+ LOG(ERROR) << "PseudoTCP connection failed: " << result;
+ CloseInternal(result, true);
+ }
+}
+
void JingleSession::OnSSLConnect(int result) {
DCHECK(!closed_);
if (result != net::OK) {
diff --git a/remoting/protocol/jingle_session.h b/remoting/protocol/jingle_session.h
index caaa82f..b47a7aa 100644
--- a/remoting/protocol/jingle_session.h
+++ b/remoting/protocol/jingle_session.h
@@ -12,11 +12,8 @@
#include "third_party/libjingle/source/talk/base/sigslot.h"
#include "third_party/libjingle/source/talk/p2p/base/session.h"
-namespace cricket {
-class PseudoTcpChannel;
-} // namespace cricket
-
namespace jingle_glue {
+class PseudoTcpAdapter;
class StreamSocketAdapter;
class TransportChannelSocketAdapter;
} // namespace jingle_glue
@@ -100,10 +97,10 @@ class JingleSession : public protocol::Session,
bool HasSession(cricket::Session* cricket_session);
cricket::Session* ReleaseSession();
- // Helper method to create and initialize SSL socket using the adapter
- // provided. The resultant SSL socket is written to |ssl_socket|.
- // Return true if successful.
- bool EstablishSSLConnection(net::ClientSocket* adapter,
+ // Helper method to create and initialize PseudoTCP + SSL socket on
+ // top of the provided |channel|. The resultant SSL socket is
+ // written to |ssl_socket|. Return true if successful.
+ bool EstablishSSLConnection(net::Socket* channel,
scoped_ptr<SocketWrapper>* ssl_socket);
// Used for Session.SignalState sigslot.
@@ -117,6 +114,8 @@ class JingleSession : public protocol::Session,
void OnAccept();
void OnTerminate();
+ void OnConnect(int result);
+
// Called by SSL socket to notify connect event.
void OnSSLConnect(int result);
@@ -152,20 +151,16 @@ class JingleSession : public protocol::Session,
// These data members are only set on the receiving side.
scoped_ptr<const CandidateSessionConfig> candidate_config_;
- // A channel is the the base channel created by libjingle.
- // A channel adapter is used to convert a jingle channel to net::Socket and
- // then there is a SocketWrapper created over net::Socket.
- // SSL socket uses SocketWrapper to provide SSL functionality.
- cricket::PseudoTcpChannel* control_channel_;
- scoped_ptr<jingle_glue::StreamSocketAdapter> control_channel_adapter_;
+ // |control_channel_| holds a channel until SSL socket is
+ // created. After that |control_ssl_socket_| owns the channel. The
+ // same is the case fo |event_channel_| and |video_channel_|.
+ scoped_ptr<jingle_glue::TransportChannelSocketAdapter> control_channel_;
scoped_ptr<SocketWrapper> control_ssl_socket_;
- cricket::PseudoTcpChannel* event_channel_;
- scoped_ptr<jingle_glue::StreamSocketAdapter> event_channel_adapter_;
+ scoped_ptr<jingle_glue::TransportChannelSocketAdapter> event_channel_;
scoped_ptr<SocketWrapper> event_ssl_socket_;
- cricket::PseudoTcpChannel* video_channel_;
- scoped_ptr<jingle_glue::StreamSocketAdapter> video_channel_adapter_;
+ scoped_ptr<jingle_glue::TransportChannelSocketAdapter> video_channel_;
scoped_ptr<SocketWrapper> video_ssl_socket_;
// Count the number of SSL connections esblished.
@@ -178,7 +173,8 @@ class JingleSession : public protocol::Session,
scoped_ptr<jingle_glue::TransportChannelSocketAdapter> video_rtcp_channel_;
// Callback called by the SSL layer.
- scoped_ptr<net::CompletionCallback> connect_callback_;
+ net::CompletionCallbackImpl<JingleSession> connect_callback_;
+ net::CompletionCallbackImpl<JingleSession> ssl_connect_callback_;
DISALLOW_COPY_AND_ASSIGN(JingleSession);
};