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