From 385857dfd414dcc1fb4941218b52417808349030 Mon Sep 17 00:00:00 2001 From: "mallinath@webrtc.org" Date: Fri, 14 Feb 2014 00:56:12 +0000 Subject: [PATCH] Update talk to 61549749. TBR=wu@webrtc.org Review URL: https://webrtc-codereview.appspot.com/8709004 git-svn-id: http://webrtc.googlecode.com/svn/trunk@5549 4adac7df-926f-26a2-2b94-8c16560cd09d --- talk/app/webrtc/peerconnection_unittest.cc | 7 +-- .../webrtc/test/peerconnectiontestwrapper.cc | 4 +- talk/app/webrtc/webrtcsession.cc | 24 +++++++-- talk/app/webrtc/webrtcsession.h | 2 + talk/app/webrtc/webrtcsession_unittest.cc | 33 +++++++++--- talk/base/asyncpacketsocket.h | 20 +++---- talk/base/asynctcpsocket.cc | 9 ++-- talk/base/asynctcpsocket.h | 8 +-- talk/base/asyncudpsocket.cc | 8 +-- talk/base/asyncudpsocket.h | 19 +++---- talk/base/natserver.cc | 7 +-- talk/base/testclient.cc | 7 +-- talk/base/testechoserver.h | 3 +- talk/base/virtualsocket_unittest.cc | 3 +- talk/p2p/base/asyncstuntcpsocket.cc | 3 +- talk/p2p/base/asyncstuntcpsocket.h | 2 +- talk/p2p/base/asyncstuntcpsocket_unittest.cc | 3 +- talk/p2p/base/dtlstransportchannel.cc | 23 +++++--- talk/p2p/base/dtlstransportchannel.h | 6 ++- .../p2p/base/dtlstransportchannel_unittest.cc | 3 +- talk/p2p/base/fakesession.h | 14 ++++- talk/p2p/base/p2ptransportchannel.cc | 10 ++-- talk/p2p/base/p2ptransportchannel.h | 3 +- talk/p2p/base/p2ptransportchannel_unittest.cc | 3 +- talk/p2p/base/port.cc | 14 +++-- talk/p2p/base/port.h | 4 +- talk/p2p/base/port_unittest.cc | 19 +++---- talk/p2p/base/portinterface.h | 5 +- talk/p2p/base/portproxy.cc | 4 +- talk/p2p/base/portproxy.h | 2 +- talk/p2p/base/rawtransportchannel.cc | 4 +- talk/p2p/base/rawtransportchannel.h | 3 +- talk/p2p/base/relayport.cc | 28 +++++----- talk/p2p/base/relayport.h | 2 +- talk/p2p/base/relayserver.cc | 3 +- talk/p2p/base/session.cc | 4 ++ talk/p2p/base/session.h | 8 +++ talk/p2p/base/session_unittest.cc | 4 +- talk/p2p/base/stunport.cc | 7 +-- talk/p2p/base/stunport.h | 2 +- talk/p2p/base/stunserver.cc | 4 +- talk/p2p/base/tcpport.cc | 8 +-- talk/p2p/base/tcpport.h | 4 +- talk/p2p/base/transport.cc | 54 +++++++++++++++++++ talk/p2p/base/transport.h | 6 +++ talk/p2p/base/transport_unittest.cc | 54 ++++++++++++++++++- talk/p2p/base/transportchannel.h | 2 +- talk/p2p/base/transportchannelimpl.h | 5 ++ talk/p2p/base/transportchannelproxy.cc | 4 +- talk/p2p/base/transportchannelproxy.h | 2 +- talk/p2p/base/turnport.cc | 17 +++--- talk/p2p/base/turnport.h | 5 +- talk/p2p/base/turnport_unittest.cc | 5 +- talk/p2p/base/turnserver.cc | 7 +-- talk/session/media/channel.cc | 3 +- talk/session/tunnel/pseudotcpchannel.cc | 3 +- 56 files changed, 370 insertions(+), 150 deletions(-) diff --git a/talk/app/webrtc/peerconnection_unittest.cc b/talk/app/webrtc/peerconnection_unittest.cc index 1b6d73d030..c3f71f1eef 100644 --- a/talk/app/webrtc/peerconnection_unittest.cc +++ b/talk/app/webrtc/peerconnection_unittest.cc @@ -969,12 +969,13 @@ class P2PTestConductor : public testing::Test { } if (audio_frame_count != -1 || video_frame_count != -1) { - // Audio or video is expected to flow, so both sides should get to the - // Connected state. + // Audio or video is expected to flow, so both clients should reach the + // Connected state, and the offerer (ICE controller) should proceed to + // Completed. // Note: These tests have been observed to fail under heavy load at // shorter timeouts, so they may be flaky. EXPECT_EQ_WAIT( - webrtc::PeerConnectionInterface::kIceConnectionConnected, + webrtc::PeerConnectionInterface::kIceConnectionCompleted, initiating_client_->ice_connection_state(), kMaxWaitForFramesMs); EXPECT_EQ_WAIT( diff --git a/talk/app/webrtc/test/peerconnectiontestwrapper.cc b/talk/app/webrtc/test/peerconnectiontestwrapper.cc index 91b66686ff..ca4b6d2f9b 100644 --- a/talk/app/webrtc/test/peerconnectiontestwrapper.cc +++ b/talk/app/webrtc/test/peerconnectiontestwrapper.cc @@ -204,7 +204,9 @@ void PeerConnectionTestWrapper::WaitForConnection() { bool PeerConnectionTestWrapper::CheckForConnection() { return (peer_connection_->ice_connection_state() == - PeerConnectionInterface::kIceConnectionConnected); + PeerConnectionInterface::kIceConnectionConnected) || + (peer_connection_->ice_connection_state() == + PeerConnectionInterface::kIceConnectionCompleted); } void PeerConnectionTestWrapper::WaitForAudio() { diff --git a/talk/app/webrtc/webrtcsession.cc b/talk/app/webrtc/webrtcsession.cc index ef6af49e5b..b2951eb36e 100644 --- a/talk/app/webrtc/webrtcsession.cc +++ b/talk/app/webrtc/webrtcsession.cc @@ -1154,12 +1154,20 @@ void WebRtcSession::OnTransportWritable(cricket::Transport* transport) { // TODO(bemasc): Expose more API from Transport to detect when // candidate selection starts or stops, due to success or failure. if (transport->all_channels_writable()) { + // By the time |SignalTransportWritable| arrives, the excess channels may + // already have been pruned, so that the Transport is Completed. The + // specification requires that transitions from Checking to Completed pass + // through Connected. This check enforces that requirement. + // (Direct transitions from Connected and Disconnected to Completed are + // allowed.) if (ice_connection_state_ == - PeerConnectionInterface::kIceConnectionChecking || - ice_connection_state_ == - PeerConnectionInterface::kIceConnectionDisconnected) { + PeerConnectionInterface::kIceConnectionChecking) { SetIceConnectionState(PeerConnectionInterface::kIceConnectionConnected); } + + SetIceConnectionState(transport->completed() ? + PeerConnectionInterface::kIceConnectionCompleted : + PeerConnectionInterface::kIceConnectionConnected); } else if (transport->HasChannels()) { // If the current state is Connected or Completed, then there were writable // channels but now there are not, so the next state must be Disconnected. @@ -1173,6 +1181,16 @@ void WebRtcSession::OnTransportWritable(cricket::Transport* transport) { } } +void WebRtcSession::OnTransportCompleted(cricket::Transport* transport) { + ASSERT(signaling_thread()->IsCurrent()); + SetIceConnectionState(PeerConnectionInterface::kIceConnectionCompleted); +} + +void WebRtcSession::OnTransportFailed(cricket::Transport* transport) { + ASSERT(signaling_thread()->IsCurrent()); + SetIceConnectionState(PeerConnectionInterface::kIceConnectionFailed); +} + void WebRtcSession::OnTransportProxyCandidatesReady( cricket::TransportProxy* proxy, const cricket::Candidates& candidates) { ASSERT(signaling_thread()->IsCurrent()); diff --git a/talk/app/webrtc/webrtcsession.h b/talk/app/webrtc/webrtcsession.h index 628aa1e789..88defcee48 100644 --- a/talk/app/webrtc/webrtcsession.h +++ b/talk/app/webrtc/webrtcsession.h @@ -230,6 +230,8 @@ class WebRtcSession : public cricket::BaseSession, virtual void OnTransportRequestSignaling(cricket::Transport* transport); virtual void OnTransportConnecting(cricket::Transport* transport); virtual void OnTransportWritable(cricket::Transport* transport); + virtual void OnTransportCompleted(cricket::Transport* transport); + virtual void OnTransportFailed(cricket::Transport* transport); virtual void OnTransportProxyCandidatesReady( cricket::TransportProxy* proxy, const cricket::Candidates& candidates); diff --git a/talk/app/webrtc/webrtcsession_unittest.cc b/talk/app/webrtc/webrtcsession_unittest.cc index ba58936e39..d9ce644aa9 100644 --- a/talk/app/webrtc/webrtcsession_unittest.cc +++ b/talk/app/webrtc/webrtcsession_unittest.cc @@ -808,13 +808,15 @@ class WebRtcSessionTest : public testing::Test { // The method sets up a call from the session to itself, in a loopback // arrangement. It also uses a firewall rule to create a temporary - // disconnection. This code is placed as a method so that it can be invoked + // disconnection, and then a permanent disconnection. + // This code is placed in a method so that it can be invoked // by multiple tests with different allocators (e.g. with and without BUNDLE). // While running the call, this method also checks if the session goes through // the correct sequence of ICE states when a connection is established, // broken, and re-established. // The Connection state should go: - // New -> Checking -> Connected -> Disconnected -> Connected. + // New -> Checking -> (Connected) -> Completed -> Disconnected -> Completed + // -> Failed. // The Gathering state should go: New -> Gathering -> Completed. void TestLoopbackCall() { AddInterface(talk_base::SocketAddress(kClientAddrHost1, kClientAddrPort)); @@ -845,10 +847,10 @@ class WebRtcSessionTest : public testing::Test { EXPECT_EQ_WAIT(PeerConnectionInterface::kIceConnectionChecking, observer_.ice_connection_state_, kIceCandidatesTimeout); - EXPECT_EQ_WAIT(PeerConnectionInterface::kIceConnectionConnected, + // The ice connection state is "Connected" too briefly to catch in a test. + EXPECT_EQ_WAIT(PeerConnectionInterface::kIceConnectionCompleted, observer_.ice_connection_state_, kIceCandidatesTimeout); - // TODO(bemasc): EXPECT(Completed) once the details are standardized. // Adding firewall rule to block ping requests, which should cause // transport channel failure. @@ -865,10 +867,21 @@ class WebRtcSessionTest : public testing::Test { // Session is automatically calling OnSignalingReady after creation of // new portallocator session which will allocate new set of candidates. - // TODO(bemasc): Change this to Completed once the details are standardized. - EXPECT_EQ_WAIT(PeerConnectionInterface::kIceConnectionConnected, + EXPECT_EQ_WAIT(PeerConnectionInterface::kIceConnectionCompleted, observer_.ice_connection_state_, kIceCandidatesTimeout); + + // Now we block ping requests and wait until the ICE connection transitions + // to the Failed state. This will take at least 30 seconds because it must + // wait for the Port to timeout. + int port_timeout = 30000; + fss_->AddRule(false, + talk_base::FP_ANY, + talk_base::FD_ANY, + talk_base::SocketAddress(kClientAddrHost1, kClientAddrPort)); + EXPECT_EQ_WAIT(PeerConnectionInterface::kIceConnectionFailed, + observer_.ice_connection_state_, + kIceCandidatesTimeout + port_timeout); } void VerifyTransportType(const std::string& content_name, @@ -2601,6 +2614,14 @@ TEST_F(WebRtcSessionTest, TestIceStatesBasic) { TestLoopbackCall(); } +// Runs the loopback call test with BUNDLE, STUN, and TCP enabled. +TEST_F(WebRtcSessionTest, TestIceStatesBundle) { + allocator_.set_flags(cricket::PORTALLOCATOR_ENABLE_SHARED_UFRAG | + cricket::PORTALLOCATOR_ENABLE_BUNDLE | + cricket::PORTALLOCATOR_DISABLE_RELAY); + TestLoopbackCall(); +} + TEST_F(WebRtcSessionTest, SetSdpFailedOnSessionError) { Init(NULL); cricket::MediaSessionOptions options; diff --git a/talk/base/asyncpacketsocket.h b/talk/base/asyncpacketsocket.h index d9e1bff66b..4fcc271440 100644 --- a/talk/base/asyncpacketsocket.h +++ b/talk/base/asyncpacketsocket.h @@ -2,26 +2,26 @@ * libjingle * Copyright 2004--2005, Google Inc. * - * Redistribution and use in source and binary forms, with or without + * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - * 1. Redistributions of source code must retain the above copyright notice, + * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products + * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO - * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ @@ -55,6 +55,8 @@ struct PacketTimeUpdateParams { // over network. struct PacketOptions { PacketOptions() : dscp(DSCP_NO_CHANGE) {} + explicit PacketOptions(DiffServCodePoint dscp) : dscp(dscp) {} + DiffServCodePoint dscp; PacketTimeUpdateParams packet_time_params; }; @@ -102,9 +104,9 @@ class AsyncPacketSocket : public sigslot::has_slots<> { virtual SocketAddress GetRemoteAddress() const = 0; // Send a packet. - virtual int Send(const void *pv, size_t cb, DiffServCodePoint dscp) = 0; + virtual int Send(const void *pv, size_t cb, const PacketOptions& options) = 0; virtual int SendTo(const void *pv, size_t cb, const SocketAddress& addr, - DiffServCodePoint) = 0; + const PacketOptions& options) = 0; // Close the socket. virtual int Close() = 0; diff --git a/talk/base/asynctcpsocket.cc b/talk/base/asynctcpsocket.cc index d2ae513fd5..6e390b4488 100644 --- a/talk/base/asynctcpsocket.cc +++ b/talk/base/asynctcpsocket.cc @@ -141,12 +141,11 @@ void AsyncTCPSocketBase::SetError(int error) { return socket_->SetError(error); } -// TODO(mallinath) - Add support of setting DSCP code on AsyncSocket. int AsyncTCPSocketBase::SendTo(const void *pv, size_t cb, const SocketAddress& addr, - DiffServCodePoint dscp) { + const talk_base::PacketOptions& options) { if (addr == GetRemoteAddress()) - return Send(pv, cb, dscp); + return Send(pv, cb, options); ASSERT(false); socket_->SetError(ENOTCONN); @@ -263,8 +262,8 @@ AsyncTCPSocket::AsyncTCPSocket(AsyncSocket* socket, bool listen) : AsyncTCPSocketBase(socket, listen, kBufSize) { } -// TODO(mallinath) - Add support of setting DSCP code on AsyncSocket. -int AsyncTCPSocket::Send(const void *pv, size_t cb, DiffServCodePoint dscp) { +int AsyncTCPSocket::Send(const void *pv, size_t cb, + const talk_base::PacketOptions& options) { if (cb > kBufSize) { SetError(EMSGSIZE); return -1; diff --git a/talk/base/asynctcpsocket.h b/talk/base/asynctcpsocket.h index a0e7a7e2f4..2b795f64f9 100644 --- a/talk/base/asynctcpsocket.h +++ b/talk/base/asynctcpsocket.h @@ -43,7 +43,8 @@ class AsyncTCPSocketBase : public AsyncPacketSocket { virtual ~AsyncTCPSocketBase(); // Pure virtual methods to send and recv data. - virtual int Send(const void *pv, size_t cb, DiffServCodePoint dscp) = 0; + virtual int Send(const void *pv, size_t cb, + const talk_base::PacketOptions& options) = 0; virtual void ProcessInput(char* data, size_t* len) = 0; // Signals incoming connection. virtual void HandleIncomingConnection(AsyncSocket* socket) = 0; @@ -51,7 +52,7 @@ class AsyncTCPSocketBase : public AsyncPacketSocket { virtual SocketAddress GetLocalAddress() const; virtual SocketAddress GetRemoteAddress() const; virtual int SendTo(const void *pv, size_t cb, const SocketAddress& addr, - DiffServCodePoint dscp); + const talk_base::PacketOptions& options); virtual int Close(); virtual State GetState() const; @@ -102,7 +103,8 @@ class AsyncTCPSocket : public AsyncTCPSocketBase { AsyncTCPSocket(AsyncSocket* socket, bool listen); virtual ~AsyncTCPSocket() {} - virtual int Send(const void* pv, size_t cb, DiffServCodePoint dscp); + virtual int Send(const void* pv, size_t cb, + const talk_base::PacketOptions& options); virtual void ProcessInput(char* data, size_t* len); virtual void HandleIncomingConnection(AsyncSocket* socket); diff --git a/talk/base/asyncudpsocket.cc b/talk/base/asyncudpsocket.cc index 50052630d9..367287f800 100644 --- a/talk/base/asyncudpsocket.cc +++ b/talk/base/asyncudpsocket.cc @@ -75,14 +75,14 @@ SocketAddress AsyncUDPSocket::GetRemoteAddress() const { return socket_->GetRemoteAddress(); } -// TODO(mallinath) - Add support of setting DSCP code on AsyncSocket. -int AsyncUDPSocket::Send(const void *pv, size_t cb, DiffServCodePoint dscp) { +int AsyncUDPSocket::Send(const void *pv, size_t cb, + const talk_base::PacketOptions& options) { return socket_->Send(pv, cb); } -// TODO(mallinath) - Add support of setting DSCP code on AsyncSocket. int AsyncUDPSocket::SendTo(const void *pv, size_t cb, - const SocketAddress& addr, DiffServCodePoint dscp) { + const SocketAddress& addr, + const talk_base::PacketOptions& options) { return socket_->SendTo(pv, cb, addr); } diff --git a/talk/base/asyncudpsocket.h b/talk/base/asyncudpsocket.h index 17e12a26c3..17fb043a39 100644 --- a/talk/base/asyncudpsocket.h +++ b/talk/base/asyncudpsocket.h @@ -2,26 +2,26 @@ * libjingle * Copyright 2004--2005, Google Inc. * - * Redistribution and use in source and binary forms, with or without + * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - * 1. Redistributions of source code must retain the above copyright notice, + * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products + * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO - * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ @@ -52,9 +52,10 @@ class AsyncUDPSocket : public AsyncPacketSocket { virtual SocketAddress GetLocalAddress() const; virtual SocketAddress GetRemoteAddress() const; - virtual int Send(const void *pv, size_t cb, DiffServCodePoint dscp); + virtual int Send(const void *pv, size_t cb, + const talk_base::PacketOptions& options); virtual int SendTo(const void *pv, size_t cb, const SocketAddress& addr, - DiffServCodePoint dscp); + const talk_base::PacketOptions& options); virtual int Close(); virtual State GetState() const; diff --git a/talk/base/natserver.cc b/talk/base/natserver.cc index 4698048717..48ea3cd4f5 100644 --- a/talk/base/natserver.cc +++ b/talk/base/natserver.cc @@ -126,8 +126,8 @@ void NATServer::OnInternalPacket( iter->second->WhitelistInsert(dest_addr); // Send the packet to its intended destination. - iter->second->socket->SendTo(buf + length, size - length, dest_addr, - DSCP_NO_CHANGE); + talk_base::PacketOptions options; + iter->second->socket->SendTo(buf + length, size - length, dest_addr, options); } void NATServer::OnExternalPacket( @@ -154,9 +154,10 @@ void NATServer::OnExternalPacket( size + kNATEncodedIPv6AddressSize, remote_addr); // Copy the data part after the address. + talk_base::PacketOptions options; std::memcpy(real_buf.get() + addrlength, buf, size); server_socket_->SendTo(real_buf.get(), size + addrlength, - iter->second->route.source(), DSCP_NO_CHANGE); + iter->second->route.source(), options); } void NATServer::Translate(const SocketAddressPair& route) { diff --git a/talk/base/testclient.cc b/talk/base/testclient.cc index 04d6030996..280c2fb6a8 100644 --- a/talk/base/testclient.cc +++ b/talk/base/testclient.cc @@ -25,7 +25,6 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "talk/base/dscp.h" #include "talk/base/testclient.h" #include "talk/base/thread.h" #include "talk/base/timeutils.h" @@ -59,12 +58,14 @@ bool TestClient::CheckConnState(AsyncPacketSocket::State state) { } int TestClient::Send(const char* buf, size_t size) { - return socket_->Send(buf, size, DSCP_NO_CHANGE); + talk_base::PacketOptions options; + return socket_->Send(buf, size, options); } int TestClient::SendTo(const char* buf, size_t size, const SocketAddress& dest) { - return socket_->SendTo(buf, size, dest, DSCP_NO_CHANGE); + talk_base::PacketOptions options; + return socket_->SendTo(buf, size, dest, options); } TestClient::Packet* TestClient::NextPacket() { diff --git a/talk/base/testechoserver.h b/talk/base/testechoserver.h index 5c1045423c..380f961536 100644 --- a/talk/base/testechoserver.h +++ b/talk/base/testechoserver.h @@ -69,7 +69,8 @@ class TestEchoServer : public sigslot::has_slots<> { void OnPacket(AsyncPacketSocket* socket, const char* buf, size_t size, const SocketAddress& remote_addr, const PacketTime& packet_time) { - socket->Send(buf, size, DSCP_NO_CHANGE); + talk_base::PacketOptions options; + socket->Send(buf, size, options); } void OnClose(AsyncPacketSocket* socket, int err) { ClientList::iterator it = diff --git a/talk/base/virtualsocket_unittest.cc b/talk/base/virtualsocket_unittest.cc index b31b8c8b07..8188e1de3b 100644 --- a/talk/base/virtualsocket_unittest.cc +++ b/talk/base/virtualsocket_unittest.cc @@ -69,7 +69,7 @@ struct Sender : public MessageHandler { count += size; memcpy(dummy, &cur_time, sizeof(cur_time)); - socket->Send(dummy, size, DSCP_NO_CHANGE); + socket->Send(dummy, size, options); last_send = cur_time; thread->PostDelayed(NextDelay(), this, 1); @@ -77,6 +77,7 @@ struct Sender : public MessageHandler { Thread* thread; scoped_ptr socket; + talk_base::PacketOptions options; bool done; uint32 rate; // bytes per second uint32 count; diff --git a/talk/p2p/base/asyncstuntcpsocket.cc b/talk/p2p/base/asyncstuntcpsocket.cc index 67178f4985..22f15ea9ec 100644 --- a/talk/p2p/base/asyncstuntcpsocket.cc +++ b/talk/p2p/base/asyncstuntcpsocket.cc @@ -65,9 +65,8 @@ AsyncStunTCPSocket::AsyncStunTCPSocket( : talk_base::AsyncTCPSocketBase(socket, listen, kBufSize) { } -// TODO(mallinath) - Add support of setting DSCP code on AsyncSocket. int AsyncStunTCPSocket::Send(const void *pv, size_t cb, - talk_base::DiffServCodePoint dscp) { + const talk_base::PacketOptions& options) { if (cb > kBufSize || cb < kPacketLenSize + kPacketLenOffset) { SetError(EMSGSIZE); return -1; diff --git a/talk/p2p/base/asyncstuntcpsocket.h b/talk/p2p/base/asyncstuntcpsocket.h index ff748d1f28..bef8e98090 100644 --- a/talk/p2p/base/asyncstuntcpsocket.h +++ b/talk/p2p/base/asyncstuntcpsocket.h @@ -48,7 +48,7 @@ class AsyncStunTCPSocket : public talk_base::AsyncTCPSocketBase { virtual ~AsyncStunTCPSocket() {} virtual int Send(const void* pv, size_t cb, - talk_base::DiffServCodePoint dscp); + const talk_base::PacketOptions& options); virtual void ProcessInput(char* data, size_t* len); virtual void HandleIncomingConnection(talk_base::AsyncSocket* socket); diff --git a/talk/p2p/base/asyncstuntcpsocket_unittest.cc b/talk/p2p/base/asyncstuntcpsocket_unittest.cc index c6a7b1b6fb..f3261df52d 100644 --- a/talk/p2p/base/asyncstuntcpsocket_unittest.cc +++ b/talk/p2p/base/asyncstuntcpsocket_unittest.cc @@ -122,8 +122,9 @@ class AsyncStunTCPSocketTest : public testing::Test, } bool Send(const void* data, size_t len) { + talk_base::PacketOptions options; size_t ret = send_socket_->Send( - reinterpret_cast(data), len, talk_base::DSCP_NO_CHANGE); + reinterpret_cast(data), len, options); vss_->ProcessMessagesUntilIdle(); return (ret == len); } diff --git a/talk/p2p/base/dtlstransportchannel.cc b/talk/p2p/base/dtlstransportchannel.cc index 472299959a..3635c04072 100644 --- a/talk/p2p/base/dtlstransportchannel.cc +++ b/talk/p2p/base/dtlstransportchannel.cc @@ -71,8 +71,9 @@ talk_base::StreamResult StreamInterfaceChannel::Write(const void* data, int* error) { // Always succeeds, since this is an unreliable transport anyway. // TODO: Should this block if channel_'s temporarily unwritable? - channel_->SendPacket( - static_cast(data), data_len, talk_base::DSCP_NO_CHANGE); + talk_base::PacketOptions packet_options; + channel_->SendPacket(static_cast(data), data_len, + packet_options); if (written) { *written = data_len; } @@ -124,6 +125,8 @@ DtlsTransportChannelWrapper::DtlsTransportChannelWrapper( &DtlsTransportChannelWrapper::OnRoleConflict); channel_->SignalRouteChange.connect(this, &DtlsTransportChannelWrapper::OnRouteChange); + channel_->SignalConnectionRemoved.connect(this, + &DtlsTransportChannelWrapper::OnConnectionRemoved); } DtlsTransportChannelWrapper::~DtlsTransportChannelWrapper() { @@ -339,9 +342,9 @@ bool DtlsTransportChannelWrapper::GetSrtpCipher(std::string* cipher) { // Called from upper layers to send a media packet. -int DtlsTransportChannelWrapper::SendPacket(const char* data, size_t size, - talk_base::DiffServCodePoint dscp, - int flags) { +int DtlsTransportChannelWrapper::SendPacket( + const char* data, size_t size, + const talk_base::PacketOptions& options, int flags) { int result = -1; switch (dtls_state_) { @@ -365,7 +368,7 @@ int DtlsTransportChannelWrapper::SendPacket(const char* data, size_t size, break; } - result = channel_->SendPacket(data, size, dscp); + result = channel_->SendPacket(data, size, options); } else { result = (dtls_->WriteAll(data, size, NULL, NULL) == talk_base::SR_SUCCESS) ? static_cast(size) : -1; @@ -373,7 +376,7 @@ int DtlsTransportChannelWrapper::SendPacket(const char* data, size_t size, break; // Not doing DTLS. case STATE_NONE: - result = channel_->SendPacket(data, size, dscp); + result = channel_->SendPacket(data, size, options); break; case STATE_CLOSED: // Can't send anything when we're closed. @@ -621,4 +624,10 @@ void DtlsTransportChannelWrapper::OnRouteChange( SignalRouteChange(this, candidate); } +void DtlsTransportChannelWrapper::OnConnectionRemoved( + TransportChannelImpl* channel) { + ASSERT(channel == channel_); + SignalConnectionRemoved(this); +} + } // namespace cricket diff --git a/talk/p2p/base/dtlstransportchannel.h b/talk/p2p/base/dtlstransportchannel.h index c9778881e1..232d400c65 100644 --- a/talk/p2p/base/dtlstransportchannel.h +++ b/talk/p2p/base/dtlstransportchannel.h @@ -127,6 +127,9 @@ class DtlsTransportChannelWrapper : public TransportChannelImpl { virtual IceRole GetIceRole() const { return channel_->GetIceRole(); } + virtual size_t GetConnectionCount() const { + return channel_->GetConnectionCount(); + } virtual bool SetLocalIdentity(talk_base::SSLIdentity *identity); virtual bool GetLocalIdentity(talk_base::SSLIdentity** identity) const; @@ -137,7 +140,7 @@ class DtlsTransportChannelWrapper : public TransportChannelImpl { // Called to send a packet (via DTLS, if turned on). virtual int SendPacket(const char* data, size_t size, - talk_base::DiffServCodePoint dscp, + const talk_base::PacketOptions& options, int flags); // TransportChannel calls that we forward to the wrapped transport. @@ -239,6 +242,7 @@ class DtlsTransportChannelWrapper : public TransportChannelImpl { void OnCandidatesAllocationDone(TransportChannelImpl* channel); void OnRoleConflict(TransportChannelImpl* channel); void OnRouteChange(TransportChannel* channel, const Candidate& candidate); + void OnConnectionRemoved(TransportChannelImpl* channel); Transport* transport_; // The transport_ that created us. talk_base::Thread* worker_thread_; // Everything should occur on this thread. diff --git a/talk/p2p/base/dtlstransportchannel_unittest.cc b/talk/p2p/base/dtlstransportchannel_unittest.cc index 7517026c25..cdab3321a5 100644 --- a/talk/p2p/base/dtlstransportchannel_unittest.cc +++ b/talk/p2p/base/dtlstransportchannel_unittest.cc @@ -245,8 +245,9 @@ class DtlsTestClient : public sigslot::has_slots<> { // Only set the bypass flag if we've activated DTLS. int flags = (identity_.get() && srtp) ? cricket::PF_SRTP_BYPASS : 0; + talk_base::PacketOptions packet_options; int rv = channels_[channel]->SendPacket( - packet.get(), size, talk_base::DSCP_NO_CHANGE, flags); + packet.get(), size, packet_options, flags); ASSERT_GT(rv, 0); ASSERT_EQ(size, static_cast(rv)); ++sent; diff --git a/talk/p2p/base/fakesession.h b/talk/p2p/base/fakesession.h index d199449945..f2c5b84d76 100644 --- a/talk/p2p/base/fakesession.h +++ b/talk/p2p/base/fakesession.h @@ -73,7 +73,8 @@ class FakeTransportChannel : public TransportChannelImpl, ice_proto_(ICEPROTO_HYBRID), remote_ice_mode_(ICEMODE_FULL), dtls_fingerprint_("", NULL, 0), - ssl_role_(talk_base::SSL_CLIENT) { + ssl_role_(talk_base::SSL_CLIENT), + connection_count_(0) { } ~FakeTransportChannel() { Reset(); @@ -100,6 +101,7 @@ class FakeTransportChannel : public TransportChannelImpl, virtual void SetIceRole(IceRole role) { role_ = role; } virtual IceRole GetIceRole() const { return role_; } + virtual size_t GetConnectionCount() const { return connection_count_; } virtual void SetIceTiebreaker(uint64 tiebreaker) { tiebreaker_ = tiebreaker; } virtual bool GetIceProtocolType(IceProtocolType* type) const { *type = ice_proto_; @@ -174,8 +176,15 @@ class FakeTransportChannel : public TransportChannelImpl, } } + void SetConnectionCount(size_t connection_count) { + size_t old_connection_count = connection_count_; + connection_count_ = connection_count; + if (connection_count_ < old_connection_count) + SignalConnectionRemoved(this); + } + virtual int SendPacket(const char* data, size_t len, - talk_base::DiffServCodePoint dscp, int flags) { + const talk_base::PacketOptions& options, int flags) { if (state_ != STATE_CONNECTED) { return -1; } @@ -313,6 +322,7 @@ class FakeTransportChannel : public TransportChannelImpl, IceMode remote_ice_mode_; talk_base::SSLFingerprint dtls_fingerprint_; talk_base::SSLRole ssl_role_; + size_t connection_count_; }; // Fake transport class, which can be passed to anything that needs a Transport. diff --git a/talk/p2p/base/p2ptransportchannel.cc b/talk/p2p/base/p2ptransportchannel.cc index 1f53874dd5..99ca858c89 100644 --- a/talk/p2p/base/p2ptransportchannel.cc +++ b/talk/p2p/base/p2ptransportchannel.cc @@ -795,7 +795,7 @@ int P2PTransportChannel::SetOption(talk_base::Socket::Option opt, int value) { // Send data to the other side, using our best connection. int P2PTransportChannel::SendPacket(const char *data, size_t len, - talk_base::DiffServCodePoint dscp, + const talk_base::PacketOptions& options, int flags) { ASSERT(worker_thread_ == talk_base::Thread::Current()); if (flags != 0) { @@ -807,7 +807,7 @@ int P2PTransportChannel::SendPacket(const char *data, size_t len, return -1; } - int sent = best_connection_->Send(data, len, dscp); + int sent = best_connection_->Send(data, len, options); if (sent <= 0) { ASSERT(sent < 0); error_ = best_connection_->GetError(); @@ -1010,8 +1010,10 @@ void P2PTransportChannel::UpdateChannelState() { bool readable = false; for (uint32 i = 0; i < connections_.size(); ++i) { - if (connections_[i]->read_state() == Connection::STATE_READABLE) + if (connections_[i]->read_state() == Connection::STATE_READABLE) { readable = true; + break; + } } set_readable(readable); } @@ -1224,6 +1226,8 @@ void P2PTransportChannel::OnConnectionDestroyed(Connection* connection) { SwitchBestConnectionTo(NULL); RequestSort(); } + + SignalConnectionRemoved(this); } // When a port is destroyed remove it from our list of ports to use for diff --git a/talk/p2p/base/p2ptransportchannel.h b/talk/p2p/base/p2ptransportchannel.h index b7c5929b15..57fc3a61af 100644 --- a/talk/p2p/base/p2ptransportchannel.h +++ b/talk/p2p/base/p2ptransportchannel.h @@ -79,6 +79,7 @@ class P2PTransportChannel : public TransportChannelImpl, virtual void SetIceRole(IceRole role); virtual IceRole GetIceRole() const { return ice_role_; } virtual void SetIceTiebreaker(uint64 tiebreaker); + virtual size_t GetConnectionCount() const { return connections_.size(); } virtual bool GetIceProtocolType(IceProtocolType* type) const; virtual void SetIceProtocolType(IceProtocolType type); virtual void SetIceCredentials(const std::string& ice_ufrag, @@ -93,7 +94,7 @@ class P2PTransportChannel : public TransportChannelImpl, // From TransportChannel: virtual int SendPacket(const char *data, size_t len, - talk_base::DiffServCodePoint dscp, int flags); + const talk_base::PacketOptions& options, int flags); virtual int SetOption(talk_base::Socket::Option opt, int value); virtual int GetError() { return error_; } virtual bool GetStats(std::vector* stats); diff --git a/talk/p2p/base/p2ptransportchannel_unittest.cc b/talk/p2p/base/p2ptransportchannel_unittest.cc index 53a39c2a10..566fd14a24 100644 --- a/talk/p2p/base/p2ptransportchannel_unittest.cc +++ b/talk/p2p/base/p2ptransportchannel_unittest.cc @@ -671,7 +671,8 @@ class P2PTransportChannelTestBase : public testing::Test, } int SendData(cricket::TransportChannel* channel, const char* data, size_t len) { - return channel->SendPacket(data, len, talk_base::DSCP_NO_CHANGE, 0); + talk_base::PacketOptions options; + return channel->SendPacket(data, len, options, 0); } bool CheckDataOnChannel(cricket::TransportChannel* channel, const char* data, int len) { diff --git a/talk/p2p/base/port.cc b/talk/p2p/base/port.cc index 38031cb2f1..e054060d38 100644 --- a/talk/p2p/base/port.cc +++ b/talk/p2p/base/port.cc @@ -630,7 +630,8 @@ void Port::SendBindingResponse(StunMessage* request, // Send the response message. talk_base::ByteBuffer buf; response.Write(&buf); - if (SendTo(buf.Data(), buf.Length(), addr, DefaultDscpValue(), false) < 0) { + talk_base::PacketOptions options(DefaultDscpValue()); + if (SendTo(buf.Data(), buf.Length(), addr, options, false) < 0) { LOG_J(LS_ERROR, this) << "Failed to send STUN ping response to " << addr.ToSensitiveString(); } @@ -684,7 +685,8 @@ void Port::SendBindingErrorResponse(StunMessage* request, // Send the response message. talk_base::ByteBuffer buf; response.Write(&buf); - SendTo(buf.Data(), buf.Length(), addr, DefaultDscpValue(), false); + talk_base::PacketOptions options(DefaultDscpValue()); + SendTo(buf.Data(), buf.Length(), addr, options, false); LOG_J(LS_INFO, this) << "Sending STUN binding error: reason=" << reason << " to " << addr.ToSensitiveString(); } @@ -932,8 +934,9 @@ void Connection::set_use_candidate_attr(bool enable) { void Connection::OnSendStunPacket(const void* data, size_t size, StunRequest* req) { + talk_base::PacketOptions options(port_->DefaultDscpValue()); if (port_->SendTo(data, size, remote_candidate_.address(), - port_->DefaultDscpValue(), false) < 0) { + options, false) < 0) { LOG_J(LS_WARNING, this) << "Failed to send STUN ping " << req->id(); } } @@ -1408,12 +1411,13 @@ ProxyConnection::ProxyConnection(Port* port, size_t index, } int ProxyConnection::Send(const void* data, size_t size, - talk_base::DiffServCodePoint dscp) { + const talk_base::PacketOptions& options) { if (write_state_ == STATE_WRITE_INIT || write_state_ == STATE_WRITE_TIMEOUT) { error_ = EWOULDBLOCK; return SOCKET_ERROR; } - int sent = port_->SendTo(data, size, remote_candidate_.address(), dscp, true); + int sent = port_->SendTo(data, size, remote_candidate_.address(), + options, true); if (sent <= 0) { ASSERT(sent < 0); error_ = port_->GetError(); diff --git a/talk/p2p/base/port.h b/talk/p2p/base/port.h index 1c43c935f2..ff68dd0314 100644 --- a/talk/p2p/base/port.h +++ b/talk/p2p/base/port.h @@ -459,7 +459,7 @@ class Connection : public talk_base::MessageHandler, // the interface of AsyncPacketSocket, which may use UDP or TCP under the // covers. virtual int Send(const void* data, size_t size, - talk_base::DiffServCodePoint dscp) = 0; + const talk_base::PacketOptions& options) = 0; // Error if Send() returns < 0 virtual int GetError() = 0; @@ -591,7 +591,7 @@ class ProxyConnection : public Connection { ProxyConnection(Port* port, size_t index, const Candidate& candidate); virtual int Send(const void* data, size_t size, - talk_base::DiffServCodePoint dscp); + const talk_base::PacketOptions& options); virtual int GetError() { return error_; } private: diff --git a/talk/p2p/base/port_unittest.cc b/talk/p2p/base/port_unittest.cc index 18c3ef74ac..a6365d54e0 100644 --- a/talk/p2p/base/port_unittest.cc +++ b/talk/p2p/base/port_unittest.cc @@ -173,7 +173,7 @@ class TestPort : public Port { } virtual int SendTo( const void* data, size_t size, const talk_base::SocketAddress& addr, - talk_base::DiffServCodePoint dscp, bool payload) { + const talk_base::PacketOptions& options, bool payload) { if (!payload) { IceMessage* msg = new IceMessage; ByteBuffer* buf = new ByteBuffer(static_cast(data), size); @@ -842,11 +842,11 @@ class FakeAsyncPacketSocket : public AsyncPacketSocket { // Send a packet. virtual int Send(const void *pv, size_t cb, - talk_base::DiffServCodePoint dscp) { + const talk_base::PacketOptions& options) { return static_cast(cb); } virtual int SendTo(const void *pv, size_t cb, const SocketAddress& addr, - talk_base::DiffServCodePoint dscp) { + const talk_base::PacketOptions& options) { return static_cast(cb); } virtual int Close() { @@ -2297,16 +2297,15 @@ TEST_F(PortTest, TestWritableState) { // Data should be unsendable until the connection is accepted. char data[] = "abcd"; int data_size = ARRAY_SIZE(data); - EXPECT_EQ(SOCKET_ERROR, - ch1.conn()->Send(data, data_size, talk_base::DSCP_NO_CHANGE)); + talk_base::PacketOptions options; + EXPECT_EQ(SOCKET_ERROR, ch1.conn()->Send(data, data_size, options)); // Accept the connection to return the binding response, transition to // writable, and allow data to be sent. ch2.AcceptConnection(); EXPECT_EQ_WAIT(Connection::STATE_WRITABLE, ch1.conn()->write_state(), kTimeout); - EXPECT_EQ(data_size, - ch1.conn()->Send(data, data_size, talk_base::DSCP_NO_CHANGE)); + EXPECT_EQ(data_size, ch1.conn()->Send(data, data_size, options)); // Ask the connection to update state as if enough time has passed to lose // full writability and 5 pings went unresponded to. We'll accomplish the @@ -2319,8 +2318,7 @@ TEST_F(PortTest, TestWritableState) { EXPECT_EQ(Connection::STATE_WRITE_UNRELIABLE, ch1.conn()->write_state()); // Data should be able to be sent in this state. - EXPECT_EQ(data_size, - ch1.conn()->Send(data, data_size, talk_base::DSCP_NO_CHANGE)); + EXPECT_EQ(data_size, ch1.conn()->Send(data, data_size, options)); // And now allow the other side to process the pings and send binding // responses. @@ -2337,8 +2335,7 @@ TEST_F(PortTest, TestWritableState) { EXPECT_EQ(Connection::STATE_WRITE_TIMEOUT, ch1.conn()->write_state()); // Now that the connection has completely timed out, data send should fail. - EXPECT_EQ(SOCKET_ERROR, - ch1.conn()->Send(data, data_size, talk_base::DSCP_NO_CHANGE)); + EXPECT_EQ(SOCKET_ERROR, ch1.conn()->Send(data, data_size, options)); ch1.Stop(); ch2.Stop(); diff --git a/talk/p2p/base/portinterface.h b/talk/p2p/base/portinterface.h index 6ea63466c9..5ebf653987 100644 --- a/talk/p2p/base/portinterface.h +++ b/talk/p2p/base/portinterface.h @@ -30,13 +30,12 @@ #include -#include "talk/base/dscp.h" #include "talk/base/socketaddress.h" #include "talk/p2p/base/transport.h" namespace talk_base { class Network; -class PacketSocketFactory; +struct PacketOptions; } namespace cricket { @@ -100,7 +99,7 @@ class PortInterface { // that of a connection or an address that has sent to us already. virtual int SendTo(const void* data, size_t size, const talk_base::SocketAddress& addr, - talk_base::DiffServCodePoint dscp, bool payload) = 0; + const talk_base::PacketOptions& options, bool payload) = 0; // Indicates that we received a successful STUN binding request from an // address that doesn't correspond to any current connection. To turn this diff --git a/talk/p2p/base/portproxy.cc b/talk/p2p/base/portproxy.cc index eae39f1612..43bb747c96 100644 --- a/talk/p2p/base/portproxy.cc +++ b/talk/p2p/base/portproxy.cc @@ -97,10 +97,10 @@ Connection* PortProxy::CreateConnection(const Candidate& remote_candidate, int PortProxy::SendTo(const void* data, size_t size, const talk_base::SocketAddress& addr, - talk_base::DiffServCodePoint dscp, + const talk_base::PacketOptions& options, bool payload) { ASSERT(impl_ != NULL); - return impl_->SendTo(data, size, addr, dscp, payload); + return impl_->SendTo(data, size, addr, options, payload); } int PortProxy::SetOption(talk_base::Socket::Option opt, diff --git a/talk/p2p/base/portproxy.h b/talk/p2p/base/portproxy.h index da326646dc..d138dc3614 100644 --- a/talk/p2p/base/portproxy.h +++ b/talk/p2p/base/portproxy.h @@ -69,7 +69,7 @@ class PortProxy : public PortInterface, public sigslot::has_slots<> { virtual int SendTo(const void* data, size_t size, const talk_base::SocketAddress& addr, - talk_base::DiffServCodePoint dscp, + const talk_base::PacketOptions& options, bool payload); virtual int SetOption(talk_base::Socket::Option opt, int value); virtual int GetOption(talk_base::Socket::Option opt, int* value); diff --git a/talk/p2p/base/rawtransportchannel.cc b/talk/p2p/base/rawtransportchannel.cc index 2baef4245a..37478ca4b5 100644 --- a/talk/p2p/base/rawtransportchannel.cc +++ b/talk/p2p/base/rawtransportchannel.cc @@ -75,7 +75,7 @@ RawTransportChannel::~RawTransportChannel() { } int RawTransportChannel::SendPacket(const char *data, size_t size, - talk_base::DiffServCodePoint dscp, + const talk_base::PacketOptions& options, int flags) { if (port_ == NULL) return -1; @@ -83,7 +83,7 @@ int RawTransportChannel::SendPacket(const char *data, size_t size, return -1; if (flags != 0) return -1; - return port_->SendTo(data, size, remote_address_, dscp, true); + return port_->SendTo(data, size, remote_address_, options, true); } int RawTransportChannel::SetOption(talk_base::Socket::Option opt, int value) { diff --git a/talk/p2p/base/rawtransportchannel.h b/talk/p2p/base/rawtransportchannel.h index 2042d5f119..52085c04fa 100644 --- a/talk/p2p/base/rawtransportchannel.h +++ b/talk/p2p/base/rawtransportchannel.h @@ -65,7 +65,7 @@ class RawTransportChannel : public TransportChannelImpl, // Implementation of normal channel packet sending. virtual int SendPacket(const char *data, size_t len, - talk_base::DiffServCodePoint dscp, int flags); + const talk_base::PacketOptions& options, int flags); virtual int SetOption(talk_base::Socket::Option opt, int value); virtual int GetError(); @@ -104,6 +104,7 @@ class RawTransportChannel : public TransportChannelImpl, virtual void SetIceUfrag(const std::string& ice_ufrag) {} virtual void SetIcePwd(const std::string& ice_pwd) {} virtual void SetRemoteIceMode(IceMode mode) {} + virtual size_t GetConnectionCount() const { return 1; } virtual bool GetStats(ConnectionInfos* infos) { return false; diff --git a/talk/p2p/base/relayport.cc b/talk/p2p/base/relayport.cc index 9112b1067d..0190aad5a3 100644 --- a/talk/p2p/base/relayport.cc +++ b/talk/p2p/base/relayport.cc @@ -67,7 +67,7 @@ class RelayConnection : public sigslot::has_slots<> { bool CheckResponse(StunMessage* msg); // Sends data to the relay server. - int Send(const void* pv, size_t cb, talk_base::DiffServCodePoint dscp); + int Send(const void* pv, size_t cb, const talk_base::PacketOptions& options); // Sends a STUN allocate request message to the relay server. void SendAllocateRequest(RelayEntry* entry, int delay); @@ -124,7 +124,7 @@ class RelayEntry : public talk_base::MessageHandler, // entry. This will wrap the packet in STUN if necessary. int SendTo(const void* data, size_t size, const talk_base::SocketAddress& addr, - talk_base::DiffServCodePoint dscp); + const talk_base::PacketOptions& options); // Schedules a keep-alive allocate request. void ScheduleKeepAlive(); @@ -166,7 +166,7 @@ class RelayEntry : public talk_base::MessageHandler, // Sends the given data on the socket to the server with no wrapping. This // returns the number of bytes written or -1 if an error occurred. int SendPacket(const void* data, size_t size, - talk_base::DiffServCodePoint dscp); + const talk_base::PacketOptions& options); }; // Handles an allocate request for a particular RelayEntry. @@ -304,7 +304,7 @@ Connection* RelayPort::CreateConnection(const Candidate& address, int RelayPort::SendTo(const void* data, size_t size, const talk_base::SocketAddress& addr, - talk_base::DiffServCodePoint dscp, + const talk_base::PacketOptions& options, bool payload) { // Try to find an entry for this specific address. Note that the first entry // created was not given an address initially, so it can be set to the first @@ -346,7 +346,7 @@ int RelayPort::SendTo(const void* data, size_t size, } // Send the actual contents to the server using the usual mechanism. - int sent = entry->SendTo(data, size, addr, dscp); + int sent = entry->SendTo(data, size, addr, options); if (sent <= 0) { ASSERT(sent < 0); error_ = entry->GetError(); @@ -426,8 +426,8 @@ bool RelayConnection::CheckResponse(StunMessage* msg) { void RelayConnection::OnSendPacket(const void* data, size_t size, StunRequest* req) { // TODO(mallinath) Find a way to get DSCP value from Port. - int sent = socket_->SendTo( - data, size, GetAddress(), talk_base::DSCP_NO_CHANGE); + talk_base::PacketOptions options; // Default dscp set to NO_CHANGE. + int sent = socket_->SendTo(data, size, GetAddress(), options); if (sent <= 0) { LOG(LS_VERBOSE) << "OnSendPacket: failed sending to " << GetAddress() << std::strerror(socket_->GetError()); @@ -436,8 +436,8 @@ void RelayConnection::OnSendPacket(const void* data, size_t size, } int RelayConnection::Send(const void* pv, size_t cb, - talk_base::DiffServCodePoint dscp) { - return socket_->SendTo(pv, cb, GetAddress(), dscp); + const talk_base::PacketOptions& options) { + return socket_->SendTo(pv, cb, GetAddress(), options); } void RelayConnection::SendAllocateRequest(RelayEntry* entry, int delay) { @@ -557,11 +557,11 @@ void RelayEntry::OnConnect(const talk_base::SocketAddress& mapped_addr, int RelayEntry::SendTo(const void* data, size_t size, const talk_base::SocketAddress& addr, - talk_base::DiffServCodePoint dscp) { + const talk_base::PacketOptions& options) { // If this connection is locked to the address given, then we can send the // packet with no wrapper. if (locked_ && (ext_addr_ == addr)) - return SendPacket(data, size, dscp); + return SendPacket(data, size, options); // Otherwise, we must wrap the given data in a STUN SEND request so that we // can communicate the destination address to the server. @@ -609,7 +609,7 @@ int RelayEntry::SendTo(const void* data, size_t size, talk_base::ByteBuffer buf; request.Write(&buf); - return SendPacket(buf.Data(), buf.Length(), dscp); + return SendPacket(buf.Data(), buf.Length(), options); } void RelayEntry::ScheduleKeepAlive() { @@ -758,12 +758,12 @@ void RelayEntry::OnReadyToSend(talk_base::AsyncPacketSocket* socket) { } int RelayEntry::SendPacket(const void* data, size_t size, - talk_base::DiffServCodePoint dscp) { + const talk_base::PacketOptions& options) { int sent = 0; if (current_connection_) { // We are connected, no need to send packets anywere else than to // the current connection. - sent = current_connection_->Send(data, size, dscp); + sent = current_connection_->Send(data, size, options); } return sent; } diff --git a/talk/p2p/base/relayport.h b/talk/p2p/base/relayport.h index 08df12f9d2..140c80fe06 100644 --- a/talk/p2p/base/relayport.h +++ b/talk/p2p/base/relayport.h @@ -93,7 +93,7 @@ class RelayPort : public Port { virtual int SendTo(const void* data, size_t size, const talk_base::SocketAddress& addr, - talk_base::DiffServCodePoint dscp, + const talk_base::PacketOptions& options, bool payload); // Dispatches the given packet to the port or connection as appropriate. diff --git a/talk/p2p/base/relayserver.cc b/talk/p2p/base/relayserver.cc index c2619c03fe..aacc2c8250 100644 --- a/talk/p2p/base/relayserver.cc +++ b/talk/p2p/base/relayserver.cc @@ -51,7 +51,8 @@ static const uint32 kMessageAcceptConnection = 1; // Calls SendTo on the given socket and logs any bad results. void Send(talk_base::AsyncPacketSocket* socket, const char* bytes, size_t size, const talk_base::SocketAddress& addr) { - int result = socket->SendTo(bytes, size, addr, talk_base::DSCP_NO_CHANGE); + talk_base::PacketOptions options; + int result = socket->SendTo(bytes, size, addr, options); if (result < static_cast(size)) { LOG(LS_ERROR) << "SendTo wrote only " << result << " of " << size << " bytes"; diff --git a/talk/p2p/base/session.cc b/talk/p2p/base/session.cc index 0bbd15d8de..e0911e13d4 100644 --- a/talk/p2p/base/session.cc +++ b/talk/p2p/base/session.cc @@ -539,6 +539,10 @@ TransportProxy* BaseSession::GetOrCreateTransportProxy( this, &BaseSession::OnTransportCandidatesAllocationDone); transport->SignalRoleConflict.connect( this, &BaseSession::OnRoleConflict); + transport->SignalCompleted.connect( + this, &BaseSession::OnTransportCompleted); + transport->SignalFailed.connect( + this, &BaseSession::OnTransportFailed); transproxy = new TransportProxy(worker_thread_, sid_, content_name, new TransportWrapper(transport)); diff --git a/talk/p2p/base/session.h b/talk/p2p/base/session.h index 8386434f94..826baaa5fb 100644 --- a/talk/p2p/base/session.h +++ b/talk/p2p/base/session.h @@ -432,6 +432,14 @@ class BaseSession : public sigslot::has_slots<>, virtual void OnTransportReadable(Transport* transport) { } + // Called when a transport has found its steady-state connections. + virtual void OnTransportCompleted(Transport* transport) { + } + + // Called when a transport has failed permanently. + virtual void OnTransportFailed(Transport* transport) { + } + // Called when a transport signals that it has new candidates. virtual void OnTransportProxyCandidatesReady(TransportProxy* proxy, const Candidates& candidates) { diff --git a/talk/p2p/base/session_unittest.cc b/talk/p2p/base/session_unittest.cc index ab4620f879..bfc4dcb944 100644 --- a/talk/p2p/base/session_unittest.cc +++ b/talk/p2p/base/session_unittest.cc @@ -32,7 +32,6 @@ #include "talk/base/base64.h" #include "talk/base/common.h" -#include "talk/base/dscp.h" #include "talk/base/gunit.h" #include "talk/base/helpers.h" #include "talk/base/logging.h" @@ -828,10 +827,11 @@ struct ChannelHandler : sigslot::has_slots<> { } void Send(const char* data, size_t size) { + talk_base::PacketOptions options; std::string data_with_id(name); data_with_id += data; int result = channel->SendPacket(data_with_id.c_str(), data_with_id.size(), - talk_base::DSCP_NO_CHANGE, 0); + options, 0); EXPECT_EQ(static_cast(data_with_id.size()), result); } diff --git a/talk/p2p/base/stunport.cc b/talk/p2p/base/stunport.cc index cee2fc4eee..95b26ac111 100644 --- a/talk/p2p/base/stunport.cc +++ b/talk/p2p/base/stunport.cc @@ -218,9 +218,9 @@ Connection* UDPPort::CreateConnection(const Candidate& address, int UDPPort::SendTo(const void* data, size_t size, const talk_base::SocketAddress& addr, - talk_base::DiffServCodePoint dscp, + const talk_base::PacketOptions& options, bool payload) { - int sent = socket_->SendTo(data, size, addr, dscp); + int sent = socket_->SendTo(data, size, addr, options); if (sent < 0) { error_ = socket_->GetError(); LOG_J(LS_ERROR, this) << "UDP send of " << size @@ -354,7 +354,8 @@ void UDPPort::SetResult(bool success) { // TODO: merge this with SendTo above. void UDPPort::OnSendPacket(const void* data, size_t size, StunRequest* req) { StunBindingRequest* sreq = static_cast(req); - if (socket_->SendTo(data, size, sreq->server_addr(), DefaultDscpValue()) < 0) + talk_base::PacketOptions options(DefaultDscpValue()); + if (socket_->SendTo(data, size, sreq->server_addr(), options) < 0) PLOG(LERROR, socket_->GetError()) << "sendto"; } diff --git a/talk/p2p/base/stunport.h b/talk/p2p/base/stunport.h index a8b89c3be5..1612c97bc5 100644 --- a/talk/p2p/base/stunport.h +++ b/talk/p2p/base/stunport.h @@ -125,7 +125,7 @@ class UDPPort : public Port { virtual int SendTo(const void* data, size_t size, const talk_base::SocketAddress& addr, - talk_base::DiffServCodePoint dscp, + const talk_base::PacketOptions& options, bool payload); void OnLocalAddressReady(talk_base::AsyncPacketSocket* socket, diff --git a/talk/p2p/base/stunserver.cc b/talk/p2p/base/stunserver.cc index 062be20687..ee6c64376b 100644 --- a/talk/p2p/base/stunserver.cc +++ b/talk/p2p/base/stunserver.cc @@ -103,8 +103,8 @@ void StunServer::SendResponse( const StunMessage& msg, const talk_base::SocketAddress& addr) { talk_base::ByteBuffer buf; msg.Write(&buf); - if (socket_->SendTo( - buf.Data(), buf.Length(), addr, talk_base::DSCP_NO_CHANGE) < 0) + talk_base::PacketOptions options; + if (socket_->SendTo(buf.Data(), buf.Length(), addr, options) < 0) LOG_ERR(LS_ERROR) << "sendto"; } diff --git a/talk/p2p/base/tcpport.cc b/talk/p2p/base/tcpport.cc index 09812443c1..d83623f7f3 100644 --- a/talk/p2p/base/tcpport.cc +++ b/talk/p2p/base/tcpport.cc @@ -135,7 +135,7 @@ void TCPPort::PrepareAddress() { int TCPPort::SendTo(const void* data, size_t size, const talk_base::SocketAddress& addr, - talk_base::DiffServCodePoint dscp, + const talk_base::PacketOptions& options, bool payload) { talk_base::AsyncPacketSocket * socket = NULL; if (TCPConnection * conn = static_cast(GetConnection(addr))) { @@ -149,7 +149,7 @@ int TCPPort::SendTo(const void* data, size_t size, return -1; // TODO: Set error_ } - int sent = socket->Send(data, size, dscp); + int sent = socket->Send(data, size, options); if (sent < 0) { error_ = socket->GetError(); LOG_J(LS_ERROR, this) << "TCP send of " << size @@ -265,7 +265,7 @@ TCPConnection::~TCPConnection() { } int TCPConnection::Send(const void* data, size_t size, - talk_base::DiffServCodePoint dscp) { + const talk_base::PacketOptions& options) { if (!socket_) { error_ = ENOTCONN; return SOCKET_ERROR; @@ -276,7 +276,7 @@ int TCPConnection::Send(const void* data, size_t size, error_ = EWOULDBLOCK; return SOCKET_ERROR; } - int sent = socket_->Send(data, size, dscp); + int sent = socket_->Send(data, size, options); if (sent < 0) { error_ = socket_->GetError(); } else { diff --git a/talk/p2p/base/tcpport.h b/talk/p2p/base/tcpport.h index 77b177a2d5..c152ec0d38 100644 --- a/talk/p2p/base/tcpport.h +++ b/talk/p2p/base/tcpport.h @@ -83,7 +83,7 @@ class TCPPort : public Port { // Handles sending using the local TCP socket. virtual int SendTo(const void* data, size_t size, const talk_base::SocketAddress& addr, - talk_base::DiffServCodePoint dscp, + const talk_base::PacketOptions& options, bool payload); // Accepts incoming TCP connection. @@ -128,7 +128,7 @@ class TCPConnection : public Connection { virtual ~TCPConnection(); virtual int Send(const void* data, size_t size, - talk_base::DiffServCodePoint dscp); + const talk_base::PacketOptions& options); virtual int GetError(); talk_base::AsyncPacketSocket* socket() { return socket_; } diff --git a/talk/p2p/base/transport.cc b/talk/p2p/base/transport.cc index 3781b2a542..95799c7cbe 100644 --- a/talk/p2p/base/transport.cc +++ b/talk/p2p/base/transport.cc @@ -53,6 +53,8 @@ enum { MSG_CONNECTING, MSG_CANDIDATEALLOCATIONCOMPLETE, MSG_ROLECONFLICT, + MSG_COMPLETED, + MSG_FAILED, }; struct ChannelParams : public talk_base::MessageData { @@ -226,6 +228,8 @@ TransportChannelImpl* Transport::CreateChannel_w(int component) { impl->SignalCandidatesAllocationDone.connect( this, &Transport::OnChannelCandidatesAllocationDone); impl->SignalRoleConflict.connect(this, &Transport::OnRoleConflict); + impl->SignalConnectionRemoved.connect( + this, &Transport::OnChannelConnectionRemoved); if (connect_requested_) { impl->Connect(); @@ -620,6 +624,50 @@ void Transport::OnRoleConflict(TransportChannelImpl* channel) { signaling_thread_->Post(this, MSG_ROLECONFLICT); } +void Transport::OnChannelConnectionRemoved(TransportChannelImpl* channel) { + ASSERT(worker_thread()->IsCurrent()); + // Determine if the Transport should move to Completed or Failed. These + // states are only available in the Controlling ICE role. + if (channel->GetIceRole() != ICEROLE_CONTROLLING) { + return; + } + + ChannelMap::iterator iter = channels_.find(channel->component()); + ASSERT(iter != channels_.end()); + // Completed and Failed can only occur after candidate allocation has stopped. + if (!iter->second.candidates_allocated()) { + return; + } + + size_t connections = channel->GetConnectionCount(); + if (connections == 0) { + // A Transport has failed if any of its channels have no remaining + // connections. + signaling_thread_->Post(this, MSG_FAILED); + } else if (connections == 1 && completed()) { + signaling_thread_->Post(this, MSG_COMPLETED); + } +} + +bool Transport::completed() const { + // A Transport's ICE process is completed if all of its channels are writable, + // have finished allocating candidates, and have pruned all but one of their + // connections. + if (!all_channels_writable()) + return false; + + ChannelMap::const_iterator iter; + for (iter = channels_.begin(); iter != channels_.end(); ++iter) { + const TransportChannelImpl* channel = iter->second.get(); + if (!(channel->GetConnectionCount() == 1 && + channel->GetIceRole() == ICEROLE_CONTROLLING && + iter->second.candidates_allocated())) { + return false; + } + } + return true; +} + void Transport::SetIceRole_w(IceRole role) { talk_base::CritScope cs(&crit_); ice_role_ = role; @@ -820,6 +868,12 @@ void Transport::OnMessage(talk_base::Message* msg) { case MSG_ROLECONFLICT: SignalRoleConflict(); break; + case MSG_COMPLETED: + SignalCompleted(this); + break; + case MSG_FAILED: + SignalFailed(this); + break; } } diff --git a/talk/p2p/base/transport.h b/talk/p2p/base/transport.h index 49ab0ea97d..9aca1a982e 100644 --- a/talk/p2p/base/transport.h +++ b/talk/p2p/base/transport.h @@ -237,6 +237,10 @@ class Transport : public talk_base::MessageHandler, sigslot::signal1 SignalReadableState; sigslot::signal1 SignalWritableState; + bool completed() const; + sigslot::signal1 SignalCompleted; + sigslot::signal1 SignalFailed; + // Returns whether the client has requested the channels to connect. bool connect_requested() const { return connect_requested_; } @@ -441,6 +445,8 @@ class Transport : public talk_base::MessageHandler, void OnChannelCandidatesAllocationDone(TransportChannelImpl* channel); // Called when there is ICE role change. void OnRoleConflict(TransportChannelImpl* channel); + // Called when the channel removes a connection. + void OnChannelConnectionRemoved(TransportChannelImpl* channel); // Dispatches messages to the appropriate handler (below). void OnMessage(talk_base::Message* msg); diff --git a/talk/p2p/base/transport_unittest.cc b/talk/p2p/base/transport_unittest.cc index c7cbc497fd..d84d4963d6 100644 --- a/talk/p2p/base/transport_unittest.cc +++ b/talk/p2p/base/transport_unittest.cc @@ -60,8 +60,12 @@ class TransportTest : public testing::Test, transport_(new FakeTransport( thread_, thread_, "test content name", NULL)), channel_(NULL), - connecting_signalled_(false) { + connecting_signalled_(false), + completed_(false), + failed_(false) { transport_->SignalConnecting.connect(this, &TransportTest::OnConnecting); + transport_->SignalCompleted.connect(this, &TransportTest::OnCompleted); + transport_->SignalFailed.connect(this, &TransportTest::OnFailed); } ~TransportTest() { transport_->DestroyAllChannels(); @@ -83,11 +87,19 @@ class TransportTest : public testing::Test, void OnConnecting(Transport* transport) { connecting_signalled_ = true; } + void OnCompleted(Transport* transport) { + completed_ = true; + } + void OnFailed(Transport* transport) { + failed_ = true; + } talk_base::Thread* thread_; talk_base::scoped_ptr transport_; FakeTransportChannel* channel_; bool connecting_signalled_; + bool completed_; + bool failed_; }; class FakeCandidateTranslator : public cricket::CandidateTranslator { @@ -172,6 +184,46 @@ TEST_F(TransportTest, TestChannelIceParameters) { EXPECT_EQ(kIcePwd1, channel_->remote_ice_pwd()); } +// This test verifies that the Completed and Failed states can be reached. +TEST_F(TransportTest, TestChannelCompletedAndFailed) { + transport_->SetIceRole(cricket::ICEROLE_CONTROLLING); + cricket::TransportDescription local_desc( + cricket::NS_JINGLE_ICE_UDP, kIceUfrag1, kIcePwd1); + ASSERT_TRUE(transport_->SetLocalTransportDescription(local_desc, + cricket::CA_OFFER, + NULL)); + EXPECT_TRUE(SetupChannel()); + + cricket::TransportDescription remote_desc( + cricket::NS_JINGLE_ICE_UDP, kIceUfrag1, kIcePwd1); + ASSERT_TRUE(transport_->SetRemoteTransportDescription(remote_desc, + cricket::CA_ANSWER, + NULL)); + + channel_->SetConnectionCount(2); + channel_->SignalCandidatesAllocationDone(channel_); + channel_->SetWritable(true); + EXPECT_TRUE_WAIT(transport_->all_channels_writable(), 100); + // ICE is not yet completed because there is still more than one connection. + EXPECT_FALSE(completed_); + EXPECT_FALSE(transport_->completed()); + EXPECT_FALSE(failed_); + + // When the connection count drops to 1, SignalCompleted should be emitted, + // and completed() should be true. + channel_->SetConnectionCount(1); + EXPECT_TRUE_WAIT(completed_, 100); + EXPECT_TRUE(transport_->completed()); + completed_ = false; + + // When the connection count drops to 0, SignalFailed should be emitted, and + // completed() should be false. + channel_->SetConnectionCount(0); + EXPECT_TRUE_WAIT(failed_, 100); + EXPECT_FALSE(transport_->completed()); + EXPECT_FALSE(completed_); +} + // Tests channel role is reversed after receiving ice-lite from remote. TEST_F(TransportTest, TestSetRemoteIceLiteInOffer) { transport_->SetIceRole(cricket::ICEROLE_CONTROLLED); diff --git a/talk/p2p/base/transportchannel.h b/talk/p2p/base/transportchannel.h index 47ba990f35..c548c1c8c1 100644 --- a/talk/p2p/base/transportchannel.h +++ b/talk/p2p/base/transportchannel.h @@ -83,7 +83,7 @@ class TransportChannel : public sigslot::has_slots<> { // Attempts to send the given packet. The return value is < 0 on failure. // TODO: Remove the default argument once channel code is updated. virtual int SendPacket(const char* data, size_t len, - talk_base::DiffServCodePoint dscp, + const talk_base::PacketOptions& options, int flags = 0) = 0; // Sets a socket option on this channel. Note that not all options are diff --git a/talk/p2p/base/transportchannelimpl.h b/talk/p2p/base/transportchannelimpl.h index c66e0c024a..25c3121886 100644 --- a/talk/p2p/base/transportchannelimpl.h +++ b/talk/p2p/base/transportchannelimpl.h @@ -53,6 +53,7 @@ class TransportChannelImpl : public TransportChannel { virtual IceRole GetIceRole() const = 0; virtual void SetIceRole(IceRole role) = 0; virtual void SetIceTiebreaker(uint64 tiebreaker) = 0; + virtual size_t GetConnectionCount() const = 0; // To toggle G-ICE/ICE. virtual bool GetIceProtocolType(IceProtocolType* type) const = 0; virtual void SetIceProtocolType(IceProtocolType type) = 0; @@ -114,6 +115,10 @@ class TransportChannelImpl : public TransportChannel { // agents. sigslot::signal1 SignalRoleConflict; + // Emitted whenever the number of connections available to the transport + // channel decreases. + sigslot::signal1 SignalConnectionRemoved; + private: DISALLOW_EVIL_CONSTRUCTORS(TransportChannelImpl); }; diff --git a/talk/p2p/base/transportchannelproxy.cc b/talk/p2p/base/transportchannelproxy.cc index 0d8cace2a8..3c4aeb1281 100644 --- a/talk/p2p/base/transportchannelproxy.cc +++ b/talk/p2p/base/transportchannelproxy.cc @@ -102,14 +102,14 @@ void TransportChannelProxy::SetImplementation(TransportChannelImpl* impl) { } int TransportChannelProxy::SendPacket(const char* data, size_t len, - talk_base::DiffServCodePoint dscp, + const talk_base::PacketOptions& options, int flags) { ASSERT(talk_base::Thread::Current() == worker_thread_); // Fail if we don't have an impl yet. if (!impl_) { return -1; } - return impl_->SendPacket(data, len, dscp, flags); + return impl_->SendPacket(data, len, options, flags); } int TransportChannelProxy::SetOption(talk_base::Socket::Option opt, int value) { diff --git a/talk/p2p/base/transportchannelproxy.h b/talk/p2p/base/transportchannelproxy.h index 196d0f6cfa..cb38c7bc49 100644 --- a/talk/p2p/base/transportchannelproxy.h +++ b/talk/p2p/base/transportchannelproxy.h @@ -64,7 +64,7 @@ class TransportChannelProxy : public TransportChannel, // Implementation of the TransportChannel interface. These simply forward to // the implementation. virtual int SendPacket(const char* data, size_t len, - talk_base::DiffServCodePoint dscp, + const talk_base::PacketOptions& options, int flags); virtual int SetOption(talk_base::Socket::Option opt, int value); virtual int GetError(); diff --git a/talk/p2p/base/turnport.cc b/talk/p2p/base/turnport.cc index eed7f8d0c8..988c29e0a7 100644 --- a/talk/p2p/base/turnport.cc +++ b/talk/p2p/base/turnport.cc @@ -153,7 +153,7 @@ class TurnEntry : public sigslot::has_slots<> { // Sends a packet to the given destination address. // This will wrap the packet in STUN if necessary. int Send(const void* data, size_t size, bool payload, - talk_base::DiffServCodePoint dscp); + const talk_base::PacketOptions& options); void OnCreatePermissionSuccess(); void OnCreatePermissionError(StunMessage* response, int code); @@ -332,7 +332,7 @@ int TurnPort::GetError() { int TurnPort::SendTo(const void* data, size_t size, const talk_base::SocketAddress& addr, - talk_base::DiffServCodePoint dscp, + const talk_base::PacketOptions& options, bool payload) { // Try to find an entry for this specific address; we should have one. TurnEntry* entry = FindEntry(addr); @@ -347,7 +347,7 @@ int TurnPort::SendTo(const void* data, size_t size, } // Send the actual contents to the server using the usual mechanism. - int sent = entry->Send(data, size, payload, dscp); + int sent = entry->Send(data, size, payload, options); if (sent <= 0) { return SOCKET_ERROR; } @@ -421,7 +421,8 @@ void TurnPort::OnResolveResult(talk_base::AsyncResolverInterface* resolver) { void TurnPort::OnSendStunPacket(const void* data, size_t size, StunRequest* request) { - if (Send(data, size, DefaultDscpValue()) < 0) { + talk_base::PacketOptions options(DefaultDscpValue()); + if (Send(data, size, options) < 0) { LOG_J(LS_ERROR, this) << "Failed to send TURN message, err=" << socket_->GetError(); } @@ -578,8 +579,8 @@ void TurnPort::AddRequestAuthInfo(StunMessage* msg) { } int TurnPort::Send(const void* data, size_t len, - talk_base::DiffServCodePoint dscp) { - return socket_->SendTo(data, len, server_address_.address, dscp); + const talk_base::PacketOptions& options) { + return socket_->SendTo(data, len, server_address_.address, options); } void TurnPort::UpdateHash() { @@ -912,7 +913,7 @@ void TurnEntry::SendChannelBindRequest(int delay) { } int TurnEntry::Send(const void* data, size_t size, bool payload, - talk_base::DiffServCodePoint dscp) { + const talk_base::PacketOptions& options) { talk_base::ByteBuffer buf; if (state_ != STATE_BOUND) { // If we haven't bound the channel yet, we have to use a Send Indication. @@ -937,7 +938,7 @@ int TurnEntry::Send(const void* data, size_t size, bool payload, buf.WriteUInt16(static_cast(size)); buf.WriteBytes(reinterpret_cast(data), size); } - return port_->Send(buf.Data(), buf.Length(), dscp); + return port_->Send(buf.Data(), buf.Length(), options); } void TurnEntry::OnCreatePermissionSuccess() { diff --git a/talk/p2p/base/turnport.h b/talk/p2p/base/turnport.h index e380a8912f..efec18bef9 100644 --- a/talk/p2p/base/turnport.h +++ b/talk/p2p/base/turnport.h @@ -74,7 +74,7 @@ class TurnPort : public Port { const Candidate& c, PortInterface::CandidateOrigin origin); virtual int SendTo(const void* data, size_t size, const talk_base::SocketAddress& addr, - talk_base::DiffServCodePoint dscp, + const talk_base::PacketOptions& options, bool payload); virtual int SetOption(talk_base::Socket::Option opt, int value); virtual int GetOption(talk_base::Socket::Option opt, int* value); @@ -145,7 +145,8 @@ class TurnPort : public Port { bool ScheduleRefresh(int lifetime); void SendRequest(StunRequest* request, int delay); - int Send(const void* data, size_t size, talk_base::DiffServCodePoint dscp); + int Send(const void* data, size_t size, + const talk_base::PacketOptions& options); void UpdateHash(); bool UpdateNonce(StunMessage* response); diff --git a/talk/p2p/base/turnport_unittest.cc b/talk/p2p/base/turnport_unittest.cc index e09c196e61..75ac6b5b9d 100644 --- a/talk/p2p/base/turnport_unittest.cc +++ b/talk/p2p/base/turnport_unittest.cc @@ -272,8 +272,8 @@ class TurnPortTest : public testing::Test, for (size_t j = 0; j < i + 1; ++j) { buf[j] = 0xFF - j; } - conn1->Send(buf, i + 1, talk_base::DSCP_NO_CHANGE); - conn2->Send(buf, i + 1, talk_base::DSCP_NO_CHANGE); + conn1->Send(buf, i + 1, options); + conn2->Send(buf, i + 1, options); main_->ProcessMessages(0); } @@ -305,6 +305,7 @@ class TurnPortTest : public testing::Test, bool test_finish_; std::vector turn_packets_; std::vector udp_packets_; + talk_base::PacketOptions options; }; // Do a normal TURN allocation. diff --git a/talk/p2p/base/turnserver.cc b/talk/p2p/base/turnserver.cc index 0bd903abe2..6595b2f75e 100644 --- a/talk/p2p/base/turnserver.cc +++ b/talk/p2p/base/turnserver.cc @@ -566,8 +566,8 @@ void TurnServer::SendStun(Connection* conn, StunMessage* msg) { void TurnServer::Send(Connection* conn, const talk_base::ByteBuffer& buf) { - conn->socket()->SendTo(buf.Data(), buf.Length(), conn->src(), - talk_base::DSCP_NO_CHANGE); + talk_base::PacketOptions options; + conn->socket()->SendTo(buf.Data(), buf.Length(), conn->src(), options); } void TurnServer::OnAllocationDestroyed(Allocation* allocation) { @@ -940,7 +940,8 @@ void TurnServer::Allocation::SendErrorResponse(const TurnMessage* req, int code, void TurnServer::Allocation::SendExternal(const void* data, size_t size, const talk_base::SocketAddress& peer) { - external_socket_->SendTo(data, size, peer, talk_base::DSCP_NO_CHANGE); + talk_base::PacketOptions options; + external_socket_->SendTo(data, size, peer, options); } void TurnServer::Allocation::OnMessage(talk_base::Message* msg) { diff --git a/talk/session/media/channel.cc b/talk/session/media/channel.cc index b177590b6f..6c0233f965 100644 --- a/talk/session/media/channel.cc +++ b/talk/session/media/channel.cc @@ -511,7 +511,8 @@ bool BaseChannel::SendPacket(bool rtcp, talk_base::Buffer* packet, } // Bon voyage. - int ret = channel->SendPacket(packet->data(), packet->length(), dscp, + talk_base::PacketOptions options(dscp); + int ret = channel->SendPacket(packet->data(), packet->length(), options, (secure() && secure_dtls()) ? PF_SRTP_BYPASS : 0); if (ret != static_cast(packet->length())) { if (channel->GetError() == EWOULDBLOCK) { diff --git a/talk/session/tunnel/pseudotcpchannel.cc b/talk/session/tunnel/pseudotcpchannel.cc index ee88797c1a..d95dc857d5 100644 --- a/talk/session/tunnel/pseudotcpchannel.cc +++ b/talk/session/tunnel/pseudotcpchannel.cc @@ -504,7 +504,8 @@ IPseudoTcpNotify::WriteResult PseudoTcpChannel::TcpWritePacket( ASSERT(cs_.CurrentThreadIsOwner()); ASSERT(tcp == tcp_); ASSERT(NULL != channel_); - int sent = channel_->SendPacket(buffer, len, talk_base::DSCP_NO_CHANGE); + talk_base::PacketOptions packet_options; + int sent = channel_->SendPacket(buffer, len, packet_options); if (sent > 0) { //LOG_F(LS_VERBOSE) << "(" << sent << ") Sent"; return IPseudoTcpNotify::WR_SUCCESS;