| OLD | NEW | 
|     1 /* |     1 /* | 
|     2  *  Copyright 2004 The WebRTC Project Authors. All rights reserved. |     2  *  Copyright 2004 The WebRTC Project Authors. All rights reserved. | 
|     3  * |     3  * | 
|     4  *  Use of this source code is governed by a BSD-style license |     4  *  Use of this source code is governed by a BSD-style license | 
|     5  *  that can be found in the LICENSE file in the root of the source |     5  *  that can be found in the LICENSE file in the root of the source | 
|     6  *  tree. An additional intellectual property rights grant can be found |     6  *  tree. An additional intellectual property rights grant can be found | 
|     7  *  in the file PATENTS.  All contributing project authors may |     7  *  in the file PATENTS.  All contributing project authors may | 
|     8  *  be found in the AUTHORS file in the root of the source tree. |     8  *  be found in the AUTHORS file in the root of the source tree. | 
|     9  */ |     9  */ | 
|    10  |    10  | 
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|    51     uint32 maximum_time, |    51     uint32 maximum_time, | 
|    52     uint32 now) { |    52     uint32 now) { | 
|    53  |    53  | 
|    54   if (pings_since_last_response.size() == 0) |    54   if (pings_since_last_response.size() == 0) | 
|    55     return false; |    55     return false; | 
|    56  |    56  | 
|    57   auto first = pings_since_last_response[0]; |    57   auto first = pings_since_last_response[0]; | 
|    58   return now > (first.sent_time + maximum_time); |    58   return now > (first.sent_time + maximum_time); | 
|    59 } |    59 } | 
|    60  |    60  | 
|    61 // GICE(ICEPROTO_GOOGLE) requires different username for RTP and RTCP. |  | 
|    62 // This function generates a different username by +1 on the last character of |  | 
|    63 // the given username (|rtp_ufrag|). |  | 
|    64 std::string GetRtcpUfragFromRtpUfrag(const std::string& rtp_ufrag) { |  | 
|    65   ASSERT(!rtp_ufrag.empty()); |  | 
|    66   if (rtp_ufrag.empty()) { |  | 
|    67     return rtp_ufrag; |  | 
|    68   } |  | 
|    69   // Change the last character to the one next to it in the base64 table. |  | 
|    70   char new_last_char; |  | 
|    71   if (!rtc::Base64::GetNextBase64Char(rtp_ufrag[rtp_ufrag.size() - 1], |  | 
|    72                                             &new_last_char)) { |  | 
|    73     // Should not be here. |  | 
|    74     ASSERT(false); |  | 
|    75   } |  | 
|    76   std::string rtcp_ufrag = rtp_ufrag; |  | 
|    77   rtcp_ufrag[rtcp_ufrag.size() - 1] = new_last_char; |  | 
|    78   ASSERT(rtcp_ufrag != rtp_ufrag); |  | 
|    79   return rtcp_ufrag; |  | 
|    80 } |  | 
|    81  |  | 
|    82 // We will restrict RTT estimates (when used for determining state) to be |    61 // We will restrict RTT estimates (when used for determining state) to be | 
|    83 // within a reasonable range. |    62 // within a reasonable range. | 
|    84 const uint32 MINIMUM_RTT = 100;   // 0.1 seconds |    63 const uint32 MINIMUM_RTT = 100;   // 0.1 seconds | 
|    85 const uint32 MAXIMUM_RTT = 3000;  // 3 seconds |    64 const uint32 MAXIMUM_RTT = 3000;  // 3 seconds | 
|    86  |    65  | 
|    87 // When we don't have any RTT data, we have to pick something reasonable.  We |    66 // When we don't have any RTT data, we have to pick something reasonable.  We | 
|    88 // use a large value just in case the connection is really slow. |    67 // use a large value just in case the connection is really slow. | 
|    89 const uint32 DEFAULT_RTT = MAXIMUM_RTT; |    68 const uint32 DEFAULT_RTT = MAXIMUM_RTT; | 
|    90  |    69  | 
|    91 // Computes our estimate of the RTT given the current estimate. |    70 // Computes our estimate of the RTT given the current estimate. | 
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   164       network_(network), |   143       network_(network), | 
|   165       ip_(ip), |   144       ip_(ip), | 
|   166       min_port_(0), |   145       min_port_(0), | 
|   167       max_port_(0), |   146       max_port_(0), | 
|   168       component_(ICE_CANDIDATE_COMPONENT_DEFAULT), |   147       component_(ICE_CANDIDATE_COMPONENT_DEFAULT), | 
|   169       generation_(0), |   148       generation_(0), | 
|   170       ice_username_fragment_(username_fragment), |   149       ice_username_fragment_(username_fragment), | 
|   171       password_(password), |   150       password_(password), | 
|   172       timeout_delay_(kPortTimeoutDelay), |   151       timeout_delay_(kPortTimeoutDelay), | 
|   173       enable_port_packets_(false), |   152       enable_port_packets_(false), | 
|   174       ice_protocol_(ICEPROTO_HYBRID), |  | 
|   175       ice_role_(ICEROLE_UNKNOWN), |   153       ice_role_(ICEROLE_UNKNOWN), | 
|   176       tiebreaker_(0), |   154       tiebreaker_(0), | 
|   177       shared_socket_(true), |   155       shared_socket_(true), | 
|   178       candidate_filter_(CF_ALL) { |   156       candidate_filter_(CF_ALL) { | 
|   179   Construct(); |   157   Construct(); | 
|   180 } |   158 } | 
|   181  |   159  | 
|   182 Port::Port(rtc::Thread* thread, |   160 Port::Port(rtc::Thread* thread, | 
|   183            const std::string& type, |   161            const std::string& type, | 
|   184            rtc::PacketSocketFactory* factory, |   162            rtc::PacketSocketFactory* factory, | 
| (...skipping 10 matching lines...) Expand all  Loading... | 
|   195       network_(network), |   173       network_(network), | 
|   196       ip_(ip), |   174       ip_(ip), | 
|   197       min_port_(min_port), |   175       min_port_(min_port), | 
|   198       max_port_(max_port), |   176       max_port_(max_port), | 
|   199       component_(ICE_CANDIDATE_COMPONENT_DEFAULT), |   177       component_(ICE_CANDIDATE_COMPONENT_DEFAULT), | 
|   200       generation_(0), |   178       generation_(0), | 
|   201       ice_username_fragment_(username_fragment), |   179       ice_username_fragment_(username_fragment), | 
|   202       password_(password), |   180       password_(password), | 
|   203       timeout_delay_(kPortTimeoutDelay), |   181       timeout_delay_(kPortTimeoutDelay), | 
|   204       enable_port_packets_(false), |   182       enable_port_packets_(false), | 
|   205       ice_protocol_(ICEPROTO_HYBRID), |  | 
|   206       ice_role_(ICEROLE_UNKNOWN), |   183       ice_role_(ICEROLE_UNKNOWN), | 
|   207       tiebreaker_(0), |   184       tiebreaker_(0), | 
|   208       shared_socket_(false), |   185       shared_socket_(false), | 
|   209       candidate_filter_(CF_ALL) { |   186       candidate_filter_(CF_ALL) { | 
|   210   ASSERT(factory_ != NULL); |   187   ASSERT(factory_ != NULL); | 
|   211   Construct(); |   188   Construct(); | 
|   212 } |   189 } | 
|   213  |   190  | 
|   214 void Port::Construct() { |   191 void Port::Construct() { | 
|   215   // If the username_fragment and password are empty, we should just create one. |   192   // TODO(pthatcher): Remove this old behavior once we're sure no one | 
 |   193   // relies on it.  If the username_fragment and password are empty, | 
 |   194   // we should just create one. | 
|   216   if (ice_username_fragment_.empty()) { |   195   if (ice_username_fragment_.empty()) { | 
|   217     ASSERT(password_.empty()); |   196     ASSERT(password_.empty()); | 
|   218     ice_username_fragment_ = rtc::CreateRandomString(ICE_UFRAG_LENGTH); |   197     ice_username_fragment_ = rtc::CreateRandomString(ICE_UFRAG_LENGTH); | 
|   219     password_ = rtc::CreateRandomString(ICE_PWD_LENGTH); |   198     password_ = rtc::CreateRandomString(ICE_PWD_LENGTH); | 
|   220   } |   199   } | 
|   221   LOG_J(LS_INFO, this) << "Port created"; |   200   LOG_J(LS_INFO, this) << "Port created"; | 
|   222 } |   201 } | 
|   223  |   202  | 
|   224 Port::~Port() { |   203 Port::~Port() { | 
|   225   // Delete all of the remaining connections.  We copy the list up front |   204   // Delete all of the remaining connections.  We copy the list up front | 
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   307     LOG_J(LS_ERROR, this) << "Received non-STUN packet from unknown address (" |   286     LOG_J(LS_ERROR, this) << "Received non-STUN packet from unknown address (" | 
|   308                           << addr.ToSensitiveString() << ")"; |   287                           << addr.ToSensitiveString() << ")"; | 
|   309   } else if (!msg) { |   288   } else if (!msg) { | 
|   310     // STUN message handled already |   289     // STUN message handled already | 
|   311   } else if (msg->type() == STUN_BINDING_REQUEST) { |   290   } else if (msg->type() == STUN_BINDING_REQUEST) { | 
|   312     LOG(LS_INFO) << "Received STUN ping " |   291     LOG(LS_INFO) << "Received STUN ping " | 
|   313                  << " id=" << rtc::hex_encode(msg->transaction_id()) |   292                  << " id=" << rtc::hex_encode(msg->transaction_id()) | 
|   314                  << " from unknown address " << addr.ToSensitiveString(); |   293                  << " from unknown address " << addr.ToSensitiveString(); | 
|   315  |   294  | 
|   316     // Check for role conflicts. |   295     // Check for role conflicts. | 
|   317     if (IsStandardIce() && |   296     if (!MaybeIceRoleConflict(addr, msg.get(), remote_username)) { | 
|   318         !MaybeIceRoleConflict(addr, msg.get(), remote_username)) { |  | 
|   319       LOG(LS_INFO) << "Received conflicting role from the peer."; |   297       LOG(LS_INFO) << "Received conflicting role from the peer."; | 
|   320       return; |   298       return; | 
|   321     } |   299     } | 
|   322  |   300  | 
|   323     SignalUnknownAddress(this, addr, proto, msg.get(), remote_username, false); |   301     SignalUnknownAddress(this, addr, proto, msg.get(), remote_username, false); | 
|   324   } else { |   302   } else { | 
|   325     // NOTE(tschmelcher): STUN_BINDING_RESPONSE is benign. It occurs if we |   303     // NOTE(tschmelcher): STUN_BINDING_RESPONSE is benign. It occurs if we | 
|   326     // pruned a connection for this port while it had STUN requests in flight, |   304     // pruned a connection for this port while it had STUN requests in flight, | 
|   327     // because we then get back responses for them, which this code correctly |   305     // because we then get back responses for them, which this code correctly | 
|   328     // does not handle. |   306     // does not handle. | 
| (...skipping 10 matching lines...) Expand all  Loading... | 
|   339   for (; iter != connections_.end(); ++iter) { |   317   for (; iter != connections_.end(); ++iter) { | 
|   340     iter->second->OnReadyToSend(); |   318     iter->second->OnReadyToSend(); | 
|   341   } |   319   } | 
|   342 } |   320 } | 
|   343  |   321  | 
|   344 size_t Port::AddPrflxCandidate(const Candidate& local) { |   322 size_t Port::AddPrflxCandidate(const Candidate& local) { | 
|   345   candidates_.push_back(local); |   323   candidates_.push_back(local); | 
|   346   return (candidates_.size() - 1); |   324   return (candidates_.size() - 1); | 
|   347 } |   325 } | 
|   348  |   326  | 
|   349 bool Port::IsStandardIce() const { |  | 
|   350   return (ice_protocol_ == ICEPROTO_RFC5245); |  | 
|   351 } |  | 
|   352  |  | 
|   353 bool Port::IsGoogleIce() const { |  | 
|   354   return (ice_protocol_ == ICEPROTO_GOOGLE); |  | 
|   355 } |  | 
|   356  |  | 
|   357 bool Port::IsHybridIce() const { |  | 
|   358   return (ice_protocol_ == ICEPROTO_HYBRID); |  | 
|   359 } |  | 
|   360  |  | 
|   361 bool Port::GetStunMessage(const char* data, size_t size, |   327 bool Port::GetStunMessage(const char* data, size_t size, | 
|   362                           const rtc::SocketAddress& addr, |   328                           const rtc::SocketAddress& addr, | 
|   363                           IceMessage** out_msg, std::string* out_username) { |   329                           IceMessage** out_msg, std::string* out_username) { | 
|   364   // NOTE: This could clearly be optimized to avoid allocating any memory. |   330   // NOTE: This could clearly be optimized to avoid allocating any memory. | 
|   365   //       However, at the data rates we'll be looking at on the client side, |   331   //       However, at the data rates we'll be looking at on the client side, | 
|   366   //       this probably isn't worth worrying about. |   332   //       this probably isn't worth worrying about. | 
|   367   ASSERT(out_msg != NULL); |   333   ASSERT(out_msg != NULL); | 
|   368   ASSERT(out_username != NULL); |   334   ASSERT(out_username != NULL); | 
|   369   *out_msg = NULL; |   335   *out_msg = NULL; | 
|   370   out_username->clear(); |   336   out_username->clear(); | 
|   371  |   337  | 
|   372   // Don't bother parsing the packet if we can tell it's not STUN. |   338   // Don't bother parsing the packet if we can tell it's not STUN. | 
|   373   // In ICE mode, all STUN packets will have a valid fingerprint. |   339   // In ICE mode, all STUN packets will have a valid fingerprint. | 
|   374   if (IsStandardIce() && !StunMessage::ValidateFingerprint(data, size)) { |   340   if (!StunMessage::ValidateFingerprint(data, size)) { | 
|   375     return false; |   341     return false; | 
|   376   } |   342   } | 
|   377  |   343  | 
|   378   // Parse the request message.  If the packet is not a complete and correct |   344   // Parse the request message.  If the packet is not a complete and correct | 
|   379   // STUN message, then ignore it. |   345   // STUN message, then ignore it. | 
|   380   rtc::scoped_ptr<IceMessage> stun_msg(new IceMessage()); |   346   rtc::scoped_ptr<IceMessage> stun_msg(new IceMessage()); | 
|   381   rtc::ByteBuffer buf(data, size); |   347   rtc::ByteBuffer buf(data, size); | 
|   382   if (!stun_msg->Read(&buf) || (buf.Length() > 0)) { |   348   if (!stun_msg->Read(&buf) || (buf.Length() > 0)) { | 
|   383     return false; |   349     return false; | 
|   384   } |   350   } | 
|   385  |   351  | 
|   386   if (stun_msg->type() == STUN_BINDING_REQUEST) { |   352   if (stun_msg->type() == STUN_BINDING_REQUEST) { | 
|   387     // Check for the presence of USERNAME and MESSAGE-INTEGRITY (if ICE) first. |   353     // Check for the presence of USERNAME and MESSAGE-INTEGRITY (if ICE) first. | 
|   388     // If not present, fail with a 400 Bad Request. |   354     // If not present, fail with a 400 Bad Request. | 
|   389     if (!stun_msg->GetByteString(STUN_ATTR_USERNAME) || |   355     if (!stun_msg->GetByteString(STUN_ATTR_USERNAME) || | 
|   390         (IsStandardIce() && |   356         !stun_msg->GetByteString(STUN_ATTR_MESSAGE_INTEGRITY)) { | 
|   391          !stun_msg->GetByteString(STUN_ATTR_MESSAGE_INTEGRITY))) { |  | 
|   392       LOG_J(LS_ERROR, this) << "Received STUN request without username/M-I " |   357       LOG_J(LS_ERROR, this) << "Received STUN request without username/M-I " | 
|   393                             << "from " << addr.ToSensitiveString(); |   358                             << "from " << addr.ToSensitiveString(); | 
|   394       SendBindingErrorResponse(stun_msg.get(), addr, STUN_ERROR_BAD_REQUEST, |   359       SendBindingErrorResponse(stun_msg.get(), addr, STUN_ERROR_BAD_REQUEST, | 
|   395                                STUN_ERROR_REASON_BAD_REQUEST); |   360                                STUN_ERROR_REASON_BAD_REQUEST); | 
|   396       return true; |   361       return true; | 
|   397     } |   362     } | 
|   398  |   363  | 
|   399     // If the username is bad or unknown, fail with a 401 Unauthorized. |   364     // If the username is bad or unknown, fail with a 401 Unauthorized. | 
|   400     std::string local_ufrag; |   365     std::string local_ufrag; | 
|   401     std::string remote_ufrag; |   366     std::string remote_ufrag; | 
|   402     IceProtocolType remote_protocol_type; |   367     if (!ParseStunUsername(stun_msg.get(), &local_ufrag, &remote_ufrag) || | 
|   403     if (!ParseStunUsername(stun_msg.get(), &local_ufrag, &remote_ufrag, |  | 
|   404                            &remote_protocol_type) || |  | 
|   405         local_ufrag != username_fragment()) { |   368         local_ufrag != username_fragment()) { | 
|   406       LOG_J(LS_ERROR, this) << "Received STUN request with bad local username " |   369       LOG_J(LS_ERROR, this) << "Received STUN request with bad local username " | 
|   407                             << local_ufrag << " from " |   370                             << local_ufrag << " from " | 
|   408                             << addr.ToSensitiveString(); |   371                             << addr.ToSensitiveString(); | 
|   409       SendBindingErrorResponse(stun_msg.get(), addr, STUN_ERROR_UNAUTHORIZED, |   372       SendBindingErrorResponse(stun_msg.get(), addr, STUN_ERROR_UNAUTHORIZED, | 
|   410                                STUN_ERROR_REASON_UNAUTHORIZED); |   373                                STUN_ERROR_REASON_UNAUTHORIZED); | 
|   411       return true; |   374       return true; | 
|   412     } |   375     } | 
|   413  |   376  | 
|   414     // Port is initialized to GOOGLE-ICE protocol type. If pings from remote |  | 
|   415     // are received before the signal message, protocol type may be different. |  | 
|   416     // Based on the STUN username, we can determine what's the remote protocol. |  | 
|   417     // This also enables us to send the response back using the same protocol |  | 
|   418     // as the request. |  | 
|   419     if (IsHybridIce()) { |  | 
|   420       SetIceProtocolType(remote_protocol_type); |  | 
|   421     } |  | 
|   422  |  | 
|   423     // If ICE, and the MESSAGE-INTEGRITY is bad, fail with a 401 Unauthorized |   377     // If ICE, and the MESSAGE-INTEGRITY is bad, fail with a 401 Unauthorized | 
|   424     if (IsStandardIce() && |   378     if (!stun_msg->ValidateMessageIntegrity(data, size, password_)) { | 
|   425         !stun_msg->ValidateMessageIntegrity(data, size, password_)) { |  | 
|   426       LOG_J(LS_ERROR, this) << "Received STUN request with bad M-I " |   379       LOG_J(LS_ERROR, this) << "Received STUN request with bad M-I " | 
|   427                             << "from " << addr.ToSensitiveString() |   380                             << "from " << addr.ToSensitiveString() | 
|   428                             << ", password_=" << password_; |   381                             << ", password_=" << password_; | 
|   429       SendBindingErrorResponse(stun_msg.get(), addr, STUN_ERROR_UNAUTHORIZED, |   382       SendBindingErrorResponse(stun_msg.get(), addr, STUN_ERROR_UNAUTHORIZED, | 
|   430                                STUN_ERROR_REASON_UNAUTHORIZED); |   383                                STUN_ERROR_REASON_UNAUTHORIZED); | 
|   431       return true; |   384       return true; | 
|   432     } |   385     } | 
|   433     out_username->assign(remote_ufrag); |   386     out_username->assign(remote_ufrag); | 
|   434   } else if ((stun_msg->type() == STUN_BINDING_RESPONSE) || |   387   } else if ((stun_msg->type() == STUN_BINDING_RESPONSE) || | 
|   435              (stun_msg->type() == STUN_BINDING_ERROR_RESPONSE)) { |   388              (stun_msg->type() == STUN_BINDING_ERROR_RESPONSE)) { | 
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   476   // Link-local IPv6 ports can only connect to other link-local IPv6 ports. |   429   // Link-local IPv6 ports can only connect to other link-local IPv6 ports. | 
|   477   if (family == AF_INET6 && |   430   if (family == AF_INET6 && | 
|   478       (IPIsLinkLocal(ip()) != IPIsLinkLocal(addr.ipaddr()))) { |   431       (IPIsLinkLocal(ip()) != IPIsLinkLocal(addr.ipaddr()))) { | 
|   479     return false; |   432     return false; | 
|   480   } |   433   } | 
|   481   return true; |   434   return true; | 
|   482 } |   435 } | 
|   483  |   436  | 
|   484 bool Port::ParseStunUsername(const StunMessage* stun_msg, |   437 bool Port::ParseStunUsername(const StunMessage* stun_msg, | 
|   485                              std::string* local_ufrag, |   438                              std::string* local_ufrag, | 
|   486                              std::string* remote_ufrag, |   439                              std::string* remote_ufrag) const { | 
|   487                              IceProtocolType* remote_protocol_type) const { |  | 
|   488   // The packet must include a username that either begins or ends with our |   440   // The packet must include a username that either begins or ends with our | 
|   489   // fragment.  It should begin with our fragment if it is a request and it |   441   // fragment.  It should begin with our fragment if it is a request and it | 
|   490   // should end with our fragment if it is a response. |   442   // should end with our fragment if it is a response. | 
|   491   local_ufrag->clear(); |   443   local_ufrag->clear(); | 
|   492   remote_ufrag->clear(); |   444   remote_ufrag->clear(); | 
|   493   const StunByteStringAttribute* username_attr = |   445   const StunByteStringAttribute* username_attr = | 
|   494         stun_msg->GetByteString(STUN_ATTR_USERNAME); |   446         stun_msg->GetByteString(STUN_ATTR_USERNAME); | 
|   495   if (username_attr == NULL) |   447   if (username_attr == NULL) | 
|   496     return false; |   448     return false; | 
|   497  |   449  | 
|   498   const std::string username_attr_str = username_attr->GetString(); |   450   // RFRAG:LFRAG | 
|   499   size_t colon_pos = username_attr_str.find(":"); |   451   const std::string username = username_attr->GetString(); | 
|   500   // If we are in hybrid mode set the appropriate ice protocol type based on |   452   size_t colon_pos = username.find(":"); | 
|   501   // the username argument style. |   453   if (colon_pos == std::string::npos) { | 
|   502   if (IsHybridIce()) { |   454     return false; | 
|   503     *remote_protocol_type = (colon_pos != std::string::npos) ? |  | 
|   504         ICEPROTO_RFC5245 : ICEPROTO_GOOGLE; |  | 
|   505   } else { |  | 
|   506     *remote_protocol_type = ice_protocol_; |  | 
|   507   } |   455   } | 
|   508   if (*remote_protocol_type == ICEPROTO_RFC5245) { |  | 
|   509     if (colon_pos != std::string::npos) {  // RFRAG:LFRAG |  | 
|   510       *local_ufrag = username_attr_str.substr(0, colon_pos); |  | 
|   511       *remote_ufrag = username_attr_str.substr( |  | 
|   512           colon_pos + 1, username_attr_str.size()); |  | 
|   513     } else { |  | 
|   514       return false; |  | 
|   515     } |  | 
|   516   } else if (*remote_protocol_type == ICEPROTO_GOOGLE) { |  | 
|   517     int remote_frag_len = static_cast<int>(username_attr_str.size()); |  | 
|   518     remote_frag_len -= static_cast<int>(username_fragment().size()); |  | 
|   519     if (remote_frag_len < 0) |  | 
|   520       return false; |  | 
|   521  |   456  | 
|   522     *local_ufrag = username_attr_str.substr(0, username_fragment().size()); |   457   *local_ufrag = username.substr(0, colon_pos); | 
|   523     *remote_ufrag = username_attr_str.substr( |   458   *remote_ufrag = username.substr(colon_pos + 1, username.size()); | 
|   524         username_fragment().size(), username_attr_str.size()); |  | 
|   525   } |  | 
|   526   return true; |   459   return true; | 
|   527 } |   460 } | 
|   528  |   461  | 
|   529 bool Port::MaybeIceRoleConflict( |   462 bool Port::MaybeIceRoleConflict( | 
|   530     const rtc::SocketAddress& addr, IceMessage* stun_msg, |   463     const rtc::SocketAddress& addr, IceMessage* stun_msg, | 
|   531     const std::string& remote_ufrag) { |   464     const std::string& remote_ufrag) { | 
|   532   // Validate ICE_CONTROLLING or ICE_CONTROLLED attributes. |   465   // Validate ICE_CONTROLLING or ICE_CONTROLLED attributes. | 
|   533   bool ret = true; |   466   bool ret = true; | 
|   534   IceRole remote_ice_role = ICEROLE_UNKNOWN; |   467   IceRole remote_ice_role = ICEROLE_UNKNOWN; | 
|   535   uint64 remote_tiebreaker = 0; |   468   uint64 remote_tiebreaker = 0; | 
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   584     default: |   517     default: | 
|   585       ASSERT(false); |   518       ASSERT(false); | 
|   586   } |   519   } | 
|   587   return ret; |   520   return ret; | 
|   588 } |   521 } | 
|   589  |   522  | 
|   590 void Port::CreateStunUsername(const std::string& remote_username, |   523 void Port::CreateStunUsername(const std::string& remote_username, | 
|   591                               std::string* stun_username_attr_str) const { |   524                               std::string* stun_username_attr_str) const { | 
|   592   stun_username_attr_str->clear(); |   525   stun_username_attr_str->clear(); | 
|   593   *stun_username_attr_str = remote_username; |   526   *stun_username_attr_str = remote_username; | 
|   594   if (IsStandardIce()) { |   527   stun_username_attr_str->append(":"); | 
|   595     // Connectivity checks from L->R will have username RFRAG:LFRAG. |  | 
|   596     stun_username_attr_str->append(":"); |  | 
|   597   } |  | 
|   598   stun_username_attr_str->append(username_fragment()); |   528   stun_username_attr_str->append(username_fragment()); | 
|   599 } |   529 } | 
|   600  |   530  | 
|   601 void Port::SendBindingResponse(StunMessage* request, |   531 void Port::SendBindingResponse(StunMessage* request, | 
|   602                                const rtc::SocketAddress& addr) { |   532                                const rtc::SocketAddress& addr) { | 
|   603   ASSERT(request->type() == STUN_BINDING_REQUEST); |   533   ASSERT(request->type() == STUN_BINDING_REQUEST); | 
|   604  |   534  | 
|   605   // Retrieve the username from the request. |   535   // Retrieve the username from the request. | 
|   606   const StunByteStringAttribute* username_attr = |   536   const StunByteStringAttribute* username_attr = | 
|   607       request->GetByteString(STUN_ATTR_USERNAME); |   537       request->GetByteString(STUN_ATTR_USERNAME); | 
| (...skipping 15 matching lines...) Expand all  Loading... | 
|   623     response.AddAttribute(new StunUInt32Attribute( |   553     response.AddAttribute(new StunUInt32Attribute( | 
|   624         STUN_ATTR_RETRANSMIT_COUNT, retransmit_attr->value())); |   554         STUN_ATTR_RETRANSMIT_COUNT, retransmit_attr->value())); | 
|   625  |   555  | 
|   626     if (retransmit_attr->value() > CONNECTION_WRITE_CONNECT_FAILURES) { |   556     if (retransmit_attr->value() > CONNECTION_WRITE_CONNECT_FAILURES) { | 
|   627       LOG_J(LS_INFO, this) |   557       LOG_J(LS_INFO, this) | 
|   628           << "Received a remote ping with high retransmit count: " |   558           << "Received a remote ping with high retransmit count: " | 
|   629           << retransmit_attr->value(); |   559           << retransmit_attr->value(); | 
|   630     } |   560     } | 
|   631   } |   561   } | 
|   632  |   562  | 
|   633   // Only GICE messages have USERNAME and MAPPED-ADDRESS in the response. |   563   response.AddAttribute( | 
|   634   // ICE messages use XOR-MAPPED-ADDRESS, and add MESSAGE-INTEGRITY. |   564       new StunXorAddressAttribute(STUN_ATTR_XOR_MAPPED_ADDRESS, addr)); | 
|   635   if (IsStandardIce()) { |   565   response.AddMessageIntegrity(password_); | 
|   636     response.AddAttribute( |   566   response.AddFingerprint(); | 
|   637         new StunXorAddressAttribute(STUN_ATTR_XOR_MAPPED_ADDRESS, addr)); |  | 
|   638     response.AddMessageIntegrity(password_); |  | 
|   639     response.AddFingerprint(); |  | 
|   640   } else if (IsGoogleIce()) { |  | 
|   641     response.AddAttribute( |  | 
|   642         new StunAddressAttribute(STUN_ATTR_MAPPED_ADDRESS, addr)); |  | 
|   643     response.AddAttribute(new StunByteStringAttribute( |  | 
|   644         STUN_ATTR_USERNAME, username_attr->GetString())); |  | 
|   645   } |  | 
|   646  |   567  | 
|   647   // The fact that we received a successful request means that this connection |   568   // The fact that we received a successful request means that this connection | 
|   648   // (if one exists) should now be readable. |   569   // (if one exists) should now be readable. | 
|   649   Connection* conn = GetConnection(addr); |   570   Connection* conn = GetConnection(addr); | 
|   650  |   571  | 
|   651   // Send the response message. |   572   // Send the response message. | 
|   652   rtc::ByteBuffer buf; |   573   rtc::ByteBuffer buf; | 
|   653   response.Write(&buf); |   574   response.Write(&buf); | 
|   654   rtc::PacketOptions options(DefaultDscpValue()); |   575   rtc::PacketOptions options(DefaultDscpValue()); | 
|   655   auto err = SendTo(buf.Data(), buf.Length(), addr, options, false); |   576   auto err = SendTo(buf.Data(), buf.Length(), addr, options, false); | 
| (...skipping 25 matching lines...) Expand all  Loading... | 
|   681   ASSERT(request->type() == STUN_BINDING_REQUEST); |   602   ASSERT(request->type() == STUN_BINDING_REQUEST); | 
|   682  |   603  | 
|   683   // Fill in the response message. |   604   // Fill in the response message. | 
|   684   StunMessage response; |   605   StunMessage response; | 
|   685   response.SetType(STUN_BINDING_ERROR_RESPONSE); |   606   response.SetType(STUN_BINDING_ERROR_RESPONSE); | 
|   686   response.SetTransactionID(request->transaction_id()); |   607   response.SetTransactionID(request->transaction_id()); | 
|   687  |   608  | 
|   688   // When doing GICE, we need to write out the error code incorrectly to |   609   // When doing GICE, we need to write out the error code incorrectly to | 
|   689   // maintain backwards compatiblility. |   610   // maintain backwards compatiblility. | 
|   690   StunErrorCodeAttribute* error_attr = StunAttribute::CreateErrorCode(); |   611   StunErrorCodeAttribute* error_attr = StunAttribute::CreateErrorCode(); | 
|   691   if (IsStandardIce()) { |   612   error_attr->SetCode(error_code); | 
|   692     error_attr->SetCode(error_code); |  | 
|   693   } else if (IsGoogleIce()) { |  | 
|   694     error_attr->SetClass(error_code / 256); |  | 
|   695     error_attr->SetNumber(error_code % 256); |  | 
|   696   } |  | 
|   697   error_attr->SetReason(reason); |   613   error_attr->SetReason(reason); | 
|   698   response.AddAttribute(error_attr); |   614   response.AddAttribute(error_attr); | 
|   699  |   615  | 
|   700   if (IsStandardIce()) { |   616   // Per Section 10.1.2, certain error cases don't get a MESSAGE-INTEGRITY, | 
|   701     // Per Section 10.1.2, certain error cases don't get a MESSAGE-INTEGRITY, |   617   // because we don't have enough information to determine the shared secret. | 
|   702     // because we don't have enough information to determine the shared secret. |   618   if (error_code != STUN_ERROR_BAD_REQUEST && | 
|   703     if (error_code != STUN_ERROR_BAD_REQUEST && |   619       error_code != STUN_ERROR_UNAUTHORIZED) | 
|   704         error_code != STUN_ERROR_UNAUTHORIZED) |   620     response.AddMessageIntegrity(password_); | 
|   705       response.AddMessageIntegrity(password_); |   621   response.AddFingerprint(); | 
|   706     response.AddFingerprint(); |  | 
|   707   } else if (IsGoogleIce()) { |  | 
|   708     // GICE responses include a username, if one exists. |  | 
|   709     const StunByteStringAttribute* username_attr = |  | 
|   710         request->GetByteString(STUN_ATTR_USERNAME); |  | 
|   711     if (username_attr) |  | 
|   712       response.AddAttribute(new StunByteStringAttribute( |  | 
|   713           STUN_ATTR_USERNAME, username_attr->GetString())); |  | 
|   714   } |  | 
|   715  |   622  | 
|   716   // Send the response message. |   623   // Send the response message. | 
|   717   rtc::ByteBuffer buf; |   624   rtc::ByteBuffer buf; | 
|   718   response.Write(&buf); |   625   response.Write(&buf); | 
|   719   rtc::PacketOptions options(DefaultDscpValue()); |   626   rtc::PacketOptions options(DefaultDscpValue()); | 
|   720   SendTo(buf.Data(), buf.Length(), addr, options, false); |   627   SendTo(buf.Data(), buf.Length(), addr, options, false); | 
|   721   LOG_J(LS_INFO, this) << "Sending STUN binding error: reason=" << reason |   628   LOG_J(LS_INFO, this) << "Sending STUN binding error: reason=" << reason | 
|   722                        << " to " << addr.ToSensitiveString(); |   629                        << " to " << addr.ToSensitiveString(); | 
|   723 } |   630 } | 
|   724  |   631  | 
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   764   ASSERT(ice_role_ == ICEROLE_CONTROLLED); |   671   ASSERT(ice_role_ == ICEROLE_CONTROLLED); | 
|   765   // If this port has no connections, then there's no reason to keep it around. |   672   // If this port has no connections, then there's no reason to keep it around. | 
|   766   // When the connections time out (both read and write), they will delete |   673   // When the connections time out (both read and write), they will delete | 
|   767   // themselves, so if we have any connections, they are either readable or |   674   // themselves, so if we have any connections, they are either readable or | 
|   768   // writable (or still connecting). |   675   // writable (or still connecting). | 
|   769   if (connections_.empty()) |   676   if (connections_.empty()) | 
|   770     Destroy(); |   677     Destroy(); | 
|   771 } |   678 } | 
|   772  |   679  | 
|   773 const std::string Port::username_fragment() const { |   680 const std::string Port::username_fragment() const { | 
|   774   if (!IsStandardIce() && |   681   return ice_username_fragment_; | 
|   775       component_ == ICE_CANDIDATE_COMPONENT_RTCP) { |  | 
|   776     // In GICE mode, we should adjust username fragment for rtcp component. |  | 
|   777     return GetRtcpUfragFromRtpUfrag(ice_username_fragment_); |  | 
|   778   } else { |  | 
|   779     return ice_username_fragment_; |  | 
|   780   } |  | 
|   781 } |   682 } | 
|   782  |   683  | 
|   783 // A ConnectionRequest is a simple STUN ping used to determine writability. |   684 // A ConnectionRequest is a simple STUN ping used to determine writability. | 
|   784 class ConnectionRequest : public StunRequest { |   685 class ConnectionRequest : public StunRequest { | 
|   785  public: |   686  public: | 
|   786   explicit ConnectionRequest(Connection* connection) |   687   explicit ConnectionRequest(Connection* connection) | 
|   787       : StunRequest(new IceMessage()), |   688       : StunRequest(new IceMessage()), | 
|   788         connection_(connection) { |   689         connection_(connection) { | 
|   789   } |   690   } | 
|   790  |   691  | 
|   791   virtual ~ConnectionRequest() { |   692   virtual ~ConnectionRequest() { | 
|   792   } |   693   } | 
|   793  |   694  | 
|   794   void Prepare(StunMessage* request) override { |   695   void Prepare(StunMessage* request) override { | 
|   795     request->SetType(STUN_BINDING_REQUEST); |   696     request->SetType(STUN_BINDING_REQUEST); | 
|   796     std::string username; |   697     std::string username; | 
|   797     connection_->port()->CreateStunUsername( |   698     connection_->port()->CreateStunUsername( | 
|   798         connection_->remote_candidate().username(), &username); |   699         connection_->remote_candidate().username(), &username); | 
|   799     request->AddAttribute( |   700     request->AddAttribute( | 
|   800         new StunByteStringAttribute(STUN_ATTR_USERNAME, username)); |   701         new StunByteStringAttribute(STUN_ATTR_USERNAME, username)); | 
|   801  |   702  | 
|   802     // connection_ already holds this ping, so subtract one from count. |   703     // connection_ already holds this ping, so subtract one from count. | 
|   803     if (connection_->port()->send_retransmit_count_attribute()) { |   704     if (connection_->port()->send_retransmit_count_attribute()) { | 
|   804       request->AddAttribute(new StunUInt32Attribute( |   705       request->AddAttribute(new StunUInt32Attribute( | 
|   805           STUN_ATTR_RETRANSMIT_COUNT, |   706           STUN_ATTR_RETRANSMIT_COUNT, | 
|   806           static_cast<uint32>( |   707           static_cast<uint32>( | 
|   807               connection_->pings_since_last_response_.size() - 1))); |   708               connection_->pings_since_last_response_.size() - 1))); | 
|   808     } |   709     } | 
|   809  |   710  | 
|   810     // Adding ICE-specific attributes to the STUN request message. |   711     // Adding ICE_CONTROLLED or ICE_CONTROLLING attribute based on the role. | 
|   811     if (connection_->port()->IsStandardIce()) { |   712     if (connection_->port()->GetIceRole() == ICEROLE_CONTROLLING) { | 
|   812       // Adding ICE_CONTROLLED or ICE_CONTROLLING attribute based on the role. |   713       request->AddAttribute(new StunUInt64Attribute( | 
|   813       if (connection_->port()->GetIceRole() == ICEROLE_CONTROLLING) { |   714           STUN_ATTR_ICE_CONTROLLING, connection_->port()->IceTiebreaker())); | 
|   814         request->AddAttribute(new StunUInt64Attribute( |   715       // Since we are trying aggressive nomination, sending USE-CANDIDATE | 
|   815             STUN_ATTR_ICE_CONTROLLING, connection_->port()->IceTiebreaker())); |   716       // attribute in every ping. | 
|   816         // Since we are trying aggressive nomination, sending USE-CANDIDATE |   717       // If we are dealing with a ice-lite end point, nomination flag | 
|   817         // attribute in every ping. |   718       // in Connection will be set to false by default. Once the connection | 
|   818         // If we are dealing with a ice-lite end point, nomination flag |   719       // becomes "best connection", nomination flag will be turned on. | 
|   819         // in Connection will be set to false by default. Once the connection |   720       if (connection_->use_candidate_attr()) { | 
|   820         // becomes "best connection", nomination flag will be turned on. |   721         request->AddAttribute(new StunByteStringAttribute( | 
|   821         if (connection_->use_candidate_attr()) { |   722             STUN_ATTR_USE_CANDIDATE)); | 
|   822           request->AddAttribute(new StunByteStringAttribute( |  | 
|   823               STUN_ATTR_USE_CANDIDATE)); |  | 
|   824         } |  | 
|   825       } else if (connection_->port()->GetIceRole() == ICEROLE_CONTROLLED) { |  | 
|   826         request->AddAttribute(new StunUInt64Attribute( |  | 
|   827             STUN_ATTR_ICE_CONTROLLED, connection_->port()->IceTiebreaker())); |  | 
|   828       } else { |  | 
|   829         ASSERT(false); |  | 
|   830       } |   723       } | 
 |   724     } else if (connection_->port()->GetIceRole() == ICEROLE_CONTROLLED) { | 
 |   725       request->AddAttribute(new StunUInt64Attribute( | 
 |   726           STUN_ATTR_ICE_CONTROLLED, connection_->port()->IceTiebreaker())); | 
 |   727     } else { | 
 |   728       ASSERT(false); | 
 |   729     } | 
