1 /* 2 * libjingle 3 * Copyright 2004--2005, Google Inc. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 3. The name of the author may not be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 #include "talk/p2p/base/portallocator.h" 29 30 #include "talk/p2p/base/portallocatorsessionproxy.h" 31 32 namespace cricket { 33 34 PortAllocatorSession::PortAllocatorSession(const std::string& content_name, 35 int component, 36 const std::string& ice_ufrag, 37 const std::string& ice_pwd, 38 uint32 flags) 39 : content_name_(content_name), 40 component_(component), 41 flags_(flags), 42 generation_(0), 43 // If PORTALLOCATOR_ENABLE_SHARED_UFRAG flag is not enabled, ignore the 44 // incoming ufrag and pwd, which will cause each Port to generate one 45 // by itself. 46 username_(flags_ & PORTALLOCATOR_ENABLE_SHARED_UFRAG ? ice_ufrag : ""), 47 password_(flags_ & PORTALLOCATOR_ENABLE_SHARED_UFRAG ? ice_pwd : "") { 48 } 49 50 PortAllocator::~PortAllocator() { 51 for (SessionMuxerMap::iterator iter = muxers_.begin(); 52 iter != muxers_.end(); ++iter) { 53 delete iter->second; 54 } 55 } 56 57 PortAllocatorSession* PortAllocator::CreateSession( 58 const std::string& sid, 59 const std::string& content_name, 60 int component, 61 const std::string& ice_ufrag, 62 const std::string& ice_pwd) { 63 if (flags_ & PORTALLOCATOR_ENABLE_BUNDLE) { 64 // If we just use |sid| as key in identifying PortAllocatorSessionMuxer, 65 // ICE restart will not result in different candidates, as |sid| will 66 // be same. To yield different candiates we are using combination of 67 // |ice_ufrag| and |ice_pwd|. 68 // Ideally |ice_ufrag| and |ice_pwd| should change together, but 69 // there can be instances where only ice_pwd will be changed. 70 std::string key_str = ice_ufrag + ":" + ice_pwd; 71 PortAllocatorSessionMuxer* muxer = GetSessionMuxer(key_str); 72 if (!muxer) { 73 PortAllocatorSession* session_impl = CreateSessionInternal( 74 content_name, component, ice_ufrag, ice_pwd); 75 // Create PortAllocatorSessionMuxer object for |session_impl|. 76 muxer = new PortAllocatorSessionMuxer(session_impl); 77 muxer->SignalDestroyed.connect( 78 this, &PortAllocator::OnSessionMuxerDestroyed); 79 // Add PortAllocatorSession to the map. 80 muxers_[key_str] = muxer; 81 } 82 PortAllocatorSessionProxy* proxy = 83 new PortAllocatorSessionProxy(content_name, component, flags_); 84 muxer->RegisterSessionProxy(proxy); 85 return proxy; 86 } 87 return CreateSessionInternal(content_name, component, ice_ufrag, ice_pwd); 88 } 89 90 PortAllocatorSessionMuxer* PortAllocator::GetSessionMuxer( 91 const std::string& key) const { 92 SessionMuxerMap::const_iterator iter = muxers_.find(key); 93 if (iter != muxers_.end()) 94 return iter->second; 95 return NULL; 96 } 97 98 void PortAllocator::OnSessionMuxerDestroyed( 99 PortAllocatorSessionMuxer* session) { 100 SessionMuxerMap::iterator iter; 101 for (iter = muxers_.begin(); iter != muxers_.end(); ++iter) { 102 if (iter->second == session) 103 break; 104 } 105 if (iter != muxers_.end()) 106 muxers_.erase(iter); 107 } 108 109 } // namespace cricket 110