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

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

Issue 2068263003: Do not delete a connection in the turn port with permission error or refresh error. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc@master
Patch Set: Merge with head Created 4 years, 6 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/turnport.h ('k') | webrtc/p2p/base/turnport_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 2012 The WebRTC Project Authors. All rights reserved. 2 * Copyright 2012 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 431 matching lines...) Expand 10 before | Expand all | Expand 10 after
442 CandidateOrigin origin) { 442 CandidateOrigin origin) {
443 // TURN-UDP can only connect to UDP candidates. 443 // TURN-UDP can only connect to UDP candidates.
444 if (!SupportsProtocol(address.protocol())) { 444 if (!SupportsProtocol(address.protocol())) {
445 return NULL; 445 return NULL;
446 } 446 }
447 447
448 if (!IsCompatibleAddress(address.address())) { 448 if (!IsCompatibleAddress(address.address())) {
449 return NULL; 449 return NULL;
450 } 450 }
451 451
452 if (state_ == STATE_DISCONNECTED) { 452 if (state_ == STATE_DISCONNECTED || state_ == STATE_RECEIVEONLY) {
453 return NULL; 453 return NULL;
454 } 454 }
455 455
456 // Create an entry, if needed, so we can get our permissions set up correctly. 456 // Create an entry, if needed, so we can get our permissions set up correctly.
457 CreateOrRefreshEntry(address.address()); 457 CreateOrRefreshEntry(address.address());
458 458
459 // A TURN port will have two candiates, STUN and TURN. STUN may not 459 // A TURN port will have two candiates, STUN and TURN. STUN may not
460 // present in all cases. If present stun candidate will be added first 460 // present in all cases. If present stun candidate will be added first
461 // and TURN candidate later. 461 // and TURN candidate later.
462 for (size_t index = 0; index < Candidates().size(); ++index) { 462 for (size_t index = 0; index < Candidates().size(); ++index) {
463 if (Candidates()[index].type() == RELAY_PORT_TYPE) { 463 if (Candidates()[index].type() == RELAY_PORT_TYPE) {
464 ProxyConnection* conn = new ProxyConnection(this, index, address); 464 ProxyConnection* conn = new ProxyConnection(this, index, address);
465 AddOrReplaceConnection(conn); 465 AddOrReplaceConnection(conn);
466 return conn; 466 return conn;
467 } 467 }
468 } 468 }
469 return NULL; 469 return NULL;
470 } 470 }
471 471
472 bool TurnPort::DestroyConnection(const rtc::SocketAddress& address) { 472 bool TurnPort::FailAndPruneConnection(const rtc::SocketAddress& address) {
473 Connection* conn = GetConnection(address); 473 Connection* conn = GetConnection(address);
474 if (conn != nullptr) { 474 if (conn != nullptr) {
475 conn->Destroy(); 475 conn->FailAndPrune();
476 return true; 476 return true;
477 } 477 }
478 return false; 478 return false;
479 } 479 }
480 480
481 int TurnPort::SetOption(rtc::Socket::Option opt, int value) { 481 int TurnPort::SetOption(rtc::Socket::Option opt, int value) {
482 if (!socket_) { 482 if (!socket_) {
483 // If socket is not created yet, these options will be applied during socket 483 // If socket is not created yet, these options will be applied during socket
484 // creation. 484 // creation.
485 socket_options_[opt] = value; 485 socket_options_[opt] = value;
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
554 } 554 }
555 555
556 // The message must be at least the size of a channel header. 556 // The message must be at least the size of a channel header.
557 if (size < TURN_CHANNEL_HEADER_SIZE) { 557 if (size < TURN_CHANNEL_HEADER_SIZE) {
558 LOG_J(LS_WARNING, this) << "Received TURN message that was too short"; 558 LOG_J(LS_WARNING, this) << "Received TURN message that was too short";
559 return false; 559 return false;
560 } 560 }
561 561
562 if (state_ == STATE_DISCONNECTED) { 562 if (state_ == STATE_DISCONNECTED) {
563 LOG_J(LS_WARNING, this) 563 LOG_J(LS_WARNING, this)
564 << "Received TURN message while the Turn port is disconnected"; 564 << "Received TURN message while the TURN port is disconnected";
565 return false; 565 return false;
566 } 566 }
567 567
568 // Check the message type, to see if is a Channel Data message. 568 // Check the message type, to see if is a Channel Data message.
569 // The message will either be channel data, a TURN data indication, or 569 // The message will either be channel data, a TURN data indication, or
570 // a response to a previous request. 570 // a response to a previous request.
571 uint16_t msg_type = rtc::GetBE16(data); 571 uint16_t msg_type = rtc::GetBE16(data);
572 if (IsTurnChannelData(msg_type)) { 572 if (IsTurnChannelData(msg_type)) {
573 HandleChannelData(msg_type, data, size, packet_time); 573 HandleChannelData(msg_type, data, size, packet_time);
574 return true; 574 return true;
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
732 server_priority_, true); 732 server_priority_, true);
733 } 733 }
734 734
735 void TurnPort::OnAllocateError() { 735 void TurnPort::OnAllocateError() {
736 // We will send SignalPortError asynchronously as this can be sent during 736 // We will send SignalPortError asynchronously as this can be sent during
737 // port initialization. This way it will not be blocking other port 737 // port initialization. This way it will not be blocking other port
738 // creation. 738 // creation.
739 thread()->Post(RTC_FROM_HERE, this, MSG_ALLOCATE_ERROR); 739 thread()->Post(RTC_FROM_HERE, this, MSG_ALLOCATE_ERROR);
740 } 740 }
741 741
742 void TurnPort::OnTurnRefreshError() { 742 void TurnPort::OnRefreshError() {
743 // Need to Close the port asynchronously because otherwise, the refresh 743 // Need to clear the requests asynchronously because otherwise, the refresh
744 // request may be deleted twice: once at the end of the message processing 744 // request may be deleted twice: once at the end of the message processing
745 // and the other in Close(). 745 // and the other in HandleRefreshError().
746 thread()->Post(RTC_FROM_HERE, this, MSG_REFRESH_ERROR); 746 thread()->Post(RTC_FROM_HERE, this, MSG_REFRESH_ERROR);
747 } 747 }
748 748
749 void TurnPort::HandleRefreshError() {
750 request_manager_.Clear();
751 state_ = STATE_RECEIVEONLY;
752 // Fail and prune all connections; stop sending data.
753 for (auto kv : connections()) {
754 kv.second->FailAndPrune();
755 }
756 }
757
749 void TurnPort::Close() { 758 void TurnPort::Close() {
750 if (!ready()) { 759 if (!ready()) {
751 OnAllocateError(); 760 OnAllocateError();
752 } 761 }
753 request_manager_.Clear(); 762 request_manager_.Clear();
754 // Stop the port from creating new connections. 763 // Stop the port from creating new connections.
755 state_ = STATE_DISCONNECTED; 764 state_ = STATE_DISCONNECTED;
756 // Delete all existing connections; stop sending data. 765 // Delete all existing connections; stop sending data.
757 for (auto kv : connections()) { 766 for (auto kv : connections()) {
758 kv.second->Destroy(); 767 kv.second->Destroy();
759 } 768 }
760 } 769 }
761 770
762 void TurnPort::OnMessage(rtc::Message* message) { 771 void TurnPort::OnMessage(rtc::Message* message) {
763 switch (message->message_id) { 772 switch (message->message_id) {
764 case MSG_ALLOCATE_ERROR: 773 case MSG_ALLOCATE_ERROR:
765 SignalPortError(this); 774 SignalPortError(this);
766 break; 775 break;
767 case MSG_ALLOCATE_MISMATCH: 776 case MSG_ALLOCATE_MISMATCH:
768 OnAllocateMismatch(); 777 OnAllocateMismatch();
769 break; 778 break;
770 case MSG_REFRESH_ERROR: 779 case MSG_REFRESH_ERROR:
771 Close(); 780 HandleRefreshError();
772 break; 781 break;
773 case MSG_TRY_ALTERNATE_SERVER: 782 case MSG_TRY_ALTERNATE_SERVER:
774 if (server_address().proto == PROTO_UDP) { 783 if (server_address().proto == PROTO_UDP) {
775 // Send another allocate request to alternate server, with the received 784 // Send another allocate request to alternate server, with the received
776 // realm and nonce values. 785 // realm and nonce values.
777 SendRequest(new TurnAllocateRequest(this), 0); 786 SendRequest(new TurnAllocateRequest(this), 0);
778 } else { 787 } else {
779 // Since it's TCP, we have to delete the connected socket and reconnect 788 // Since it's TCP, we have to delete the connected socket and reconnect
780 // with the alternate server. PrepareAddress will send stun binding once 789 // with the alternate server. PrepareAddress will send stun binding once
781 // the new socket is connected. 790 // the new socket is connected.
(...skipping 488 matching lines...) Expand 10 before | Expand all | Expand 10 after
1270 if (error_code->code() == STUN_ERROR_STALE_NONCE) { 1279 if (error_code->code() == STUN_ERROR_STALE_NONCE) {
1271 if (port_->UpdateNonce(response)) { 1280 if (port_->UpdateNonce(response)) {
1272 // Send RefreshRequest immediately. 1281 // Send RefreshRequest immediately.
1273 port_->SendRequest(new TurnRefreshRequest(port_), 0); 1282 port_->SendRequest(new TurnRefreshRequest(port_), 0);
1274 } 1283 }
1275 } else { 1284 } else {
1276 LOG_J(LS_WARNING, port_) << "Received TURN refresh error response" 1285 LOG_J(LS_WARNING, port_) << "Received TURN refresh error response"
1277 << ", id=" << rtc::hex_encode(id()) 1286 << ", id=" << rtc::hex_encode(id())
1278 << ", code=" << error_code->code() 1287 << ", code=" << error_code->code()
1279 << ", rtt=" << Elapsed(); 1288 << ", rtt=" << Elapsed();
1280 port_->OnTurnRefreshError(); 1289 port_->OnRefreshError();
1281 port_->SignalTurnRefreshResult(port_, error_code->code()); 1290 port_->SignalTurnRefreshResult(port_, error_code->code());
1282 } 1291 }
1283 } 1292 }
1284 1293
1285 void TurnRefreshRequest::OnTimeout() { 1294 void TurnRefreshRequest::OnTimeout() {
1286 LOG_J(LS_WARNING, port_) << "TURN refresh timeout " << rtc::hex_encode(id()); 1295 LOG_J(LS_WARNING, port_) << "TURN refresh timeout " << rtc::hex_encode(id());
1287 port_->OnTurnRefreshError(); 1296 port_->OnRefreshError();
1288 } 1297 }
1289 1298
1290 TurnCreatePermissionRequest::TurnCreatePermissionRequest( 1299 TurnCreatePermissionRequest::TurnCreatePermissionRequest(
1291 TurnPort* port, TurnEntry* entry, 1300 TurnPort* port, TurnEntry* entry,
1292 const rtc::SocketAddress& ext_addr) 1301 const rtc::SocketAddress& ext_addr)
1293 : StunRequest(new TurnMessage()), 1302 : StunRequest(new TurnMessage()),
1294 port_(port), 1303 port_(port),
1295 entry_(entry), 1304 entry_(entry),
1296 ext_addr_(ext_addr) { 1305 ext_addr_(ext_addr) {
1297 entry_->SignalDestroyed.connect( 1306 entry_->SignalDestroyed.connect(
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
1484 << delay << "ms."; 1493 << delay << "ms.";
1485 } 1494 }
1486 } 1495 }
1487 1496
1488 void TurnEntry::OnCreatePermissionError(StunMessage* response, int code) { 1497 void TurnEntry::OnCreatePermissionError(StunMessage* response, int code) {
1489 if (code == STUN_ERROR_STALE_NONCE) { 1498 if (code == STUN_ERROR_STALE_NONCE) {
1490 if (port_->UpdateNonce(response)) { 1499 if (port_->UpdateNonce(response)) {
1491 SendCreatePermissionRequest(0); 1500 SendCreatePermissionRequest(0);
1492 } 1501 }
1493 } else { 1502 } else {
1494 port_->DestroyConnection(ext_addr_); 1503 bool found = port_->FailAndPruneConnection(ext_addr_);
juberti 2016/06/23 21:07:29 Shouldn't we destroy the connection if we can't cr
pthatcher1 2016/06/23 21:29:23 Not if the TURN server doesn't check for CreatePer
1504 if (found) {
1505 LOG(LS_ERROR) << "Received TURN CreatePermission error response, "
1506 << "code=" << code << "; pruned connection.";
1507 }
1495 // Send signal with error code. 1508 // Send signal with error code.
1496 port_->SignalCreatePermissionResult(port_, ext_addr_, code); 1509 port_->SignalCreatePermissionResult(port_, ext_addr_, code);
1497 Connection* c = port_->GetConnection(ext_addr_);
1498 if (c) {
1499 LOG_J(LS_ERROR, c) << "Received TURN CreatePermission error response, "
1500 << "code=" << code << "; killing connection.";
1501 c->FailAndDestroy();
1502 }
1503 } 1510 }
1504 } 1511 }
1505 1512
1506 void TurnEntry::OnCreatePermissionTimeout() { 1513 void TurnEntry::OnCreatePermissionTimeout() {
1507 port_->DestroyConnection(ext_addr_); 1514 port_->FailAndPruneConnection(ext_addr_);
1508 } 1515 }
1509 1516
1510 void TurnEntry::OnChannelBindSuccess() { 1517 void TurnEntry::OnChannelBindSuccess() {
1511 LOG_J(LS_INFO, port_) << "Channel bind for " << ext_addr_.ToSensitiveString() 1518 LOG_J(LS_INFO, port_) << "Channel bind for " << ext_addr_.ToSensitiveString()
1512 << " succeeded"; 1519 << " succeeded";
1513 ASSERT(state_ == STATE_BINDING || state_ == STATE_BOUND); 1520 ASSERT(state_ == STATE_BINDING || state_ == STATE_BOUND);
1514 state_ = STATE_BOUND; 1521 state_ = STATE_BOUND;
1515 } 1522 }
1516 1523
1517 void TurnEntry::OnChannelBindError(StunMessage* response, int code) { 1524 void TurnEntry::OnChannelBindError(StunMessage* response, int code) {
1518 // If the channel bind fails due to errors other than STATE_NONCE, 1525 // If the channel bind fails due to errors other than STATE_NONCE,
1519 // we just destroy the connection and rely on ICE restart to re-establish 1526 // we will fail and prune the connection and rely on ICE restart to
1520 // the connection. 1527 // re-establish a new connection if needed.
1521 if (code == STUN_ERROR_STALE_NONCE) { 1528 if (code == STUN_ERROR_STALE_NONCE) {
1522 if (port_->UpdateNonce(response)) { 1529 if (port_->UpdateNonce(response)) {
1523 // Send channel bind request with fresh nonce. 1530 // Send channel bind request with fresh nonce.
1524 SendChannelBindRequest(0); 1531 SendChannelBindRequest(0);
1525 } 1532 }
1526 } else { 1533 } else {
1527 state_ = STATE_UNBOUND; 1534 state_ = STATE_UNBOUND;
1528 port_->DestroyConnection(ext_addr_); 1535 port_->FailAndPruneConnection(ext_addr_);
juberti 2016/06/23 21:07:29 This also seems like an error that should be fatal
1529 } 1536 }
1530 } 1537 }
1531 void TurnEntry::OnChannelBindTimeout() { 1538 void TurnEntry::OnChannelBindTimeout() {
1532 state_ = STATE_UNBOUND; 1539 state_ = STATE_UNBOUND;
1533 port_->DestroyConnection(ext_addr_); 1540 port_->FailAndPruneConnection(ext_addr_);
1534 } 1541 }
1535 } // namespace cricket 1542 } // namespace cricket
OLDNEW
« no previous file with comments | « webrtc/p2p/base/turnport.h ('k') | webrtc/p2p/base/turnport_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698