Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / third_party / libjingle / source / talk / p2p / base / port.cc
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/port.h"
29
30 #include <algorithm>
31 #include <vector>
32
33 #include "talk/base/base64.h"
34 #include "talk/base/crc32.h"
35 #include "talk/base/helpers.h"
36 #include "talk/base/logging.h"
37 #include "talk/base/messagedigest.h"
38 #include "talk/base/scoped_ptr.h"
39 #include "talk/base/stringencode.h"
40 #include "talk/base/stringutils.h"
41 #include "talk/p2p/base/common.h"
42
43 namespace {
44
45 // Determines whether we have seen at least the given maximum number of
46 // pings fail to have a response.
47 inline bool TooManyFailures(
48     const std::vector<uint32>& pings_since_last_response,
49     uint32 maximum_failures,
50     uint32 rtt_estimate,
51     uint32 now) {
52
53   // If we haven't sent that many pings, then we can't have failed that many.
54   if (pings_since_last_response.size() < maximum_failures)
55     return false;
56
57   // Check if the window in which we would expect a response to the ping has
58   // already elapsed.
59   return pings_since_last_response[maximum_failures - 1] + rtt_estimate < now;
60 }
61
62 // Determines whether we have gone too long without seeing any response.
63 inline bool TooLongWithoutResponse(
64     const std::vector<uint32>& pings_since_last_response,
65     uint32 maximum_time,
66     uint32 now) {
67
68   if (pings_since_last_response.size() == 0)
69     return false;
70
71   return pings_since_last_response[0] + maximum_time < now;
72 }
73
74 // GICE(ICEPROTO_GOOGLE) requires different username for RTP and RTCP.
75 // This function generates a different username by +1 on the last character of
76 // the given username (|rtp_ufrag|).
77 std::string GetRtcpUfragFromRtpUfrag(const std::string& rtp_ufrag) {
78   ASSERT(!rtp_ufrag.empty());
79   if (rtp_ufrag.empty()) {
80     return rtp_ufrag;
81   }
82   // Change the last character to the one next to it in the base64 table.
83   char new_last_char;
84   if (!talk_base::Base64::GetNextBase64Char(rtp_ufrag[rtp_ufrag.size() - 1],
85                                             &new_last_char)) {
86     // Should not be here.
87     ASSERT(false);
88   }
89   std::string rtcp_ufrag = rtp_ufrag;
90   rtcp_ufrag[rtcp_ufrag.size() - 1] = new_last_char;
91   ASSERT(rtcp_ufrag != rtp_ufrag);
92   return rtcp_ufrag;
93 }
94
95 // We will restrict RTT estimates (when used for determining state) to be
96 // within a reasonable range.
97 const uint32 MINIMUM_RTT = 100;   // 0.1 seconds
98 const uint32 MAXIMUM_RTT = 3000;  // 3 seconds
99
100 // When we don't have any RTT data, we have to pick something reasonable.  We
101 // use a large value just in case the connection is really slow.
102 const uint32 DEFAULT_RTT = MAXIMUM_RTT;
103
104 // Computes our estimate of the RTT given the current estimate.
105 inline uint32 ConservativeRTTEstimate(uint32 rtt) {
106   return talk_base::_max(MINIMUM_RTT, talk_base::_min(MAXIMUM_RTT, 2 * rtt));
107 }
108
109 // Weighting of the old rtt value to new data.
110 const int RTT_RATIO = 3;  // 3 : 1
111
112 // The delay before we begin checking if this port is useless.
113 const int kPortTimeoutDelay = 30 * 1000;  // 30 seconds
114
115 // Used by the Connection.
116 const uint32 MSG_DELETE = 1;
117 }
118
119 namespace cricket {
120
121 // TODO(ronghuawu): Use "host", "srflx", "prflx" and "relay". But this requires
122 // the signaling part be updated correspondingly as well.
123 const char LOCAL_PORT_TYPE[] = "local";
124 const char STUN_PORT_TYPE[] = "stun";
125 const char PRFLX_PORT_TYPE[] = "prflx";
126 const char RELAY_PORT_TYPE[] = "relay";
127
128 const char UDP_PROTOCOL_NAME[] = "udp";
129 const char TCP_PROTOCOL_NAME[] = "tcp";
130 const char SSLTCP_PROTOCOL_NAME[] = "ssltcp";
131
132 static const char* const PROTO_NAMES[] = { UDP_PROTOCOL_NAME,
133                                            TCP_PROTOCOL_NAME,
134                                            SSLTCP_PROTOCOL_NAME };
135
136 const char* ProtoToString(ProtocolType proto) {
137   return PROTO_NAMES[proto];
138 }
139
140 bool StringToProto(const char* value, ProtocolType* proto) {
141   for (size_t i = 0; i <= PROTO_LAST; ++i) {
142     if (_stricmp(PROTO_NAMES[i], value) == 0) {
143       *proto = static_cast<ProtocolType>(i);
144       return true;
145     }
146   }
147   return false;
148 }
149
150 // Foundation:  An arbitrary string that is the same for two candidates
151 //   that have the same type, base IP address, protocol (UDP, TCP,
152 //   etc.), and STUN or TURN server.  If any of these are different,
153 //   then the foundation will be different.  Two candidate pairs with
154 //   the same foundation pairs are likely to have similar network
155 //   characteristics.  Foundations are used in the frozen algorithm.
156 static std::string ComputeFoundation(
157     const std::string& type,
158     const std::string& protocol,
159     const talk_base::SocketAddress& base_address) {
160   std::ostringstream ost;
161   ost << type << base_address.ipaddr().ToString() << protocol;
162   return talk_base::ToString<uint32>(talk_base::ComputeCrc32(ost.str()));
163 }
164
165 Port::Port(talk_base::Thread* thread, talk_base::PacketSocketFactory* factory,
166            talk_base::Network* network, const talk_base::IPAddress& ip,
167            const std::string& username_fragment, const std::string& password)
168     : thread_(thread),
169       factory_(factory),
170       send_retransmit_count_attribute_(false),
171       network_(network),
172       ip_(ip),
173       min_port_(0),
174       max_port_(0),
175       component_(ICE_CANDIDATE_COMPONENT_DEFAULT),
176       generation_(0),
177       ice_username_fragment_(username_fragment),
178       password_(password),
179       timeout_delay_(kPortTimeoutDelay),
180       enable_port_packets_(false),
181       ice_protocol_(ICEPROTO_HYBRID),
182       ice_role_(ICEROLE_UNKNOWN),
183       tiebreaker_(0),
184       shared_socket_(true) {
185   Construct();
186 }
187
188 Port::Port(talk_base::Thread* thread, const std::string& type,
189            talk_base::PacketSocketFactory* factory,
190            talk_base::Network* network, const talk_base::IPAddress& ip,
191            int min_port, int max_port, const std::string& username_fragment,
192            const std::string& password)
193     : thread_(thread),
194       factory_(factory),
195       type_(type),
196       send_retransmit_count_attribute_(false),
197       network_(network),
198       ip_(ip),
199       min_port_(min_port),
200       max_port_(max_port),
201       component_(ICE_CANDIDATE_COMPONENT_DEFAULT),
202       generation_(0),
203       ice_username_fragment_(username_fragment),
204       password_(password),
205       timeout_delay_(kPortTimeoutDelay),
206       enable_port_packets_(false),
207       ice_protocol_(ICEPROTO_HYBRID),
208       ice_role_(ICEROLE_UNKNOWN),
209       tiebreaker_(0),
210       shared_socket_(false) {
211   ASSERT(factory_ != NULL);
212   Construct();
213 }
214
215 void Port::Construct() {
216   // If the username_fragment and password are empty, we should just create one.
217   if (ice_username_fragment_.empty()) {
218     ASSERT(password_.empty());
219     ice_username_fragment_ = talk_base::CreateRandomString(ICE_UFRAG_LENGTH);
220     password_ = talk_base::CreateRandomString(ICE_PWD_LENGTH);
221   }
222   LOG_J(LS_INFO, this) << "Port created";
223 }
224
225 Port::~Port() {
226   // Delete all of the remaining connections.  We copy the list up front
227   // because each deletion will cause it to be modified.
228
229   std::vector<Connection*> list;
230
231   AddressMap::iterator iter = connections_.begin();
232   while (iter != connections_.end()) {
233     list.push_back(iter->second);
234     ++iter;
235   }
236
237   for (uint32 i = 0; i < list.size(); i++)
238     delete list[i];
239 }
240
241 Connection* Port::GetConnection(const talk_base::SocketAddress& remote_addr) {
242   AddressMap::const_iterator iter = connections_.find(remote_addr);
243   if (iter != connections_.end())
244     return iter->second;
245   else
246     return NULL;
247 }
248
249 void Port::AddAddress(const talk_base::SocketAddress& address,
250                       const talk_base::SocketAddress& base_address,
251                       const std::string& protocol,
252                       const std::string& type,
253                       uint32 type_preference,
254                       bool final) {
255   Candidate c;
256   c.set_id(talk_base::CreateRandomString(8));
257   c.set_component(component_);
258   c.set_type(type);
259   c.set_protocol(protocol);
260   c.set_address(address);
261   c.set_priority(c.GetPriority(type_preference, network_->preference()));
262   c.set_username(username_fragment());
263   c.set_password(password_);
264   c.set_network_name(network_->name());
265   c.set_generation(generation_);
266   c.set_related_address(related_address_);
267   c.set_foundation(ComputeFoundation(type, protocol, base_address));
268   candidates_.push_back(c);
269   SignalCandidateReady(this, c);
270
271   if (final) {
272     SignalPortComplete(this);
273   }
274 }
275
276 void Port::AddConnection(Connection* conn) {
277   connections_[conn->remote_candidate().address()] = conn;
278   conn->SignalDestroyed.connect(this, &Port::OnConnectionDestroyed);
279   SignalConnectionCreated(this, conn);
280 }
281
282 void Port::OnReadPacket(
283     const char* data, size_t size, const talk_base::SocketAddress& addr,
284     ProtocolType proto) {
285   // If the user has enabled port packets, just hand this over.
286   if (enable_port_packets_) {
287     SignalReadPacket(this, data, size, addr);
288     return;
289   }
290
291   // If this is an authenticated STUN request, then signal unknown address and
292   // send back a proper binding response.
293   talk_base::scoped_ptr<IceMessage> msg;
294   std::string remote_username;
295   if (!GetStunMessage(data, size, addr, msg.accept(), &remote_username)) {
296     LOG_J(LS_ERROR, this) << "Received non-STUN packet from unknown address ("
297                           << addr.ToSensitiveString() << ")";
298   } else if (!msg) {
299     // STUN message handled already
300   } else if (msg->type() == STUN_BINDING_REQUEST) {
301     // Check for role conflicts.
302     if (IsStandardIce() &&
303         !MaybeIceRoleConflict(addr, msg.get(), remote_username)) {
304       LOG(LS_INFO) << "Received conflicting role from the peer.";
305       return;
306     }
307
308     SignalUnknownAddress(this, addr, proto, msg.get(), remote_username, false);
309   } else {
310     // NOTE(tschmelcher): STUN_BINDING_RESPONSE is benign. It occurs if we
311     // pruned a connection for this port while it had STUN requests in flight,
312     // because we then get back responses for them, which this code correctly
313     // does not handle.
314     if (msg->type() != STUN_BINDING_RESPONSE) {
315       LOG_J(LS_ERROR, this) << "Received unexpected STUN message type ("
316                             << msg->type() << ") from unknown address ("
317                             << addr.ToSensitiveString() << ")";
318     }
319   }
320 }
321
322 void Port::OnReadyToSend() {
323   AddressMap::iterator iter = connections_.begin();
324   for (; iter != connections_.end(); ++iter) {
325     iter->second->OnReadyToSend();
326   }
327 }
328
329 size_t Port::AddPrflxCandidate(const Candidate& local) {
330   candidates_.push_back(local);
331   return (candidates_.size() - 1);
332 }
333
334 bool Port::IsStandardIce() const {
335   return (ice_protocol_ == ICEPROTO_RFC5245);
336 }
337
338 bool Port::IsGoogleIce() const {
339   return (ice_protocol_ == ICEPROTO_GOOGLE);
340 }
341
342 bool Port::IsHybridIce() const {
343   return (ice_protocol_ == ICEPROTO_HYBRID);
344 }
345
346 bool Port::GetStunMessage(const char* data, size_t size,
347                           const talk_base::SocketAddress& addr,
348                           IceMessage** out_msg, std::string* out_username) {
349   // NOTE: This could clearly be optimized to avoid allocating any memory.
350   //       However, at the data rates we'll be looking at on the client side,
351   //       this probably isn't worth worrying about.
352   ASSERT(out_msg != NULL);
353   ASSERT(out_username != NULL);
354   *out_msg = NULL;
355   out_username->clear();
356
357   // Don't bother parsing the packet if we can tell it's not STUN.
358   // In ICE mode, all STUN packets will have a valid fingerprint.
359   if (IsStandardIce() && !StunMessage::ValidateFingerprint(data, size)) {
360     return false;
361   }
362
363   // Parse the request message.  If the packet is not a complete and correct
364   // STUN message, then ignore it.
365   talk_base::scoped_ptr<IceMessage> stun_msg(new IceMessage());
366   talk_base::ByteBuffer buf(data, size);
367   if (!stun_msg->Read(&buf) || (buf.Length() > 0)) {
368     return false;
369   }
370
371   if (stun_msg->type() == STUN_BINDING_REQUEST) {
372     // Check for the presence of USERNAME and MESSAGE-INTEGRITY (if ICE) first.
373     // If not present, fail with a 400 Bad Request.
374     if (!stun_msg->GetByteString(STUN_ATTR_USERNAME) ||
375         (IsStandardIce() &&
376          !stun_msg->GetByteString(STUN_ATTR_MESSAGE_INTEGRITY))) {
377       LOG_J(LS_ERROR, this) << "Received STUN request without username/M-I "
378                             << "from " << addr.ToSensitiveString();
379       SendBindingErrorResponse(stun_msg.get(), addr, STUN_ERROR_BAD_REQUEST,
380                                STUN_ERROR_REASON_BAD_REQUEST);
381       return true;
382     }
383
384     // If the username is bad or unknown, fail with a 401 Unauthorized.
385     std::string local_ufrag;
386     std::string remote_ufrag;
387     IceProtocolType remote_protocol_type;
388     if (!ParseStunUsername(stun_msg.get(), &local_ufrag, &remote_ufrag,
389                            &remote_protocol_type) ||
390         local_ufrag != username_fragment()) {
391       LOG_J(LS_ERROR, this) << "Received STUN request with bad local username "
392                             << local_ufrag << " from "
393                             << addr.ToSensitiveString();
394       SendBindingErrorResponse(stun_msg.get(), addr, STUN_ERROR_UNAUTHORIZED,
395                                STUN_ERROR_REASON_UNAUTHORIZED);
396       return true;
397     }
398
399     // Port is initialized to GOOGLE-ICE protocol type. If pings from remote
400     // are received before the signal message, protocol type may be different.
401     // Based on the STUN username, we can determine what's the remote protocol.
402     // This also enables us to send the response back using the same protocol
403     // as the request.
404     if (IsHybridIce()) {
405       SetIceProtocolType(remote_protocol_type);
406     }
407
408     // If ICE, and the MESSAGE-INTEGRITY is bad, fail with a 401 Unauthorized
409     if (IsStandardIce() &&
410         !stun_msg->ValidateMessageIntegrity(data, size, password_)) {
411       LOG_J(LS_ERROR, this) << "Received STUN request with bad M-I "
412                             << "from " << addr.ToSensitiveString();
413       SendBindingErrorResponse(stun_msg.get(), addr, STUN_ERROR_UNAUTHORIZED,
414                                STUN_ERROR_REASON_UNAUTHORIZED);
415       return true;
416     }
417     out_username->assign(remote_ufrag);
418   } else if ((stun_msg->type() == STUN_BINDING_RESPONSE) ||
419              (stun_msg->type() == STUN_BINDING_ERROR_RESPONSE)) {
420     if (stun_msg->type() == STUN_BINDING_ERROR_RESPONSE) {
421       if (const StunErrorCodeAttribute* error_code = stun_msg->GetErrorCode()) {
422         LOG_J(LS_ERROR, this) << "Received STUN binding error:"
423                               << " class=" << error_code->eclass()
424                               << " number=" << error_code->number()
425                               << " reason='" << error_code->reason() << "'"
426                               << " from " << addr.ToSensitiveString();
427         // Return message to allow error-specific processing
428       } else {
429         LOG_J(LS_ERROR, this) << "Received STUN binding error without a error "
430                               << "code from " << addr.ToSensitiveString();
431         return true;
432       }
433     }
434     // NOTE: Username should not be used in verifying response messages.
435     out_username->clear();
436   } else if (stun_msg->type() == STUN_BINDING_INDICATION) {
437     LOG_J(LS_VERBOSE, this) << "Received STUN binding indication:"
438                             << " from " << addr.ToSensitiveString();
439     out_username->clear();
440     // No stun attributes will be verified, if it's stun indication message.
441     // Returning from end of the this method.
442   } else {
443     LOG_J(LS_ERROR, this) << "Received STUN packet with invalid type ("
444                           << stun_msg->type() << ") from "
445                           << addr.ToSensitiveString();
446     return true;
447   }
448
449   // Return the STUN message found.
450   *out_msg = stun_msg.release();
451   return true;
452 }
453
454 bool Port::IsCompatibleAddress(const talk_base::SocketAddress& addr) {
455   int family = ip().family();
456   // We use single-stack sockets, so families must match.
457   if (addr.family() != family) {
458     return false;
459   }
460   // Link-local IPv6 ports can only connect to other link-local IPv6 ports.
461   if (family == AF_INET6 && (IPIsPrivate(ip()) != IPIsPrivate(addr.ipaddr()))) {
462     return false;
463   }
464   return true;
465 }
466
467 bool Port::ParseStunUsername(const StunMessage* stun_msg,
468                              std::string* local_ufrag,
469                              std::string* remote_ufrag,
470                              IceProtocolType* remote_protocol_type) const {
471   // The packet must include a username that either begins or ends with our
472   // fragment.  It should begin with our fragment if it is a request and it
473   // should end with our fragment if it is a response.
474   local_ufrag->clear();
475   remote_ufrag->clear();
476   const StunByteStringAttribute* username_attr =
477         stun_msg->GetByteString(STUN_ATTR_USERNAME);
478   if (username_attr == NULL)
479     return false;
480
481   const std::string username_attr_str = username_attr->GetString();
482   size_t colon_pos = username_attr_str.find(":");
483   // If we are in hybrid mode set the appropriate ice protocol type based on
484   // the username argument style.
485   if (IsHybridIce()) {
486     *remote_protocol_type = (colon_pos != std::string::npos) ?
487         ICEPROTO_RFC5245 : ICEPROTO_GOOGLE;
488   } else {
489     *remote_protocol_type = ice_protocol_;
490   }
491   if (*remote_protocol_type == ICEPROTO_RFC5245) {
492     if (colon_pos != std::string::npos) {  // RFRAG:LFRAG
493       *local_ufrag = username_attr_str.substr(0, colon_pos);
494       *remote_ufrag = username_attr_str.substr(
495           colon_pos + 1, username_attr_str.size());
496     } else {
497       return false;
498     }
499   } else if (*remote_protocol_type == ICEPROTO_GOOGLE) {
500     int remote_frag_len = static_cast<int>(username_attr_str.size());
501     remote_frag_len -= static_cast<int>(username_fragment().size());
502     if (remote_frag_len < 0)
503       return false;
504
505     *local_ufrag = username_attr_str.substr(0, username_fragment().size());
506     *remote_ufrag = username_attr_str.substr(
507         username_fragment().size(), username_attr_str.size());
508   }
509   return true;
510 }
511
512 bool Port::MaybeIceRoleConflict(
513     const talk_base::SocketAddress& addr, IceMessage* stun_msg,
514     const std::string& remote_ufrag) {
515   // Validate ICE_CONTROLLING or ICE_CONTROLLED attributes.
516   bool ret = true;
517   IceRole remote_ice_role = ICEROLE_UNKNOWN;
518   uint64 remote_tiebreaker = 0;
519   const StunUInt64Attribute* stun_attr =
520       stun_msg->GetUInt64(STUN_ATTR_ICE_CONTROLLING);
521   if (stun_attr) {
522     remote_ice_role = ICEROLE_CONTROLLING;
523     remote_tiebreaker = stun_attr->value();
524   }
525
526   // If |remote_ufrag| is same as port local username fragment and
527   // tie breaker value received in the ping message matches port
528   // tiebreaker value this must be a loopback call.
529   // We will treat this as valid scenario.
530   if (remote_ice_role == ICEROLE_CONTROLLING &&
531       username_fragment() == remote_ufrag &&
532       remote_tiebreaker == IceTiebreaker()) {
533     return true;
534   }
535
536   stun_attr = stun_msg->GetUInt64(STUN_ATTR_ICE_CONTROLLED);
537   if (stun_attr) {
538     remote_ice_role = ICEROLE_CONTROLLED;
539     remote_tiebreaker = stun_attr->value();
540   }
541
542   switch (ice_role_) {
543     case ICEROLE_CONTROLLING:
544       if (ICEROLE_CONTROLLING == remote_ice_role) {
545         if (remote_tiebreaker >= tiebreaker_) {
546           SignalRoleConflict(this);
547         } else {
548           // Send Role Conflict (487) error response.
549           SendBindingErrorResponse(stun_msg, addr,
550               STUN_ERROR_ROLE_CONFLICT, STUN_ERROR_REASON_ROLE_CONFLICT);
551           ret = false;
552         }
553       }
554       break;
555     case ICEROLE_CONTROLLED:
556       if (ICEROLE_CONTROLLED == remote_ice_role) {
557         if (remote_tiebreaker < tiebreaker_) {
558           SignalRoleConflict(this);
559         } else {
560           // Send Role Conflict (487) error response.
561           SendBindingErrorResponse(stun_msg, addr,
562               STUN_ERROR_ROLE_CONFLICT, STUN_ERROR_REASON_ROLE_CONFLICT);
563           ret = false;
564         }
565       }
566       break;
567     default:
568       ASSERT(false);
569   }
570   return ret;
571 }
572
573 void Port::CreateStunUsername(const std::string& remote_username,
574                               std::string* stun_username_attr_str) const {
575   stun_username_attr_str->clear();
576   *stun_username_attr_str = remote_username;
577   if (IsStandardIce()) {
578     // Connectivity checks from L->R will have username RFRAG:LFRAG.
579     stun_username_attr_str->append(":");
580   }
581   stun_username_attr_str->append(username_fragment());
582 }
583
584 void Port::SendBindingResponse(StunMessage* request,
585                                const talk_base::SocketAddress& addr) {
586   ASSERT(request->type() == STUN_BINDING_REQUEST);
587
588   // Retrieve the username from the request.
589   const StunByteStringAttribute* username_attr =
590       request->GetByteString(STUN_ATTR_USERNAME);
591   ASSERT(username_attr != NULL);
592   if (username_attr == NULL) {
593     // No valid username, skip the response.
594     return;
595   }
596
597   // Fill in the response message.
598   StunMessage response;
599   response.SetType(STUN_BINDING_RESPONSE);
600   response.SetTransactionID(request->transaction_id());
601   const StunUInt32Attribute* retransmit_attr =
602       request->GetUInt32(STUN_ATTR_RETRANSMIT_COUNT);
603   if (retransmit_attr) {
604     // Inherit the incoming retransmit value in the response so the other side
605     // can see our view of lost pings.
606     response.AddAttribute(new StunUInt32Attribute(
607         STUN_ATTR_RETRANSMIT_COUNT, retransmit_attr->value()));
608
609     if (retransmit_attr->value() > CONNECTION_WRITE_CONNECT_FAILURES) {
610       LOG_J(LS_INFO, this)
611           << "Received a remote ping with high retransmit count: "
612           << retransmit_attr->value();
613     }
614   }
615
616   // Only GICE messages have USERNAME and MAPPED-ADDRESS in the response.
617   // ICE messages use XOR-MAPPED-ADDRESS, and add MESSAGE-INTEGRITY.
618   if (IsStandardIce()) {
619     response.AddAttribute(
620         new StunXorAddressAttribute(STUN_ATTR_XOR_MAPPED_ADDRESS, addr));
621     response.AddMessageIntegrity(password_);
622     response.AddFingerprint();
623   } else if (IsGoogleIce()) {
624     response.AddAttribute(
625         new StunAddressAttribute(STUN_ATTR_MAPPED_ADDRESS, addr));
626     response.AddAttribute(new StunByteStringAttribute(
627         STUN_ATTR_USERNAME, username_attr->GetString()));
628   }
629
630   // Send the response message.
631   talk_base::ByteBuffer buf;
632   response.Write(&buf);
633   talk_base::PacketOptions options(DefaultDscpValue());
634   if (SendTo(buf.Data(), buf.Length(), addr, options, false) < 0) {
635     LOG_J(LS_ERROR, this) << "Failed to send STUN ping response to "
636                           << addr.ToSensitiveString();
637   }
638
639   // The fact that we received a successful request means that this connection
640   // (if one exists) should now be readable.
641   Connection* conn = GetConnection(addr);
642   ASSERT(conn != NULL);
643   if (conn)
644     conn->ReceivedPing();
645 }
646
647 void Port::SendBindingErrorResponse(StunMessage* request,
648                                     const talk_base::SocketAddress& addr,
649                                     int error_code, const std::string& reason) {
650   ASSERT(request->type() == STUN_BINDING_REQUEST);
651
652   // Fill in the response message.
653   StunMessage response;
654   response.SetType(STUN_BINDING_ERROR_RESPONSE);
655   response.SetTransactionID(request->transaction_id());
656
657   // When doing GICE, we need to write out the error code incorrectly to
658   // maintain backwards compatiblility.
659   StunErrorCodeAttribute* error_attr = StunAttribute::CreateErrorCode();
660   if (IsStandardIce()) {
661     error_attr->SetCode(error_code);
662   } else if (IsGoogleIce()) {
663     error_attr->SetClass(error_code / 256);
664     error_attr->SetNumber(error_code % 256);
665   }
666   error_attr->SetReason(reason);
667   response.AddAttribute(error_attr);
668
669   if (IsStandardIce()) {
670     // Per Section 10.1.2, certain error cases don't get a MESSAGE-INTEGRITY,
671     // because we don't have enough information to determine the shared secret.
672     if (error_code != STUN_ERROR_BAD_REQUEST &&
673         error_code != STUN_ERROR_UNAUTHORIZED)
674       response.AddMessageIntegrity(password_);
675     response.AddFingerprint();
676   } else if (IsGoogleIce()) {
677     // GICE responses include a username, if one exists.
678     const StunByteStringAttribute* username_attr =
679         request->GetByteString(STUN_ATTR_USERNAME);
680     if (username_attr)
681       response.AddAttribute(new StunByteStringAttribute(
682           STUN_ATTR_USERNAME, username_attr->GetString()));
683   }
684
685   // Send the response message.
686   talk_base::ByteBuffer buf;
687   response.Write(&buf);
688   talk_base::PacketOptions options(DefaultDscpValue());
689   SendTo(buf.Data(), buf.Length(), addr, options, false);
690   LOG_J(LS_INFO, this) << "Sending STUN binding error: reason=" << reason
691                        << " to " << addr.ToSensitiveString();
692 }
693
694 void Port::OnMessage(talk_base::Message *pmsg) {
695   ASSERT(pmsg->message_id == MSG_CHECKTIMEOUT);
696   CheckTimeout();
697 }
698
699 std::string Port::ToString() const {
700   std::stringstream ss;
701   ss << "Port[" << content_name_ << ":" << component_
702      << ":" << generation_ << ":" << type_
703      << ":" << network_->ToString() << "]";
704   return ss.str();
705 }
706
707 void Port::EnablePortPackets() {
708   enable_port_packets_ = true;
709 }
710
711 void Port::OnConnectionDestroyed(Connection* conn) {
712   AddressMap::iterator iter =
713       connections_.find(conn->remote_candidate().address());
714   ASSERT(iter != connections_.end());
715   connections_.erase(iter);
716
717   // On the controlled side, ports time out, but only after all connections
718   // fail.  Note: If a new connection is added after this message is posted,
719   // but it fails and is removed before kPortTimeoutDelay, then this message
720   //  will still cause the Port to be destroyed.
721   if (ice_role_ == ICEROLE_CONTROLLED)
722     thread_->PostDelayed(timeout_delay_, this, MSG_CHECKTIMEOUT);
723 }
724
725 void Port::Destroy() {
726   ASSERT(connections_.empty());
727   LOG_J(LS_INFO, this) << "Port deleted";
728   SignalDestroyed(this);
729   delete this;
730 }
731
732 void Port::CheckTimeout() {
733   ASSERT(ice_role_ == ICEROLE_CONTROLLED);
734   // If this port has no connections, then there's no reason to keep it around.
735   // When the connections time out (both read and write), they will delete
736   // themselves, so if we have any connections, they are either readable or
737   // writable (or still connecting).
738   if (connections_.empty())
739     Destroy();
740 }
741
742 const std::string Port::username_fragment() const {
743   if (!IsStandardIce() &&
744       component_ == ICE_CANDIDATE_COMPONENT_RTCP) {
745     // In GICE mode, we should adjust username fragment for rtcp component.
746     return GetRtcpUfragFromRtpUfrag(ice_username_fragment_);
747   } else {
748     return ice_username_fragment_;
749   }
750 }
751
752 // A ConnectionRequest is a simple STUN ping used to determine writability.
753 class ConnectionRequest : public StunRequest {
754  public:
755   explicit ConnectionRequest(Connection* connection)
756       : StunRequest(new IceMessage()),
757         connection_(connection) {
758   }
759
760   virtual ~ConnectionRequest() {
761   }
762
763   virtual void Prepare(StunMessage* request) {
764     request->SetType(STUN_BINDING_REQUEST);
765     std::string username;
766     connection_->port()->CreateStunUsername(
767         connection_->remote_candidate().username(), &username);
768     request->AddAttribute(
769         new StunByteStringAttribute(STUN_ATTR_USERNAME, username));
770
771     // connection_ already holds this ping, so subtract one from count.
772     if (connection_->port()->send_retransmit_count_attribute()) {
773       request->AddAttribute(new StunUInt32Attribute(
774           STUN_ATTR_RETRANSMIT_COUNT,
775           static_cast<uint32>(
776               connection_->pings_since_last_response_.size() - 1)));
777     }
778
779     // Adding ICE-specific attributes to the STUN request message.
780     if (connection_->port()->IsStandardIce()) {
781       // Adding ICE_CONTROLLED or ICE_CONTROLLING attribute based on the role.
782       if (connection_->port()->GetIceRole() == ICEROLE_CONTROLLING) {
783         request->AddAttribute(new StunUInt64Attribute(
784             STUN_ATTR_ICE_CONTROLLING, connection_->port()->IceTiebreaker()));
785         // Since we are trying aggressive nomination, sending USE-CANDIDATE
786         // attribute in every ping.
787         // If we are dealing with a ice-lite end point, nomination flag
788         // in Connection will be set to false by default. Once the connection
789         // becomes "best connection", nomination flag will be turned on.
790         if (connection_->use_candidate_attr()) {
791           request->AddAttribute(new StunByteStringAttribute(
792               STUN_ATTR_USE_CANDIDATE));
793         }
794       } else if (connection_->port()->GetIceRole() == ICEROLE_CONTROLLED) {
795         request->AddAttribute(new StunUInt64Attribute(
796             STUN_ATTR_ICE_CONTROLLED, connection_->port()->IceTiebreaker()));
797       } else {
798         ASSERT(false);
799       }
800
801       // Adding PRIORITY Attribute.
802       // Changing the type preference to Peer Reflexive and local preference
803       // and component id information is unchanged from the original priority.
804       // priority = (2^24)*(type preference) +
805       //           (2^8)*(local preference) +
806       //           (2^0)*(256 - component ID)
807       uint32 prflx_priority = ICE_TYPE_PREFERENCE_PRFLX << 24 |
808           (connection_->local_candidate().priority() & 0x00FFFFFF);
809       request->AddAttribute(
810           new StunUInt32Attribute(STUN_ATTR_PRIORITY, prflx_priority));
811
812       // Adding Message Integrity attribute.
813       request->AddMessageIntegrity(connection_->remote_candidate().password());
814       // Adding Fingerprint.
815       request->AddFingerprint();
816     }
817   }
818
819   virtual void OnResponse(StunMessage* response) {
820     connection_->OnConnectionRequestResponse(this, response);
821   }
822
823   virtual void OnErrorResponse(StunMessage* response) {
824     connection_->OnConnectionRequestErrorResponse(this, response);
825   }
826
827   virtual void OnTimeout() {
828     connection_->OnConnectionRequestTimeout(this);
829   }
830
831   virtual int GetNextDelay() {
832     // Each request is sent only once.  After a single delay , the request will
833     // time out.
834     timeout_ = true;
835     return CONNECTION_RESPONSE_TIMEOUT;
836   }
837
838  private:
839   Connection* connection_;
840 };
841
842 //
843 // Connection
844 //
845
846 Connection::Connection(Port* port, size_t index,
847                        const Candidate& remote_candidate)
848   : port_(port), local_candidate_index_(index),
849     remote_candidate_(remote_candidate), read_state_(STATE_READ_INIT),
850     write_state_(STATE_WRITE_INIT), connected_(true), pruned_(false),
851     use_candidate_attr_(false), remote_ice_mode_(ICEMODE_FULL),
852     requests_(port->thread()), rtt_(DEFAULT_RTT), last_ping_sent_(0),
853     last_ping_received_(0), last_data_received_(0),
854     last_ping_response_received_(0), reported_(false), state_(STATE_WAITING) {
855   // All of our connections start in WAITING state.
856   // TODO(mallinath) - Start connections from STATE_FROZEN.
857   // Wire up to send stun packets
858   requests_.SignalSendPacket.connect(this, &Connection::OnSendStunPacket);
859   LOG_J(LS_INFO, this) << "Connection created";
860 }
861
862 Connection::~Connection() {
863 }
864
865 const Candidate& Connection::local_candidate() const {
866   ASSERT(local_candidate_index_ < port_->Candidates().size());
867   return port_->Candidates()[local_candidate_index_];
868 }
869
870 uint64 Connection::priority() const {
871   uint64 priority = 0;
872   // RFC 5245 - 5.7.2.  Computing Pair Priority and Ordering Pairs
873   // Let G be the priority for the candidate provided by the controlling
874   // agent.  Let D be the priority for the candidate provided by the
875   // controlled agent.
876   // pair priority = 2^32*MIN(G,D) + 2*MAX(G,D) + (G>D?1:0)
877   IceRole role = port_->GetIceRole();
878   if (role != ICEROLE_UNKNOWN) {
879     uint32 g = 0;
880     uint32 d = 0;
881     if (role == ICEROLE_CONTROLLING) {
882       g = local_candidate().priority();
883       d = remote_candidate_.priority();
884     } else {
885       g = remote_candidate_.priority();
886       d = local_candidate().priority();
887     }
888     priority = talk_base::_min(g, d);
889     priority = priority << 32;
890     priority += 2 * talk_base::_max(g, d) + (g > d ? 1 : 0);
891   }
892   return priority;
893 }
894
895 void Connection::set_read_state(ReadState value) {
896   ReadState old_value = read_state_;
897   read_state_ = value;
898   if (value != old_value) {
899     LOG_J(LS_VERBOSE, this) << "set_read_state";
900     SignalStateChange(this);
901     CheckTimeout();
902   }
903 }
904
905 void Connection::set_write_state(WriteState value) {
906   WriteState old_value = write_state_;
907   write_state_ = value;
908   if (value != old_value) {
909     LOG_J(LS_VERBOSE, this) << "set_write_state";
910     SignalStateChange(this);
911     CheckTimeout();
912   }
913 }
914
915 void Connection::set_state(State state) {
916   State old_state = state_;
917   state_ = state;
918   if (state != old_state) {
919     LOG_J(LS_VERBOSE, this) << "set_state";
920   }
921 }
922
923 void Connection::set_connected(bool value) {
924   bool old_value = connected_;
925   connected_ = value;
926   if (value != old_value) {
927     LOG_J(LS_VERBOSE, this) << "set_connected";
928   }
929 }
930
931 void Connection::set_use_candidate_attr(bool enable) {
932   use_candidate_attr_ = enable;
933 }
934
935 void Connection::OnSendStunPacket(const void* data, size_t size,
936                                   StunRequest* req) {
937   talk_base::PacketOptions options(port_->DefaultDscpValue());
938   if (port_->SendTo(data, size, remote_candidate_.address(),
939                     options, false) < 0) {
940     LOG_J(LS_WARNING, this) << "Failed to send STUN ping " << req->id();
941   }
942 }
943
944 void Connection::OnReadPacket(
945   const char* data, size_t size, const talk_base::PacketTime& packet_time) {
946   talk_base::scoped_ptr<IceMessage> msg;
947   std::string remote_ufrag;
948   const talk_base::SocketAddress& addr(remote_candidate_.address());
949   if (!port_->GetStunMessage(data, size, addr, msg.accept(), &remote_ufrag)) {
950     // The packet did not parse as a valid STUN message
951
952     // If this connection is readable, then pass along the packet.
953     if (read_state_ == STATE_READABLE) {
954       // readable means data from this address is acceptable
955       // Send it on!
956
957       last_data_received_ = talk_base::Time();
958       recv_rate_tracker_.Update(size);
959       SignalReadPacket(this, data, size, packet_time);
960
961       // If timed out sending writability checks, start up again
962       if (!pruned_ && (write_state_ == STATE_WRITE_TIMEOUT)) {
963         LOG(LS_WARNING) << "Received a data packet on a timed-out Connection. "
964                         << "Resetting state to STATE_WRITE_INIT.";
965         set_write_state(STATE_WRITE_INIT);
966       }
967     } else {
968       // Not readable means the remote address hasn't sent a valid
969       // binding request yet.
970
971       LOG_J(LS_WARNING, this)
972         << "Received non-STUN packet from an unreadable connection.";
973     }
974   } else if (!msg) {
975     // The packet was STUN, but failed a check and was handled internally.
976   } else {
977     // The packet is STUN and passed the Port checks.
978     // Perform our own checks to ensure this packet is valid.
979     // If this is a STUN request, then update the readable bit and respond.
980     // If this is a STUN response, then update the writable bit.
981     switch (msg->type()) {
982       case STUN_BINDING_REQUEST:
983         if (remote_ufrag == remote_candidate_.username()) {
984           // Check for role conflicts.
985           if (port_->IsStandardIce() &&
986               !port_->MaybeIceRoleConflict(addr, msg.get(), remote_ufrag)) {
987             // Received conflicting role from the peer.
988             LOG(LS_INFO) << "Received conflicting role from the peer.";
989             return;
990           }
991
992           // Incoming, validated stun request from remote peer.
993           // This call will also set the connection readable.
994           port_->SendBindingResponse(msg.get(), addr);
995
996           // If timed out sending writability checks, start up again
997           if (!pruned_ && (write_state_ == STATE_WRITE_TIMEOUT))
998             set_write_state(STATE_WRITE_INIT);
999
1000           if ((port_->IsStandardIce()) &&
1001               (port_->GetIceRole() == ICEROLE_CONTROLLED)) {
1002             const StunByteStringAttribute* use_candidate_attr =
1003                 msg->GetByteString(STUN_ATTR_USE_CANDIDATE);
1004             if (use_candidate_attr)
1005               SignalUseCandidate(this);
1006           }
1007         } else {
1008           // The packet had the right local username, but the remote username
1009           // was not the right one for the remote address.
1010           LOG_J(LS_ERROR, this)
1011             << "Received STUN request with bad remote username "
1012             << remote_ufrag;
1013           port_->SendBindingErrorResponse(msg.get(), addr,
1014                                           STUN_ERROR_UNAUTHORIZED,
1015                                           STUN_ERROR_REASON_UNAUTHORIZED);
1016
1017         }
1018         break;
1019
1020       // Response from remote peer. Does it match request sent?
1021       // This doesn't just check, it makes callbacks if transaction
1022       // id's match.
1023       case STUN_BINDING_RESPONSE:
1024       case STUN_BINDING_ERROR_RESPONSE:
1025         if (port_->IsGoogleIce() ||
1026             msg->ValidateMessageIntegrity(
1027                 data, size, remote_candidate().password())) {
1028           requests_.CheckResponse(msg.get());
1029         }
1030         // Otherwise silently discard the response message.
1031         break;
1032
1033       // Remote end point sent an STUN indication instead of regular
1034       // binding request. In this case |last_ping_received_| will be updated.
1035       // Otherwise we can mark connection to read timeout. No response will be
1036       // sent in this scenario.
1037       case STUN_BINDING_INDICATION:
1038         if (port_->IsStandardIce() && read_state_ == STATE_READABLE) {
1039           ReceivedPing();
1040         } else {
1041           LOG_J(LS_WARNING, this) << "Received STUN binding indication "
1042                                   << "from an unreadable connection.";
1043         }
1044         break;
1045
1046       default:
1047         ASSERT(false);
1048         break;
1049     }
1050   }
1051 }
1052
1053 void Connection::OnReadyToSend() {
1054   if (write_state_ == STATE_WRITABLE) {
1055     SignalReadyToSend(this);
1056   }
1057 }
1058
1059 void Connection::Prune() {
1060   if (!pruned_) {
1061     LOG_J(LS_VERBOSE, this) << "Connection pruned";
1062     pruned_ = true;
1063     requests_.Clear();
1064     set_write_state(STATE_WRITE_TIMEOUT);
1065   }
1066 }
1067
1068 void Connection::Destroy() {
1069   LOG_J(LS_VERBOSE, this) << "Connection destroyed";
1070   set_read_state(STATE_READ_TIMEOUT);
1071   set_write_state(STATE_WRITE_TIMEOUT);
1072 }
1073
1074 void Connection::UpdateState(uint32 now) {
1075   uint32 rtt = ConservativeRTTEstimate(rtt_);
1076
1077   std::string pings;
1078   for (size_t i = 0; i < pings_since_last_response_.size(); ++i) {
1079     char buf[32];
1080     talk_base::sprintfn(buf, sizeof(buf), "%u",
1081         pings_since_last_response_[i]);
1082     pings.append(buf).append(" ");
1083   }
1084   LOG_J(LS_VERBOSE, this) << "UpdateState(): pings_since_last_response_=" <<
1085       pings << ", rtt=" << rtt << ", now=" << now;
1086
1087   // Check the readable state.
1088   //
1089   // Since we don't know how many pings the other side has attempted, the best
1090   // test we can do is a simple window.
1091   // If other side has not sent ping after connection has become readable, use
1092   // |last_data_received_| as the indication.
1093   // If remote endpoint is doing RFC 5245, it's not required to send ping
1094   // after connection is established. If this connection is serving a data
1095   // channel, it may not be in a position to send media continuously. Do not
1096   // mark connection timeout if it's in RFC5245 mode.
1097   // Below check will be performed with end point if it's doing google-ice.
1098   if (port_->IsGoogleIce() && (read_state_ == STATE_READABLE) &&
1099       (last_ping_received_ + CONNECTION_READ_TIMEOUT <= now) &&
1100       (last_data_received_ + CONNECTION_READ_TIMEOUT <= now)) {
1101     LOG_J(LS_INFO, this) << "Unreadable after "
1102                          << now - last_ping_received_
1103                          << " ms without a ping,"
1104                          << " ms since last received response="
1105                          << now - last_ping_response_received_
1106                          << " ms since last received data="
1107                          << now - last_data_received_
1108                          << " rtt=" << rtt;
1109     set_read_state(STATE_READ_TIMEOUT);
1110   }
1111
1112   // Check the writable state.  (The order of these checks is important.)
1113   //
1114   // Before becoming unwritable, we allow for a fixed number of pings to fail
1115   // (i.e., receive no response).  We also have to give the response time to
1116   // get back, so we include a conservative estimate of this.
1117   //
1118   // Before timing out writability, we give a fixed amount of time.  This is to
1119   // allow for changes in network conditions.
1120
1121   if ((write_state_ == STATE_WRITABLE) &&
1122       TooManyFailures(pings_since_last_response_,
1123                       CONNECTION_WRITE_CONNECT_FAILURES,
1124                       rtt,
1125                       now) &&
1126       TooLongWithoutResponse(pings_since_last_response_,
1127                              CONNECTION_WRITE_CONNECT_TIMEOUT,
1128                              now)) {
1129     uint32 max_pings = CONNECTION_WRITE_CONNECT_FAILURES;
1130     LOG_J(LS_INFO, this) << "Unwritable after " << max_pings
1131                          << " ping failures and "
1132                          << now - pings_since_last_response_[0]
1133                          << " ms without a response,"
1134                          << " ms since last received ping="
1135                          << now - last_ping_received_
1136                          << " ms since last received data="
1137                          << now - last_data_received_
1138                          << " rtt=" << rtt;
1139     set_write_state(STATE_WRITE_UNRELIABLE);
1140   }
1141
1142   if ((write_state_ == STATE_WRITE_UNRELIABLE ||
1143        write_state_ == STATE_WRITE_INIT) &&
1144       TooLongWithoutResponse(pings_since_last_response_,
1145                              CONNECTION_WRITE_TIMEOUT,
1146                              now)) {
1147     LOG_J(LS_INFO, this) << "Timed out after "
1148                          << now - pings_since_last_response_[0]
1149                          << " ms without a response, rtt=" << rtt;
1150     set_write_state(STATE_WRITE_TIMEOUT);
1151   }
1152 }
1153
1154 void Connection::Ping(uint32 now) {
1155   ASSERT(connected_);
1156   last_ping_sent_ = now;
1157   pings_since_last_response_.push_back(now);
1158   ConnectionRequest *req = new ConnectionRequest(this);
1159   LOG_J(LS_VERBOSE, this) << "Sending STUN ping " << req->id() << " at " << now;
1160   requests_.Send(req);
1161   state_ = STATE_INPROGRESS;
1162 }
1163
1164 void Connection::ReceivedPing() {
1165   last_ping_received_ = talk_base::Time();
1166   set_read_state(STATE_READABLE);
1167 }
1168
1169 std::string Connection::ToString() const {
1170   const char CONNECT_STATE_ABBREV[2] = {
1171     '-',  // not connected (false)
1172     'C',  // connected (true)
1173   };
1174   const char READ_STATE_ABBREV[3] = {
1175     '-',  // STATE_READ_INIT
1176     'R',  // STATE_READABLE
1177     'x',  // STATE_READ_TIMEOUT
1178   };
1179   const char WRITE_STATE_ABBREV[4] = {
1180     'W',  // STATE_WRITABLE
1181     'w',  // STATE_WRITE_UNRELIABLE
1182     '-',  // STATE_WRITE_INIT
1183     'x',  // STATE_WRITE_TIMEOUT
1184   };
1185   const std::string ICESTATE[4] = {
1186     "W",  // STATE_WAITING
1187     "I",  // STATE_INPROGRESS
1188     "S",  // STATE_SUCCEEDED
1189     "F"   // STATE_FAILED
1190   };
1191   const Candidate& local = local_candidate();
1192   const Candidate& remote = remote_candidate();
1193   std::stringstream ss;
1194   ss << "Conn[" << port_->content_name()
1195      << ":" << local.id() << ":" << local.component()
1196      << ":" << local.generation()
1197      << ":" << local.type() << ":" << local.protocol()
1198      << ":" << local.address().ToSensitiveString()
1199      << "->" << remote.id() << ":" << remote.component()
1200      << ":" << remote.generation()
1201      << ":" << remote.type() << ":"
1202      << remote.protocol() << ":" << remote.address().ToSensitiveString()
1203      << "|"
1204      << CONNECT_STATE_ABBREV[connected()]
1205      << READ_STATE_ABBREV[read_state()]
1206      << WRITE_STATE_ABBREV[write_state()]
1207      << ICESTATE[state()]
1208      << "|";
1209   if (rtt_ < DEFAULT_RTT) {
1210     ss << rtt_ << "]";
1211   } else {
1212     ss << "-]";
1213   }
1214   return ss.str();
1215 }
1216
1217 std::string Connection::ToSensitiveString() const {
1218   return ToString();
1219 }
1220
1221 void Connection::OnConnectionRequestResponse(ConnectionRequest* request,
1222                                              StunMessage* response) {
1223   // We've already validated that this is a STUN binding response with
1224   // the correct local and remote username for this connection.
1225   // So if we're not already, become writable. We may be bringing a pruned
1226   // connection back to life, but if we don't really want it, we can always
1227   // prune it again.
1228   uint32 rtt = request->Elapsed();
1229   set_write_state(STATE_WRITABLE);
1230   set_state(STATE_SUCCEEDED);
1231
1232   if (remote_ice_mode_ == ICEMODE_LITE) {
1233     // A ice-lite end point never initiates ping requests. This will allow
1234     // us to move to STATE_READABLE.
1235     ReceivedPing();
1236   }
1237
1238   std::string pings;
1239   for (size_t i = 0; i < pings_since_last_response_.size(); ++i) {
1240     char buf[32];
1241     talk_base::sprintfn(buf, sizeof(buf), "%u",
1242         pings_since_last_response_[i]);
1243     pings.append(buf).append(" ");
1244   }
1245
1246   talk_base::LoggingSeverity level =
1247       (pings_since_last_response_.size() > CONNECTION_WRITE_CONNECT_FAILURES) ?
1248           talk_base::LS_INFO : talk_base::LS_VERBOSE;
1249
1250   LOG_JV(level, this) << "Received STUN ping response " << request->id()
1251                       << ", pings_since_last_response_=" << pings
1252                       << ", rtt=" << rtt;
1253
1254   pings_since_last_response_.clear();
1255   last_ping_response_received_ = talk_base::Time();
1256   rtt_ = (RTT_RATIO * rtt_ + rtt) / (RTT_RATIO + 1);
1257
1258   // Peer reflexive candidate is only for RFC 5245 ICE.
1259   if (port_->IsStandardIce()) {
1260     MaybeAddPrflxCandidate(request, response);
1261   }
1262 }
1263
1264 void Connection::OnConnectionRequestErrorResponse(ConnectionRequest* request,
1265                                                   StunMessage* response) {
1266   const StunErrorCodeAttribute* error_attr = response->GetErrorCode();
1267   int error_code = STUN_ERROR_GLOBAL_FAILURE;
1268   if (error_attr) {
1269     if (port_->IsGoogleIce()) {
1270       // When doing GICE, the error code is written out incorrectly, so we need
1271       // to unmunge it here.
1272       error_code = error_attr->eclass() * 256 + error_attr->number();
1273     } else {
1274       error_code = error_attr->code();
1275     }
1276   }
1277
1278   if (error_code == STUN_ERROR_UNKNOWN_ATTRIBUTE ||
1279       error_code == STUN_ERROR_SERVER_ERROR ||
1280       error_code == STUN_ERROR_UNAUTHORIZED) {
1281     // Recoverable error, retry
1282   } else if (error_code == STUN_ERROR_STALE_CREDENTIALS) {
1283     // Race failure, retry
1284   } else if (error_code == STUN_ERROR_ROLE_CONFLICT) {
1285     HandleRoleConflictFromPeer();
1286   } else {
1287     // This is not a valid connection.
1288     LOG_J(LS_ERROR, this) << "Received STUN error response, code="
1289                           << error_code << "; killing connection";
1290     set_state(STATE_FAILED);
1291     set_write_state(STATE_WRITE_TIMEOUT);
1292   }
1293 }
1294
1295 void Connection::OnConnectionRequestTimeout(ConnectionRequest* request) {
1296   // Log at LS_INFO if we miss a ping on a writable connection.
1297   talk_base::LoggingSeverity sev = (write_state_ == STATE_WRITABLE) ?
1298       talk_base::LS_INFO : talk_base::LS_VERBOSE;
1299   LOG_JV(sev, this) << "Timing-out STUN ping " << request->id()
1300                     << " after " << request->Elapsed() << " ms";
1301 }
1302
1303 void Connection::CheckTimeout() {
1304   // If both read and write have timed out or read has never initialized, then
1305   // this connection can contribute no more to p2p socket unless at some later
1306   // date readability were to come back.  However, we gave readability a long
1307   // time to timeout, so at this point, it seems fair to get rid of this
1308   // connection.
1309   if ((read_state_ == STATE_READ_TIMEOUT ||
1310        read_state_ == STATE_READ_INIT) &&
1311       write_state_ == STATE_WRITE_TIMEOUT) {
1312     port_->thread()->Post(this, MSG_DELETE);
1313   }
1314 }
1315
1316 void Connection::HandleRoleConflictFromPeer() {
1317   port_->SignalRoleConflict(port_);
1318 }
1319
1320 void Connection::OnMessage(talk_base::Message *pmsg) {
1321   ASSERT(pmsg->message_id == MSG_DELETE);
1322
1323   LOG_J(LS_INFO, this) << "Connection deleted";
1324   SignalDestroyed(this);
1325   delete this;
1326 }
1327
1328 size_t Connection::recv_bytes_second() {
1329   return recv_rate_tracker_.units_second();
1330 }
1331
1332 size_t Connection::recv_total_bytes() {
1333   return recv_rate_tracker_.total_units();
1334 }
1335
1336 size_t Connection::sent_bytes_second() {
1337   return send_rate_tracker_.units_second();
1338 }
1339
1340 size_t Connection::sent_total_bytes() {
1341   return send_rate_tracker_.total_units();
1342 }
1343
1344 void Connection::MaybeAddPrflxCandidate(ConnectionRequest* request,
1345                                         StunMessage* response) {
1346   // RFC 5245
1347   // The agent checks the mapped address from the STUN response.  If the
1348   // transport address does not match any of the local candidates that the
1349   // agent knows about, the mapped address represents a new candidate -- a
1350   // peer reflexive candidate.
1351   const StunAddressAttribute* addr =
1352       response->GetAddress(STUN_ATTR_XOR_MAPPED_ADDRESS);
1353   if (!addr) {
1354     LOG(LS_WARNING) << "Connection::OnConnectionRequestResponse - "
1355                     << "No MAPPED-ADDRESS or XOR-MAPPED-ADDRESS found in the "
1356                     << "stun response message";
1357     return;
1358   }
1359
1360   bool known_addr = false;
1361   for (size_t i = 0; i < port_->Candidates().size(); ++i) {
1362     if (port_->Candidates()[i].address() == addr->GetAddress()) {
1363       known_addr = true;
1364       break;
1365     }
1366   }
1367   if (known_addr) {
1368     return;
1369   }
1370
1371   // RFC 5245
1372   // Its priority is set equal to the value of the PRIORITY attribute
1373   // in the Binding request.
1374   const StunUInt32Attribute* priority_attr =
1375       request->msg()->GetUInt32(STUN_ATTR_PRIORITY);
1376   if (!priority_attr) {
1377     LOG(LS_WARNING) << "Connection::OnConnectionRequestResponse - "
1378                     << "No STUN_ATTR_PRIORITY found in the "
1379                     << "stun response message";
1380     return;
1381   }
1382   const uint32 priority = priority_attr->value();
1383   std::string id = talk_base::CreateRandomString(8);
1384
1385   Candidate new_local_candidate;
1386   new_local_candidate.set_id(id);
1387   new_local_candidate.set_component(local_candidate().component());
1388   new_local_candidate.set_type(PRFLX_PORT_TYPE);
1389   new_local_candidate.set_protocol(local_candidate().protocol());
1390   new_local_candidate.set_address(addr->GetAddress());
1391   new_local_candidate.set_priority(priority);
1392   new_local_candidate.set_username(local_candidate().username());
1393   new_local_candidate.set_password(local_candidate().password());
1394   new_local_candidate.set_network_name(local_candidate().network_name());
1395   new_local_candidate.set_related_address(local_candidate().address());
1396   new_local_candidate.set_foundation(
1397       ComputeFoundation(PRFLX_PORT_TYPE, local_candidate().protocol(),
1398                         local_candidate().address()));
1399
1400   // Change the local candidate of this Connection to the new prflx candidate.
1401   local_candidate_index_ = port_->AddPrflxCandidate(new_local_candidate);
1402
1403   // SignalStateChange to force a re-sort in P2PTransportChannel as this
1404   // Connection's local candidate has changed.
1405   SignalStateChange(this);
1406 }
1407
1408 ProxyConnection::ProxyConnection(Port* port, size_t index,
1409                                  const Candidate& candidate)
1410   : Connection(port, index, candidate), error_(0) {
1411 }
1412
1413 int ProxyConnection::Send(const void* data, size_t size,
1414                           const talk_base::PacketOptions& options) {
1415   if (write_state_ == STATE_WRITE_INIT || write_state_ == STATE_WRITE_TIMEOUT) {
1416     error_ = EWOULDBLOCK;
1417     return SOCKET_ERROR;
1418   }
1419   int sent = port_->SendTo(data, size, remote_candidate_.address(),
1420                            options, true);
1421   if (sent <= 0) {
1422     ASSERT(sent < 0);
1423     error_ = port_->GetError();
1424   } else {
1425     send_rate_tracker_.Update(sent);
1426   }
1427   return sent;
1428 }
1429
1430 }  // namespace cricket