Chromium Code Reviews| 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 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 161 rtc::Thread* network_thread, | 161 rtc::Thread* network_thread, |
| 162 rtc::Thread* signaling_thread, | 162 rtc::Thread* signaling_thread, |
| 163 MediaChannel* media_channel, | 163 MediaChannel* media_channel, |
| 164 const std::string& content_name, | 164 const std::string& content_name, |
| 165 bool rtcp_mux_required, | 165 bool rtcp_mux_required, |
| 166 bool srtp_required) | 166 bool srtp_required) |
| 167 : worker_thread_(worker_thread), | 167 : worker_thread_(worker_thread), |
| 168 network_thread_(network_thread), | 168 network_thread_(network_thread), |
| 169 signaling_thread_(signaling_thread), | 169 signaling_thread_(signaling_thread), |
| 170 content_name_(content_name), | 170 content_name_(content_name), |
| 171 rtcp_mux_required_(rtcp_mux_required), | |
| 171 rtp_transport_(rtcp_mux_required), | 172 rtp_transport_(rtcp_mux_required), |
| 172 srtp_required_(srtp_required), | 173 srtp_required_(srtp_required), |
| 173 media_channel_(media_channel), | 174 media_channel_(media_channel), |
| 174 selected_candidate_pair_(nullptr) { | 175 selected_candidate_pair_(nullptr) { |
| 175 RTC_DCHECK(worker_thread_ == rtc::Thread::Current()); | 176 RTC_DCHECK(worker_thread_ == rtc::Thread::Current()); |
| 176 #if defined(ENABLE_EXTERNAL_AUTH) | 177 #if defined(ENABLE_EXTERNAL_AUTH) |
| 177 srtp_filter_.EnableExternalAuth(); | 178 srtp_filter_.EnableExternalAuth(); |
| 178 #endif | 179 #endif |
| 180 rtp_transport_.SignalReadyToSend.connect( | |
| 181 this, &BaseChannel::OnTransportReadyToSend); | |
| 179 LOG(LS_INFO) << "Created channel for " << content_name; | 182 LOG(LS_INFO) << "Created channel for " << content_name; |
| 180 } | 183 } |
| 181 | 184 |
| 182 BaseChannel::~BaseChannel() { | 185 BaseChannel::~BaseChannel() { |
| 183 TRACE_EVENT0("webrtc", "BaseChannel::~BaseChannel"); | 186 TRACE_EVENT0("webrtc", "BaseChannel::~BaseChannel"); |
| 184 RTC_DCHECK(worker_thread_ == rtc::Thread::Current()); | 187 RTC_DCHECK(worker_thread_ == rtc::Thread::Current()); |
| 185 Deinit(); | 188 Deinit(); |
| 186 StopConnectionMonitor(); | 189 StopConnectionMonitor(); |
| 187 // Eats any outstanding messages or packets. | 190 // Eats any outstanding messages or packets. |
| 188 worker_thread_->Clear(&invoker_); | 191 worker_thread_->Clear(&invoker_); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 243 rtcp_packet_transport); | 246 rtcp_packet_transport); |
| 244 | 247 |
| 245 if (rtp_dtls_transport_ && | 248 if (rtp_dtls_transport_ && |
| 246 !SetDtlsSrtpCryptoSuites_n(rtp_dtls_transport_, false)) { | 249 !SetDtlsSrtpCryptoSuites_n(rtp_dtls_transport_, false)) { |
| 247 return false; | 250 return false; |
| 248 } | 251 } |
| 249 if (rtcp_dtls_transport_ && | 252 if (rtcp_dtls_transport_ && |
| 250 !SetDtlsSrtpCryptoSuites_n(rtcp_dtls_transport_, true)) { | 253 !SetDtlsSrtpCryptoSuites_n(rtcp_dtls_transport_, true)) { |
| 251 return false; | 254 return false; |
| 252 } | 255 } |
| 253 if (rtp_transport_.rtcp_mux_required()) { | 256 if (rtcp_mux_required_) { |
| 254 rtcp_mux_filter_.SetActive(); | 257 rtcp_mux_filter_.SetActive(); |
| 255 } | 258 } |
| 256 return true; | 259 return true; |
| 257 } | 260 } |
| 258 | 261 |
| 259 void BaseChannel::Deinit() { | 262 void BaseChannel::Deinit() { |
| 260 RTC_DCHECK(worker_thread_->IsCurrent()); | 263 RTC_DCHECK(worker_thread_->IsCurrent()); |
| 261 media_channel_->SetInterface(NULL); | 264 media_channel_->SetInterface(NULL); |
| 262 // Packets arrive on the network thread, processing packets calls virtual | 265 // Packets arrive on the network thread, processing packets calls virtual |
| 263 // functions, so need to stop this process in Deinit that is called in | 266 // functions, so need to stop this process in Deinit that is called in |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 336 SetTransport_n(true, rtcp_dtls_transport, rtcp_packet_transport); | 339 SetTransport_n(true, rtcp_dtls_transport, rtcp_packet_transport); |
| 337 } | 340 } |
| 338 | 341 |
| 339 LOG(LS_INFO) << "Setting RTP Transport for " << content_name() << " on " | 342 LOG(LS_INFO) << "Setting RTP Transport for " << content_name() << " on " |
| 340 << debug_name << " transport " << rtp_packet_transport; | 343 << debug_name << " transport " << rtp_packet_transport; |
| 341 SetTransport_n(false, rtp_dtls_transport, rtp_packet_transport); | 344 SetTransport_n(false, rtp_dtls_transport, rtp_packet_transport); |
| 342 | 345 |
| 343 // Update aggregate writable/ready-to-send state between RTP and RTCP upon | 346 // Update aggregate writable/ready-to-send state between RTP and RTCP upon |
| 344 // setting new transport channels. | 347 // setting new transport channels. |
| 345 UpdateWritableState_n(); | 348 UpdateWritableState_n(); |
| 346 // We can only update ready-to-send after updating writability. | |
| 347 // | |
| 348 // On setting a new channel, assume it's ready to send if it's writable, | |
| 349 // because we have no way of knowing otherwise (the channel doesn't give us | |
| 350 // "was last send successful?"). | |
| 351 // | |
| 352 // This won't always be accurate (the last SendPacket call from another | |
| 353 // BaseChannel could have resulted in an error), but even so, we'll just | |
| 354 // encounter the error again and update "ready to send" accordingly. | |
| 355 SetTransportChannelReadyToSend( | |
| 356 false, rtp_packet_transport && rtp_packet_transport->writable()); | |
| 357 SetTransportChannelReadyToSend( | |
| 358 true, rtcp_packet_transport && rtcp_packet_transport->writable()); | |
| 359 } | 349 } |
| 360 | 350 |
| 361 void BaseChannel::SetTransport_n( | 351 void BaseChannel::SetTransport_n( |
| 362 bool rtcp, | 352 bool rtcp, |
| 363 DtlsTransportInternal* new_dtls_transport, | 353 DtlsTransportInternal* new_dtls_transport, |
| 364 rtc::PacketTransportInternal* new_packet_transport) { | 354 rtc::PacketTransportInternal* new_packet_transport) { |
| 365 RTC_DCHECK(network_thread_->IsCurrent()); | 355 RTC_DCHECK(network_thread_->IsCurrent()); |
| 366 DtlsTransportInternal*& old_dtls_transport = | 356 DtlsTransportInternal*& old_dtls_transport = |
| 367 rtcp ? rtcp_dtls_transport_ : rtp_dtls_transport_; | 357 rtcp ? rtcp_dtls_transport_ : rtp_dtls_transport_; |
| 368 rtc::PacketTransportInternal* old_packet_transport = | 358 rtc::PacketTransportInternal* old_packet_transport = |
| 369 rtcp ? rtp_transport_.rtcp_packet_transport() | 359 rtcp ? rtp_transport_.rtcp_packet_transport() |
| 370 : rtp_transport_.rtp_packet_transport(); | 360 : rtp_transport_.rtp_packet_transport(); |
| 371 | 361 |
| 372 if (!old_packet_transport && !new_packet_transport) { | 362 if (!old_packet_transport && !new_packet_transport) { |
| 373 // Nothing to do. | 363 // Nothing to do. |
| 374 return; | 364 return; |
| 375 } | 365 } |
| 376 | 366 |
| 377 RTC_DCHECK(old_packet_transport != new_packet_transport); | 367 RTC_DCHECK(old_packet_transport != new_packet_transport); |
| 378 if (old_dtls_transport) { | 368 if (old_dtls_transport) { |
| 379 DisconnectFromDtlsTransport(old_dtls_transport); | 369 DisconnectFromDtlsTransport(old_dtls_transport); |
| 380 } else if (old_packet_transport) { | 370 } else if (old_packet_transport) { |
| 381 DisconnectFromPacketTransport(old_packet_transport); | 371 DisconnectFromPacketTransport(old_packet_transport); |
| 382 } | 372 } |
| 383 | 373 |
| 384 if (rtcp) { | 374 if (rtcp) { |
| 385 rtp_transport_.set_rtcp_packet_transport(new_packet_transport); | 375 rtp_transport_.SetRtcpPacketTransport(new_packet_transport); |
| 386 } else { | 376 } else { |
| 387 rtp_transport_.set_rtp_packet_transport(new_packet_transport); | 377 rtp_transport_.SetRtpPacketTransport(new_packet_transport); |
| 388 } | 378 } |
| 389 old_dtls_transport = new_dtls_transport; | 379 old_dtls_transport = new_dtls_transport; |
| 390 | 380 |
| 391 // If there's no new transport, we're done after disconnecting from old one. | 381 // If there's no new transport, we're done after disconnecting from old one. |
| 392 if (!new_packet_transport) { | 382 if (!new_packet_transport) { |
| 393 return; | 383 return; |
| 394 } | 384 } |
| 395 | 385 |
| 396 if (rtcp && new_dtls_transport) { | 386 if (rtcp && new_dtls_transport) { |
| 397 RTC_CHECK(!(ShouldSetupDtlsSrtp_n() && srtp_filter_.IsActive())) | 387 RTC_CHECK(!(ShouldSetupDtlsSrtp_n() && srtp_filter_.IsActive())) |
| 398 << "Setting RTCP for DTLS/SRTP after SrtpFilter is active " | 388 << "Setting RTCP for DTLS/SRTP after SrtpFilter is active " |
| 399 << "should never happen."; | 389 << "should never happen."; |
| 400 } | 390 } |
| 391 | |
| 401 if (new_dtls_transport) { | 392 if (new_dtls_transport) { |
| 402 ConnectToDtlsTransport(new_dtls_transport); | 393 ConnectToDtlsTransport(new_dtls_transport); |
| 403 } else { | 394 } else { |
| 404 ConnectToPacketTransport(new_packet_transport); | 395 ConnectToPacketTransport(new_packet_transport); |
| 405 } | 396 } |
| 406 auto& socket_options = rtcp ? rtcp_socket_options_ : socket_options_; | 397 auto& socket_options = rtcp ? rtcp_socket_options_ : socket_options_; |
| 407 for (const auto& pair : socket_options) { | 398 for (const auto& pair : socket_options) { |
| 408 new_packet_transport->SetOption(pair.first, pair.second); | 399 new_packet_transport->SetOption(pair.first, pair.second); |
| 409 } | 400 } |
| 410 } | 401 } |
| 411 | 402 |
| 412 void BaseChannel::ConnectToDtlsTransport(DtlsTransportInternal* transport) { | 403 void BaseChannel::ConnectToDtlsTransport(DtlsTransportInternal* transport) { |
| 413 RTC_DCHECK(network_thread_->IsCurrent()); | 404 RTC_DCHECK(network_thread_->IsCurrent()); |
| 414 | 405 |
| 406 // TODO(zstein): de-dup with ConnectToPacketTransport | |
| 415 transport->SignalWritableState.connect(this, &BaseChannel::OnWritableState); | 407 transport->SignalWritableState.connect(this, &BaseChannel::OnWritableState); |
| 416 transport->SignalReadPacket.connect(this, &BaseChannel::OnPacketRead); | 408 transport->SignalReadPacket.connect(this, &BaseChannel::OnPacketRead); |
| 417 transport->SignalReadyToSend.connect(this, &BaseChannel::OnReadyToSend); | |
| 418 transport->SignalDtlsState.connect(this, &BaseChannel::OnDtlsState); | 409 transport->SignalDtlsState.connect(this, &BaseChannel::OnDtlsState); |
| 419 transport->SignalSentPacket.connect(this, &BaseChannel::SignalSentPacket_n); | 410 transport->SignalSentPacket.connect(this, &BaseChannel::SignalSentPacket_n); |
| 420 transport->ice_transport()->SignalSelectedCandidatePairChanged.connect( | 411 transport->ice_transport()->SignalSelectedCandidatePairChanged.connect( |
| 421 this, &BaseChannel::OnSelectedCandidatePairChanged); | 412 this, &BaseChannel::OnSelectedCandidatePairChanged); |
| 422 } | 413 } |
| 423 | 414 |
| 424 void BaseChannel::DisconnectFromDtlsTransport( | 415 void BaseChannel::DisconnectFromDtlsTransport( |
| 425 DtlsTransportInternal* transport) { | 416 DtlsTransportInternal* transport) { |
| 426 RTC_DCHECK(network_thread_->IsCurrent()); | 417 RTC_DCHECK(network_thread_->IsCurrent()); |
| 427 OnSelectedCandidatePairChanged(transport->ice_transport(), nullptr, -1, | 418 OnSelectedCandidatePairChanged(transport->ice_transport(), nullptr, -1, |
| 428 false); | 419 false); |
| 429 | 420 |
| 430 transport->SignalWritableState.disconnect(this); | 421 transport->SignalWritableState.disconnect(this); |
| 431 transport->SignalReadPacket.disconnect(this); | 422 transport->SignalReadPacket.disconnect(this); |
| 432 transport->SignalReadyToSend.disconnect(this); | |
| 433 transport->SignalDtlsState.disconnect(this); | 423 transport->SignalDtlsState.disconnect(this); |
| 434 transport->SignalSentPacket.disconnect(this); | 424 transport->SignalSentPacket.disconnect(this); |
| 435 transport->ice_transport()->SignalSelectedCandidatePairChanged.disconnect( | 425 transport->ice_transport()->SignalSelectedCandidatePairChanged.disconnect( |
| 436 this); | 426 this); |
| 437 } | 427 } |
| 438 | 428 |
| 439 void BaseChannel::ConnectToPacketTransport( | 429 void BaseChannel::ConnectToPacketTransport( |
| 440 rtc::PacketTransportInternal* transport) { | 430 rtc::PacketTransportInternal* transport) { |
| 441 RTC_DCHECK_RUN_ON(network_thread_); | 431 RTC_DCHECK_RUN_ON(network_thread_); |
| 442 transport->SignalWritableState.connect(this, &BaseChannel::OnWritableState); | 432 transport->SignalWritableState.connect(this, &BaseChannel::OnWritableState); |
| 443 transport->SignalReadPacket.connect(this, &BaseChannel::OnPacketRead); | 433 transport->SignalReadPacket.connect(this, &BaseChannel::OnPacketRead); |
| 444 transport->SignalReadyToSend.connect(this, &BaseChannel::OnReadyToSend); | |
| 445 transport->SignalSentPacket.connect(this, &BaseChannel::SignalSentPacket_n); | 434 transport->SignalSentPacket.connect(this, &BaseChannel::SignalSentPacket_n); |
| 446 } | 435 } |
| 447 | 436 |
| 448 void BaseChannel::DisconnectFromPacketTransport( | 437 void BaseChannel::DisconnectFromPacketTransport( |
| 449 rtc::PacketTransportInternal* transport) { | 438 rtc::PacketTransportInternal* transport) { |
| 450 RTC_DCHECK_RUN_ON(network_thread_); | 439 RTC_DCHECK_RUN_ON(network_thread_); |
| 451 transport->SignalWritableState.disconnect(this); | 440 transport->SignalWritableState.disconnect(this); |
| 452 transport->SignalReadPacket.disconnect(this); | 441 transport->SignalReadPacket.disconnect(this); |
| 453 transport->SignalReadyToSend.disconnect(this); | |
| 454 transport->SignalSentPacket.disconnect(this); | 442 transport->SignalSentPacket.disconnect(this); |
| 455 } | 443 } |
| 456 | 444 |
| 457 bool BaseChannel::Enable(bool enable) { | 445 bool BaseChannel::Enable(bool enable) { |
| 458 worker_thread_->Invoke<void>( | 446 worker_thread_->Invoke<void>( |
| 459 RTC_FROM_HERE, | 447 RTC_FROM_HERE, |
| 460 Bind(enable ? &BaseChannel::EnableMedia_w : &BaseChannel::DisableMedia_w, | 448 Bind(enable ? &BaseChannel::EnableMedia_w : &BaseChannel::DisableMedia_w, |
| 461 this)); | 449 this)); |
| 462 return true; | 450 return true; |
| 463 } | 451 } |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 523 RTC_DCHECK(network_thread_->IsCurrent()); | 511 RTC_DCHECK(network_thread_->IsCurrent()); |
| 524 if (!rtp_dtls_transport_) { | 512 if (!rtp_dtls_transport_) { |
| 525 return false; | 513 return false; |
| 526 } | 514 } |
| 527 return rtp_dtls_transport_->ice_transport()->GetStats(infos); | 515 return rtp_dtls_transport_->ice_transport()->GetStats(infos); |
| 528 } | 516 } |
| 529 | 517 |
| 530 bool BaseChannel::NeedsRtcpTransport() { | 518 bool BaseChannel::NeedsRtcpTransport() { |
| 531 // If this BaseChannel doesn't require RTCP mux and we haven't fully | 519 // If this BaseChannel doesn't require RTCP mux and we haven't fully |
| 532 // negotiated RTCP mux, we need an RTCP transport. | 520 // negotiated RTCP mux, we need an RTCP transport. |
| 533 return !rtp_transport_.rtcp_mux_required() && | 521 return !rtcp_mux_required_ && !rtcp_mux_filter_.IsFullyActive(); |
| 534 !rtcp_mux_filter_.IsFullyActive(); | |
| 535 } | 522 } |
| 536 | 523 |
| 537 bool BaseChannel::IsReadyToReceiveMedia_w() const { | 524 bool BaseChannel::IsReadyToReceiveMedia_w() const { |
| 538 // Receive data if we are enabled and have local content, | 525 // Receive data if we are enabled and have local content, |
| 539 return enabled() && IsReceiveContentDirection(local_content_direction_); | 526 return enabled() && IsReceiveContentDirection(local_content_direction_); |
| 540 } | 527 } |
| 541 | 528 |
| 542 bool BaseChannel::IsReadyToSendMedia_w() const { | 529 bool BaseChannel::IsReadyToSendMedia_w() const { |
| 543 // Need to access some state updated on the network thread. | 530 // Need to access some state updated on the network thread. |
| 544 return network_thread_->Invoke<bool>( | 531 return network_thread_->Invoke<bool>( |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 611 // OnPacketRead gets called from P2PSocket; now pass data to MediaEngine | 598 // OnPacketRead gets called from P2PSocket; now pass data to MediaEngine |
| 612 RTC_DCHECK(network_thread_->IsCurrent()); | 599 RTC_DCHECK(network_thread_->IsCurrent()); |
| 613 | 600 |
| 614 // When using RTCP multiplexing we might get RTCP packets on the RTP | 601 // When using RTCP multiplexing we might get RTCP packets on the RTP |
| 615 // transport. We feed RTP traffic into the demuxer to determine if it is RTCP. | 602 // transport. We feed RTP traffic into the demuxer to determine if it is RTCP. |
| 616 bool rtcp = PacketIsRtcp(transport, data, len); | 603 bool rtcp = PacketIsRtcp(transport, data, len); |
| 617 rtc::CopyOnWriteBuffer packet(data, len); | 604 rtc::CopyOnWriteBuffer packet(data, len); |
| 618 HandlePacket(rtcp, &packet, packet_time); | 605 HandlePacket(rtcp, &packet, packet_time); |
| 619 } | 606 } |
| 620 | 607 |
| 621 void BaseChannel::OnReadyToSend(rtc::PacketTransportInternal* transport) { | |
| 622 RTC_DCHECK(transport == rtp_transport_.rtp_packet_transport() || | |
| 623 transport == rtp_transport_.rtcp_packet_transport()); | |
| 624 SetTransportChannelReadyToSend( | |
| 625 transport == rtp_transport_.rtcp_packet_transport(), true); | |
| 626 } | |
| 627 | |
| 628 void BaseChannel::OnDtlsState(DtlsTransportInternal* transport, | 608 void BaseChannel::OnDtlsState(DtlsTransportInternal* transport, |
| 629 DtlsTransportState state) { | 609 DtlsTransportState state) { |
| 630 if (!ShouldSetupDtlsSrtp_n()) { | 610 if (!ShouldSetupDtlsSrtp_n()) { |
| 631 return; | 611 return; |
| 632 } | 612 } |
| 633 | 613 |
| 634 // Reset the srtp filter if it's not the CONNECTED state. For the CONNECTED | 614 // Reset the srtp filter if it's not the CONNECTED state. For the CONNECTED |
| 635 // state, setting up DTLS-SRTP context is deferred to ChannelWritable_w to | 615 // state, setting up DTLS-SRTP context is deferred to ChannelWritable_w to |
| 636 // cover other scenarios like the whole transport is writable (not just this | 616 // cover other scenarios like the whole transport is writable (not just this |
| 637 // TransportChannel) or when TransportChannel is attached after DTLS is | 617 // TransportChannel) or when TransportChannel is attached after DTLS is |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 661 last_sent_packet_id); | 641 last_sent_packet_id); |
| 662 | 642 |
| 663 UpdateTransportOverhead(); | 643 UpdateTransportOverhead(); |
| 664 } | 644 } |
| 665 invoker_.AsyncInvoke<void>( | 645 invoker_.AsyncInvoke<void>( |
| 666 RTC_FROM_HERE, worker_thread_, | 646 RTC_FROM_HERE, worker_thread_, |
| 667 Bind(&MediaChannel::OnNetworkRouteChanged, media_channel_, transport_name, | 647 Bind(&MediaChannel::OnNetworkRouteChanged, media_channel_, transport_name, |
| 668 network_route)); | 648 network_route)); |
| 669 } | 649 } |
| 670 | 650 |
| 671 void BaseChannel::SetTransportChannelReadyToSend(bool rtcp, bool ready) { | 651 void BaseChannel::OnTransportReadyToSend(bool ready) { |
| 672 RTC_DCHECK(network_thread_->IsCurrent()); | |
| 673 if (rtcp) { | |
| 674 rtcp_ready_to_send_ = ready; | |
| 675 } else { | |
| 676 rtp_ready_to_send_ = ready; | |
| 677 } | |
| 678 | |
| 679 bool ready_to_send = | |
| 680 (rtp_ready_to_send_ && | |
| 681 // In the case of rtcp mux |rtcp_packet_transport_| will be null. | |
| 682 (rtcp_ready_to_send_ || !rtp_transport_.rtcp_packet_transport())); | |
| 683 | |
| 684 invoker_.AsyncInvoke<void>( | 652 invoker_.AsyncInvoke<void>( |
| 685 RTC_FROM_HERE, worker_thread_, | 653 RTC_FROM_HERE, worker_thread_, |
| 686 Bind(&MediaChannel::OnReadyToSend, media_channel_, ready_to_send)); | 654 Bind(&MediaChannel::OnReadyToSend, media_channel_, ready)); |
| 687 } | 655 } |
| 688 | 656 |
| 689 bool BaseChannel::PacketIsRtcp(const rtc::PacketTransportInternal* transport, | 657 bool BaseChannel::PacketIsRtcp(const rtc::PacketTransportInternal* transport, |
| 690 const char* data, | 658 const char* data, |
| 691 size_t len) { | 659 size_t len) { |
| 692 return (transport == rtp_transport_.rtcp_packet_transport() || | 660 return (transport == rtp_transport_.rtcp_packet_transport() || |
| 693 rtcp_mux_filter_.DemuxRtcp(data, static_cast<int>(len))); | 661 rtcp_mux_filter_.DemuxRtcp(data, static_cast<int>(len))); |
| 694 } | 662 } |
| 695 | 663 |
| 696 bool BaseChannel::SendPacket(bool rtcp, | 664 bool BaseChannel::SendPacket(bool rtcp, |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 711 data->options = options; | 679 data->options = options; |
| 712 network_thread_->Post(RTC_FROM_HERE, this, message_id, data); | 680 network_thread_->Post(RTC_FROM_HERE, this, message_id, data); |
| 713 return true; | 681 return true; |
| 714 } | 682 } |
| 715 TRACE_EVENT0("webrtc", "BaseChannel::SendPacket"); | 683 TRACE_EVENT0("webrtc", "BaseChannel::SendPacket"); |
| 716 | 684 |
| 717 // Now that we are on the correct thread, ensure we have a place to send this | 685 // Now that we are on the correct thread, ensure we have a place to send this |
| 718 // packet before doing anything. (We might get RTCP packets that we don't | 686 // packet before doing anything. (We might get RTCP packets that we don't |
| 719 // intend to send.) If we've negotiated RTCP mux, send RTCP over the RTP | 687 // intend to send.) If we've negotiated RTCP mux, send RTCP over the RTP |
| 720 // transport. | 688 // transport. |
| 721 rtc::PacketTransportInternal* transport = | 689 const bool send_on_rtcp = rtcp && !rtcp_mux_filter_.IsActive(); |
|
Taylor Brandstetter
2017/04/19 05:56:33
This could be moved into RtpTransport, if rtcp_mux
Zach Stein
2017/04/20 19:59:10
Done.
| |
| 722 (!rtcp || rtcp_mux_filter_.IsActive()) | 690 if (!rtp_transport_.IsWritable(send_on_rtcp)) { |
| 723 ? rtp_transport_.rtp_packet_transport() | |
| 724 : rtp_transport_.rtcp_packet_transport(); | |
| 725 if (!transport || !transport->writable()) { | |
| 726 return false; | 691 return false; |
| 727 } | 692 } |
| 728 | 693 |
| 729 // Protect ourselves against crazy data. | 694 // Protect ourselves against crazy data. |
| 730 if (!ValidPacket(rtcp, packet)) { | 695 if (!ValidPacket(rtcp, packet)) { |
| 731 LOG(LS_ERROR) << "Dropping outgoing " << content_name_ << " " | 696 LOG(LS_ERROR) << "Dropping outgoing " << content_name_ << " " |
| 732 << PacketType(rtcp) | 697 << PacketType(rtcp) |
| 733 << " packet: wrong size=" << packet->size(); | 698 << " packet: wrong size=" << packet->size(); |
| 734 return false; | 699 return false; |
| 735 } | 700 } |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 811 // However, there shouldn't be any RTP packets sent before SRTP is set up | 776 // However, there shouldn't be any RTP packets sent before SRTP is set up |
| 812 // (and SetSend(true) is called). | 777 // (and SetSend(true) is called). |
| 813 LOG(LS_ERROR) << "Can't send outgoing RTP packet when SRTP is inactive" | 778 LOG(LS_ERROR) << "Can't send outgoing RTP packet when SRTP is inactive" |
| 814 << " and crypto is required"; | 779 << " and crypto is required"; |
| 815 RTC_NOTREACHED(); | 780 RTC_NOTREACHED(); |
| 816 return false; | 781 return false; |
| 817 } | 782 } |
| 818 | 783 |
| 819 // Bon voyage. | 784 // Bon voyage. |
| 820 int flags = (secure() && secure_dtls()) ? PF_SRTP_BYPASS : PF_NORMAL; | 785 int flags = (secure() && secure_dtls()) ? PF_SRTP_BYPASS : PF_NORMAL; |
| 821 int ret = transport->SendPacket(packet->data<char>(), packet->size(), | 786 return rtp_transport_.SendPacket(send_on_rtcp, packet, updated_options, |
| 822 updated_options, flags); | 787 flags); |
| 823 if (ret != static_cast<int>(packet->size())) { | |
| 824 if (transport->GetError() == ENOTCONN) { | |
| 825 LOG(LS_WARNING) << "Got ENOTCONN from transport."; | |
| 826 SetTransportChannelReadyToSend(rtcp, false); | |
| 827 } | |
| 828 return false; | |
| 829 } | |
| 830 return true; | |
| 831 } | 788 } |
| 832 | 789 |
| 833 bool BaseChannel::WantsPacket(bool rtcp, const rtc::CopyOnWriteBuffer* packet) { | 790 bool BaseChannel::WantsPacket(bool rtcp, const rtc::CopyOnWriteBuffer* packet) { |
| 834 // Protect ourselves against crazy data. | 791 // Protect ourselves against crazy data. |
| 835 if (!ValidPacket(rtcp, packet)) { | 792 if (!ValidPacket(rtcp, packet)) { |
| 836 LOG(LS_ERROR) << "Dropping incoming " << content_name_ << " " | 793 LOG(LS_ERROR) << "Dropping incoming " << content_name_ << " " |
| 837 << PacketType(rtcp) | 794 << PacketType(rtcp) |
| 838 << " packet: wrong size=" << packet->size(); | 795 << " packet: wrong size=" << packet->size(); |
| 839 return false; | 796 return false; |
| 840 } | 797 } |
| (...skipping 411 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1252 } | 1209 } |
| 1253 return true; | 1210 return true; |
| 1254 } | 1211 } |
| 1255 | 1212 |
| 1256 bool BaseChannel::SetRtcpMux_n(bool enable, | 1213 bool BaseChannel::SetRtcpMux_n(bool enable, |
| 1257 ContentAction action, | 1214 ContentAction action, |
| 1258 ContentSource src, | 1215 ContentSource src, |
| 1259 std::string* error_desc) { | 1216 std::string* error_desc) { |
| 1260 // Provide a more specific error message for the RTCP mux "require" policy | 1217 // Provide a more specific error message for the RTCP mux "require" policy |
| 1261 // case. | 1218 // case. |
| 1262 if (rtp_transport_.rtcp_mux_required() && !enable) { | 1219 if (rtcp_mux_required_ && !enable) { |
| 1263 SafeSetError( | 1220 SafeSetError( |
| 1264 "rtcpMuxPolicy is 'require', but media description does not " | 1221 "rtcpMuxPolicy is 'require', but media description does not " |
| 1265 "contain 'a=rtcp-mux'.", | 1222 "contain 'a=rtcp-mux'.", |
| 1266 error_desc); | 1223 error_desc); |
| 1267 return false; | 1224 return false; |
| 1268 } | 1225 } |
| 1269 bool ret = false; | 1226 bool ret = false; |
| 1270 switch (action) { | 1227 switch (action) { |
| 1271 case CA_OFFER: | 1228 case CA_OFFER: |
| 1272 ret = rtcp_mux_filter_.SetOffer(enable, src); | 1229 ret = rtcp_mux_filter_.SetOffer(enable, src); |
| 1230 // TODO(zstein): rtp_transport_.set_rtcp_mux_enabled here? | |
|
Taylor Brandstetter
2017/04/19 05:56:33
I think you could do "rtp_transport_.set_rtcp_mux_
Zach Stein
2017/04/20 19:59:10
I think that is just what I want - thanks!
| |
| 1273 break; | 1231 break; |
| 1274 case CA_PRANSWER: | 1232 case CA_PRANSWER: |
| 1275 // This may activate RTCP muxing, but we don't yet destroy the transport | 1233 // This may activate RTCP muxing, but we don't yet destroy the transport |
| 1276 // because the final answer may deactivate it. | 1234 // because the final answer may deactivate it. |
| 1277 ret = rtcp_mux_filter_.SetProvisionalAnswer(enable, src); | 1235 ret = rtcp_mux_filter_.SetProvisionalAnswer(enable, src); |
| 1236 // TODO(zstein): rtp_transport_.set_rtcp_mux_enabled here? | |
| 1278 break; | 1237 break; |
| 1279 case CA_ANSWER: | 1238 case CA_ANSWER: |
| 1280 ret = rtcp_mux_filter_.SetAnswer(enable, src); | 1239 ret = rtcp_mux_filter_.SetAnswer(enable, src); |
| 1281 if (ret && rtcp_mux_filter_.IsActive()) { | 1240 if (ret && rtcp_mux_filter_.IsActive()) { |
| 1282 // We permanently activated RTCP muxing; signal that we no longer need | 1241 // We permanently activated RTCP muxing; signal that we no longer need |
| 1283 // the RTCP transport. | 1242 // the RTCP transport. |
| 1284 std::string debug_name = | 1243 std::string debug_name = |
| 1285 transport_name_.empty() | 1244 transport_name_.empty() |
| 1286 ? rtp_transport_.rtp_packet_transport()->debug_name() | 1245 ? rtp_transport_.rtp_packet_transport()->debug_name() |
| 1287 : transport_name_; | 1246 : transport_name_; |
| 1288 ; | 1247 ; |
| 1289 LOG(LS_INFO) << "Enabling rtcp-mux for " << content_name() | 1248 LOG(LS_INFO) << "Enabling rtcp-mux for " << content_name() |
| 1290 << "; no longer need RTCP transport for " << debug_name; | 1249 << "; no longer need RTCP transport for " << debug_name; |
| 1291 if (rtp_transport_.rtcp_packet_transport()) { | 1250 if (rtp_transport_.rtcp_packet_transport()) { |
| 1292 SetTransport_n(true, nullptr, nullptr); | 1251 SetTransport_n(true, nullptr, nullptr); |
| 1293 SignalRtcpMuxFullyActive(transport_name_); | 1252 SignalRtcpMuxFullyActive(transport_name_); |
| 1294 } | 1253 } |
| 1295 UpdateWritableState_n(); | 1254 UpdateWritableState_n(); |
| 1296 SetTransportChannelReadyToSend(true, false); | 1255 // TODO(zstein): Maybe rtcp_mux_filter should signal these changes. |
|
Taylor Brandstetter
2017/04/19 05:56:33
Since its state will always change synchronously,
Zach Stein
2017/04/20 19:59:10
Acknowledged.
| |
| 1256 rtp_transport_.set_rtcp_mux_enabled(true); | |
| 1297 } | 1257 } |
| 1298 break; | 1258 break; |
| 1299 case CA_UPDATE: | 1259 case CA_UPDATE: |
| 1300 // No RTCP mux info. | 1260 // No RTCP mux info. |
| 1301 ret = true; | 1261 ret = true; |
| 1302 break; | 1262 break; |
| 1303 default: | 1263 default: |
| 1304 break; | 1264 break; |
| 1305 } | 1265 } |
| 1306 if (!ret) { | 1266 if (!ret) { |
| (...skipping 1179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2486 signaling_thread()->Post(RTC_FROM_HERE, this, MSG_READYTOSENDDATA, | 2446 signaling_thread()->Post(RTC_FROM_HERE, this, MSG_READYTOSENDDATA, |
| 2487 new DataChannelReadyToSendMessageData(writable)); | 2447 new DataChannelReadyToSendMessageData(writable)); |
| 2488 } | 2448 } |
| 2489 | 2449 |
| 2490 void RtpDataChannel::GetSrtpCryptoSuites_n( | 2450 void RtpDataChannel::GetSrtpCryptoSuites_n( |
| 2491 std::vector<int>* crypto_suites) const { | 2451 std::vector<int>* crypto_suites) const { |
| 2492 GetSupportedDataCryptoSuites(crypto_options(), crypto_suites); | 2452 GetSupportedDataCryptoSuites(crypto_options(), crypto_suites); |
| 2493 } | 2453 } |
| 2494 | 2454 |
| 2495 } // namespace cricket | 2455 } // namespace cricket |
| OLD | NEW |