10e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org/* 20e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * libjingle 30e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * Copyright 2004--2006, Google Inc. 40e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * 50e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * Redistribution and use in source and binary forms, with or without 60e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * modification, are permitted provided that the following conditions are met: 70e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * 80e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * 1. Redistributions of source code must retain the above copyright notice, 90e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * this list of conditions and the following disclaimer. 100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * 2. Redistributions in binary form must reproduce the above copyright notice, 110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * this list of conditions and the following disclaimer in the documentation 120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * and/or other materials provided with the distribution. 130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * 3. The name of the author may not be used to endorse or promote products 140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * derived from this software without specific prior written permission. 150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * 160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org */ 270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include <string> 29cf81adffe15fa8ea0f333432e41f6d504148f18abuildbot@webrtc.org#include "pseudotcpchannel.h" 30cf81adffe15fa8ea0f333432e41f6d504148f18abuildbot@webrtc.org#include "talk/p2p/base/candidate.h" 31cf81adffe15fa8ea0f333432e41f6d504148f18abuildbot@webrtc.org#include "talk/p2p/base/transportchannel.h" 322a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/basictypes.h" 332a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/common.h" 342a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/logging.h" 352a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/scoped_ptr.h" 362a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/stringutils.h" 370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 382a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.orgusing namespace rtc; 390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgnamespace cricket { 410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 422a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.orgextern const rtc::ConstantLabel SESSION_STATES[]; 430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// MSG_WK_* - worker thread messages 450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// MSG_ST_* - stream thread messages 460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// MSG_SI_* - signal thread messages 470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgenum { 490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org MSG_WK_CLOCK = 1, 500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org MSG_WK_PURGE, 510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org MSG_ST_EVENT, 520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org MSG_SI_DESTROYCHANNEL, 530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org MSG_SI_DESTROY, 540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}; 550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgstruct EventData : public MessageData { 570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org int event, error; 580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org EventData(int ev, int err = 0) : event(ev), error(err) { } 590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}; 600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org/////////////////////////////////////////////////////////////////////////////// 620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// PseudoTcpChannel::InternalStream 630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org/////////////////////////////////////////////////////////////////////////////// 640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgclass PseudoTcpChannel::InternalStream : public StreamInterface { 660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgpublic: 670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org InternalStream(PseudoTcpChannel* parent); 680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org virtual ~InternalStream(); 690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org virtual StreamState GetState() const; 710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org virtual StreamResult Read(void* buffer, size_t buffer_len, 720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org size_t* read, int* error); 730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org virtual StreamResult Write(const void* data, size_t data_len, 740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org size_t* written, int* error); 750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org virtual void Close(); 760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgprivate: 780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // parent_ is accessed and modified exclusively on the event thread, to 790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // avoid thread contention. This means that the PseudoTcpChannel cannot go 800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // away until after it receives a Close() from TunnelStream. 810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org PseudoTcpChannel* parent_; 820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}; 830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org/////////////////////////////////////////////////////////////////////////////// 850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// PseudoTcpChannel 860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// Member object lifetime summaries: 870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// session_ - passed in constructor, cleared when channel_ goes away. 880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// channel_ - created in Connect, destroyed when session_ or tcp_ goes away. 890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// tcp_ - created in Connect, destroyed when channel_ goes away, or connection 900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// closes. 910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// worker_thread_ - created when channel_ is created, purged when channel_ is 920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// destroyed. 930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// stream_ - created in GetStream, destroyed by owner at arbitrary time. 940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// this - created in constructor, destroyed when worker_thread_ and stream_ 950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// are both gone. 960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org/////////////////////////////////////////////////////////////////////////////// 970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// 990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// Signal thread methods 1000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// 1010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgPseudoTcpChannel::PseudoTcpChannel(Thread* stream_thread, Session* session) 1030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org : signal_thread_(session->session_manager()->signaling_thread()), 1040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org worker_thread_(NULL), 1050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org stream_thread_(stream_thread), 1060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org session_(session), channel_(NULL), tcp_(NULL), stream_(NULL), 1070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org stream_readable_(false), pending_read_event_(false), 1080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ready_to_connect_(false) { 1090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(signal_thread_->IsCurrent()); 1100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(NULL != session_); 1110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 1120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgPseudoTcpChannel::~PseudoTcpChannel() { 1140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(signal_thread_->IsCurrent()); 1150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(worker_thread_ == NULL); 1160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(session_ == NULL); 1170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(channel_ == NULL); 1180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(stream_ == NULL); 1190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(tcp_ == NULL); 1200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 1210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool PseudoTcpChannel::Connect(const std::string& content_name, 1230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org const std::string& channel_name, 1240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org int component) { 1250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(signal_thread_->IsCurrent()); 1260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org CritScope lock(&cs_); 1270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (channel_) 1290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 1300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(session_ != NULL); 1320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org worker_thread_ = session_->session_manager()->worker_thread(); 1330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org content_name_ = content_name; 1340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org channel_ = session_->CreateChannel( 1350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org content_name, channel_name, component); 1360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org channel_name_ = channel_name; 1370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org channel_->SetOption(Socket::OPT_DONTFRAGMENT, 1); 1380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org channel_->SignalDestroyed.connect(this, 1400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org &PseudoTcpChannel::OnChannelDestroyed); 1410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org channel_->SignalWritableState.connect(this, 1420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org &PseudoTcpChannel::OnChannelWritableState); 1430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org channel_->SignalReadPacket.connect(this, 1440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org &PseudoTcpChannel::OnChannelRead); 1450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org channel_->SignalRouteChange.connect(this, 1460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org &PseudoTcpChannel::OnChannelConnectionChanged); 1470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(tcp_ == NULL); 1490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org tcp_ = new PseudoTcp(this, 0); 1500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (session_->initiator()) { 1510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Since we may try several protocols and network adapters that won't work, 1520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // waiting until we get our first writable notification before initiating 1530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // TCP negotiation. 1540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ready_to_connect_ = true; 1550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 1560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 1580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 1590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgStreamInterface* PseudoTcpChannel::GetStream() { 1610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(signal_thread_->IsCurrent()); 1620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org CritScope lock(&cs_); 1630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(NULL != session_); 1640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!stream_) 1650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org stream_ = new PseudoTcpChannel::InternalStream(this); 1660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org //TODO("should we disallow creation of new stream at some point?"); 1670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return stream_; 1680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 1690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid PseudoTcpChannel::OnChannelDestroyed(TransportChannel* channel) { 1710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG_F(LS_INFO) << "(" << channel->component() << ")"; 1720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(signal_thread_->IsCurrent()); 1730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org CritScope lock(&cs_); 1740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(channel == channel_); 1750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org signal_thread_->Clear(this, MSG_SI_DESTROYCHANNEL); 1760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // When MSG_WK_PURGE is received, we know there will be no more messages from 1770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // the worker thread. 1780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org worker_thread_->Clear(this, MSG_WK_CLOCK); 1790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org worker_thread_->Post(this, MSG_WK_PURGE); 1800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org session_ = NULL; 1810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org channel_ = NULL; 1820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if ((stream_ != NULL) 1830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org && ((tcp_ == NULL) || (tcp_->State() != PseudoTcp::TCP_CLOSED))) 1840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org stream_thread_->Post(this, MSG_ST_EVENT, new EventData(SE_CLOSE, 0)); 1850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (tcp_) { 1860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org tcp_->Close(true); 1870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org AdjustClock(); 1880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 1890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org SignalChannelClosed(this); 1900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 1910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid PseudoTcpChannel::OnSessionTerminate(Session* session) { 1930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // When the session terminates before we even connected 1940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org CritScope lock(&cs_); 1950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (session_ != NULL && channel_ == NULL) { 1960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(session == session_); 1970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(worker_thread_ == NULL); 1980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(tcp_ == NULL); 1990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_INFO) << "Destroying unconnected PseudoTcpChannel"; 2000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org session_ = NULL; 2010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (stream_ != NULL) 2020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org stream_thread_->Post(this, MSG_ST_EVENT, new EventData(SE_CLOSE, -1)); 2030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 2040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Even though session_ is being destroyed, we mustn't clear the pointer, 2060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // since we'll need it to tear down channel_. 2070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // 2080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // TODO: Is it always the case that if channel_ != NULL then we'll get 2090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // a channel-destroyed notification? 2100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 2110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid PseudoTcpChannel::GetOption(PseudoTcp::Option opt, int* value) { 2130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(signal_thread_->IsCurrent()); 2140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org CritScope lock(&cs_); 2150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(tcp_ != NULL); 2160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org tcp_->GetOption(opt, value); 2170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 2180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid PseudoTcpChannel::SetOption(PseudoTcp::Option opt, int value) { 2200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(signal_thread_->IsCurrent()); 2210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org CritScope lock(&cs_); 2220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(tcp_ != NULL); 2230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org tcp_->SetOption(opt, value); 2240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 2250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// 2270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// Stream thread methods 2280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// 2290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgStreamState PseudoTcpChannel::GetState() const { 2310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(stream_ != NULL && stream_thread_->IsCurrent()); 2320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org CritScope lock(&cs_); 2330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!session_) 2340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return SS_CLOSED; 2350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!tcp_) 2360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return SS_OPENING; 2370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org switch (tcp_->State()) { 2380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case PseudoTcp::TCP_LISTEN: 2390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case PseudoTcp::TCP_SYN_SENT: 2400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case PseudoTcp::TCP_SYN_RECEIVED: 2410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return SS_OPENING; 2420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case PseudoTcp::TCP_ESTABLISHED: 2430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return SS_OPEN; 2440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case PseudoTcp::TCP_CLOSED: 2450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org default: 2460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return SS_CLOSED; 2470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 2480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 2490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgStreamResult PseudoTcpChannel::Read(void* buffer, size_t buffer_len, 2510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org size_t* read, int* error) { 2520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(stream_ != NULL && stream_thread_->IsCurrent()); 2530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org CritScope lock(&cs_); 2540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!tcp_) 2550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return SR_BLOCK; 2560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org stream_readable_ = false; 2580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org int result = tcp_->Recv(static_cast<char*>(buffer), buffer_len); 2590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org //LOG_F(LS_VERBOSE) << "Recv returned: " << result; 2600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (result > 0) { 2610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (read) 2620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *read = result; 2630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // PseudoTcp doesn't currently support repeated Readable signals. Simulate 2640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // them here. 2650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org stream_readable_ = true; 2660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!pending_read_event_) { 2670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org pending_read_event_ = true; 2680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org stream_thread_->Post(this, MSG_ST_EVENT, new EventData(SE_READ), true); 2690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 2700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return SR_SUCCESS; 2710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else if (IsBlockingError(tcp_->GetError())) { 2720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return SR_BLOCK; 2730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else { 2740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (error) 2750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *error = tcp_->GetError(); 2760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return SR_ERROR; 2770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 2780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // This spot is never reached. 2790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 2800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgStreamResult PseudoTcpChannel::Write(const void* data, size_t data_len, 2820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org size_t* written, int* error) { 2830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(stream_ != NULL && stream_thread_->IsCurrent()); 2840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org CritScope lock(&cs_); 2850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!tcp_) 2860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return SR_BLOCK; 2870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org int result = tcp_->Send(static_cast<const char*>(data), data_len); 2880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org //LOG_F(LS_VERBOSE) << "Send returned: " << result; 2890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (result > 0) { 2900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (written) 2910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *written = result; 2920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return SR_SUCCESS; 2930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else if (IsBlockingError(tcp_->GetError())) { 2940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return SR_BLOCK; 2950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else { 2960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (error) 2970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *error = tcp_->GetError(); 2980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return SR_ERROR; 2990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 3000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // This spot is never reached. 3010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 3020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid PseudoTcpChannel::Close() { 3040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(stream_ != NULL && stream_thread_->IsCurrent()); 3050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org CritScope lock(&cs_); 3060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org stream_ = NULL; 3070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Clear out any pending event notifications 3080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org stream_thread_->Clear(this, MSG_ST_EVENT); 3090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (tcp_) { 3100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org tcp_->Close(false); 3110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org AdjustClock(); 3120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else { 3130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org CheckDestroy(); 3140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 3150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 3160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// 3180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// Worker thread methods 3190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// 3200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid PseudoTcpChannel::OnChannelWritableState(TransportChannel* channel) { 3220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG_F(LS_VERBOSE) << "[" << channel_name_ << "]"; 3230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(worker_thread_->IsCurrent()); 3240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org CritScope lock(&cs_); 3250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!channel_) { 3260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG_F(LS_WARNING) << "NULL channel"; 3270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return; 3280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 3290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(channel == channel_); 3300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!tcp_) { 3310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG_F(LS_WARNING) << "NULL tcp"; 3320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return; 3330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 3340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!ready_to_connect_ || !channel->writable()) 3350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return; 3360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ready_to_connect_ = false; 3380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org tcp_->Connect(); 3390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org AdjustClock(); 3400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 3410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid PseudoTcpChannel::OnChannelRead(TransportChannel* channel, 343f89a403cd8db88001322bbb0765c4636fd123700wu@webrtc.org const char* data, size_t size, 3442a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org const rtc::PacketTime& packet_time, 345f89a403cd8db88001322bbb0765c4636fd123700wu@webrtc.org int flags) { 3460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org //LOG_F(LS_VERBOSE) << "(" << size << ")"; 3470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(worker_thread_->IsCurrent()); 3480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org CritScope lock(&cs_); 3490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!channel_) { 3500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG_F(LS_WARNING) << "NULL channel"; 3510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return; 3520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 3530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(channel == channel_); 3540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!tcp_) { 3550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG_F(LS_WARNING) << "NULL tcp"; 3560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return; 3570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 3580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org tcp_->NotifyPacket(data, size); 3590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org AdjustClock(); 3600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 3610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid PseudoTcpChannel::OnChannelConnectionChanged(TransportChannel* channel, 3630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org const Candidate& candidate) { 3640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG_F(LS_VERBOSE) << "[" << channel_name_ << "]"; 3650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(worker_thread_->IsCurrent()); 3660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org CritScope lock(&cs_); 3670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!channel_) { 3680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG_F(LS_WARNING) << "NULL channel"; 3690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return; 3700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 3710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(channel == channel_); 3720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!tcp_) { 3730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG_F(LS_WARNING) << "NULL tcp"; 3740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return; 3750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 3760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org uint16 mtu = 1280; // safe default 3780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org int family = candidate.address().family(); 3790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org Socket* socket = 3800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org worker_thread_->socketserver()->CreateAsyncSocket(family, SOCK_DGRAM); 3812a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::scoped_ptr<Socket> mtu_socket(socket); 3820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (socket == NULL) { 3830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG_F(LS_WARNING) << "Couldn't create socket while estimating MTU."; 3840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else { 3850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (mtu_socket->Connect(candidate.address()) < 0 || 3860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org mtu_socket->EstimateMTU(&mtu) < 0) { 3870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG_F(LS_WARNING) << "Failed to estimate MTU, error=" 3880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org << mtu_socket->GetError(); 3890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 3900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 3910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG_F(LS_VERBOSE) << "Using MTU of " << mtu << " bytes"; 3930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org tcp_->NotifyMTU(mtu); 3940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org AdjustClock(); 3950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 3960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid PseudoTcpChannel::OnTcpOpen(PseudoTcp* tcp) { 3980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG_F(LS_VERBOSE) << "[" << channel_name_ << "]"; 3990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(cs_.CurrentThreadIsOwner()); 4000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(worker_thread_->IsCurrent()); 4010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(tcp == tcp_); 4020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (stream_) { 4030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org stream_readable_ = true; 4040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org pending_read_event_ = true; 4050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org stream_thread_->Post(this, MSG_ST_EVENT, 4060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org new EventData(SE_OPEN | SE_READ | SE_WRITE)); 4070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 4080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 4090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid PseudoTcpChannel::OnTcpReadable(PseudoTcp* tcp) { 4110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org //LOG_F(LS_VERBOSE); 4120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(cs_.CurrentThreadIsOwner()); 4130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(worker_thread_->IsCurrent()); 4140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(tcp == tcp_); 4150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (stream_) { 4160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org stream_readable_ = true; 4170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!pending_read_event_) { 4180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org pending_read_event_ = true; 4190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org stream_thread_->Post(this, MSG_ST_EVENT, new EventData(SE_READ)); 4200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 4210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 4220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 4230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid PseudoTcpChannel::OnTcpWriteable(PseudoTcp* tcp) { 4250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org //LOG_F(LS_VERBOSE); 4260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(cs_.CurrentThreadIsOwner()); 4270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(worker_thread_->IsCurrent()); 4280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(tcp == tcp_); 4290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (stream_) 4300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org stream_thread_->Post(this, MSG_ST_EVENT, new EventData(SE_WRITE)); 4310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 4320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid PseudoTcpChannel::OnTcpClosed(PseudoTcp* tcp, uint32 nError) { 4340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG_F(LS_VERBOSE) << "[" << channel_name_ << "]"; 4350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(cs_.CurrentThreadIsOwner()); 4360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(worker_thread_->IsCurrent()); 4370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(tcp == tcp_); 4380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (stream_) 4390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org stream_thread_->Post(this, MSG_ST_EVENT, new EventData(SE_CLOSE, nError)); 4400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 4410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// 4430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// Multi-thread methods 4440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// 4450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid PseudoTcpChannel::OnMessage(Message* pmsg) { 4470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (pmsg->message_id == MSG_WK_CLOCK) { 4480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(worker_thread_->IsCurrent()); 4500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org //LOG(LS_INFO) << "PseudoTcpChannel::OnMessage(MSG_WK_CLOCK)"; 4510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org CritScope lock(&cs_); 4520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (tcp_) { 4530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org tcp_->NotifyClock(PseudoTcp::Now()); 4540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org AdjustClock(false); 4550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 4560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else if (pmsg->message_id == MSG_WK_PURGE) { 4580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(worker_thread_->IsCurrent()); 4600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG_F(LS_INFO) << "(MSG_WK_PURGE)"; 4610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // At this point, we know there are no additional worker thread messages. 4620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org CritScope lock(&cs_); 4630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(NULL == session_); 4640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(NULL == channel_); 4650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org worker_thread_ = NULL; 4660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org CheckDestroy(); 4670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else if (pmsg->message_id == MSG_ST_EVENT) { 4690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(stream_thread_->IsCurrent()); 4710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org //LOG(LS_INFO) << "PseudoTcpChannel::OnMessage(MSG_ST_EVENT, " 4720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // << data->event << ", " << data->error << ")"; 4730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(stream_ != NULL); 4740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org EventData* data = static_cast<EventData*>(pmsg->pdata); 4750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (data->event & SE_READ) { 4760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org CritScope lock(&cs_); 4770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org pending_read_event_ = false; 4780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 4790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org stream_->SignalEvent(stream_, data->event, data->error); 4800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org delete data; 4810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else if (pmsg->message_id == MSG_SI_DESTROYCHANNEL) { 4830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(signal_thread_->IsCurrent()); 4850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG_F(LS_INFO) << "(MSG_SI_DESTROYCHANNEL)"; 4860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(session_ != NULL); 4870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(channel_ != NULL); 4880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org session_->DestroyChannel(content_name_, channel_->component()); 4890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else if (pmsg->message_id == MSG_SI_DESTROY) { 4910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(signal_thread_->IsCurrent()); 4930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG_F(LS_INFO) << "(MSG_SI_DESTROY)"; 4940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // The message queue is empty, so it is safe to destroy ourselves. 4950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org delete this; 4960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else { 4980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(false); 4990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 5000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 5010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 5020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgIPseudoTcpNotify::WriteResult PseudoTcpChannel::TcpWritePacket( 5030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org PseudoTcp* tcp, const char* buffer, size_t len) { 5040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(cs_.CurrentThreadIsOwner()); 5050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(tcp == tcp_); 5060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(NULL != channel_); 5072a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::PacketOptions packet_options; 508f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.org int sent = channel_->SendPacket(buffer, len, packet_options); 5090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (sent > 0) { 5100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org //LOG_F(LS_VERBOSE) << "(" << sent << ") Sent"; 5110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return IPseudoTcpNotify::WR_SUCCESS; 5120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else if (IsBlockingError(channel_->GetError())) { 5130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG_F(LS_VERBOSE) << "Blocking"; 5140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return IPseudoTcpNotify::WR_SUCCESS; 5150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else if (channel_->GetError() == EMSGSIZE) { 5160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG_F(LS_ERROR) << "EMSGSIZE"; 5170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return IPseudoTcpNotify::WR_TOO_LARGE; 5180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else { 5190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org PLOG(LS_ERROR, channel_->GetError()) << "PseudoTcpChannel::TcpWritePacket"; 5200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(false); 5210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return IPseudoTcpNotify::WR_FAIL; 5220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 5230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 5240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 5250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid PseudoTcpChannel::AdjustClock(bool clear) { 5260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(cs_.CurrentThreadIsOwner()); 5270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(NULL != tcp_); 5280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 5290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org long timeout = 0; 5300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (tcp_->GetNextClock(PseudoTcp::Now(), timeout)) { 5310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(NULL != channel_); 5320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Reset the next clock, by clearing the old and setting a new one. 5330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (clear) 5340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org worker_thread_->Clear(this, MSG_WK_CLOCK); 5350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org worker_thread_->PostDelayed(_max(timeout, 0L), this, MSG_WK_CLOCK); 5360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return; 5370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 5380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 5390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org delete tcp_; 5400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org tcp_ = NULL; 5410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ready_to_connect_ = false; 5420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 5430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (channel_) { 5440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // If TCP has failed, no need for channel_ anymore 5450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org signal_thread_->Post(this, MSG_SI_DESTROYCHANNEL); 5460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 5470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 5480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 5490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid PseudoTcpChannel::CheckDestroy() { 5500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(cs_.CurrentThreadIsOwner()); 5510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if ((worker_thread_ != NULL) || (stream_ != NULL)) 5520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return; 5530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org signal_thread_->Post(this, MSG_SI_DESTROY); 5540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 5550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 5560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org/////////////////////////////////////////////////////////////////////////////// 5570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// PseudoTcpChannel::InternalStream 5580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org/////////////////////////////////////////////////////////////////////////////// 5590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 5600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgPseudoTcpChannel::InternalStream::InternalStream(PseudoTcpChannel* parent) 5610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org : parent_(parent) { 5620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 5630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 5640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgPseudoTcpChannel::InternalStream::~InternalStream() { 5650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org Close(); 5660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 5670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 5680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgStreamState PseudoTcpChannel::InternalStream::GetState() const { 5690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!parent_) 5700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return SS_CLOSED; 5710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return parent_->GetState(); 5720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 5730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 5740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgStreamResult PseudoTcpChannel::InternalStream::Read( 5750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org void* buffer, size_t buffer_len, size_t* read, int* error) { 5760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!parent_) { 5770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (error) 5780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *error = ENOTCONN; 5790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return SR_ERROR; 5800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 5810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return parent_->Read(buffer, buffer_len, read, error); 5820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 5830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 5840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgStreamResult PseudoTcpChannel::InternalStream::Write( 5850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org const void* data, size_t data_len, size_t* written, int* error) { 5860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!parent_) { 5870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (error) 5880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *error = ENOTCONN; 5890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return SR_ERROR; 5900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 5910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return parent_->Write(data, data_len, written, error); 5920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 5930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 5940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid PseudoTcpChannel::InternalStream::Close() { 5950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!parent_) 5960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return; 5970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org parent_->Close(); 5980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org parent_ = NULL; 5990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 6000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 6010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org/////////////////////////////////////////////////////////////////////////////// 6020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 6030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} // namespace cricket 604