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/port.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: RemoteCandidate(const Candidate & c,Port * origin_port)56 RemoteCandidate(const Candidate& c, Port* origin_port) 57 : Candidate(c), origin_port_(origin_port) {} 58 origin_port()59 Port* origin_port() { return origin_port_; } 60 61 private: 62 Port* 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 &name, 71 const std::string &content_type, 72 P2PTransport* transport, 73 PortAllocator *allocator); 74 virtual ~P2PTransportChannel(); 75 76 // From TransportChannelImpl: GetTransport()77 virtual Transport* GetTransport() { return transport_; } 78 virtual void Connect(); 79 virtual void Reset(); 80 virtual void OnSignalingReady(); 81 82 // From TransportChannel: 83 virtual int SendPacket(const char *data, size_t len); 84 virtual int SetOption(talk_base::Socket::Option opt, int value); GetError()85 virtual int GetError() { return error_; } 86 87 // This hack is here to allow the SocketMonitor to downcast to the 88 // P2PTransportChannel safely. GetP2PChannel()89 virtual P2PTransportChannel* GetP2PChannel() { return this; } 90 91 // These are used by the connection monitor. 92 sigslot::signal1<P2PTransportChannel*> SignalConnectionMonitor; connections()93 const std::vector<Connection *>& connections() const { return connections_; } best_connection()94 Connection* best_connection() const { return best_connection_; } 95 96 // Handler for internal messages. 97 virtual void OnMessage(talk_base::Message *pmsg); 98 99 virtual void OnCandidate(const Candidate& candidate); 100 101 private: 102 void Allocate(); 103 void CancelPendingAllocate(); 104 void UpdateConnectionStates(); 105 void RequestSort(); 106 void SortConnections(); 107 void SwitchBestConnectionTo(Connection* conn); 108 void UpdateChannelState(); 109 void HandleWritable(); 110 void HandleNotWritable(); 111 void HandleAllTimedOut(); 112 Connection* GetBestConnectionOnNetwork(talk_base::Network* network); 113 bool CreateConnections(const Candidate &remote_candidate, Port* origin_port, 114 bool readable); 115 bool CreateConnection(Port* port, const Candidate& remote_candidate, 116 Port* origin_port, bool readable); 117 void RememberRemoteCandidate(const Candidate& remote_candidate, 118 Port* origin_port); 119 void OnUnknownAddress(Port *port, const talk_base::SocketAddress &addr, 120 StunMessage *stun_msg, 121 const std::string &remote_username); 122 void OnPortReady(PortAllocatorSession *session, Port* port); 123 void OnCandidatesReady(PortAllocatorSession *session, 124 const std::vector<Candidate>& candidates); 125 void OnConnectionStateChange(Connection *connection); 126 void OnConnectionDestroyed(Connection *connection); 127 void OnPortDestroyed(Port* port); 128 void OnReadPacket(Connection *connection, const char *data, size_t len); 129 void OnSort(); 130 void OnPing(); 131 bool IsPingable(Connection* conn); 132 Connection* FindNextPingableConnection(); 133 uint32 NumPingableConnections(); allocator_session()134 PortAllocatorSession* allocator_session() { 135 return allocator_sessions_.back(); 136 } 137 void AddAllocatorSession(PortAllocatorSession* session); 138 thread()139 talk_base::Thread* thread() const { return worker_thread_; } 140 141 P2PTransport* transport_; 142 PortAllocator *allocator_; 143 talk_base::Thread *worker_thread_; 144 bool waiting_for_signaling_; 145 int error_; 146 std::vector<PortAllocatorSession*> allocator_sessions_; 147 std::vector<Port *> ports_; 148 std::vector<Connection *> connections_; 149 Connection *best_connection_; 150 std::vector<RemoteCandidate> remote_candidates_; 151 // indicates whether StartGetAllCandidates has been called 152 bool pinging_started_; 153 bool sort_dirty_; // indicates whether another sort is needed right now 154 bool was_writable_; 155 bool was_timed_out_; 156 typedef std::map<talk_base::Socket::Option, int> OptionMap; 157 OptionMap options_; 158 159 DISALLOW_EVIL_CONSTRUCTORS(P2PTransportChannel); 160 }; 161 162 } // namespace cricket 163 164 #endif // TALK_P2P_BASE_P2PTRANSPORTCHANNEL_H_ 165