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