OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. | 2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 460 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
471 } | 471 } |
472 } | 472 } |
473 | 473 |
474 // The STUN binding request may arrive after setRemoteDescription and before | 474 // The STUN binding request may arrive after setRemoteDescription and before |
475 // adding remote candidate, so we need to set the password to the shared | 475 // adding remote candidate, so we need to set the password to the shared |
476 // password if the user name matches. | 476 // password if the user name matches. |
477 if (remote_password.empty() && remote_username == remote_ice_ufrag_) { | 477 if (remote_password.empty() && remote_username == remote_ice_ufrag_) { |
478 remote_password = remote_ice_pwd_; | 478 remote_password = remote_ice_pwd_; |
479 } | 479 } |
480 | 480 |
481 Candidate new_remote_candidate; | 481 Candidate remote_candidate; |
482 if (candidate != NULL) { | 482 bool remote_candidate_is_new = (candidate == nullptr); |
483 new_remote_candidate = *candidate; | 483 if (!remote_candidate_is_new) { |
| 484 remote_candidate = *candidate; |
484 if (ufrag_per_port) { | 485 if (ufrag_per_port) { |
485 new_remote_candidate.set_address(address); | 486 remote_candidate.set_address(address); |
486 } | 487 } |
487 } else { | 488 } else { |
488 // Create a new candidate with this address. | 489 // Create a new candidate with this address. |
489 std::string type; | 490 std::string type; |
| 491 int remote_candidate_priority; |
490 if (port->IceProtocol() == ICEPROTO_RFC5245) { | 492 if (port->IceProtocol() == ICEPROTO_RFC5245) { |
| 493 // RFC 5245 |
| 494 // If the source transport address of the request does not match any |
| 495 // existing remote candidates, it represents a new peer reflexive remote |
| 496 // candidate. |
491 type = PRFLX_PORT_TYPE; | 497 type = PRFLX_PORT_TYPE; |
| 498 |
| 499 // The priority of the candidate is set to the PRIORITY attribute |
| 500 // from the request. |
| 501 const StunUInt32Attribute* priority_attr = |
| 502 stun_msg->GetUInt32(STUN_ATTR_PRIORITY); |
| 503 if (!priority_attr) { |
| 504 LOG(LS_WARNING) << "P2PTransportChannel::OnUnknownAddress - " |
| 505 << "No STUN_ATTR_PRIORITY found in the " |
| 506 << "stun request message"; |
| 507 port->SendBindingErrorResponse(stun_msg, address, |
| 508 STUN_ERROR_BAD_REQUEST, |
| 509 STUN_ERROR_REASON_BAD_REQUEST); |
| 510 return; |
| 511 } |
| 512 remote_candidate_priority = priority_attr->value(); |
492 } else { | 513 } else { |
493 // G-ICE doesn't support prflx candidate. | 514 // G-ICE doesn't support prflx candidate. |
494 // We set candidate type to STUN_PORT_TYPE if the binding request comes | 515 // We set candidate type to STUN_PORT_TYPE if the binding request comes |
495 // from a relay port or the shared socket is used. Otherwise we use the | 516 // from a relay port or the shared socket is used. Otherwise we use the |
496 // port's type as the candidate type. | 517 // port's type as the candidate type. |
497 if (port->Type() == RELAY_PORT_TYPE || port->SharedSocket()) { | 518 if (port->Type() == RELAY_PORT_TYPE || port->SharedSocket()) { |
498 type = STUN_PORT_TYPE; | 519 type = STUN_PORT_TYPE; |
499 } else { | 520 } else { |
500 type = port->Type(); | 521 type = port->Type(); |
501 } | 522 } |
| 523 remote_candidate_priority = remote_candidate.GetPriority( |
| 524 ICE_TYPE_PREFERENCE_PRFLX, port->Network()->preference(), 0); |
502 } | 525 } |
503 | 526 |
504 new_remote_candidate = | 527 remote_candidate = |
505 Candidate(component(), ProtoToString(proto), address, 0, | 528 Candidate(component(), ProtoToString(proto), address, 0, |
506 remote_username, remote_password, type, 0U, ""); | 529 remote_username, remote_password, type, 0U, ""); |
507 | 530 |
508 // From RFC 5245, section-7.2.1.3: | 531 // From RFC 5245, section-7.2.1.3: |
509 // The foundation of the candidate is set to an arbitrary value, different | 532 // The foundation of the candidate is set to an arbitrary value, different |
510 // from the foundation for all other remote candidates. | 533 // from the foundation for all other remote candidates. |
511 new_remote_candidate.set_foundation( | 534 remote_candidate.set_foundation( |
512 rtc::ToString<uint32>(rtc::ComputeCrc32(new_remote_candidate.id()))); | 535 rtc::ToString<uint32>(rtc::ComputeCrc32(remote_candidate.id()))); |
513 | 536 |
514 new_remote_candidate.set_priority(new_remote_candidate.GetPriority( | 537 remote_candidate.set_priority(remote_candidate_priority); |
515 ICE_TYPE_PREFERENCE_PRFLX, port->Network()->preference(), 0)); | |
516 } | 538 } |
517 | 539 |
518 if (port->IceProtocol() == ICEPROTO_RFC5245) { | 540 if (port->IceProtocol() == ICEPROTO_RFC5245) { |
519 // RFC 5245 | |
520 // If the source transport address of the request does not match any | |
521 // existing remote candidates, it represents a new peer reflexive remote | |
522 // candidate. | |
523 | |
524 // The priority of the candidate is set to the PRIORITY attribute | |
525 // from the request. | |
526 const StunUInt32Attribute* priority_attr = | |
527 stun_msg->GetUInt32(STUN_ATTR_PRIORITY); | |
528 if (!priority_attr) { | |
529 LOG(LS_WARNING) << "P2PTransportChannel::OnUnknownAddress - " | |
530 << "No STUN_ATTR_PRIORITY found in the " | |
531 << "stun request message"; | |
532 port->SendBindingErrorResponse(stun_msg, address, | |
533 STUN_ERROR_BAD_REQUEST, | |
534 STUN_ERROR_REASON_BAD_REQUEST); | |
535 return; | |
536 } | |
537 new_remote_candidate.set_priority(priority_attr->value()); | |
538 | |
539 // RFC5245, the agent constructs a pair whose local candidate is equal to | 541 // RFC5245, the agent constructs a pair whose local candidate is equal to |
540 // the transport address on which the STUN request was received, and a | 542 // the transport address on which the STUN request was received, and a |
541 // remote candidate equal to the source transport address where the | 543 // remote candidate equal to the source transport address where the |
542 // request came from. | 544 // request came from. |
543 | 545 |
544 // There shouldn't be an existing connection with this remote address. | 546 // There shouldn't be an existing connection with this remote address. |
545 // When ports are muxed, this channel might get multiple unknown address | 547 // When ports are muxed, this channel might get multiple unknown address |
546 // signals. In that case if the connection is already exists, we should | 548 // signals. In that case if the connection is already exists, we should |
547 // simply ignore the signal othewise send server error. | 549 // simply ignore the signal othewise send server error. |
548 if (port->GetConnection(new_remote_candidate.address())) { | 550 if (port->GetConnection(remote_candidate.address())) { |
549 if (port_muxed) { | 551 if (port_muxed) { |
550 LOG(LS_INFO) << "Connection already exists for peer reflexive " | 552 LOG(LS_INFO) << "Connection already exists for peer reflexive " |
551 << "candidate: " << new_remote_candidate.ToString(); | 553 << "candidate: " << remote_candidate.ToString(); |
552 return; | 554 return; |
553 } else { | 555 } else { |
554 ASSERT(false); | 556 ASSERT(false); |
555 port->SendBindingErrorResponse(stun_msg, address, | 557 port->SendBindingErrorResponse(stun_msg, address, |
556 STUN_ERROR_SERVER_ERROR, | 558 STUN_ERROR_SERVER_ERROR, |
557 STUN_ERROR_REASON_SERVER_ERROR); | 559 STUN_ERROR_REASON_SERVER_ERROR); |
558 return; | 560 return; |
559 } | 561 } |
560 } | 562 } |
561 | 563 |
562 Connection* connection = port->CreateConnection( | 564 Connection* connection = port->CreateConnection( |
563 new_remote_candidate, cricket::PortInterface::ORIGIN_THIS_PORT); | 565 remote_candidate, cricket::PortInterface::ORIGIN_THIS_PORT); |
564 if (!connection) { | 566 if (!connection) { |
565 ASSERT(false); | 567 ASSERT(false); |
566 port->SendBindingErrorResponse(stun_msg, address, | 568 port->SendBindingErrorResponse(stun_msg, address, |
567 STUN_ERROR_SERVER_ERROR, | 569 STUN_ERROR_SERVER_ERROR, |
568 STUN_ERROR_REASON_SERVER_ERROR); | 570 STUN_ERROR_REASON_SERVER_ERROR); |
569 return; | 571 return; |
570 } | 572 } |
571 | 573 |
572 LOG(LS_INFO) << "Adding connection from peer reflexive candidate: " | 574 LOG(LS_INFO) << "Adding connection from " |
573 << new_remote_candidate.ToString(); | 575 << (remote_candidate_is_new ? "peer reflexive" : "resurrected") |
| 576 << " candidate: " << remote_candidate.ToString(); |
574 AddConnection(connection); | 577 AddConnection(connection); |
575 connection->ReceivedPing(); | 578 connection->ReceivedPing(); |
576 | 579 |
577 // Send the pinger a successful stun response. | 580 // Send the pinger a successful stun response. |
578 port->SendBindingResponse(stun_msg, address); | 581 port->SendBindingResponse(stun_msg, address); |
579 | 582 |
580 // Update the list of connections since we just added another. We do this | 583 // Update the list of connections since we just added another. We do this |
581 // after sending the response since it could (in principle) delete the | 584 // after sending the response since it could (in principle) delete the |
582 // connection in question. | 585 // connection in question. |
583 SortConnections(); | 586 SortConnections(); |
584 } else { | 587 } else { |
585 // Check for connectivity to this address. Create connections | 588 // Check for connectivity to this address. Create connections |
586 // to this address across all local ports. First, add this as a new remote | 589 // to this address across all local ports. First, add this as a new remote |
587 // address | 590 // address |
588 if (!CreateConnections(new_remote_candidate, port, true)) { | 591 if (!CreateConnections(remote_candidate, port, true)) { |
589 // Hopefully this won't occur, because changing a destination address | 592 // Hopefully this won't occur, because changing a destination address |
590 // shouldn't cause a new connection to fail | 593 // shouldn't cause a new connection to fail |
591 ASSERT(false); | 594 ASSERT(false); |
592 port->SendBindingErrorResponse(stun_msg, address, STUN_ERROR_SERVER_ERROR, | 595 port->SendBindingErrorResponse(stun_msg, address, STUN_ERROR_SERVER_ERROR, |
593 STUN_ERROR_REASON_SERVER_ERROR); | 596 STUN_ERROR_REASON_SERVER_ERROR); |
594 return; | 597 return; |
595 } | 598 } |
596 | 599 |
597 // Send the pinger a successful stun response. | 600 // Send the pinger a successful stun response. |
598 port->SendBindingResponse(stun_msg, address); | 601 port->SendBindingResponse(stun_msg, address); |
(...skipping 769 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1368 SignalReadPacket(this, data, len, packet_time, 0); | 1371 SignalReadPacket(this, data, len, packet_time, 0); |
1369 } | 1372 } |
1370 | 1373 |
1371 void P2PTransportChannel::OnReadyToSend(Connection* connection) { | 1374 void P2PTransportChannel::OnReadyToSend(Connection* connection) { |
1372 if (connection == best_connection_ && writable()) { | 1375 if (connection == best_connection_ && writable()) { |
1373 SignalReadyToSend(this); | 1376 SignalReadyToSend(this); |
1374 } | 1377 } |
1375 } | 1378 } |
1376 | 1379 |
1377 } // namespace cricket | 1380 } // namespace cricket |
OLD | NEW |