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/asyncpacketsocket.h" 44 #include "talk/base/sigslot.h" 45 #include "talk/p2p/base/candidate.h" 46 #include "talk/p2p/base/portinterface.h" 47 #include "talk/p2p/base/portallocator.h" 48 #include "talk/p2p/base/transport.h" 49 #include "talk/p2p/base/transportchannelimpl.h" 50 #include "talk/p2p/base/p2ptransport.h" 51 52 namespace cricket { 53 54 // Adds the port on which the candidate originated. 55 class RemoteCandidate : public Candidate { 56 public: 57 RemoteCandidate(const Candidate& c, PortInterface* origin_port) 58 : Candidate(c), origin_port_(origin_port) {} 59 60 PortInterface* origin_port() { return origin_port_; } 61 62 private: 63 PortInterface* origin_port_; 64 }; 65 66 // P2PTransportChannel manages the candidates and connection process to keep 67 // two P2P clients connected to each other. 68 class P2PTransportChannel : public TransportChannelImpl, 69 public talk_base::MessageHandler { 70 public: 71 P2PTransportChannel(const std::string& content_name, 72 int component, 73 P2PTransport* transport, 74 PortAllocator *allocator); 75 virtual ~P2PTransportChannel(); 76 77 // From TransportChannelImpl: 78 virtual Transport* GetTransport() { return transport_; } 79 virtual void SetIceRole(IceRole role); 80 virtual IceRole GetIceRole() const { return ice_role_; } 81 virtual void SetIceTiebreaker(uint64 tiebreaker); 82 virtual void SetIceProtocolType(IceProtocolType type); 83 virtual void SetIceCredentials(const std::string& ice_ufrag, 84 const std::string& ice_pwd); 85 virtual void SetRemoteIceCredentials(const std::string& ice_ufrag, 86 const std::string& ice_pwd); 87 virtual void SetRemoteIceMode(IceMode mode); 88 virtual void Connect(); 89 virtual void Reset(); 90 virtual void OnSignalingReady(); 91 virtual void OnCandidate(const Candidate& candidate); 92 93 // From TransportChannel: 94 virtual int SendPacket(const char *data, size_t len, 95 talk_base::DiffServCodePoint dscp, int flags); 96 virtual int SetOption(talk_base::Socket::Option opt, int value); 97 virtual int GetError() { return error_; } 98 virtual bool GetStats(std::vector<ConnectionInfo>* stats); 99 100 const Connection* best_connection() const { return best_connection_; } 101 void set_incoming_only(bool value) { incoming_only_ = value; } 102 103 // Note: This is only for testing purpose. 104 // |ports_| should not be changed from outside. 105 const std::vector<PortInterface *>& ports() { return ports_; } 106 107 IceMode remote_ice_mode() const { return remote_ice_mode_; } 108 109 // DTLS methods. 110 virtual bool IsDtlsActive() const { return false; } 111 112 // Default implementation. 113 virtual bool GetSslRole(talk_base::SSLRole* role) const { 114 return false; 115 } 116 117 virtual bool SetSslRole(talk_base::SSLRole role) { 118 return false; 119 } 120 121 // Set up the ciphers to use for DTLS-SRTP. 122 virtual bool SetSrtpCiphers(const std::vector<std::string>& ciphers) { 123 return false; 124 } 125 126 // Find out which DTLS-SRTP cipher was negotiated 127 virtual bool GetSrtpCipher(std::string* cipher) { 128 return false; 129 } 130 131 // Returns false because the channel is not encrypted by default. 132 virtual bool GetLocalIdentity(talk_base::SSLIdentity** identity) const { 133 return false; 134 } 135 136 virtual bool GetRemoteCertificate(talk_base::SSLCertificate** cert) const { 137 return false; 138 } 139 140 // Allows key material to be extracted for external encryption. 141 virtual bool ExportKeyingMaterial( 142 const std::string& label, 143 const uint8* context, 144 size_t context_len, 145 bool use_context, 146 uint8* result, 147 size_t result_len) { 148 return false; 149 } 150 151 virtual bool SetLocalIdentity(talk_base::SSLIdentity* identity) { 152 return false; 153 } 154 155 // Set DTLS Remote fingerprint. Must be after local identity set. 156 virtual bool SetRemoteFingerprint( 157 const std::string& digest_alg, 158 const uint8* digest, 159 size_t digest_len) { 160 return false; 161 } 162 163 // Helper method used only in unittest. 164 talk_base::DiffServCodePoint DefaultDscpValue() const; 165 166 private: 167 talk_base::Thread* thread() { return worker_thread_; } 168 PortAllocatorSession* allocator_session() { 169 return allocator_sessions_.back(); 170 } 171 172 void Allocate(); 173 void UpdateConnectionStates(); 174 void RequestSort(); 175 void SortConnections(); 176 void SwitchBestConnectionTo(Connection* conn); 177 void UpdateChannelState(); 178 void HandleWritable(); 179 void HandleNotWritable(); 180 void HandleAllTimedOut(); 181 182 Connection* GetBestConnectionOnNetwork(talk_base::Network* network); 183 bool CreateConnections(const Candidate &remote_candidate, 184 PortInterface* origin_port, bool readable); 185 bool CreateConnection(PortInterface* port, const Candidate& remote_candidate, 186 PortInterface* origin_port, bool readable); 187 bool FindConnection(cricket::Connection* connection) const; 188 189 uint32 GetRemoteCandidateGeneration(const Candidate& candidate); 190 void RememberRemoteCandidate(const Candidate& remote_candidate, 191 PortInterface* origin_port); 192 bool IsPingable(Connection* conn); 193 Connection* FindNextPingableConnection(); 194 void PingConnection(Connection* conn); 195 void AddAllocatorSession(PortAllocatorSession* session); 196 void AddConnection(Connection* connection); 197 198 void OnPortReady(PortAllocatorSession *session, PortInterface* port); 199 void OnCandidatesReady(PortAllocatorSession *session, 200 const std::vector<Candidate>& candidates); 201 void OnCandidatesAllocationDone(PortAllocatorSession* session); 202 void OnUnknownAddress(PortInterface* port, 203 const talk_base::SocketAddress& addr, 204 ProtocolType proto, 205 IceMessage* stun_msg, 206 const std::string& remote_username, 207 bool port_muxed); 208 void OnPortDestroyed(PortInterface* port); 209 void OnRoleConflict(PortInterface* port); 210 211 void OnConnectionStateChange(Connection* connection); 212 void OnReadPacket(Connection *connection, const char *data, size_t len, 213 const talk_base::PacketTime& packet_time); 214 void OnReadyToSend(Connection* connection); 215 void OnConnectionDestroyed(Connection *connection); 216 217 void OnUseCandidate(Connection* conn); 218 219 virtual void OnMessage(talk_base::Message *pmsg); 220 void OnSort(); 221 void OnPing(); 222 223 P2PTransport* transport_; 224 PortAllocator *allocator_; 225 talk_base::Thread *worker_thread_; 226 bool incoming_only_; 227 bool waiting_for_signaling_; 228 int error_; 229 std::vector<PortAllocatorSession*> allocator_sessions_; 230 std::vector<PortInterface *> ports_; 231 std::vector<Connection *> connections_; 232 Connection* best_connection_; 233 // Connection selected by the controlling agent. This should be used only 234 // at controlled side when protocol type is RFC5245. 235 Connection* pending_best_connection_; 236 std::vector<RemoteCandidate> remote_candidates_; 237 bool sort_dirty_; // indicates whether another sort is needed right now 238 bool was_writable_; 239 typedef std::map<talk_base::Socket::Option, int> OptionMap; 240 OptionMap options_; 241 std::string ice_ufrag_; 242 std::string ice_pwd_; 243 std::string remote_ice_ufrag_; 244 std::string remote_ice_pwd_; 245 IceProtocolType protocol_type_; 246 IceMode remote_ice_mode_; 247 IceRole ice_role_; 248 uint64 tiebreaker_; 249 uint32 remote_candidate_generation_; 250 251 DISALLOW_EVIL_CONSTRUCTORS(P2PTransportChannel); 252 }; 253 254 } // namespace cricket 255 256 #endif // TALK_P2P_BASE_P2PTRANSPORTCHANNEL_H_ 257