diff options
-rw-r--r-- | jingle/glue/channel_socket_adapter.cc | 25 | ||||
-rw-r--r-- | jingle/glue/channel_socket_adapter_unittest.cc | 2 | ||||
-rw-r--r-- | remoting/protocol/jingle_session.cc | 105 | ||||
-rw-r--r-- | remoting/protocol/jingle_session.h | 34 |
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); }; |