|   831  |   730  | 
|   832       // Adding PRIORITY Attribute. |   731     // Adding PRIORITY Attribute. | 
|   833       // Changing the type preference to Peer Reflexive and local preference |   732     // Changing the type preference to Peer Reflexive and local preference | 
|   834       // and component id information is unchanged from the original priority. |   733     // and component id information is unchanged from the original priority. | 
|   835       // priority = (2^24)*(type preference) + |   734     // priority = (2^24)*(type preference) + | 
|   836       //           (2^8)*(local preference) + |   735     //           (2^8)*(local preference) + | 
|   837       //           (2^0)*(256 - component ID) |   736     //           (2^0)*(256 - component ID) | 
|   838       uint32 prflx_priority = ICE_TYPE_PREFERENCE_PRFLX << 24 | |   737     uint32 prflx_priority = ICE_TYPE_PREFERENCE_PRFLX << 24 | | 
|   839           (connection_->local_candidate().priority() & 0x00FFFFFF); |   738         (connection_->local_candidate().priority() & 0x00FFFFFF); | 
|   840       request->AddAttribute( |   739     request->AddAttribute( | 
|   841           new StunUInt32Attribute(STUN_ATTR_PRIORITY, prflx_priority)); |   740         new StunUInt32Attribute(STUN_ATTR_PRIORITY, prflx_priority)); | 
|   842  |   741  | 
|   843       // Adding Message Integrity attribute. |   742     // Adding Message Integrity attribute. | 
|   844       request->AddMessageIntegrity(connection_->remote_candidate().password()); |   743     request->AddMessageIntegrity(connection_->remote_candidate().password()); | 
|   845       // Adding Fingerprint. |   744     // Adding Fingerprint. | 
|   846       request->AddFingerprint(); |   745     request->AddFingerprint(); | 
|   847     } |  | 
|   848   } |   746   } | 
|   849  |   747  | 
|   850   void OnResponse(StunMessage* response) override { |   748   void OnResponse(StunMessage* response) override { | 
|   851     connection_->OnConnectionRequestResponse(this, response); |   749     connection_->OnConnectionRequestResponse(this, response); | 
|   852   } |   750   } | 
|   853  |   751  | 
|   854   void OnErrorResponse(StunMessage* response) override { |   752   void OnErrorResponse(StunMessage* response) override { | 
|   855     connection_->OnConnectionRequestErrorResponse(this, response); |   753     connection_->OnConnectionRequestErrorResponse(this, response); | 
|   856   } |   754   } | 
|   857  |   755  | 
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1035     // If this is a STUN response, then update the writable bit. |   933     // If this is a STUN response, then update the writable bit. | 
|  1036     // Log at LS_INFO if we receive a ping on an unwritable connection. |   934     // Log at LS_INFO if we receive a ping on an unwritable connection. | 
|  1037     rtc::LoggingSeverity sev = (!writable() ? rtc::LS_INFO : rtc::LS_VERBOSE); |   935     rtc::LoggingSeverity sev = (!writable() ? rtc::LS_INFO : rtc::LS_VERBOSE); | 
|  1038     switch (msg->type()) { |   936     switch (msg->type()) { | 
|  1039       case STUN_BINDING_REQUEST: |   937       case STUN_BINDING_REQUEST: | 
|  1040         LOG_JV(sev, this) << "Received STUN ping" |   938         LOG_JV(sev, this) << "Received STUN ping" | 
|  1041                           << ", id=" << rtc::hex_encode(msg->transaction_id()); |   939                           << ", id=" << rtc::hex_encode(msg->transaction_id()); | 
|  1042  |   940  | 
|  1043         if (remote_ufrag == remote_candidate_.username()) { |   941         if (remote_ufrag == remote_candidate_.username()) { | 
|  1044           // Check for role conflicts. |   942           // Check for role conflicts. | 
|  1045           if (port_->IsStandardIce() && |   943           if (!port_->MaybeIceRoleConflict(addr, msg.get(), remote_ufrag)) { | 
|  1046               !port_->MaybeIceRoleConflict(addr, msg.get(), remote_ufrag)) { |  | 
|  1047             // Received conflicting role from the peer. |   944             // Received conflicting role from the peer. | 
|  1048             LOG(LS_INFO) << "Received conflicting role from the peer."; |   945             LOG(LS_INFO) << "Received conflicting role from the peer."; | 
|  1049             return; |   946             return; | 
|  1050           } |   947           } | 
|  1051  |   948  | 
|  1052           // Incoming, validated stun request from remote peer. |   949           // Incoming, validated stun request from remote peer. | 
|  1053           // This call will also set the connection readable. |   950           // This call will also set the connection readable. | 
|  1054           port_->SendBindingResponse(msg.get(), addr); |   951           port_->SendBindingResponse(msg.get(), addr); | 
|  1055  |   952  | 
|  1056           // If timed out sending writability checks, start up again |   953           // If timed out sending writability checks, start up again | 
|  1057           if (!pruned_ && (write_state_ == STATE_WRITE_TIMEOUT)) |   954           if (!pruned_ && (write_state_ == STATE_WRITE_TIMEOUT)) | 
|  1058             set_write_state(STATE_WRITE_INIT); |   955             set_write_state(STATE_WRITE_INIT); | 
|  1059  |   956  | 
|  1060           if ((port_->IsStandardIce()) && |   957           if (port_->GetIceRole() == ICEROLE_CONTROLLED) { | 
|  1061               (port_->GetIceRole() == ICEROLE_CONTROLLED)) { |  | 
|  1062             const StunByteStringAttribute* use_candidate_attr = |   958             const StunByteStringAttribute* use_candidate_attr = | 
|  1063                 msg->GetByteString(STUN_ATTR_USE_CANDIDATE); |   959                 msg->GetByteString(STUN_ATTR_USE_CANDIDATE); | 
|  1064             if (use_candidate_attr) { |   960             if (use_candidate_attr) { | 
|  1065               set_nominated(true); |   961               set_nominated(true); | 
|  1066               SignalNominated(this); |   962               SignalNominated(this); | 
|  1067             } |   963             } | 
|  1068           } |   964           } | 
|  1069         } else { |   965         } else { | 
|  1070           // The packet had the right local username, but the remote username |   966           // The packet had the right local username, but the remote username | 
|  1071           // was not the right one for the remote address. |   967           // was not the right one for the remote address. | 
|  1072           LOG_J(LS_ERROR, this) |   968           LOG_J(LS_ERROR, this) | 
|  1073             << "Received STUN request with bad remote username " |   969             << "Received STUN request with bad remote username " | 
|  1074             << remote_ufrag; |   970             << remote_ufrag; | 
|  1075           port_->SendBindingErrorResponse(msg.get(), addr, |   971           port_->SendBindingErrorResponse(msg.get(), addr, | 
|  1076                                           STUN_ERROR_UNAUTHORIZED, |   972                                           STUN_ERROR_UNAUTHORIZED, | 
|  1077                                           STUN_ERROR_REASON_UNAUTHORIZED); |   973                                           STUN_ERROR_REASON_UNAUTHORIZED); | 
|  1078  |   974  | 
|  1079         } |   975         } | 
|  1080         break; |   976         break; | 
|  1081  |   977  | 
|  1082       // Response from remote peer. Does it match request sent? |   978       // Response from remote peer. Does it match request sent? | 
|  1083       // This doesn't just check, it makes callbacks if transaction |   979       // This doesn't just check, it makes callbacks if transaction | 
|  1084       // id's match. |   980       // id's match. | 
|  1085       case STUN_BINDING_RESPONSE: |   981       case STUN_BINDING_RESPONSE: | 
|  1086       case STUN_BINDING_ERROR_RESPONSE: |   982       case STUN_BINDING_ERROR_RESPONSE: | 
|  1087         if (port_->IsGoogleIce() || |   983         if (msg->ValidateMessageIntegrity( | 
|  1088             msg->ValidateMessageIntegrity( |  | 
|  1089                 data, size, remote_candidate().password())) { |   984                 data, size, remote_candidate().password())) { | 
|  1090           requests_.CheckResponse(msg.get()); |   985           requests_.CheckResponse(msg.get()); | 
|  1091         } |   986         } | 
|  1092         // Otherwise silently discard the response message. |   987         // Otherwise silently discard the response message. | 
|  1093         break; |   988         break; | 
|  1094  |   989  | 
|  1095       // Remote end point sent an STUN indication instead of regular |   990       // Remote end point sent an STUN indication instead of regular | 
|  1096       // binding request. In this case |last_ping_received_| will be updated. |   991       // binding request. In this case |last_ping_received_| will be updated. | 
|  1097       // Otherwise we can mark connection to read timeout. No response will be |   992       // Otherwise we can mark connection to read timeout. No response will be | 
|  1098       // sent in this scenario. |   993       // sent in this scenario. | 
|  1099       case STUN_BINDING_INDICATION: |   994       case STUN_BINDING_INDICATION: | 
|  1100         if (port_->IsStandardIce() && read_state_ == STATE_READABLE) { |   995         if (read_state_ == STATE_READABLE) { | 
|  1101           ReceivedPing(); |   996           ReceivedPing(); | 
|  1102         } else { |   997         } else { | 
|  1103           LOG_J(LS_WARNING, this) << "Received STUN binding indication " |   998           LOG_J(LS_WARNING, this) << "Received STUN binding indication " | 
|  1104                                   << "from an unreadable connection."; |   999                                   << "from an unreadable connection."; | 
|  1105         } |  1000         } | 
|  1106         break; |  1001         break; | 
|  1107  |  1002  | 
|  1108       default: |  1003       default: | 
|  1109         ASSERT(false); |  1004         ASSERT(false); | 
|  1110         break; |  1005         break; | 
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1158     PrintPingsSinceLastResponse(&pings, 5); |  1053     PrintPingsSinceLastResponse(&pings, 5); | 
|  1159     LOG_J(LS_VERBOSE, this) << "UpdateState()" |  1054     LOG_J(LS_VERBOSE, this) << "UpdateState()" | 
|  1160                             << ", ms since last received response=" |  1055                             << ", ms since last received response=" | 
|  1161                             << now - last_ping_response_received_ |  1056                             << now - last_ping_response_received_ | 
|  1162                             << ", ms since last received data=" |  1057                             << ", ms since last received data=" | 
|  1163                             << now - last_data_received_ |  1058                             << now - last_data_received_ | 
|  1164                             << ", rtt=" << rtt |  1059                             << ", rtt=" << rtt | 
|  1165                             << ", pings_since_last_response=" << pings; |  1060                             << ", pings_since_last_response=" << pings; | 
|  1166   } |  1061   } | 
|  1167  |  1062  | 
|  1168   // Check the readable state. |  | 
|  1169   // |  | 
|  1170   // Since we don't know how many pings the other side has attempted, the best |  | 
|  1171   // test we can do is a simple window. |  | 
|  1172   // If other side has not sent ping after connection has become readable, use |  | 
|  1173   // |last_data_received_| as the indication. |  | 
|  1174   // If remote endpoint is doing RFC 5245, it's not required to send ping |  | 
|  1175   // after connection is established. If this connection is serving a data |  | 
|  1176   // channel, it may not be in a position to send media continuously. Do not |  | 
|  1177   // mark connection timeout if it's in RFC5245 mode. |  | 
|  1178   // Below check will be performed with end point if it's doing google-ice. |  | 
|  1179   if (port_->IsGoogleIce() && (read_state_ == STATE_READABLE) && |  | 
|  1180       (last_ping_received_ + CONNECTION_READ_TIMEOUT <= now) && |  | 
|  1181       (last_data_received_ + CONNECTION_READ_TIMEOUT <= now)) { |  | 
|  1182     LOG_J(LS_INFO, this) << "Unreadable after " << now - last_ping_received_ |  | 
|  1183                          << " ms without a ping," |  | 
|  1184                          << " ms since last received response=" |  | 
|  1185                          << now - last_ping_response_received_ |  | 
|  1186                          << " ms since last received data=" |  | 
|  1187                          << now - last_data_received_ |  | 
|  1188                          << " rtt=" << rtt; |  | 
|  1189     set_read_state(STATE_READ_TIMEOUT); |  | 
|  1190   } |  | 
|  1191  |  | 
|  1192   // Check the writable state.  (The order of these checks is important.) |  1063   // Check the writable state.  (The order of these checks is important.) | 
|  1193   // |  1064   // | 
|  1194   // Before becoming unwritable, we allow for a fixed number of pings to fail |  1065   // Before becoming unwritable, we allow for a fixed number of pings to fail | 
|  1195   // (i.e., receive no response).  We also have to give the response time to |  1066   // (i.e., receive no response).  We also have to give the response time to | 
|  1196   // get back, so we include a conservative estimate of this. |  1067   // get back, so we include a conservative estimate of this. | 
|  1197   // |  1068   // | 
|  1198   // Before timing out writability, we give a fixed amount of time.  This is to |  1069   // Before timing out writability, we give a fixed amount of time.  This is to | 
|  1199   // allow for changes in network conditions. |  1070   // allow for changes in network conditions. | 
|  1200  |  1071  | 
|  1201   if ((write_state_ == STATE_WRITABLE) && |  1072   if ((write_state_ == STATE_WRITABLE) && | 
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1340     LOG_JV(sev, this) << "Received STUN ping response" |  1211     LOG_JV(sev, this) << "Received STUN ping response" | 
|  1341                       << ", id=" << rtc::hex_encode(request->id()) |  1212                       << ", id=" << rtc::hex_encode(request->id()) | 
|  1342                       << ", code=0"  // Makes logging easier to parse. |  1213                       << ", code=0"  // Makes logging easier to parse. | 
|  1343                       << ", rtt=" << rtt |  1214                       << ", rtt=" << rtt | 
|  1344                       << ", use_candidate=" << use_candidate |  1215                       << ", use_candidate=" << use_candidate | 
|  1345                       << ", pings_since_last_response=" << pings; |  1216                       << ", pings_since_last_response=" << pings; | 
|  1346   } |  1217   } | 
|  1347  |  1218  | 
|  1348   rtt_ = (RTT_RATIO * rtt_ + rtt) / (RTT_RATIO + 1); |  1219   rtt_ = (RTT_RATIO * rtt_ + rtt) / (RTT_RATIO + 1); | 
|  1349  |  1220  | 
|  1350   // Peer reflexive candidate is only for RFC 5245 ICE. |  1221   MaybeAddPrflxCandidate(request, response); | 
|  1351   if (port_->IsStandardIce()) { |  | 
|  1352     MaybeAddPrflxCandidate(request, response); |  | 
|  1353   } |  | 
|  1354 } |  1222 } | 
|  1355  |  1223  | 
|  1356 void Connection::OnConnectionRequestErrorResponse(ConnectionRequest* request, |  1224 void Connection::OnConnectionRequestErrorResponse(ConnectionRequest* request, | 
|  1357                                                   StunMessage* response) { |  1225                                                   StunMessage* response) { | 
|  1358   const StunErrorCodeAttribute* error_attr = response->GetErrorCode(); |  1226   const StunErrorCodeAttribute* error_attr = response->GetErrorCode(); | 
|  1359   int error_code = STUN_ERROR_GLOBAL_FAILURE; |  1227   int error_code = STUN_ERROR_GLOBAL_FAILURE; | 
|  1360   if (error_attr) { |  1228   if (error_attr) { | 
|  1361     if (port_->IsGoogleIce()) { |  1229     error_code = error_attr->code(); | 
|  1362       // When doing GICE, the error code is written out incorrectly, so we need |  | 
|  1363       // to unmunge it here. |  | 
|  1364       error_code = error_attr->eclass() * 256 + error_attr->number(); |  | 
|  1365     } else { |  | 
|  1366       error_code = error_attr->code(); |  | 
|  1367     } |  | 
|  1368   } |  1230   } | 
|  1369  |  1231  | 
|  1370   LOG_J(LS_INFO, this) << "Received STUN error response" |  1232   LOG_J(LS_INFO, this) << "Received STUN error response" | 
|  1371                        << " id=" << rtc::hex_encode(request->id()) |  1233                        << " id=" << rtc::hex_encode(request->id()) | 
|  1372                        << " code=" << error_code |  1234                        << " code=" << error_code | 
|  1373                        << " rtt=" << request->Elapsed(); |  1235                        << " rtt=" << request->Elapsed(); | 
|  1374  |  1236  | 
|  1375   if (error_code == STUN_ERROR_UNKNOWN_ATTRIBUTE || |  1237   if (error_code == STUN_ERROR_UNKNOWN_ATTRIBUTE || | 
|  1376       error_code == STUN_ERROR_SERVER_ERROR || |  1238       error_code == STUN_ERROR_SERVER_ERROR || | 
|  1377       error_code == STUN_ERROR_UNAUTHORIZED) { |  1239       error_code == STUN_ERROR_UNAUTHORIZED) { | 
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1563     ASSERT(sent < 0); |  1425     ASSERT(sent < 0); | 
|  1564     error_ = port_->GetError(); |  1426     error_ = port_->GetError(); | 
|  1565     sent_packets_discarded_++; |  1427     sent_packets_discarded_++; | 
|  1566   } else { |  1428   } else { | 
|  1567     send_rate_tracker_.AddSamples(sent); |  1429     send_rate_tracker_.AddSamples(sent); | 
|  1568   } |  1430   } | 
|  1569   return sent; |  1431   return sent; | 
|  1570 } |  1432 } | 
|  1571  |  1433  | 
|  1572 }  // namespace cricket |  1434 }  // namespace cricket | 
| OLD | NEW |