Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3)

Side by Side Diff: webrtc/p2p/base/port.cc

Issue 1303393002: Reland "Remove GICE (gone forever!) and PORTALLOCATOR_ENABLE_SHARED_UFRAG (enabled forever)." becau… (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Add memcheck suppression Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « webrtc/p2p/base/port.h ('k') | webrtc/p2p/base/port_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
1033 // If this is a STUN response, then update the writable bit. 931 // If this is a STUN response, then update the writable bit.
1034 // Log at LS_INFO if we receive a ping on an unwritable connection. 932 // Log at LS_INFO if we receive a ping on an unwritable connection.
1035 rtc::LoggingSeverity sev = (!writable() ? rtc::LS_INFO : rtc::LS_VERBOSE); 933 rtc::LoggingSeverity sev = (!writable() ? rtc::LS_INFO : rtc::LS_VERBOSE);
1036 switch (msg->type()) { 934 switch (msg->type()) {
1037 case STUN_BINDING_REQUEST: 935 case STUN_BINDING_REQUEST:
1038 LOG_JV(sev, this) << "Received STUN ping" 936 LOG_JV(sev, this) << "Received STUN ping"
1039 << ", id=" << rtc::hex_encode(msg->transaction_id()); 937 << ", id=" << rtc::hex_encode(msg->transaction_id());
1040 938
1041 if (remote_ufrag == remote_candidate_.username()) { 939 if (remote_ufrag == remote_candidate_.username()) {
1042 // Check for role conflicts. 940 // Check for role conflicts.
1043 if (port_->IsStandardIce() && 941 if (!port_->MaybeIceRoleConflict(addr, msg.get(), remote_ufrag)) {
1044 !port_->MaybeIceRoleConflict(addr, msg.get(), remote_ufrag)) {
1045 // Received conflicting role from the peer. 942 // Received conflicting role from the peer.
1046 LOG(LS_INFO) << "Received conflicting role from the peer."; 943 LOG(LS_INFO) << "Received conflicting role from the peer.";
1047 return; 944 return;
1048 } 945 }
1049 946
1050 // Incoming, validated stun request from remote peer. 947 // Incoming, validated stun request from remote peer.
1051 // This call will also set the connection readable. 948 // This call will also set the connection readable.
1052 port_->SendBindingResponse(msg.get(), addr); 949 port_->SendBindingResponse(msg.get(), addr);
1053 950
1054 // If timed out sending writability checks, start up again 951 // If timed out sending writability checks, start up again
1055 if (!pruned_ && (write_state_ == STATE_WRITE_TIMEOUT)) 952 if (!pruned_ && (write_state_ == STATE_WRITE_TIMEOUT))
1056 set_write_state(STATE_WRITE_INIT); 953 set_write_state(STATE_WRITE_INIT);
1057 954
1058 if ((port_->IsStandardIce()) && 955 if (port_->GetIceRole() == ICEROLE_CONTROLLED) {
1059 (port_->GetIceRole() == ICEROLE_CONTROLLED)) {
1060 const StunByteStringAttribute* use_candidate_attr = 956 const StunByteStringAttribute* use_candidate_attr =
1061 msg->GetByteString(STUN_ATTR_USE_CANDIDATE); 957 msg->GetByteString(STUN_ATTR_USE_CANDIDATE);
1062 if (use_candidate_attr) { 958 if (use_candidate_attr) {
1063 set_nominated(true); 959 set_nominated(true);
1064 SignalNominated(this); 960 SignalNominated(this);
1065 } 961 }
1066 } 962 }
1067 } else { 963 } else {
1068 // The packet had the right local username, but the remote username 964 // The packet had the right local username, but the remote username
1069 // was not the right one for the remote address. 965 // was not the right one for the remote address.
1070 LOG_J(LS_ERROR, this) 966 LOG_J(LS_ERROR, this)
1071 << "Received STUN request with bad remote username " 967 << "Received STUN request with bad remote username "
1072 << remote_ufrag; 968 << remote_ufrag;
1073 port_->SendBindingErrorResponse(msg.get(), addr, 969 port_->SendBindingErrorResponse(msg.get(), addr,
1074 STUN_ERROR_UNAUTHORIZED, 970 STUN_ERROR_UNAUTHORIZED,
1075 STUN_ERROR_REASON_UNAUTHORIZED); 971 STUN_ERROR_REASON_UNAUTHORIZED);
1076 972
1077 } 973 }
1078 break; 974 break;
1079 975
1080 // Response from remote peer. Does it match request sent? 976 // Response from remote peer. Does it match request sent?
1081 // This doesn't just check, it makes callbacks if transaction 977 // This doesn't just check, it makes callbacks if transaction
1082 // id's match. 978 // id's match.
1083 case STUN_BINDING_RESPONSE: 979 case STUN_BINDING_RESPONSE:
1084 case STUN_BINDING_ERROR_RESPONSE: 980 case STUN_BINDING_ERROR_RESPONSE:
1085 if (port_->IsGoogleIce() || 981 if (msg->ValidateMessageIntegrity(
1086 msg->ValidateMessageIntegrity(
1087 data, size, remote_candidate().password())) { 982 data, size, remote_candidate().password())) {
1088 requests_.CheckResponse(msg.get()); 983 requests_.CheckResponse(msg.get());
1089 } 984 }
1090 // Otherwise silently discard the response message. 985 // Otherwise silently discard the response message.
1091 break; 986 break;
1092 987
1093 // Remote end point sent an STUN indication instead of regular 988 // Remote end point sent an STUN indication instead of regular
1094 // binding request. In this case |last_ping_received_| will be updated. 989 // binding request. In this case |last_ping_received_| will be updated.
1095 // Otherwise we can mark connection to read timeout. No response will be 990 // Otherwise we can mark connection to read timeout. No response will be
1096 // sent in this scenario. 991 // sent in this scenario.
1097 case STUN_BINDING_INDICATION: 992 case STUN_BINDING_INDICATION:
1098 if (port_->IsStandardIce() && read_state_ == STATE_READABLE) { 993 if (read_state_ == STATE_READABLE) {
1099 ReceivedPing(); 994 ReceivedPing();
1100 } else { 995 } else {
1101 LOG_J(LS_WARNING, this) << "Received STUN binding indication " 996 LOG_J(LS_WARNING, this) << "Received STUN binding indication "
1102 << "from an unreadable connection."; 997 << "from an unreadable connection.";
1103 } 998 }
1104 break; 999 break;
1105 1000
1106 default: 1001 default:
1107 ASSERT(false); 1002 ASSERT(false);
1108 break; 1003 break;
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
1156 PrintPingsSinceLastResponse(&pings, 5); 1051 PrintPingsSinceLastResponse(&pings, 5);
1157 LOG_J(LS_VERBOSE, this) << "UpdateState()" 1052 LOG_J(LS_VERBOSE, this) << "UpdateState()"
1158 << ", ms since last received response=" 1053 << ", ms since last received response="
1159 << now - last_ping_response_received_ 1054 << now - last_ping_response_received_
1160 << ", ms since last received data=" 1055 << ", ms since last received data="
1161 << now - last_data_received_ 1056 << now - last_data_received_
1162 << ", rtt=" << rtt 1057 << ", rtt=" << rtt
1163 << ", pings_since_last_response=" << pings; 1058 << ", pings_since_last_response=" << pings;
1164 } 1059 }
1165 1060
1166 // Check the readable state.
1167 //
1168 // Since we don't know how many pings the other side has attempted, the best
1169 // test we can do is a simple window.
1170 // If other side has not sent ping after connection has become readable, use
1171 // |last_data_received_| as the indication.
1172 // If remote endpoint is doing RFC 5245, it's not required to send ping
1173 // after connection is established. If this connection is serving a data
1174 // channel, it may not be in a position to send media continuously. Do not
1175 // mark connection timeout if it's in RFC5245 mode.
1176 // Below check will be performed with end point if it's doing google-ice.
1177 if (port_->IsGoogleIce() && (read_state_ == STATE_READABLE) &&
1178 (last_ping_received_ + CONNECTION_READ_TIMEOUT <= now) &&
1179 (last_data_received_ + CONNECTION_READ_TIMEOUT <= now)) {
1180 LOG_J(LS_INFO, this) << "Unreadable after " << now - last_ping_received_
1181 << " ms without a ping,"
1182 << " ms since last received response="
1183 << now - last_ping_response_received_
1184 << " ms since last received data="
1185 << now - last_data_received_
1186 << " rtt=" << rtt;
1187 set_read_state(STATE_READ_TIMEOUT);
1188 }
1189
1190 // Check the writable state. (The order of these checks is important.) 1061 // Check the writable state. (The order of these checks is important.)
1191 // 1062 //
1192 // Before becoming unwritable, we allow for a fixed number of pings to fail 1063 // Before becoming unwritable, we allow for a fixed number of pings to fail
1193 // (i.e., receive no response). We also have to give the response time to 1064 // (i.e., receive no response). We also have to give the response time to
1194 // get back, so we include a conservative estimate of this. 1065 // get back, so we include a conservative estimate of this.
1195 // 1066 //
1196 // Before timing out writability, we give a fixed amount of time. This is to 1067 // Before timing out writability, we give a fixed amount of time. This is to
1197 // allow for changes in network conditions. 1068 // allow for changes in network conditions.
1198 1069
1199 if ((write_state_ == STATE_WRITABLE) && 1070 if ((write_state_ == STATE_WRITABLE) &&
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
1338 LOG_JV(sev, this) << "Received STUN ping response" 1209 LOG_JV(sev, this) << "Received STUN ping response"
1339 << ", id=" << rtc::hex_encode(request->id()) 1210 << ", id=" << rtc::hex_encode(request->id())
1340 << ", code=0" // Makes logging easier to parse. 1211 << ", code=0" // Makes logging easier to parse.
1341 << ", rtt=" << rtt 1212 << ", rtt=" << rtt
1342 << ", use_candidate=" << use_candidate 1213 << ", use_candidate=" << use_candidate
1343 << ", pings_since_last_response=" << pings; 1214 << ", pings_since_last_response=" << pings;
1344 } 1215 }
1345 1216
1346 rtt_ = (RTT_RATIO * rtt_ + rtt) / (RTT_RATIO + 1); 1217 rtt_ = (RTT_RATIO * rtt_ + rtt) / (RTT_RATIO + 1);
1347 1218
1348 // Peer reflexive candidate is only for RFC 5245 ICE. 1219 MaybeAddPrflxCandidate(request, response);
1349 if (port_->IsStandardIce()) {
1350 MaybeAddPrflxCandidate(request, response);
1351 }
1352 } 1220 }
1353 1221
1354 void Connection::OnConnectionRequestErrorResponse(ConnectionRequest* request, 1222 void Connection::OnConnectionRequestErrorResponse(ConnectionRequest* request,
1355 StunMessage* response) { 1223 StunMessage* response) {
1356 const StunErrorCodeAttribute* error_attr = response->GetErrorCode(); 1224 const StunErrorCodeAttribute* error_attr = response->GetErrorCode();
1357 int error_code = STUN_ERROR_GLOBAL_FAILURE; 1225 int error_code = STUN_ERROR_GLOBAL_FAILURE;
1358 if (error_attr) { 1226 if (error_attr) {
1359 if (port_->IsGoogleIce()) { 1227 error_code = error_attr->code();
1360 // When doing GICE, the error code is written out incorrectly, so we need
1361 // to unmunge it here.
1362 error_code = error_attr->eclass() * 256 + error_attr->number();
1363 } else {
1364 error_code = error_attr->code();
1365 }
1366 } 1228 }
1367 1229
1368 LOG_J(LS_INFO, this) << "Received STUN error response" 1230 LOG_J(LS_INFO, this) << "Received STUN error response"
1369 << " id=" << rtc::hex_encode(request->id()) 1231 << " id=" << rtc::hex_encode(request->id())
1370 << " code=" << error_code 1232 << " code=" << error_code
1371 << " rtt=" << request->Elapsed(); 1233 << " rtt=" << request->Elapsed();
1372 1234
1373 if (error_code == STUN_ERROR_UNKNOWN_ATTRIBUTE || 1235 if (error_code == STUN_ERROR_UNKNOWN_ATTRIBUTE ||
1374 error_code == STUN_ERROR_SERVER_ERROR || 1236 error_code == STUN_ERROR_SERVER_ERROR ||
1375 error_code == STUN_ERROR_UNAUTHORIZED) { 1237 error_code == STUN_ERROR_UNAUTHORIZED) {
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
1561 ASSERT(sent < 0); 1423 ASSERT(sent < 0);
1562 error_ = port_->GetError(); 1424 error_ = port_->GetError();
1563 sent_packets_discarded_++; 1425 sent_packets_discarded_++;
1564 } else { 1426 } else {
1565 send_rate_tracker_.Update(sent); 1427 send_rate_tracker_.Update(sent);
1566 } 1428 }
1567 return sent; 1429 return sent;
1568 } 1430 }
1569 1431
1570 } // namespace cricket 1432 } // namespace cricket
OLDNEW
« no previous file with comments | « webrtc/p2p/base/port.h ('k') | webrtc/p2p/base/port_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698