OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |