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