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