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