OLD | NEW |
1 /* | 1 /* |
2 * libjingle | 2 * libjingle |
3 * Copyright 2004 Google Inc. | 3 * Copyright 2004 Google Inc. |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions are met: | 6 * modification, are permitted provided that the following conditions are met: |
7 * | 7 * |
8 * 1. Redistributions of source code must retain the above copyright notice, | 8 * 1. Redistributions of source code must retain the above copyright notice, |
9 * this list of conditions and the following disclaimer. | 9 * this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright notice, | 10 * 2. Redistributions in binary form must reproduce the above copyright notice, |
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
242 } | 242 } |
243 | 243 |
244 bool BaseChannel::SetTransport_w(const std::string& transport_name) { | 244 bool BaseChannel::SetTransport_w(const std::string& transport_name) { |
245 ASSERT(worker_thread_ == rtc::Thread::Current()); | 245 ASSERT(worker_thread_ == rtc::Thread::Current()); |
246 | 246 |
247 if (transport_name == transport_name_) { | 247 if (transport_name == transport_name_) { |
248 // Nothing to do if transport name isn't changing | 248 // Nothing to do if transport name isn't changing |
249 return true; | 249 return true; |
250 } | 250 } |
251 | 251 |
252 // When using DTLS-SRTP, we must reset the SrtpFilter every time the transport | |
253 // changes and wait until the DTLS handshake is complete to set the newly | |
254 // negotiated parameters. | |
255 if (ShouldSetupDtlsSrtp()) { | |
256 srtp_filter_.ResetParams(); | |
257 } | |
258 | |
259 set_transport_channel(transport_controller_->CreateTransportChannel_w( | 252 set_transport_channel(transport_controller_->CreateTransportChannel_w( |
260 transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTP)); | 253 transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTP)); |
261 if (!transport_channel()) { | 254 if (!transport_channel()) { |
262 return false; | 255 return false; |
263 } | 256 } |
264 if (rtcp_transport_enabled()) { | 257 if (rtcp_transport_enabled()) { |
265 LOG(LS_INFO) << "Create RTCP TransportChannel for " << content_name() | 258 LOG(LS_INFO) << "Create RTCP TransportChannel for " << content_name() |
266 << " on " << transport_name << " transport "; | 259 << " on " << transport_name << " transport "; |
267 set_rtcp_transport_channel(transport_controller_->CreateTransportChannel_w( | 260 set_rtcp_transport_channel(transport_controller_->CreateTransportChannel_w( |
268 transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTCP)); | 261 transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTCP)); |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
318 | 311 |
319 if (old_tc) { | 312 if (old_tc) { |
320 DisconnectFromTransportChannel(old_tc); | 313 DisconnectFromTransportChannel(old_tc); |
321 transport_controller_->DestroyTransportChannel_w( | 314 transport_controller_->DestroyTransportChannel_w( |
322 transport_name_, cricket::ICE_CANDIDATE_COMPONENT_RTCP); | 315 transport_name_, cricket::ICE_CANDIDATE_COMPONENT_RTCP); |
323 } | 316 } |
324 | 317 |
325 rtcp_transport_channel_ = new_tc; | 318 rtcp_transport_channel_ = new_tc; |
326 | 319 |
327 if (new_tc) { | 320 if (new_tc) { |
328 RTC_CHECK(!(ShouldSetupDtlsSrtp() && srtp_filter_.IsActive())) | |
329 << "Setting RTCP for DTLS/SRTP after SrtpFilter is active " | |
330 << "should never happen."; | |
331 ConnectToTransportChannel(new_tc); | 321 ConnectToTransportChannel(new_tc); |
332 for (const auto& pair : rtcp_socket_options_) { | 322 for (const auto& pair : rtcp_socket_options_) { |
333 new_tc->SetOption(pair.first, pair.second); | 323 new_tc->SetOption(pair.first, pair.second); |
334 } | 324 } |
335 } | 325 } |
336 | 326 |
337 // Update aggregate writable/ready-to-send state between RTP and RTCP upon | 327 // Update aggregate writable/ready-to-send state between RTP and RTCP upon |
338 // setting new channel | 328 // setting new channel |
339 UpdateWritableState_w(); | 329 UpdateWritableState_w(); |
340 SetReadyToSend(true, new_tc && new_tc->writable()); | 330 SetReadyToSend(true, new_tc && new_tc->writable()); |
341 } | 331 } |
342 | 332 |
343 void BaseChannel::ConnectToTransportChannel(TransportChannel* tc) { | 333 void BaseChannel::ConnectToTransportChannel(TransportChannel* tc) { |
344 ASSERT(worker_thread_ == rtc::Thread::Current()); | 334 ASSERT(worker_thread_ == rtc::Thread::Current()); |
345 | 335 |
346 tc->SignalWritableState.connect(this, &BaseChannel::OnWritableState); | 336 tc->SignalWritableState.connect(this, &BaseChannel::OnWritableState); |
347 tc->SignalReadPacket.connect(this, &BaseChannel::OnChannelRead); | 337 tc->SignalReadPacket.connect(this, &BaseChannel::OnChannelRead); |
348 tc->SignalReadyToSend.connect(this, &BaseChannel::OnReadyToSend); | 338 tc->SignalReadyToSend.connect(this, &BaseChannel::OnReadyToSend); |
349 tc->SignalDtlsState.connect(this, &BaseChannel::OnDtlsState); | |
350 } | 339 } |
351 | 340 |
352 void BaseChannel::DisconnectFromTransportChannel(TransportChannel* tc) { | 341 void BaseChannel::DisconnectFromTransportChannel(TransportChannel* tc) { |
353 ASSERT(worker_thread_ == rtc::Thread::Current()); | 342 ASSERT(worker_thread_ == rtc::Thread::Current()); |
354 | 343 |
355 tc->SignalWritableState.disconnect(this); | 344 tc->SignalWritableState.disconnect(this); |
356 tc->SignalReadPacket.disconnect(this); | 345 tc->SignalReadPacket.disconnect(this); |
357 tc->SignalReadyToSend.disconnect(this); | 346 tc->SignalReadyToSend.disconnect(this); |
358 tc->SignalDtlsState.disconnect(this); | |
359 } | 347 } |
360 | 348 |
361 bool BaseChannel::Enable(bool enable) { | 349 bool BaseChannel::Enable(bool enable) { |
362 worker_thread_->Invoke<void>(Bind( | 350 worker_thread_->Invoke<void>(Bind( |
363 enable ? &BaseChannel::EnableMedia_w : &BaseChannel::DisableMedia_w, | 351 enable ? &BaseChannel::EnableMedia_w : &BaseChannel::DisableMedia_w, |
364 this)); | 352 this)); |
365 return true; | 353 return true; |
366 } | 354 } |
367 | 355 |
368 bool BaseChannel::AddRecvStream(const StreamParams& sp) { | 356 bool BaseChannel::AddRecvStream(const StreamParams& sp) { |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
421 } | 409 } |
422 | 410 |
423 bool BaseChannel::IsReadyToReceive() const { | 411 bool BaseChannel::IsReadyToReceive() const { |
424 // Receive data if we are enabled and have local content, | 412 // Receive data if we are enabled and have local content, |
425 return enabled() && IsReceiveContentDirection(local_content_direction_); | 413 return enabled() && IsReceiveContentDirection(local_content_direction_); |
426 } | 414 } |
427 | 415 |
428 bool BaseChannel::IsReadyToSend() const { | 416 bool BaseChannel::IsReadyToSend() const { |
429 // Send outgoing data if we are enabled, have local and remote content, | 417 // Send outgoing data if we are enabled, have local and remote content, |
430 // and we have had some form of connectivity. | 418 // and we have had some form of connectivity. |
431 return enabled() && IsReceiveContentDirection(remote_content_direction_) && | 419 return enabled() && |
| 420 IsReceiveContentDirection(remote_content_direction_) && |
432 IsSendContentDirection(local_content_direction_) && | 421 IsSendContentDirection(local_content_direction_) && |
433 was_ever_writable() && | 422 was_ever_writable(); |
434 (srtp_filter_.IsActive() || !ShouldSetupDtlsSrtp()); | |
435 } | 423 } |
436 | 424 |
437 bool BaseChannel::SendPacket(rtc::Buffer* packet, | 425 bool BaseChannel::SendPacket(rtc::Buffer* packet, |
438 const rtc::PacketOptions& options) { | 426 const rtc::PacketOptions& options) { |
439 return SendPacket(false, packet, options); | 427 return SendPacket(false, packet, options); |
440 } | 428 } |
441 | 429 |
442 bool BaseChannel::SendRtcp(rtc::Buffer* packet, | 430 bool BaseChannel::SendRtcp(rtc::Buffer* packet, |
443 const rtc::PacketOptions& options) { | 431 const rtc::PacketOptions& options) { |
444 return SendPacket(true, packet, options); | 432 return SendPacket(true, packet, options); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
479 bool rtcp = PacketIsRtcp(channel, data, len); | 467 bool rtcp = PacketIsRtcp(channel, data, len); |
480 rtc::Buffer packet(data, len); | 468 rtc::Buffer packet(data, len); |
481 HandlePacket(rtcp, &packet, packet_time); | 469 HandlePacket(rtcp, &packet, packet_time); |
482 } | 470 } |
483 | 471 |
484 void BaseChannel::OnReadyToSend(TransportChannel* channel) { | 472 void BaseChannel::OnReadyToSend(TransportChannel* channel) { |
485 ASSERT(channel == transport_channel_ || channel == rtcp_transport_channel_); | 473 ASSERT(channel == transport_channel_ || channel == rtcp_transport_channel_); |
486 SetReadyToSend(channel == rtcp_transport_channel_, true); | 474 SetReadyToSend(channel == rtcp_transport_channel_, true); |
487 } | 475 } |
488 | 476 |
489 void BaseChannel::OnDtlsState(TransportChannel* channel, | |
490 DtlsTransportState state) { | |
491 if (!ShouldSetupDtlsSrtp()) { | |
492 return; | |
493 } | |
494 | |
495 // Reset the srtp filter if it's not the CONNECTED state. For the CONNECTED | |
496 // state, setting up DTLS-SRTP context is deferred to ChannelWritable_w to | |
497 // cover other scenarios like the whole channel is writable (not just this | |
498 // TransportChannel) or when TransportChannel is attached after DTLS is | |
499 // negotiated. | |
500 if (state != DTLS_TRANSPORT_CONNECTED) { | |
501 srtp_filter_.ResetParams(); | |
502 } | |
503 } | |
504 | |
505 void BaseChannel::SetReadyToSend(bool rtcp, bool ready) { | 477 void BaseChannel::SetReadyToSend(bool rtcp, bool ready) { |
506 if (rtcp) { | 478 if (rtcp) { |
507 rtcp_ready_to_send_ = ready; | 479 rtcp_ready_to_send_ = ready; |
508 } else { | 480 } else { |
509 rtp_ready_to_send_ = ready; | 481 rtp_ready_to_send_ = ready; |
510 } | 482 } |
511 | 483 |
512 if (rtp_ready_to_send_ && | 484 if (rtp_ready_to_send_ && |
513 // In the case of rtcp mux |rtcp_transport_channel_| will be null. | 485 // In the case of rtcp mux |rtcp_transport_channel_| will be null. |
514 (rtcp_ready_to_send_ || !rtcp_transport_channel_)) { | 486 (rtcp_ready_to_send_ || !rtcp_transport_channel_)) { |
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
782 if (transport_channel_ && transport_channel_->writable() && | 754 if (transport_channel_ && transport_channel_->writable() && |
783 (!rtcp_transport_channel_ || rtcp_transport_channel_->writable())) { | 755 (!rtcp_transport_channel_ || rtcp_transport_channel_->writable())) { |
784 ChannelWritable_w(); | 756 ChannelWritable_w(); |
785 } else { | 757 } else { |
786 ChannelNotWritable_w(); | 758 ChannelNotWritable_w(); |
787 } | 759 } |
788 } | 760 } |
789 | 761 |
790 void BaseChannel::ChannelWritable_w() { | 762 void BaseChannel::ChannelWritable_w() { |
791 ASSERT(worker_thread_ == rtc::Thread::Current()); | 763 ASSERT(worker_thread_ == rtc::Thread::Current()); |
792 if (writable_) { | 764 if (writable_) |
793 return; | 765 return; |
794 } | |
795 | 766 |
796 LOG(LS_INFO) << "Channel writable (" << content_name_ << ")" | 767 LOG(LS_INFO) << "Channel writable (" << content_name_ << ")" |
797 << (was_ever_writable_ ? "" : " for the first time"); | 768 << (was_ever_writable_ ? "" : " for the first time"); |
798 | 769 |
799 std::vector<ConnectionInfo> infos; | 770 std::vector<ConnectionInfo> infos; |
800 transport_channel_->GetStats(&infos); | 771 transport_channel_->GetStats(&infos); |
801 for (std::vector<ConnectionInfo>::const_iterator it = infos.begin(); | 772 for (std::vector<ConnectionInfo>::const_iterator it = infos.begin(); |
802 it != infos.end(); ++it) { | 773 it != infos.end(); ++it) { |
803 if (it->best_connection) { | 774 if (it->best_connection) { |
804 LOG(LS_INFO) << "Using " << it->local_candidate.ToSensitiveString() | 775 LOG(LS_INFO) << "Using " << it->local_candidate.ToSensitiveString() |
805 << "->" << it->remote_candidate.ToSensitiveString(); | 776 << "->" << it->remote_candidate.ToSensitiveString(); |
806 break; | 777 break; |
807 } | 778 } |
808 } | 779 } |
809 | 780 |
| 781 // If we're doing DTLS-SRTP, now is the time. |
| 782 if (!was_ever_writable_ && ShouldSetupDtlsSrtp()) { |
| 783 if (!SetupDtlsSrtp(false)) { |
| 784 SignalDtlsSetupFailure_w(false); |
| 785 return; |
| 786 } |
| 787 |
| 788 if (rtcp_transport_channel_) { |
| 789 if (!SetupDtlsSrtp(true)) { |
| 790 SignalDtlsSetupFailure_w(true); |
| 791 return; |
| 792 } |
| 793 } |
| 794 } |
| 795 |
810 was_ever_writable_ = true; | 796 was_ever_writable_ = true; |
811 MaybeSetupDtlsSrtp_w(); | |
812 writable_ = true; | 797 writable_ = true; |
813 ChangeState(); | 798 ChangeState(); |
814 } | 799 } |
815 | 800 |
816 void BaseChannel::SignalDtlsSetupFailure_w(bool rtcp) { | 801 void BaseChannel::SignalDtlsSetupFailure_w(bool rtcp) { |
817 ASSERT(worker_thread() == rtc::Thread::Current()); | 802 ASSERT(worker_thread() == rtc::Thread::Current()); |
818 signaling_thread()->Invoke<void>(Bind( | 803 signaling_thread()->Invoke<void>(Bind( |
819 &BaseChannel::SignalDtlsSetupFailure_s, this, rtcp)); | 804 &BaseChannel::SignalDtlsSetupFailure_s, this, rtcp)); |
820 } | 805 } |
821 | 806 |
822 void BaseChannel::SignalDtlsSetupFailure_s(bool rtcp) { | 807 void BaseChannel::SignalDtlsSetupFailure_s(bool rtcp) { |
823 ASSERT(signaling_thread() == rtc::Thread::Current()); | 808 ASSERT(signaling_thread() == rtc::Thread::Current()); |
824 SignalDtlsSetupFailure(this, rtcp); | 809 SignalDtlsSetupFailure(this, rtcp); |
825 } | 810 } |
826 | 811 |
827 bool BaseChannel::SetDtlsSrtpCryptoSuites(TransportChannel* tc, bool rtcp) { | 812 bool BaseChannel::SetDtlsSrtpCryptoSuites(TransportChannel* tc, bool rtcp) { |
828 std::vector<int> crypto_suites; | 813 std::vector<int> crypto_suites; |
829 // We always use the default SRTP crypto suites for RTCP, but we may use | 814 // We always use the default SRTP crypto suites for RTCP, but we may use |
830 // different crypto suites for RTP depending on the media type. | 815 // different crypto suites for RTP depending on the media type. |
831 if (!rtcp) { | 816 if (!rtcp) { |
832 GetSrtpCryptoSuites(&crypto_suites); | 817 GetSrtpCryptoSuites(&crypto_suites); |
833 } else { | 818 } else { |
834 GetDefaultSrtpCryptoSuites(&crypto_suites); | 819 GetDefaultSrtpCryptoSuites(&crypto_suites); |
835 } | 820 } |
836 return tc->SetSrtpCryptoSuites(crypto_suites); | 821 return tc->SetSrtpCryptoSuites(crypto_suites); |
837 } | 822 } |
838 | 823 |
839 bool BaseChannel::ShouldSetupDtlsSrtp() const { | 824 bool BaseChannel::ShouldSetupDtlsSrtp() const { |
840 // Since DTLS is applied to all channels, checking RTP should be enough. | 825 return true; |
841 return transport_channel_ && transport_channel_->IsDtlsActive(); | |
842 } | 826 } |
843 | 827 |
844 // This function returns true if either DTLS-SRTP is not in use | 828 // This function returns true if either DTLS-SRTP is not in use |
845 // *or* DTLS-SRTP is successfully set up. | 829 // *or* DTLS-SRTP is successfully set up. |
846 bool BaseChannel::SetupDtlsSrtp(bool rtcp_channel) { | 830 bool BaseChannel::SetupDtlsSrtp(bool rtcp_channel) { |
847 bool ret = false; | 831 bool ret = false; |
848 | 832 |
849 TransportChannel* channel = | 833 TransportChannel* channel = |
850 rtcp_channel ? rtcp_transport_channel_ : transport_channel_; | 834 rtcp_channel ? rtcp_transport_channel_ : transport_channel_; |
851 | 835 |
852 RTC_DCHECK(channel->IsDtlsActive()); | 836 // No DTLS |
| 837 if (!channel->IsDtlsActive()) |
| 838 return true; |
853 | 839 |
854 int selected_crypto_suite; | 840 int selected_crypto_suite; |
855 | 841 |
856 if (!channel->GetSrtpCryptoSuite(&selected_crypto_suite)) { | 842 if (!channel->GetSrtpCryptoSuite(&selected_crypto_suite)) { |
857 LOG(LS_ERROR) << "No DTLS-SRTP selected crypto suite"; | 843 LOG(LS_ERROR) << "No DTLS-SRTP selected crypto suite"; |
858 return false; | 844 return false; |
859 } | 845 } |
860 | 846 |
861 LOG(LS_INFO) << "Installing keys from DTLS-SRTP on " | 847 LOG(LS_INFO) << "Installing keys from DTLS-SRTP on " |
862 << content_name() << " " | 848 << content_name() << " " |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
922 } | 908 } |
923 | 909 |
924 if (!ret) | 910 if (!ret) |
925 LOG(LS_WARNING) << "DTLS-SRTP key installation failed"; | 911 LOG(LS_WARNING) << "DTLS-SRTP key installation failed"; |
926 else | 912 else |
927 dtls_keyed_ = true; | 913 dtls_keyed_ = true; |
928 | 914 |
929 return ret; | 915 return ret; |
930 } | 916 } |
931 | 917 |
932 void BaseChannel::MaybeSetupDtlsSrtp_w() { | |
933 if (srtp_filter_.IsActive()) { | |
934 return; | |
935 } | |
936 | |
937 if (!ShouldSetupDtlsSrtp()) { | |
938 return; | |
939 } | |
940 | |
941 if (!SetupDtlsSrtp(false)) { | |
942 SignalDtlsSetupFailure_w(false); | |
943 return; | |
944 } | |
945 | |
946 if (rtcp_transport_channel_) { | |
947 if (!SetupDtlsSrtp(true)) { | |
948 SignalDtlsSetupFailure_w(true); | |
949 return; | |
950 } | |
951 } | |
952 } | |
953 | |
954 void BaseChannel::ChannelNotWritable_w() { | 918 void BaseChannel::ChannelNotWritable_w() { |
955 ASSERT(worker_thread_ == rtc::Thread::Current()); | 919 ASSERT(worker_thread_ == rtc::Thread::Current()); |
956 if (!writable_) | 920 if (!writable_) |
957 return; | 921 return; |
958 | 922 |
959 LOG(LS_INFO) << "Channel not writable (" << content_name_ << ")"; | 923 LOG(LS_INFO) << "Channel not writable (" << content_name_ << ")"; |
960 writable_ = false; | 924 writable_ = false; |
961 ChangeState(); | 925 ChangeState(); |
962 } | 926 } |
963 | 927 |
(...skipping 1328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2292 // that the transport channel is ready. | 2256 // that the transport channel is ready. |
2293 signaling_thread()->Post(this, MSG_READYTOSENDDATA, | 2257 signaling_thread()->Post(this, MSG_READYTOSENDDATA, |
2294 new DataChannelReadyToSendMessageData(writable)); | 2258 new DataChannelReadyToSendMessageData(writable)); |
2295 } | 2259 } |
2296 | 2260 |
2297 void DataChannel::GetSrtpCryptoSuites(std::vector<int>* crypto_suites) const { | 2261 void DataChannel::GetSrtpCryptoSuites(std::vector<int>* crypto_suites) const { |
2298 GetSupportedDataCryptoSuites(crypto_suites); | 2262 GetSupportedDataCryptoSuites(crypto_suites); |
2299 } | 2263 } |
2300 | 2264 |
2301 bool DataChannel::ShouldSetupDtlsSrtp() const { | 2265 bool DataChannel::ShouldSetupDtlsSrtp() const { |
2302 return (data_channel_type_ == DCT_RTP) && BaseChannel::ShouldSetupDtlsSrtp(); | 2266 return (data_channel_type_ == DCT_RTP); |
2303 } | 2267 } |
2304 | 2268 |
2305 void DataChannel::OnStreamClosedRemotely(uint32_t sid) { | 2269 void DataChannel::OnStreamClosedRemotely(uint32_t sid) { |
2306 rtc::TypedMessageData<uint32_t>* message = | 2270 rtc::TypedMessageData<uint32_t>* message = |
2307 new rtc::TypedMessageData<uint32_t>(sid); | 2271 new rtc::TypedMessageData<uint32_t>(sid); |
2308 signaling_thread()->Post(this, MSG_STREAMCLOSEDREMOTELY, message); | 2272 signaling_thread()->Post(this, MSG_STREAMCLOSEDREMOTELY, message); |
2309 } | 2273 } |
2310 | 2274 |
2311 } // namespace cricket | 2275 } // namespace cricket |
OLD | NEW |