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 #ifndef TALK_P2P_BASE_PORT_H_ 29 #define TALK_P2P_BASE_PORT_H_ 30 31 #include <string> 32 #include <vector> 33 #include <map> 34 35 #include "talk/base/network.h" 36 #include "talk/base/packetsocketfactory.h" 37 #include "talk/base/proxyinfo.h" 38 #include "talk/base/ratetracker.h" 39 #include "talk/base/sigslot.h" 40 #include "talk/base/socketaddress.h" 41 #include "talk/base/thread.h" 42 #include "talk/p2p/base/candidate.h" 43 #include "talk/p2p/base/stun.h" 44 #include "talk/p2p/base/stunrequest.h" 45 46 namespace talk_base { 47 class AsyncPacketSocket; 48 } 49 50 namespace cricket { 51 52 class Connection; 53 class ConnectionRequest; 54 55 enum ProtocolType { 56 PROTO_UDP, 57 PROTO_TCP, 58 PROTO_SSLTCP, 59 PROTO_LAST = PROTO_SSLTCP 60 }; 61 62 const char* ProtoToString(ProtocolType proto); 63 bool StringToProto(const char* value, ProtocolType* proto); 64 65 struct ProtocolAddress { 66 talk_base::SocketAddress address; 67 ProtocolType proto; 68 69 ProtocolAddress(const talk_base::SocketAddress& a, ProtocolType p) 70 : address(a), proto(p) { } 71 }; 72 73 // Represents a local communication mechanism that can be used to create 74 // connections to similar mechanisms of the other client. Subclasses of this 75 // one add support for specific mechanisms like local UDP ports. 76 class Port : public talk_base::MessageHandler, public sigslot::has_slots<> { 77 public: 78 Port(talk_base::Thread* thread, const std::string& type, 79 talk_base::PacketSocketFactory* factory, talk_base::Network* network, 80 uint32 ip, int min_port, int max_port); 81 virtual ~Port(); 82 83 // The thread on which this port performs its I/O. 84 talk_base::Thread* thread() { return thread_; } 85 86 // The factory used to create the sockets of this port. 87 talk_base::PacketSocketFactory* socket_factory() const { return factory_; } 88 void set_socket_factory(talk_base::PacketSocketFactory* factory) { 89 factory_ = factory; 90 } 91 92 // Each port is identified by a name (for debugging purposes). 93 const std::string& name() const { return name_; } 94 void set_name(const std::string& name) { name_ = name; } 95 96 // In order to establish a connection to this Port (so that real data can be 97 // sent through), the other side must send us a STUN binding request that is 98 // authenticated with this username and password. 99 // Fills in the username fragment and password. These will be initially set 100 // in the constructor to random values. Subclasses or tests can override. 101 // TODO: Change this to "username" rather than "username_fragment". 102 const std::string& username_fragment() const { return username_frag_; } 103 void set_username_fragment(const std::string& username) { 104 username_frag_ = username; 105 } 106 107 const std::string& password() const { return password_; } 108 void set_password(const std::string& password) { password_ = password; } 109 110 111 // A value in [0,1] that indicates the preference for this port versus other 112 // ports on this client. (Larger indicates more preference.) 113 float preference() const { return preference_; } 114 void set_preference(float preference) { preference_ = preference; } 115 116 // Identifies the port type. 117 const std::string& type() const { return type_; } 118 119 // Identifies network that this port was allocated on. 120 talk_base::Network* network() { return network_; } 121 122 // Identifies the generation that this port was created in. 123 uint32 generation() { return generation_; } 124 void set_generation(uint32 generation) { generation_ = generation; } 125 126 // PrepareAddress will attempt to get an address for this port that other 127 // clients can send to. It may take some time before the address is read. 128 // Once it is ready, we will send SignalAddressReady. If errors are 129 // preventing the port from getting an address, it may send 130 // SignalAddressError. 131 virtual void PrepareAddress() = 0; 132 sigslot::signal1<Port*> SignalAddressReady; 133 sigslot::signal1<Port*> SignalAddressError; 134 135 // Provides all of the above information in one handy object. 136 const std::vector<Candidate>& candidates() const { return candidates_; } 137 138 // Returns a map containing all of the connections of this port, keyed by the 139 // remote address. 140 typedef std::map<talk_base::SocketAddress, Connection*> AddressMap; 141 const AddressMap& connections() { return connections_; } 142 143 // Returns the connection to the given address or NULL if none exists. 144 Connection* GetConnection(const talk_base::SocketAddress& remote_addr); 145 146 // Creates a new connection to the given address. 147 enum CandidateOrigin { ORIGIN_THIS_PORT, ORIGIN_OTHER_PORT, ORIGIN_MESSAGE }; 148 virtual Connection* CreateConnection(const Candidate& remote_candidate, 149 CandidateOrigin origin) = 0; 150 151 // Called each time a connection is created. 152 sigslot::signal2<Port*, Connection*> SignalConnectionCreated; 153 154 // Sends the given packet to the given address, provided that the address is 155 // that of a connection or an address that has sent to us already. 156 virtual int SendTo( 157 const void* data, size_t size, const talk_base::SocketAddress& addr, 158 bool payload) = 0; 159 160 // Indicates that we received a successful STUN binding request from an 161 // address that doesn't correspond to any current connection. To turn this 162 // into a real connection, call CreateConnection. 163 sigslot::signal4<Port*, const talk_base::SocketAddress&, StunMessage*, 164 const std::string&> SignalUnknownAddress; 165 166 // Sends a response message (normal or error) to the given request. One of 167 // these methods should be called as a response to SignalUnknownAddress. 168 // NOTE: You MUST call CreateConnection BEFORE SendBindingResponse. 169 void SendBindingResponse(StunMessage* request, 170 const talk_base::SocketAddress& addr); 171 void SendBindingErrorResponse( 172 StunMessage* request, const talk_base::SocketAddress& addr, 173 int error_code, const std::string& reason); 174 175 // Indicates that errors occurred when performing I/O. 176 sigslot::signal2<Port*, int> SignalReadError; 177 sigslot::signal2<Port*, int> SignalWriteError; 178 179 // Functions on the underlying socket(s). 180 virtual int SetOption(talk_base::Socket::Option opt, int value) = 0; 181 virtual int GetError() = 0; 182 183 void set_proxy(const std::string& user_agent, 184 const talk_base::ProxyInfo& proxy) { 185 user_agent_ = user_agent; 186 proxy_ = proxy; 187 } 188 const std::string& user_agent() { return user_agent_; } 189 const talk_base::ProxyInfo& proxy() { return proxy_; } 190 191 // Normally, packets arrive through a connection (or they result signaling of 192 // unknown address). Calling this method turns off delivery of packets 193 // through their respective connection and instead delivers every packet 194 // through this port. 195 void EnablePortPackets(); 196 sigslot::signal4<Port*, const char*, size_t, const talk_base::SocketAddress&> 197 SignalReadPacket; 198 199 // Indicates to the port that its official use has now begun. This will 200 // start the timer that checks to see if the port is being used. 201 void Start(); 202 203 // Called if the port has no connections and is no longer useful. 204 void Destroy(); 205 206 // Signaled when this port decides to delete itself because it no longer has 207 // any usefulness. 208 sigslot::signal1<Port*> SignalDestroyed; 209 210 virtual void OnMessage(talk_base::Message *pmsg); 211 212 // Debugging description of this port 213 std::string ToString() const; 214 215 protected: 216 // Fills in the local address of the port. 217 void AddAddress(const talk_base::SocketAddress& address, 218 const std::string& protocol, bool final); 219 220 // Adds the given connection to the list. (Deleting removes them.) 221 void AddConnection(Connection* conn); 222 223 // Called when a packet is received from an unknown address that is not 224 // currently a connection. If this is an authenticated STUN binding request, 225 // then we will signal the client. 226 void OnReadPacket(const char* data, size_t size, 227 const talk_base::SocketAddress& addr); 228 229 230 // If the given data comprises a complete and correct STUN message then the 231 // return value is true, otherwise false. If the message username corresponds 232 // with this port's username fragment, msg will contain the parsed STUN 233 // message. Otherwise, the function may send a STUN response internally. 234 // remote_username contains the remote fragment of the STUN username. 235 bool GetStunMessage(const char* data, size_t size, 236 const talk_base::SocketAddress& addr, 237 StunMessage** out_msg, std::string* out_username); 238 239 // TODO: make these members private 240 talk_base::Thread* thread_; 241 talk_base::PacketSocketFactory* factory_; 242 std::string type_; 243 talk_base::Network* network_; 244 uint32 ip_; 245 int min_port_; 246 int max_port_; 247 uint32 generation_; 248 std::string name_; 249 std::string username_frag_; 250 std::string password_; 251 float preference_; 252 std::vector<Candidate> candidates_; 253 AddressMap connections_; 254 enum Lifetime { LT_PRESTART, LT_PRETIMEOUT, LT_POSTTIMEOUT } lifetime_; 255 bool enable_port_packets_; 256 257 private: 258 // Called when one of our connections deletes itself. 259 void OnConnectionDestroyed(Connection* conn); 260 261 // Checks if this port is useless, and hence, should be destroyed. 262 void CheckTimeout(); 263 264 // Information to use when going through a proxy. 265 std::string user_agent_; 266 talk_base::ProxyInfo proxy_; 267 268 friend class Connection; 269 }; 270 271 // Represents a communication link between a port on the local client and a 272 // port on the remote client. 273 class Connection : public talk_base::MessageHandler, 274 public sigslot::has_slots<> { 275 public: 276 virtual ~Connection(); 277 278 // The local port where this connection sends and receives packets. 279 Port* port() { return port_; } 280 const Port* port() const { return port_; } 281 282 // Returns the description of the local port 283 virtual const Candidate& local_candidate() const; 284 285 // Returns the description of the remote port to which we communicate. 286 const Candidate& remote_candidate() const { return remote_candidate_; } 287 288 enum ReadState { 289 STATE_READABLE = 0, // we have received pings recently 290 STATE_READ_TIMEOUT = 1 // we haven't received pings in a while 291 }; 292 293 ReadState read_state() const { return read_state_; } 294 295 enum WriteState { 296 STATE_WRITABLE = 0, // we have received ping responses recently 297 STATE_WRITE_CONNECT = 1, // we have had a few ping failures 298 STATE_WRITE_TIMEOUT = 2 // we have had a large number of ping failures 299 }; 300 301 WriteState write_state() const { return write_state_; } 302 303 // Determines whether the connection has finished connecting. This can only 304 // be false for TCP connections. 305 bool connected() const { return connected_; } 306 307 // Estimate of the round-trip time over this connection. 308 uint32 rtt() const { return rtt_; } 309 310 size_t sent_total_bytes(); 311 size_t sent_bytes_second(); 312 size_t recv_total_bytes(); 313 size_t recv_bytes_second(); 314 sigslot::signal1<Connection*> SignalStateChange; 315 316 // Sent when the connection has decided that it is no longer of value. It 317 // will delete itself immediately after this call. 318 sigslot::signal1<Connection*> SignalDestroyed; 319 320 // The connection can send and receive packets asynchronously. This matches 321 // the interface of AsyncPacketSocket, which may use UDP or TCP under the 322 // covers. 323 virtual int Send(const void* data, size_t size) = 0; 324 325 // Error if Send() returns < 0 326 virtual int GetError() = 0; 327 328 sigslot::signal3<Connection*, const char*, size_t> SignalReadPacket; 329 330 // Called when a packet is received on this connection. 331 void OnReadPacket(const char* data, size_t size); 332 333 // Called when a connection is determined to be no longer useful to us. We 334 // still keep it around in case the other side wants to use it. But we can 335 // safely stop pinging on it and we can allow it to time out if the other 336 // side stops using it as well. 337 bool pruned() const { return pruned_; } 338 void Prune(); 339 340 // Makes the connection go away. 341 void Destroy(); 342 343 // Checks that the state of this connection is up-to-date. The argument is 344 // the current time, which is compared against various timeouts. 345 void UpdateState(uint32 now); 346 347 // Called when this connection should try checking writability again. 348 uint32 last_ping_sent() const { return last_ping_sent_; } 349 void Ping(uint32 now); 350 351 // Called whenever a valid ping is received on this connection. This is 352 // public because the connection intercepts the first ping for us. 353 void ReceivedPing(); 354 355 // Debugging description of this connection 356 std::string ToString() const; 357 358 bool reported() const { return reported_; } 359 void set_reported(bool reported) { reported_ = reported;} 360 361 protected: 362 // Constructs a new connection to the given remote port. 363 Connection(Port* port, size_t index, const Candidate& candidate); 364 365 // Called back when StunRequestManager has a stun packet to send 366 void OnSendStunPacket(const void* data, size_t size, StunRequest* req); 367 368 // Callbacks from ConnectionRequest 369 void OnConnectionRequestResponse(ConnectionRequest* req, 370 StunMessage* response); 371 void OnConnectionRequestErrorResponse(ConnectionRequest* req, 372 StunMessage* response); 373 void OnConnectionRequestTimeout(ConnectionRequest* req); 374 375 // Changes the state and signals if necessary. 376 void set_read_state(ReadState value); 377 void set_write_state(WriteState value); 378 void set_connected(bool value); 379 380 // Checks if this connection is useless, and hence, should be destroyed. 381 void CheckTimeout(); 382 383 void OnMessage(talk_base::Message *pmsg); 384 385 Port* port_; 386 size_t local_candidate_index_; 387 Candidate remote_candidate_; 388 ReadState read_state_; 389 WriteState write_state_; 390 bool connected_; 391 bool pruned_; 392 StunRequestManager requests_; 393 uint32 rtt_; 394 uint32 last_ping_sent_; // last time we sent a ping to the other side 395 uint32 last_ping_received_; // last time we received a ping from the other 396 // side 397 uint32 last_data_received_; 398 std::vector<uint32> pings_since_last_response_; 399 400 talk_base::RateTracker recv_rate_tracker_; 401 talk_base::RateTracker send_rate_tracker_; 402 403 private: 404 bool reported_; 405 406 friend class Port; 407 friend class ConnectionRequest; 408 }; 409 410 // ProxyConnection defers all the interesting work to the port 411 class ProxyConnection : public Connection { 412 public: 413 ProxyConnection(Port* port, size_t index, const Candidate& candidate); 414 415 virtual int Send(const void* data, size_t size); 416 virtual int GetError() { return error_; } 417 418 private: 419 int error_; 420 }; 421 422 } // namespace cricket 423 424 #endif // TALK_P2P_BASE_PORT_H_ 425