Home | History | Annotate | Download | only in base
      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 
     43 namespace {
     44 
     45 // Determines whether we have seen at least the given maximum number of
     46 // pings fail to have a response.
     47 inline bool TooManyFailures(
     48     const std::vector<uint32>& pings_since_last_response,
     49     uint32 maximum_failures,
     50     uint32 rtt_estimate,
     51     uint32 now) {
     52 
     53   // If we haven't sent that many pings, then we can't have failed that many.
     54   if (pings_since_last_response.size() < maximum_failures)
     55     return false;
     56 
     57   // Check if the window in which we would expect a response to the ping has
     58   // already elapsed.
     59   return pings_since_last_response[maximum_failures - 1] + rtt_estimate < now;
     60 }
     61 
     62 // Determines whether we have gone too long without seeing any response.
     63 inline bool TooLongWithoutResponse(
     64     const std::vector<uint32>& pings_since_last_response,
     65     uint32 maximum_time,
     66     uint32 now) {
     67 
     68   if (pings_since_last_response.size() == 0)
     69     return false;
     70 
     71   return pings_since_last_response[0] + maximum_time < now;
     72 }
     73 
     74 // GICE(ICEPROTO_GOOGLE) requires different username for RTP and RTCP.
     75 // This function generates a different username by +1 on the last character of
     76 // the given username (|rtp_ufrag|).
     77 std::string GetRtcpUfragFromRtpUfrag(const std::string& rtp_ufrag) {
     78   ASSERT(!rtp_ufrag.empty());
     79   if (rtp_ufrag.empty()) {
     80     return rtp_ufrag;
     81   }
     82   // Change the last character to the one next to it in the base64 table.
     83   char new_last_char;
     84   if (!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.
     97 const uint32 MINIMUM_RTT = 100;   // 0.1 seconds
     98 const uint32 MAXIMUM_RTT = 3000;  // 3 seconds
     99 
    100 // When we don't have any RTT data, we have to pick something reasonable.  We
    101 // use a large value just in case the connection is really slow.
    102 const uint32 DEFAULT_RTT = MAXIMUM_RTT;
    103 
    104 // Computes our estimate of the RTT given the current estimate.
    105 inline uint32 ConservativeRTTEstimate(uint32 rtt) {
    106   return rtc::_max(MINIMUM_RTT, rtc::_min(MAXIMUM_RTT, 2 * rtt));
    107 }
    108 
    109 // Weighting of the old rtt value to new data.
    110 const int RTT_RATIO = 3;  // 3 : 1
    111 
    112 // The delay before we begin checking if this port is useless.
    113 const int kPortTimeoutDelay = 30 * 1000;  // 30 seconds
    114 
    115 // Used by the Connection.
    116 const uint32 MSG_DELETE = 1;
    117 }
    118 
    119 namespace cricket {
    120 
    121 // TODO(ronghuawu): Use "host", "srflx", "prflx" and "relay". But this requires
    122 // the signaling part be updated correspondingly as well.
    123 const char LOCAL_PORT_TYPE[] = "local";
    124 const char STUN_PORT_TYPE[] = "stun";
    125 const char PRFLX_PORT_TYPE[] = "prflx";
    126 const char RELAY_PORT_TYPE[] = "relay";
    127 
    128 const char UDP_PROTOCOL_NAME[] = "udp";
    129 const char TCP_PROTOCOL_NAME[] = "tcp";
    130 const char SSLTCP_PROTOCOL_NAME[] = "ssltcp";
    131 
    132 static const char* const PROTO_NAMES[] = { UDP_PROTOCOL_NAME,
    133                                            TCP_PROTOCOL_NAME,
    134                                            SSLTCP_PROTOCOL_NAME };
    135 
    136 const char* ProtoToString(ProtocolType proto) {
    137   return PROTO_NAMES[proto];
    138 }
    139 
    140 bool StringToProto(const char* value, ProtocolType* proto) {
    141   for (size_t i = 0; i <= PROTO_LAST; ++i) {
    142     if (_stricmp(PROTO_NAMES[i], value) == 0) {
    143       *proto = static_cast<ProtocolType>(i);
    144       return true;
    145     }
    146   }
    147   return false;
    148 }
    149 
    150 // RFC 6544, TCP candidate encoding rules.
    151 const int DISCARD_PORT = 9;
    152 const char TCPTYPE_ACTIVE_STR[] = "active";
    153 const char TCPTYPE_PASSIVE_STR[] = "passive";
    154 const 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.
    162 static 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 
    171 Port::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 
    194 Port::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 
    221 void 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 
    231 Port::~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 
    247 Connection* 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 
    255 void 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 
    291 void Port::AddConnection(Connection* conn) {
    292   connections_[conn->remote_candidate().address()] = conn;
    293   conn->SignalDestroyed.connect(this, &Port::OnConnectionDestroyed);
    294   SignalConnectionCreated(this, conn);
    295 }
    296 
    297 void 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 
    337 void Port::OnReadyToSend() {
    338   AddressMap::iterator iter = connections_.begin();
    339   for (; iter != connections_.end(); ++iter) {
    340     iter->second->OnReadyToSend();
    341   }
    342 }
    343 
    344 size_t Port::AddPrflxCandidate(const Candidate& local) {
    345   candidates_.push_back(local);
    346   return (candidates_.size() - 1);
    347 }
    348 
    349 bool Port::IsStandardIce() const {
    350   return (ice_protocol_ == ICEPROTO_RFC5245);
    351 }
    352 
    353 bool Port::IsGoogleIce() const {
    354   return (ice_protocol_ == ICEPROTO_GOOGLE);
    355 }
    356 
    357 bool Port::IsHybridIce() const {
    358   return (ice_protocol_ == ICEPROTO_HYBRID);
    359 }
    360 
    361 bool 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 
    469 bool 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 
    482 bool 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 
    527 bool 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 
    588 void 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 
    599 void 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 
    662 void 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 
    709 void Port::OnMessage(rtc::Message *pmsg) {
    710   ASSERT(pmsg->message_id == MSG_CHECKTIMEOUT);
    711   CheckTimeout();
    712 }
    713 
    714 std::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 
    722 void Port::EnablePortPackets() {
    723   enable_port_packets_ = true;
    724 }
    725 
    726 void 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 
    740 void Port::Destroy() {
    741   ASSERT(connections_.empty());
    742   LOG_J(LS_INFO, this) << "Port deleted";
    743   SignalDestroyed(this);
    744   delete this;
    745 }
    746 
    747 void 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 
    757 const 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.
    768 class 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 
    861 Connection::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 
    877 Connection::~Connection() {
    878 }
    879 
    880 const Candidate& Connection::local_candidate() const {
    881   ASSERT(local_candidate_index_ < port_->Candidates().size());
    882   return port_->Candidates()[local_candidate_index_];
    883 }
    884 
    885 uint64 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 
    910 void 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 
    920 void 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 
    930 void 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 
    938 void 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 
    946 void Connection::set_use_candidate_attr(bool enable) {
    947   use_candidate_attr_ = enable;
    948 }
    949 
    950 void 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 
    959 void 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 
   1068 void Connection::OnReadyToSend() {
   1069   if (write_state_ == STATE_WRITABLE) {
   1070     SignalReadyToSend(this);
   1071   }
   1072 }
   1073 
   1074 void 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 
   1083 void 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 
   1089 void 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 
   1169 void 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 
   1179 void Connection::ReceivedPing() {
   1180   last_ping_received_ = rtc::Time();
   1181   set_read_state(STATE_READABLE);
   1182 }
   1183 
   1184 std::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 
   1231 std::string Connection::ToSensitiveString() const {
   1232   return ToString();
   1233 }
   1234 
   1235 void 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 
   1278 void 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 
   1309 void 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 
   1317 void 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 
   1330 void Connection::HandleRoleConflictFromPeer() {
   1331   port_->SignalRoleConflict(port_);
   1332 }
   1333 
   1334 void 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 
   1342 size_t Connection::recv_bytes_second() {
   1343   return recv_rate_tracker_.units_second();
   1344 }
   1345 
   1346 size_t Connection::recv_total_bytes() {
   1347   return recv_rate_tracker_.total_units();
   1348 }
   1349 
   1350 size_t Connection::sent_bytes_second() {
   1351   return send_rate_tracker_.units_second();
   1352 }
   1353 
   1354 size_t Connection::sent_total_bytes() {
   1355   return send_rate_tracker_.total_units();
   1356 }
   1357 
   1358 void 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 
   1422 ProxyConnection::ProxyConnection(Port* port, size_t index,
   1423                                  const Candidate& candidate)
   1424   : Connection(port, index, candidate), error_(0) {
   1425 }
   1426 
   1427 int 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