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 // P2PTransportChannel wraps up the state management of the connection between 29 // two P2P clients. Clients have candidate ports for connecting, and 30 // connections which are combinations of candidates from each end (Alice and 31 // Bob each have candidates, one candidate from Alice and one candidate from 32 // Bob are used to make a connection, repeat to make many connections). 33 // 34 // When all of the available connections become invalid (non-writable), we 35 // kick off a process of determining more candidates and more connections. 36 // 37 #ifndef TALK_P2P_BASE_P2PTRANSPORTCHANNEL_H_ 38 #define TALK_P2P_BASE_P2PTRANSPORTCHANNEL_H_ 39 40 #include <map> 41 #include <vector> 42 #include <string> 43 #include "talk/base/sigslot.h" 44 #include "talk/p2p/base/candidate.h" 45 #include "talk/p2p/base/portinterface.h" 46 #include "talk/p2p/base/portallocator.h" 47 #include "talk/p2p/base/transport.h" 48 #include "talk/p2p/base/transportchannelimpl.h" 49 #include "talk/p2p/base/p2ptransport.h" 50 51 namespace cricket { 52 53 // Adds the port on which the candidate originated. 54 class RemoteCandidate : public Candidate { 55 public: 56 RemoteCandidate(const Candidate& c, PortInterface* origin_port) 57 : Candidate(c), origin_port_(origin_port) {} 58 59 PortInterface* origin_port() { return origin_port_; } 60 61 private: 62 PortInterface* origin_port_; 63 }; 64 65 // P2PTransportChannel manages the candidates and connection process to keep 66 // two P2P clients connected to each other. 67 class P2PTransportChannel : public TransportChannelImpl, 68 public talk_base::MessageHandler { 69 public: 70 P2PTransportChannel(const std::string& content_name, 71 int component, 72 P2PTransport* transport, 73 PortAllocator *allocator); 74 virtual ~P2PTransportChannel(); 75 76 // From TransportChannelImpl: 77 virtual Transport* GetTransport() { return transport_; } 78 virtual void SetIceRole(IceRole role); 79 virtual IceRole GetIceRole() const { return ice_role_; } 80 virtual void SetIceTiebreaker(uint64 tiebreaker); 81 virtual void SetIceProtocolType(IceProtocolType type); 82 virtual void SetIceCredentials(const std::string& ice_ufrag, 83 const std::string& ice_pwd); 84 virtual void SetRemoteIceCredentials(const std::string& ice_ufrag, 85 const std::string& ice_pwd); 86 virtual void SetRemoteIceMode(IceMode mode); 87 virtual void Connect(); 88 virtual void Reset(); 89 virtual void OnSignalingReady(); 90 virtual void OnCandidate(const Candidate& candidate); 91 92 // From TransportChannel: 93 virtual int SendPacket(const char *data, size_t len, int flags); 94 virtual int SetOption(talk_base::Socket::Option opt, int value); 95 virtual int GetError() { return error_; } 96 virtual bool GetStats(std::vector<ConnectionInfo>* stats); 97 98 const Connection* best_connection() const { return best_connection_; } 99 void set_incoming_only(bool value) { incoming_only_ = value; } 100 101 // Note: This is only for testing purpose. 102 // |ports_| should not be changed from outside. 103 const std::vector<PortInterface *>& ports() { return ports_; } 104 105 IceMode remote_ice_mode() const { return remote_ice_mode_; } 106 107 private: 108 talk_base::Thread* thread() { return worker_thread_; } 109 PortAllocatorSession* allocator_session() { 110 return allocator_sessions_.back(); 111 } 112 113 void Allocate(); 114 void UpdateConnectionStates(); 115 void RequestSort(); 116 void SortConnections(); 117 void SwitchBestConnectionTo(Connection* conn); 118 void UpdateChannelState(); 119 void HandleWritable(); 120 void HandleNotWritable(); 121 void HandleAllTimedOut(); 122 123 Connection* GetBestConnectionOnNetwork(talk_base::Network* network); 124 bool CreateConnections(const Candidate &remote_candidate, 125 PortInterface* origin_port, bool readable); 126 bool CreateConnection(PortInterface* port, const Candidate& remote_candidate, 127 PortInterface* origin_port, bool readable); 128 bool FindConnection(cricket::Connection* connection) const; 129 130 uint32 GetRemoteCandidateGeneration(const Candidate& candidate); 131 void RememberRemoteCandidate(const Candidate& remote_candidate, 132 PortInterface* origin_port); 133 bool IsPingable(Connection* conn); 134 Connection* FindNextPingableConnection(); 135 void PingConnection(Connection* conn); 136 void AddAllocatorSession(PortAllocatorSession* session); 137 void AddConnection(Connection* connection); 138 139 void OnPortReady(PortAllocatorSession *session, PortInterface* port); 140 void OnCandidatesReady(PortAllocatorSession *session, 141 const std::vector<Candidate>& candidates); 142 void OnCandidatesAllocationDone(PortAllocatorSession* session); 143 void OnUnknownAddress(PortInterface* port, 144 const talk_base::SocketAddress& addr, 145 ProtocolType proto, 146 IceMessage* stun_msg, 147 const std::string& remote_username, 148 bool port_muxed); 149 void OnPortDestroyed(PortInterface* port); 150 void OnRoleConflict(PortInterface* port); 151 152 void OnConnectionStateChange(Connection *connection); 153 void OnReadPacket(Connection *connection, const char *data, size_t len); 154 void OnReadyToSend(Connection* connection); 155 void OnConnectionDestroyed(Connection *connection); 156 157 void OnUseCandidate(Connection* conn); 158 159 virtual void OnMessage(talk_base::Message *pmsg); 160 void OnSort(); 161 void OnPing(); 162 163 P2PTransport* transport_; 164 PortAllocator *allocator_; 165 talk_base::Thread *worker_thread_; 166 bool incoming_only_; 167 bool waiting_for_signaling_; 168 int error_; 169 std::vector<PortAllocatorSession*> allocator_sessions_; 170 std::vector<PortInterface *> ports_; 171 std::vector<Connection *> connections_; 172 Connection* best_connection_; 173 // Connection selected by the controlling agent. This should be used only 174 // at controlled side when protocol type is RFC5245. 175 Connection* pending_best_connection_; 176 std::vector<RemoteCandidate> remote_candidates_; 177 bool sort_dirty_; // indicates whether another sort is needed right now 178 bool was_writable_; 179 typedef std::map<talk_base::Socket::Option, int> OptionMap; 180 OptionMap options_; 181 std::string ice_ufrag_; 182 std::string ice_pwd_; 183 std::string remote_ice_ufrag_; 184 std::string remote_ice_pwd_; 185 IceProtocolType protocol_type_; 186 IceMode remote_ice_mode_; 187 IceRole ice_role_; 188 uint64 tiebreaker_; 189 uint32 remote_candidate_generation_; 190 191 DISALLOW_EVIL_CONSTRUCTORS(P2PTransportChannel); 192 }; 193 194 } // namespace cricket 195 196 #endif // TALK_P2P_BASE_P2PTRANSPORTCHANNEL_H_ 197