10e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org/* 20e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * libjingle 37ce0f9ed8df94129fddd70cdf0a53aa86d6b9d48fischman@webrtc.org * Copyright 2004, 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 "talk/p2p/base/transport.h" 290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include "talk/p2p/base/candidate.h" 310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include "talk/p2p/base/constants.h" 320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include "talk/p2p/base/parsing.h" 3358c89b128d6e4dbe00a9a18bb3029f63bd43ce6dmallinath@webrtc.org#include "talk/p2p/base/port.h" 34cf81adffe15fa8ea0f333432e41f6d504148f18abuildbot@webrtc.org#include "talk/p2p/base/sessionmanager.h" 350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include "talk/p2p/base/transportchannelimpl.h" 3613b2d035e2e7f2f18e3a4d3377bc1a09f43a4ff9buildbot@webrtc.org#include "webrtc/libjingle/xmllite/xmlelement.h" 370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include "talk/xmpp/constants.h" 38cf81adffe15fa8ea0f333432e41f6d504148f18abuildbot@webrtc.org#include "webrtc/base/bind.h" 39cf81adffe15fa8ea0f333432e41f6d504148f18abuildbot@webrtc.org#include "webrtc/base/common.h" 40cf81adffe15fa8ea0f333432e41f6d504148f18abuildbot@webrtc.org#include "webrtc/base/logging.h" 410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgnamespace cricket { 430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 442a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.orgusing rtc::Bind; 452007187dab65bb5d6f602355216534d6dd4ceaf2mallinath@webrtc.org 460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgenum { 472007187dab65bb5d6f602355216534d6dd4ceaf2mallinath@webrtc.org MSG_ONSIGNALINGREADY = 1, 482007187dab65bb5d6f602355216534d6dd4ceaf2mallinath@webrtc.org MSG_ONREMOTECANDIDATE, 492007187dab65bb5d6f602355216534d6dd4ceaf2mallinath@webrtc.org MSG_READSTATE, 502007187dab65bb5d6f602355216534d6dd4ceaf2mallinath@webrtc.org MSG_WRITESTATE, 512007187dab65bb5d6f602355216534d6dd4ceaf2mallinath@webrtc.org MSG_REQUESTSIGNALING, 522007187dab65bb5d6f602355216534d6dd4ceaf2mallinath@webrtc.org MSG_CANDIDATEREADY, 532007187dab65bb5d6f602355216534d6dd4ceaf2mallinath@webrtc.org MSG_ROUTECHANGE, 542007187dab65bb5d6f602355216534d6dd4ceaf2mallinath@webrtc.org MSG_CONNECTING, 552007187dab65bb5d6f602355216534d6dd4ceaf2mallinath@webrtc.org MSG_CANDIDATEALLOCATIONCOMPLETE, 562007187dab65bb5d6f602355216534d6dd4ceaf2mallinath@webrtc.org MSG_ROLECONFLICT, 57f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.org MSG_COMPLETED, 58f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.org MSG_FAILED, 590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}; 600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 612a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.orgstruct ChannelParams : public rtc::MessageData { 620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ChannelParams() : channel(NULL), candidate(NULL) {} 630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org explicit ChannelParams(int component) 640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org : component(component), channel(NULL), candidate(NULL) {} 650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org explicit ChannelParams(Candidate* candidate) 660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org : channel(NULL), candidate(candidate) { 670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ~ChannelParams() { 700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org delete candidate; 710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org std::string name; 740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org int component; 750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org TransportChannelImpl* channel; 760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org Candidate* candidate; 770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}; 780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 79f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.orgstatic std::string IceProtoToString(TransportProtocol proto) { 80f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org std::string proto_str; 81f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org switch (proto) { 82f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org case ICEPROTO_GOOGLE: 83f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org proto_str = "gice"; 84f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org break; 85f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org case ICEPROTO_HYBRID: 86f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org proto_str = "hybrid"; 87f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org break; 88f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org case ICEPROTO_RFC5245: 89f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org proto_str = "ice"; 90f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org break; 91f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org default: 92f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org ASSERT(false); 93f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org break; 94f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org } 95f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org return proto_str; 96f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org} 97f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org 983922cbc3a79d8ed6052eaeaf3e3f297096162f10buildbot@webrtc.orgstatic bool VerifyIceParams(const TransportDescription& desc) { 993922cbc3a79d8ed6052eaeaf3e3f297096162f10buildbot@webrtc.org // For legacy protocols. 1003922cbc3a79d8ed6052eaeaf3e3f297096162f10buildbot@webrtc.org if (desc.ice_ufrag.empty() && desc.ice_pwd.empty()) 1013922cbc3a79d8ed6052eaeaf3e3f297096162f10buildbot@webrtc.org return true; 1023922cbc3a79d8ed6052eaeaf3e3f297096162f10buildbot@webrtc.org 1033922cbc3a79d8ed6052eaeaf3e3f297096162f10buildbot@webrtc.org if (desc.ice_ufrag.length() < ICE_UFRAG_MIN_LENGTH || 1043922cbc3a79d8ed6052eaeaf3e3f297096162f10buildbot@webrtc.org desc.ice_ufrag.length() > ICE_UFRAG_MAX_LENGTH) { 1053922cbc3a79d8ed6052eaeaf3e3f297096162f10buildbot@webrtc.org return false; 1063922cbc3a79d8ed6052eaeaf3e3f297096162f10buildbot@webrtc.org } 1073922cbc3a79d8ed6052eaeaf3e3f297096162f10buildbot@webrtc.org if (desc.ice_pwd.length() < ICE_PWD_MIN_LENGTH || 1083922cbc3a79d8ed6052eaeaf3e3f297096162f10buildbot@webrtc.org desc.ice_pwd.length() > ICE_PWD_MAX_LENGTH) { 1093922cbc3a79d8ed6052eaeaf3e3f297096162f10buildbot@webrtc.org return false; 1103922cbc3a79d8ed6052eaeaf3e3f297096162f10buildbot@webrtc.org } 1113922cbc3a79d8ed6052eaeaf3e3f297096162f10buildbot@webrtc.org return true; 1123922cbc3a79d8ed6052eaeaf3e3f297096162f10buildbot@webrtc.org} 1133922cbc3a79d8ed6052eaeaf3e3f297096162f10buildbot@webrtc.org 114f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.orgbool BadTransportDescription(const std::string& desc, std::string* err_desc) { 115f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org if (err_desc) { 116f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org *err_desc = desc; 117f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org } 118f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org LOG(LS_ERROR) << desc; 119f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org return false; 120f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org} 121f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org 12239c443b6209621f0e8537e14514cc4c8b1dd5fadjiayl@webrtc.orgbool IceCredentialsChanged(const std::string& old_ufrag, 12339c443b6209621f0e8537e14514cc4c8b1dd5fadjiayl@webrtc.org const std::string& old_pwd, 12439c443b6209621f0e8537e14514cc4c8b1dd5fadjiayl@webrtc.org const std::string& new_ufrag, 12539c443b6209621f0e8537e14514cc4c8b1dd5fadjiayl@webrtc.org const std::string& new_pwd) { 12639c443b6209621f0e8537e14514cc4c8b1dd5fadjiayl@webrtc.org // TODO(jiayl): The standard (RFC 5245 Section 9.1.1.1) says that ICE should 12739c443b6209621f0e8537e14514cc4c8b1dd5fadjiayl@webrtc.org // restart when both the ufrag and password are changed, but we do restart 12839c443b6209621f0e8537e14514cc4c8b1dd5fadjiayl@webrtc.org // when either ufrag or passwrod is changed to keep compatible with GICE. We 12939c443b6209621f0e8537e14514cc4c8b1dd5fadjiayl@webrtc.org // should clean this up when GICE is no longer used. 13039c443b6209621f0e8537e14514cc4c8b1dd5fadjiayl@webrtc.org return (old_ufrag != new_ufrag) || (old_pwd != new_pwd); 13139c443b6209621f0e8537e14514cc4c8b1dd5fadjiayl@webrtc.org} 13239c443b6209621f0e8537e14514cc4c8b1dd5fadjiayl@webrtc.org 13339c443b6209621f0e8537e14514cc4c8b1dd5fadjiayl@webrtc.orgstatic bool IceCredentialsChanged(const TransportDescription& old_desc, 13439c443b6209621f0e8537e14514cc4c8b1dd5fadjiayl@webrtc.org const TransportDescription& new_desc) { 13539c443b6209621f0e8537e14514cc4c8b1dd5fadjiayl@webrtc.org return IceCredentialsChanged(old_desc.ice_ufrag, old_desc.ice_pwd, 13639c443b6209621f0e8537e14514cc4c8b1dd5fadjiayl@webrtc.org new_desc.ice_ufrag, new_desc.ice_pwd); 13739c443b6209621f0e8537e14514cc4c8b1dd5fadjiayl@webrtc.org} 13839c443b6209621f0e8537e14514cc4c8b1dd5fadjiayl@webrtc.org 1392a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.orgTransport::Transport(rtc::Thread* signaling_thread, 1402a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::Thread* worker_thread, 1410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org const std::string& content_name, 1420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org const std::string& type, 1430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org PortAllocator* allocator) 1440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org : signaling_thread_(signaling_thread), 1450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org worker_thread_(worker_thread), 1460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org content_name_(content_name), 1470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org type_(type), 1480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org allocator_(allocator), 1490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org destroyed_(false), 1500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org readable_(TRANSPORT_STATE_NONE), 1510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org writable_(TRANSPORT_STATE_NONE), 1520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org was_writable_(false), 1530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org connect_requested_(false), 154e560834da4ee5a5f38a96a8cb9290c5ce1096989mallinath@webrtc.org ice_role_(ICEROLE_UNKNOWN), 1550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org tiebreaker_(0), 1560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org protocol_(ICEPROTO_HYBRID), 1570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org remote_ice_mode_(ICEMODE_FULL) { 1580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 1590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgTransport::~Transport() { 1610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(signaling_thread_->IsCurrent()); 1620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(destroyed_); 1630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 1640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 165e560834da4ee5a5f38a96a8cb9290c5ce1096989mallinath@webrtc.orgvoid Transport::SetIceRole(IceRole role) { 1662007187dab65bb5d6f602355216534d6dd4ceaf2mallinath@webrtc.org worker_thread_->Invoke<void>(Bind(&Transport::SetIceRole_w, this, role)); 1670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 1680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1692a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.orgvoid Transport::SetIdentity(rtc::SSLIdentity* identity) { 1702007187dab65bb5d6f602355216534d6dd4ceaf2mallinath@webrtc.org worker_thread_->Invoke<void>(Bind(&Transport::SetIdentity_w, this, identity)); 1715aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org} 1725aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org 1732a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.orgbool Transport::GetIdentity(rtc::SSLIdentity** identity) { 17462fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org // The identity is set on the worker thread, so for safety it must also be 17562fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org // acquired on the worker thread. 17662fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org return worker_thread_->Invoke<bool>( 17762fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org Bind(&Transport::GetIdentity_w, this, identity)); 17862fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org} 17962fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org 1802a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.orgbool Transport::GetRemoteCertificate(rtc::SSLCertificate** cert) { 18162fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org // Channels can be deleted on the worker thread, so for safety the remote 18262fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org // certificate is acquired on the worker thread. 18362fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org return worker_thread_->Invoke<bool>( 18462fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org Bind(&Transport::GetRemoteCertificate_w, this, cert)); 18562fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org} 18662fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org 1872a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.orgbool Transport::GetRemoteCertificate_w(rtc::SSLCertificate** cert) { 18862fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org ASSERT(worker_thread()->IsCurrent()); 18962fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org if (channels_.empty()) 19062fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org return false; 19162fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org 19262fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org ChannelMap::iterator iter = channels_.begin(); 19362fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org return iter->second->GetRemoteCertificate(cert); 19462fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org} 19562fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org 1960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool Transport::SetLocalTransportDescription( 197f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org const TransportDescription& description, 198f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org ContentAction action, 199f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org std::string* error_desc) { 2002007187dab65bb5d6f602355216534d6dd4ceaf2mallinath@webrtc.org return worker_thread_->Invoke<bool>(Bind( 201f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org &Transport::SetLocalTransportDescription_w, this, 202f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org description, action, error_desc)); 2030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 2040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool Transport::SetRemoteTransportDescription( 206f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org const TransportDescription& description, 207f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org ContentAction action, 208f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org std::string* error_desc) { 2092007187dab65bb5d6f602355216534d6dd4ceaf2mallinath@webrtc.org return worker_thread_->Invoke<bool>(Bind( 210f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org &Transport::SetRemoteTransportDescription_w, this, 211f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org description, action, error_desc)); 2120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 2130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgTransportChannelImpl* Transport::CreateChannel(int component) { 2152007187dab65bb5d6f602355216534d6dd4ceaf2mallinath@webrtc.org return worker_thread_->Invoke<TransportChannelImpl*>(Bind( 2162007187dab65bb5d6f602355216534d6dd4ceaf2mallinath@webrtc.org &Transport::CreateChannel_w, this, component)); 2170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 2180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgTransportChannelImpl* Transport::CreateChannel_w(int component) { 2200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(worker_thread()->IsCurrent()); 2210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org TransportChannelImpl *impl; 2222a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::CritScope cs(&crit_); 2230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Create the entry if it does not exist. 2250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org bool impl_exists = false; 2260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (channels_.find(component) == channels_.end()) { 2270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org impl = CreateTransportChannel(component); 2280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org channels_[component] = ChannelMapEntry(impl); 2290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else { 2300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org impl = channels_[component].get(); 2310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org impl_exists = true; 2320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 2330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Increase the ref count. 2350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org channels_[component].AddRef(); 2360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org destroyed_ = false; 2370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (impl_exists) { 2390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // If this is an existing channel, we should just return it without 2400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // connecting to all the signal again. 2410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return impl; 2420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 2430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Push down our transport state to the new channel. 245e560834da4ee5a5f38a96a8cb9290c5ce1096989mallinath@webrtc.org impl->SetIceRole(ice_role_); 246e560834da4ee5a5f38a96a8cb9290c5ce1096989mallinath@webrtc.org impl->SetIceTiebreaker(tiebreaker_); 247b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org // TODO(ronghuawu): Change CreateChannel_w to be able to return error since 248b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org // below Apply**Description_w calls can fail. 249b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org if (local_description_) 250f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org ApplyLocalTransportDescription_w(impl, NULL); 251b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org if (remote_description_) 252b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org ApplyRemoteTransportDescription_w(impl, NULL); 253b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org if (local_description_ && remote_description_) 254b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org ApplyNegotiatedTransportDescription_w(impl, NULL); 2550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org impl->SignalReadableState.connect(this, &Transport::OnChannelReadableState); 2570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org impl->SignalWritableState.connect(this, &Transport::OnChannelWritableState); 2580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org impl->SignalRequestSignaling.connect( 2590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org this, &Transport::OnChannelRequestSignaling); 2600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org impl->SignalCandidateReady.connect(this, &Transport::OnChannelCandidateReady); 2610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org impl->SignalRouteChange.connect(this, &Transport::OnChannelRouteChange); 2620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org impl->SignalCandidatesAllocationDone.connect( 2630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org this, &Transport::OnChannelCandidatesAllocationDone); 2640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org impl->SignalRoleConflict.connect(this, &Transport::OnRoleConflict); 265f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.org impl->SignalConnectionRemoved.connect( 266f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.org this, &Transport::OnChannelConnectionRemoved); 2670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (connect_requested_) { 2690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org impl->Connect(); 2700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (channels_.size() == 1) { 2710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // If this is the first channel, then indicate that we have started 2720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // connecting. 2730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org signaling_thread()->Post(this, MSG_CONNECTING, NULL); 2740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 2750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 2760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return impl; 2770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 2780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgTransportChannelImpl* Transport::GetChannel(int component) { 2802a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::CritScope cs(&crit_); 2810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ChannelMap::iterator iter = channels_.find(component); 2820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return (iter != channels_.end()) ? iter->second.get() : NULL; 2830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 2840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool Transport::HasChannels() { 2862a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::CritScope cs(&crit_); 2870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return !channels_.empty(); 2880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 2890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid Transport::DestroyChannel(int component) { 2912007187dab65bb5d6f602355216534d6dd4ceaf2mallinath@webrtc.org worker_thread_->Invoke<void>(Bind( 2922007187dab65bb5d6f602355216534d6dd4ceaf2mallinath@webrtc.org &Transport::DestroyChannel_w, this, component)); 2930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 2940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid Transport::DestroyChannel_w(int component) { 2960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(worker_thread()->IsCurrent()); 2970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org TransportChannelImpl* impl = NULL; 2990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org { 3002a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::CritScope cs(&crit_); 3010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ChannelMap::iterator iter = channels_.find(component); 3020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (iter == channels_.end()) 3030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return; 3040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org iter->second.DecRef(); 3060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!iter->second.ref()) { 3070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org impl = iter->second.get(); 3080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org channels_.erase(iter); 3090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 3100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 3110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (connect_requested_ && channels_.empty()) { 3130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // We're no longer attempting to connect. 3140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org signaling_thread()->Post(this, MSG_CONNECTING, NULL); 3150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 3160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (impl) { 3180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Check in case the deleted channel was the only non-writable channel. 3190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org OnChannelWritableState(impl); 3200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org DestroyTransportChannel(impl); 3210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 3220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 3230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid Transport::ConnectChannels() { 3250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(signaling_thread()->IsCurrent()); 3262007187dab65bb5d6f602355216534d6dd4ceaf2mallinath@webrtc.org worker_thread_->Invoke<void>(Bind(&Transport::ConnectChannels_w, this)); 3270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 3280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid Transport::ConnectChannels_w() { 3300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(worker_thread()->IsCurrent()); 3310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (connect_requested_ || channels_.empty()) 3320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return; 3330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org connect_requested_ = true; 3340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org signaling_thread()->Post( 3350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org this, MSG_CANDIDATEREADY, NULL); 3360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!local_description_) { 3380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // TOOD(mallinath) : TransportDescription(TD) shouldn't be generated here. 3390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // As Transport must know TD is offer or answer and cricket::Transport 3400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // doesn't have the capability to decide it. This should be set by the 3410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Session. 3420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Session must generate local TD before remote candidates pushed when 3430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // initiate request initiated by the remote. 3440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_INFO) << "Transport::ConnectChannels_w: No local description has " 3450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org << "been set. Will generate one."; 3460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org TransportDescription desc(NS_GINGLE_P2P, std::vector<std::string>(), 3472a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::CreateRandomString(ICE_UFRAG_LENGTH), 3482a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::CreateRandomString(ICE_PWD_LENGTH), 349a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org ICEMODE_FULL, CONNECTIONROLE_NONE, NULL, 350a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org Candidates()); 351f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org SetLocalTransportDescription_w(desc, CA_OFFER, NULL); 3520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 3530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org CallChannels_w(&TransportChannelImpl::Connect); 3550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!channels_.empty()) { 3560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org signaling_thread()->Post(this, MSG_CONNECTING, NULL); 3570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 3580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 3590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid Transport::OnConnecting_s() { 3610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(signaling_thread()->IsCurrent()); 3620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org SignalConnecting(this); 3630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 3640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid Transport::DestroyAllChannels() { 3660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(signaling_thread()->IsCurrent()); 3672007187dab65bb5d6f602355216534d6dd4ceaf2mallinath@webrtc.org worker_thread_->Invoke<void>( 3682007187dab65bb5d6f602355216534d6dd4ceaf2mallinath@webrtc.org Bind(&Transport::DestroyAllChannels_w, this)); 3690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org worker_thread()->Clear(this); 3700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org signaling_thread()->Clear(this); 3710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org destroyed_ = true; 3720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 3730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid Transport::DestroyAllChannels_w() { 3750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(worker_thread()->IsCurrent()); 3760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org std::vector<TransportChannelImpl*> impls; 3770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org { 3782a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::CritScope cs(&crit_); 3790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org for (ChannelMap::iterator iter = channels_.begin(); 3800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org iter != channels_.end(); 3810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ++iter) { 3820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org iter->second.DecRef(); 3830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!iter->second.ref()) 3840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org impls.push_back(iter->second.get()); 3850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 3860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 3870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org channels_.clear(); 3880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org for (size_t i = 0; i < impls.size(); ++i) 3910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org DestroyTransportChannel(impls[i]); 3920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 3930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid Transport::ResetChannels() { 3950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(signaling_thread()->IsCurrent()); 3962007187dab65bb5d6f602355216534d6dd4ceaf2mallinath@webrtc.org worker_thread_->Invoke<void>(Bind(&Transport::ResetChannels_w, this)); 3970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 3980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid Transport::ResetChannels_w() { 4000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(worker_thread()->IsCurrent()); 4010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // We are no longer attempting to connect 4030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org connect_requested_ = false; 4040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Clear out the old messages, they aren't relevant 4062a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::CritScope cs(&crit_); 4070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ready_candidates_.clear(); 4080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Reset all of the channels 4100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org CallChannels_w(&TransportChannelImpl::Reset); 4110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 4120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid Transport::OnSignalingReady() { 4140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(signaling_thread()->IsCurrent()); 4150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (destroyed_) return; 4160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org worker_thread()->Post(this, MSG_ONSIGNALINGREADY, NULL); 4180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Notify the subclass. 4200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org OnTransportSignalingReady(); 4210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 4220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid Transport::CallChannels_w(TransportChannelFunc func) { 4240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(worker_thread()->IsCurrent()); 4252a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::CritScope cs(&crit_); 4260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org for (ChannelMap::iterator iter = channels_.begin(); 4270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org iter != channels_.end(); 4280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ++iter) { 4290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ((iter->second.get())->*func)(); 4300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 4310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 4320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool Transport::VerifyCandidate(const Candidate& cand, std::string* error) { 4340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // No address zero. 4350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (cand.address().IsNil() || cand.address().IsAny()) { 4360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *error = "candidate has address of zero"; 4370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 4380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 4390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Disallow all ports below 1024, except for 80 and 443 on public addresses. 4410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org int port = cand.address().port(); 44258c89b128d6e4dbe00a9a18bb3029f63bd43ce6dmallinath@webrtc.org if (cand.protocol() == TCP_PROTOCOL_NAME && 44358c89b128d6e4dbe00a9a18bb3029f63bd43ce6dmallinath@webrtc.org (cand.tcptype() == TCPTYPE_ACTIVE_STR || port == 0)) { 4447ce0f9ed8df94129fddd70cdf0a53aa86d6b9d48fischman@webrtc.org // Expected for active-only candidates per 4457ce0f9ed8df94129fddd70cdf0a53aa86d6b9d48fischman@webrtc.org // http://tools.ietf.org/html/rfc6544#section-4.5 so no error. 44658c89b128d6e4dbe00a9a18bb3029f63bd43ce6dmallinath@webrtc.org // Libjingle clients emit port 0, in "active" mode. 44758c89b128d6e4dbe00a9a18bb3029f63bd43ce6dmallinath@webrtc.org return true; 4487ce0f9ed8df94129fddd70cdf0a53aa86d6b9d48fischman@webrtc.org } 4490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (port < 1024) { 4500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if ((port != 80) && (port != 443)) { 4510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *error = "candidate has port below 1024, but not 80 or 443"; 4520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 4530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 4540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (cand.address().IsPrivateIP()) { 4560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *error = "candidate has port of 80 or 443 with private IP address"; 4570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 4580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 4590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 4600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 4620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 4630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool Transport::GetStats(TransportStats* stats) { 4660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(signaling_thread()->IsCurrent()); 4672007187dab65bb5d6f602355216534d6dd4ceaf2mallinath@webrtc.org return worker_thread_->Invoke<bool>(Bind( 4682007187dab65bb5d6f602355216534d6dd4ceaf2mallinath@webrtc.org &Transport::GetStats_w, this, stats)); 4690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 4700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool Transport::GetStats_w(TransportStats* stats) { 4720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(worker_thread()->IsCurrent()); 4730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org stats->content_name = content_name(); 4740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org stats->channel_stats.clear(); 4750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org for (ChannelMap::iterator iter = channels_.begin(); 4760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org iter != channels_.end(); 4770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ++iter) { 4780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org TransportChannelStats substats; 4790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org substats.component = iter->second->component(); 4800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!iter->second->GetStats(&substats.connection_infos)) { 4810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 4820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 4830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org stats->channel_stats.push_back(substats); 4840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 4850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 4860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 4870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4882a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.orgbool Transport::GetSslRole(rtc::SSLRole* ssl_role) const { 4892007187dab65bb5d6f602355216534d6dd4ceaf2mallinath@webrtc.org return worker_thread_->Invoke<bool>(Bind( 4902007187dab65bb5d6f602355216534d6dd4ceaf2mallinath@webrtc.org &Transport::GetSslRole_w, this, ssl_role)); 491a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org} 492a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org 4930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid Transport::OnRemoteCandidates(const std::vector<Candidate>& candidates) { 4940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org for (std::vector<Candidate>::const_iterator iter = candidates.begin(); 4950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org iter != candidates.end(); 4960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ++iter) { 4970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org OnRemoteCandidate(*iter); 4980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 4990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 5000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 5010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid Transport::OnRemoteCandidate(const Candidate& candidate) { 5020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(signaling_thread()->IsCurrent()); 5030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (destroyed_) return; 5040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 5050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!HasChannel(candidate.component())) { 5060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_WARNING) << "Ignoring candidate for unknown component " 5070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org << candidate.component(); 5080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return; 5090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 5100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 5110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ChannelParams* params = new ChannelParams(new Candidate(candidate)); 5120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org worker_thread()->Post(this, MSG_ONREMOTECANDIDATE, params); 5130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 5140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 5150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid Transport::OnRemoteCandidate_w(const Candidate& candidate) { 5160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(worker_thread()->IsCurrent()); 5170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ChannelMap::iterator iter = channels_.find(candidate.component()); 5180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // It's ok for a channel to go away while this message is in transit. 5190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (iter != channels_.end()) { 5200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org iter->second->OnCandidate(candidate); 5210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 5220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 5230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 5240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid Transport::OnChannelReadableState(TransportChannel* channel) { 5250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(worker_thread()->IsCurrent()); 5260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org signaling_thread()->Post(this, MSG_READSTATE, NULL); 5270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 5280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 5290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid Transport::OnChannelReadableState_s() { 5300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(signaling_thread()->IsCurrent()); 5310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org TransportState readable = GetTransportState_s(true); 5320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (readable_ != readable) { 5330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org readable_ = readable; 5340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org SignalReadableState(this); 5350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 5360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 5370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 5380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid Transport::OnChannelWritableState(TransportChannel* channel) { 5390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(worker_thread()->IsCurrent()); 5400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org signaling_thread()->Post(this, MSG_WRITESTATE, NULL); 541b1ad2cd39fca8ea62e7dc512e788a414b328db7dhenrike@webrtc.org 542b1ad2cd39fca8ea62e7dc512e788a414b328db7dhenrike@webrtc.org MaybeCompleted_w(); 5430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 5440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 5450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid Transport::OnChannelWritableState_s() { 5460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(signaling_thread()->IsCurrent()); 5470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org TransportState writable = GetTransportState_s(false); 5480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (writable_ != writable) { 5490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org was_writable_ = (writable_ == TRANSPORT_STATE_ALL); 5500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org writable_ = writable; 5510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org SignalWritableState(this); 5520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 5530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 5540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 5550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgTransportState Transport::GetTransportState_s(bool read) { 5560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(signaling_thread()->IsCurrent()); 5572a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::CritScope cs(&crit_); 5580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org bool any = false; 5590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org bool all = !channels_.empty(); 5600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org for (ChannelMap::iterator iter = channels_.begin(); 5610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org iter != channels_.end(); 5620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ++iter) { 5630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org bool b = (read ? iter->second->readable() : 5640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org iter->second->writable()); 5650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org any = any || b; 5660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org all = all && b; 5670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 5680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (all) { 5690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return TRANSPORT_STATE_ALL; 5700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else if (any) { 5710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return TRANSPORT_STATE_SOME; 5720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else { 5730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return TRANSPORT_STATE_NONE; 5740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 5750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 5760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 5770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid Transport::OnChannelRequestSignaling(TransportChannelImpl* channel) { 5780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(worker_thread()->IsCurrent()); 5790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ChannelParams* params = new ChannelParams(channel->component()); 5800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org signaling_thread()->Post(this, MSG_REQUESTSIGNALING, params); 5810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 5820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 5830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid Transport::OnChannelRequestSignaling_s(int component) { 5840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(signaling_thread()->IsCurrent()); 5850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_INFO) << "Transport: " << content_name_ << ", allocating candidates"; 5860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Resetting ICE state for the channel. 5870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org { 5882a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::CritScope cs(&crit_); 5890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ChannelMap::iterator iter = channels_.find(component); 5900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (iter != channels_.end()) 5910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org iter->second.set_candidates_allocated(false); 5920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 5930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org SignalRequestSignaling(this); 5940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 5950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 5960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid Transport::OnChannelCandidateReady(TransportChannelImpl* channel, 5970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org const Candidate& candidate) { 5980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(worker_thread()->IsCurrent()); 5992a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::CritScope cs(&crit_); 6000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ready_candidates_.push_back(candidate); 6010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 6020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // We hold any messages until the client lets us connect. 6030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (connect_requested_) { 6040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org signaling_thread()->Post( 6050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org this, MSG_CANDIDATEREADY, NULL); 6060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 6070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 6080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 6090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid Transport::OnChannelCandidateReady_s() { 6100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(signaling_thread()->IsCurrent()); 6110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(connect_requested_); 6120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 6130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org std::vector<Candidate> candidates; 6140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org { 6152a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::CritScope cs(&crit_); 6160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org candidates.swap(ready_candidates_); 6170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 6180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 6190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // we do the deleting of Candidate* here to keep the new above and 6200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // delete below close to each other 6210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!candidates.empty()) { 6220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org SignalCandidatesReady(this, candidates); 6230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 6240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 6250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 6260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid Transport::OnChannelRouteChange(TransportChannel* channel, 6270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org const Candidate& remote_candidate) { 6280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(worker_thread()->IsCurrent()); 6290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ChannelParams* params = new ChannelParams(new Candidate(remote_candidate)); 6300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org params->channel = static_cast<cricket::TransportChannelImpl*>(channel); 6310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org signaling_thread()->Post(this, MSG_ROUTECHANGE, params); 6320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 6330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 6340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid Transport::OnChannelRouteChange_s(const TransportChannel* channel, 6350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org const Candidate& remote_candidate) { 6360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(signaling_thread()->IsCurrent()); 6370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org SignalRouteChange(this, remote_candidate.component(), remote_candidate); 6380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 6390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 6400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid Transport::OnChannelCandidatesAllocationDone( 6410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org TransportChannelImpl* channel) { 6420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(worker_thread()->IsCurrent()); 6432a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::CritScope cs(&crit_); 6440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ChannelMap::iterator iter = channels_.find(channel->component()); 6450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(iter != channels_.end()); 6460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_INFO) << "Transport: " << content_name_ << ", component " 6470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org << channel->component() << " allocation complete"; 6480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org iter->second.set_candidates_allocated(true); 6490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 6500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // If all channels belonging to this Transport got signal, then 6510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // forward this signal to upper layer. 6520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Can this signal arrive before all transport channels are created? 6530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org for (iter = channels_.begin(); iter != channels_.end(); ++iter) { 6540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!iter->second.candidates_allocated()) 6550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return; 6560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 6570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org signaling_thread_->Post(this, MSG_CANDIDATEALLOCATIONCOMPLETE); 658b1ad2cd39fca8ea62e7dc512e788a414b328db7dhenrike@webrtc.org 659b1ad2cd39fca8ea62e7dc512e788a414b328db7dhenrike@webrtc.org MaybeCompleted_w(); 6600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 6610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 6620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid Transport::OnChannelCandidatesAllocationDone_s() { 6630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(signaling_thread()->IsCurrent()); 6640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_INFO) << "Transport: " << content_name_ << " allocation complete"; 6650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org SignalCandidatesAllocationDone(this); 6660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 6670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 6680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid Transport::OnRoleConflict(TransportChannelImpl* channel) { 6690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org signaling_thread_->Post(this, MSG_ROLECONFLICT); 6700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 6710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 672f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.orgvoid Transport::OnChannelConnectionRemoved(TransportChannelImpl* channel) { 673f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.org ASSERT(worker_thread()->IsCurrent()); 674b1ad2cd39fca8ea62e7dc512e788a414b328db7dhenrike@webrtc.org MaybeCompleted_w(); 675b1ad2cd39fca8ea62e7dc512e788a414b328db7dhenrike@webrtc.org 676b1ad2cd39fca8ea62e7dc512e788a414b328db7dhenrike@webrtc.org // Check if the state is now Failed. 677b1ad2cd39fca8ea62e7dc512e788a414b328db7dhenrike@webrtc.org // Failed is only available in the Controlling ICE role. 678f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.org if (channel->GetIceRole() != ICEROLE_CONTROLLING) { 679f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.org return; 680f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.org } 681f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.org 682f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.org ChannelMap::iterator iter = channels_.find(channel->component()); 683f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.org ASSERT(iter != channels_.end()); 684b1ad2cd39fca8ea62e7dc512e788a414b328db7dhenrike@webrtc.org // Failed can only occur after candidate allocation has stopped. 685f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.org if (!iter->second.candidates_allocated()) { 686f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.org return; 687f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.org } 688f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.org 689f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.org size_t connections = channel->GetConnectionCount(); 690f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.org if (connections == 0) { 691f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.org // A Transport has failed if any of its channels have no remaining 692f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.org // connections. 693f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.org signaling_thread_->Post(this, MSG_FAILED); 694f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.org } 695f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.org} 696f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.org 697b1ad2cd39fca8ea62e7dc512e788a414b328db7dhenrike@webrtc.orgvoid Transport::MaybeCompleted_w() { 698b1ad2cd39fca8ea62e7dc512e788a414b328db7dhenrike@webrtc.org ASSERT(worker_thread()->IsCurrent()); 699b1ad2cd39fca8ea62e7dc512e788a414b328db7dhenrike@webrtc.org 700f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.org // A Transport's ICE process is completed if all of its channels are writable, 701f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.org // have finished allocating candidates, and have pruned all but one of their 702f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.org // connections. 703f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.org ChannelMap::const_iterator iter; 704f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.org for (iter = channels_.begin(); iter != channels_.end(); ++iter) { 705f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.org const TransportChannelImpl* channel = iter->second.get(); 706b1ad2cd39fca8ea62e7dc512e788a414b328db7dhenrike@webrtc.org if (!(channel->writable() && 707b1ad2cd39fca8ea62e7dc512e788a414b328db7dhenrike@webrtc.org channel->GetConnectionCount() == 1 && 708f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.org channel->GetIceRole() == ICEROLE_CONTROLLING && 709f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.org iter->second.candidates_allocated())) { 710b1ad2cd39fca8ea62e7dc512e788a414b328db7dhenrike@webrtc.org return; 711f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.org } 712f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.org } 713b1ad2cd39fca8ea62e7dc512e788a414b328db7dhenrike@webrtc.org 714b1ad2cd39fca8ea62e7dc512e788a414b328db7dhenrike@webrtc.org signaling_thread_->Post(this, MSG_COMPLETED); 715f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.org} 716f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.org 717e560834da4ee5a5f38a96a8cb9290c5ce1096989mallinath@webrtc.orgvoid Transport::SetIceRole_w(IceRole role) { 7182a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::CritScope cs(&crit_); 719e560834da4ee5a5f38a96a8cb9290c5ce1096989mallinath@webrtc.org ice_role_ = role; 7200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org for (ChannelMap::iterator iter = channels_.begin(); 7210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org iter != channels_.end(); ++iter) { 722e560834da4ee5a5f38a96a8cb9290c5ce1096989mallinath@webrtc.org iter->second->SetIceRole(ice_role_); 7230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 7240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 7250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 7260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid Transport::SetRemoteIceMode_w(IceMode mode) { 7272a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::CritScope cs(&crit_); 7280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org remote_ice_mode_ = mode; 7290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Shouldn't channels be created after this method executed? 7300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org for (ChannelMap::iterator iter = channels_.begin(); 7310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org iter != channels_.end(); ++iter) { 7320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org iter->second->SetRemoteIceMode(remote_ice_mode_); 7330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 7340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 7350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 7360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool Transport::SetLocalTransportDescription_w( 737f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org const TransportDescription& desc, 738f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org ContentAction action, 739f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org std::string* error_desc) { 7400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org bool ret = true; 7412a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::CritScope cs(&crit_); 7420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 7433922cbc3a79d8ed6052eaeaf3e3f297096162f10buildbot@webrtc.org if (!VerifyIceParams(desc)) { 7443922cbc3a79d8ed6052eaeaf3e3f297096162f10buildbot@webrtc.org return BadTransportDescription("Invalid ice-ufrag or ice-pwd length", 7453922cbc3a79d8ed6052eaeaf3e3f297096162f10buildbot@webrtc.org error_desc); 7463922cbc3a79d8ed6052eaeaf3e3f297096162f10buildbot@webrtc.org } 7473922cbc3a79d8ed6052eaeaf3e3f297096162f10buildbot@webrtc.org 74839c443b6209621f0e8537e14514cc4c8b1dd5fadjiayl@webrtc.org if (local_description_ && IceCredentialsChanged(*local_description_, desc)) { 74939c443b6209621f0e8537e14514cc4c8b1dd5fadjiayl@webrtc.org IceRole new_ice_role = (action == CA_OFFER) ? ICEROLE_CONTROLLING 75039c443b6209621f0e8537e14514cc4c8b1dd5fadjiayl@webrtc.org : ICEROLE_CONTROLLED; 75139c443b6209621f0e8537e14514cc4c8b1dd5fadjiayl@webrtc.org 75239c443b6209621f0e8537e14514cc4c8b1dd5fadjiayl@webrtc.org // It must be called before ApplyLocalTransportDescription_w, which may 75339c443b6209621f0e8537e14514cc4c8b1dd5fadjiayl@webrtc.org // trigger an ICE restart and depends on the new ICE role. 75439c443b6209621f0e8537e14514cc4c8b1dd5fadjiayl@webrtc.org SetIceRole_w(new_ice_role); 75539c443b6209621f0e8537e14514cc4c8b1dd5fadjiayl@webrtc.org } 75639c443b6209621f0e8537e14514cc4c8b1dd5fadjiayl@webrtc.org 7573922cbc3a79d8ed6052eaeaf3e3f297096162f10buildbot@webrtc.org local_description_.reset(new TransportDescription(desc)); 75839c443b6209621f0e8537e14514cc4c8b1dd5fadjiayl@webrtc.org 7590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org for (ChannelMap::iterator iter = channels_.begin(); 7600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org iter != channels_.end(); ++iter) { 761f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org ret &= ApplyLocalTransportDescription_w(iter->second.get(), error_desc); 7620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 7630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!ret) 7640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 7650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 7660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // If PRANSWER/ANSWER is set, we should decide transport protocol type. 7670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (action == CA_PRANSWER || action == CA_ANSWER) { 768f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org ret &= NegotiateTransportDescription_w(action, error_desc); 7690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 7700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return ret; 7710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 7720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 7730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool Transport::SetRemoteTransportDescription_w( 774f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org const TransportDescription& desc, 775f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org ContentAction action, 776f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org std::string* error_desc) { 7770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org bool ret = true; 7782a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::CritScope cs(&crit_); 7790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 7803922cbc3a79d8ed6052eaeaf3e3f297096162f10buildbot@webrtc.org if (!VerifyIceParams(desc)) { 7813922cbc3a79d8ed6052eaeaf3e3f297096162f10buildbot@webrtc.org return BadTransportDescription("Invalid ice-ufrag or ice-pwd length", 7823922cbc3a79d8ed6052eaeaf3e3f297096162f10buildbot@webrtc.org error_desc); 7833922cbc3a79d8ed6052eaeaf3e3f297096162f10buildbot@webrtc.org } 7843922cbc3a79d8ed6052eaeaf3e3f297096162f10buildbot@webrtc.org 7853922cbc3a79d8ed6052eaeaf3e3f297096162f10buildbot@webrtc.org remote_description_.reset(new TransportDescription(desc)); 7860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org for (ChannelMap::iterator iter = channels_.begin(); 7870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org iter != channels_.end(); ++iter) { 788f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org ret &= ApplyRemoteTransportDescription_w(iter->second.get(), error_desc); 7890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 7900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 7910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // If PRANSWER/ANSWER is set, we should decide transport protocol type. 7920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (action == CA_PRANSWER || action == CA_ANSWER) { 793f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org ret = NegotiateTransportDescription_w(CA_OFFER, error_desc); 7940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 7950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return ret; 7960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 7970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 798f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.orgbool Transport::ApplyLocalTransportDescription_w(TransportChannelImpl* ch, 799f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org std::string* error_desc) { 800b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org // If existing protocol_type is HYBRID, we may have not chosen the final 801b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org // protocol type, so update the channel protocol type from the 802b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org // local description. Otherwise, skip updating the protocol type. 803b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org // We check for HYBRID to avoid accidental changes; in the case of a 804b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org // session renegotiation, the new offer will have the google-ice ICE option, 805b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org // so we need to make sure we don't switch back from ICE mode to HYBRID 806b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org // when this happens. 807b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org // There are some other ways we could have solved this, but this is the 808b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org // simplest. The ultimate solution will be to get rid of GICE altogether. 809b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org IceProtocolType protocol_type; 810b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org if (ch->GetIceProtocolType(&protocol_type) && 811b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org protocol_type == ICEPROTO_HYBRID) { 812b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org ch->SetIceProtocolType( 813b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org TransportProtocolFromDescription(local_description())); 814b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org } 8150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ch->SetIceCredentials(local_description_->ice_ufrag, 8160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org local_description_->ice_pwd); 8170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 8180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 8190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 820f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.orgbool Transport::ApplyRemoteTransportDescription_w(TransportChannelImpl* ch, 821f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org std::string* error_desc) { 8220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ch->SetRemoteIceCredentials(remote_description_->ice_ufrag, 8230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org remote_description_->ice_pwd); 8240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 8250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 8260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 827a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.orgbool Transport::ApplyNegotiatedTransportDescription_w( 828f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org TransportChannelImpl* channel, std::string* error_desc) { 8290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org channel->SetIceProtocolType(protocol_); 8300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org channel->SetRemoteIceMode(remote_ice_mode_); 831a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org return true; 8320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 8330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 834f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.orgbool Transport::NegotiateTransportDescription_w(ContentAction local_role, 835f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org std::string* error_desc) { 8360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // TODO(ekr@rtfm.com): This is ICE-specific stuff. Refactor into 8370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // P2PTransport. 8380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org const TransportDescription* offer; 8390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org const TransportDescription* answer; 8400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 841a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org if (local_role == CA_OFFER) { 8420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org offer = local_description_.get(); 8430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org answer = remote_description_.get(); 8440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else { 8450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org offer = remote_description_.get(); 8460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org answer = local_description_.get(); 8470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 8480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 8490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org TransportProtocol offer_proto = TransportProtocolFromDescription(offer); 8500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org TransportProtocol answer_proto = TransportProtocolFromDescription(answer); 8510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 8520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // If offered protocol is gice/ice, then we expect to receive matching 8530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // protocol in answer, anything else is treated as an error. 8540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // HYBRID is not an option when offered specific protocol. 8550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // If offered protocol is HYBRID and answered protocol is HYBRID then 8560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // gice is preferred protocol. 8570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // TODO(mallinath) - Answer from local or remote should't have both ice 8580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // and gice support. It should always pick which protocol it wants to use. 8590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Once WebRTC stops supporting gice (for backward compatibility), HYBRID in 8600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // answer must be treated as error. 8610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if ((offer_proto == ICEPROTO_GOOGLE || offer_proto == ICEPROTO_RFC5245) && 8620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org (offer_proto != answer_proto)) { 863f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org std::ostringstream desc; 864f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org desc << "Offer and answer protocol mismatch: " 865f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org << IceProtoToString(offer_proto) 866f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org << " vs " 867f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org << IceProtoToString(answer_proto); 868f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org return BadTransportDescription(desc.str(), error_desc); 8690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 8700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org protocol_ = answer_proto == ICEPROTO_HYBRID ? ICEPROTO_GOOGLE : answer_proto; 8710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 872e560834da4ee5a5f38a96a8cb9290c5ce1096989mallinath@webrtc.org // If transport is in ICEROLE_CONTROLLED and remote end point supports only 8730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // ice_lite, this local end point should take CONTROLLING role. 874e560834da4ee5a5f38a96a8cb9290c5ce1096989mallinath@webrtc.org if (ice_role_ == ICEROLE_CONTROLLED && 8750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org remote_description_->ice_mode == ICEMODE_LITE) { 876e560834da4ee5a5f38a96a8cb9290c5ce1096989mallinath@webrtc.org SetIceRole_w(ICEROLE_CONTROLLING); 8770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 8780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 8790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Update remote ice_mode to all existing channels. 8800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org remote_ice_mode_ = remote_description_->ice_mode; 8810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 8820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Now that we have negotiated everything, push it downward. 8830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Note that we cache the result so that if we have race conditions 8840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // between future SetRemote/SetLocal invocations and new channel 8850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // creation, we have the negotiation state saved until a new 8860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // negotiation happens. 8870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org for (ChannelMap::iterator iter = channels_.begin(); 8880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org iter != channels_.end(); 8890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ++iter) { 890f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org if (!ApplyNegotiatedTransportDescription_w(iter->second.get(), error_desc)) 891a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org return false; 8920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 8930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 8940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 8950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 8962a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.orgvoid Transport::OnMessage(rtc::Message* msg) { 8970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org switch (msg->message_id) { 8980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case MSG_ONSIGNALINGREADY: 8990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org CallChannels_w(&TransportChannelImpl::OnSignalingReady); 9000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org break; 9010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case MSG_ONREMOTECANDIDATE: { 9020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ChannelParams* params = static_cast<ChannelParams*>(msg->pdata); 9030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org OnRemoteCandidate_w(*params->candidate); 9040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org delete params; 9050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 9060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org break; 9070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case MSG_CONNECTING: 9080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org OnConnecting_s(); 9090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org break; 9100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case MSG_READSTATE: 9110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org OnChannelReadableState_s(); 9120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org break; 9130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case MSG_WRITESTATE: 9140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org OnChannelWritableState_s(); 9150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org break; 9160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case MSG_REQUESTSIGNALING: { 9170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ChannelParams* params = static_cast<ChannelParams*>(msg->pdata); 9180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org OnChannelRequestSignaling_s(params->component); 9190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org delete params; 9200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 9210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org break; 9220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case MSG_CANDIDATEREADY: 9230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org OnChannelCandidateReady_s(); 9240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org break; 9250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case MSG_ROUTECHANGE: { 9260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ChannelParams* params = static_cast<ChannelParams*>(msg->pdata); 9270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org OnChannelRouteChange_s(params->channel, *params->candidate); 9280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org delete params; 9290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 9300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org break; 9310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case MSG_CANDIDATEALLOCATIONCOMPLETE: 9320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org OnChannelCandidatesAllocationDone_s(); 9330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org break; 9340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case MSG_ROLECONFLICT: 9350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org SignalRoleConflict(); 9360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org break; 937f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.org case MSG_COMPLETED: 938f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.org SignalCompleted(this); 939f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.org break; 940f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.org case MSG_FAILED: 941f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.org SignalFailed(this); 942f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.org break; 9430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 9440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 9450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 9460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool TransportParser::ParseAddress(const buzz::XmlElement* elem, 9470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org const buzz::QName& address_name, 9480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org const buzz::QName& port_name, 9492a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::SocketAddress* address, 9500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ParseError* error) { 9510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!elem->HasAttr(address_name)) 9520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return BadParse("address does not have " + address_name.LocalPart(), error); 9530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!elem->HasAttr(port_name)) 9540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return BadParse("address does not have " + port_name.LocalPart(), error); 9550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 9560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org address->SetIP(elem->Attr(address_name)); 9570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org std::istringstream ist(elem->Attr(port_name)); 9580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org int port = 0; 9590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ist >> port; 9600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org address->SetPort(port); 9610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 9620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 9630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 9640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 9650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// We're GICE if the namespace is NS_GOOGLE_P2P, or if NS_JINGLE_ICE_UDP is 9660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// used and the GICE ice-option is set. 9670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgTransportProtocol TransportProtocolFromDescription( 9680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org const TransportDescription* desc) { 9690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(desc != NULL); 9700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (desc->transport_type == NS_JINGLE_ICE_UDP) { 9710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return (desc->HasOption(ICE_OPTION_GICE)) ? 9720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ICEPROTO_HYBRID : ICEPROTO_RFC5245; 9730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 9740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return ICEPROTO_GOOGLE; 9750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 9760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 9770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} // namespace cricket 978