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