OLD | NEW |
---|---|
1 /* | 1 /* |
2 * libjingle | 2 * libjingle |
3 * Copyright 2009 Google Inc. | 3 * Copyright 2009 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 463 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
474 return true; | 474 return true; |
475 } | 475 } |
476 | 476 |
477 /////////////////////////////////////////////////////////////////////////////// | 477 /////////////////////////////////////////////////////////////////////////////// |
478 // SrtpSession | 478 // SrtpSession |
479 | 479 |
480 #ifdef HAVE_SRTP | 480 #ifdef HAVE_SRTP |
481 | 481 |
482 bool SrtpSession::inited_ = false; | 482 bool SrtpSession::inited_ = false; |
483 | 483 |
484 // This lock protects SrtpSession::inited_ and SrtpSession::sessions_. | 484 // This lock protects SrtpSession::inited_. |
485 rtc::GlobalLockPod SrtpSession::lock_; | 485 rtc::GlobalLockPod SrtpSession::lock_; |
486 | 486 |
487 SrtpSession::SrtpSession() | 487 SrtpSession::SrtpSession() |
488 : session_(NULL), | 488 : session_(NULL), |
489 rtp_auth_tag_len_(0), | 489 rtp_auth_tag_len_(0), |
490 rtcp_auth_tag_len_(0), | 490 rtcp_auth_tag_len_(0), |
491 srtp_stat_(new SrtpStat()), | 491 srtp_stat_(new SrtpStat()), |
492 last_send_seq_num_(-1) { | 492 last_send_seq_num_(-1) { |
493 { | 493 thread_checker_.DetachFromThread(); |
juberti
2015/11/10 17:20:35
Remind me - is this called on a different thread t
joachim
2015/11/10 17:30:25
You're right, looks like this is always called fro
| |
494 rtc::GlobalLockScope ls(&lock_); | |
495 sessions()->push_back(this); | |
496 } | |
497 SignalSrtpError.repeat(srtp_stat_->SignalSrtpError); | 494 SignalSrtpError.repeat(srtp_stat_->SignalSrtpError); |
498 } | 495 } |
499 | 496 |
500 SrtpSession::~SrtpSession() { | 497 SrtpSession::~SrtpSession() { |
501 { | 498 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
502 rtc::GlobalLockScope ls(&lock_); | |
503 sessions()->erase(std::find(sessions()->begin(), sessions()->end(), this)); | |
504 } | |
505 if (session_) { | 499 if (session_) { |
500 session_->user_data = nullptr; | |
506 srtp_dealloc(session_); | 501 srtp_dealloc(session_); |
507 } | 502 } |
508 } | 503 } |
509 | 504 |
510 bool SrtpSession::SetSend(const std::string& cs, const uint8_t* key, int len) { | 505 bool SrtpSession::SetSend(const std::string& cs, const uint8_t* key, int len) { |
511 return SetKey(ssrc_any_outbound, cs, key, len); | 506 return SetKey(ssrc_any_outbound, cs, key, len); |
512 } | 507 } |
513 | 508 |
514 bool SrtpSession::SetRecv(const std::string& cs, const uint8_t* key, int len) { | 509 bool SrtpSession::SetRecv(const std::string& cs, const uint8_t* key, int len) { |
515 return SetKey(ssrc_any_inbound, cs, key, len); | 510 return SetKey(ssrc_any_inbound, cs, key, len); |
516 } | 511 } |
517 | 512 |
518 bool SrtpSession::ProtectRtp(void* p, int in_len, int max_len, int* out_len) { | 513 bool SrtpSession::ProtectRtp(void* p, int in_len, int max_len, int* out_len) { |
514 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | |
519 if (!session_) { | 515 if (!session_) { |
520 LOG(LS_WARNING) << "Failed to protect SRTP packet: no SRTP Session"; | 516 LOG(LS_WARNING) << "Failed to protect SRTP packet: no SRTP Session"; |
521 return false; | 517 return false; |
522 } | 518 } |
523 | 519 |
524 int need_len = in_len + rtp_auth_tag_len_; // NOLINT | 520 int need_len = in_len + rtp_auth_tag_len_; // NOLINT |
525 if (max_len < need_len) { | 521 if (max_len < need_len) { |
526 LOG(LS_WARNING) << "Failed to protect SRTP packet: The buffer length " | 522 LOG(LS_WARNING) << "Failed to protect SRTP packet: The buffer length " |
527 << max_len << " is less than the needed " << need_len; | 523 << max_len << " is less than the needed " << need_len; |
528 return false; | 524 return false; |
(...skipping 22 matching lines...) Expand all Loading... | |
551 int max_len, | 547 int max_len, |
552 int* out_len, | 548 int* out_len, |
553 int64_t* index) { | 549 int64_t* index) { |
554 if (!ProtectRtp(p, in_len, max_len, out_len)) { | 550 if (!ProtectRtp(p, in_len, max_len, out_len)) { |
555 return false; | 551 return false; |
556 } | 552 } |
557 return (index) ? GetSendStreamPacketIndex(p, in_len, index) : true; | 553 return (index) ? GetSendStreamPacketIndex(p, in_len, index) : true; |
558 } | 554 } |
559 | 555 |
560 bool SrtpSession::ProtectRtcp(void* p, int in_len, int max_len, int* out_len) { | 556 bool SrtpSession::ProtectRtcp(void* p, int in_len, int max_len, int* out_len) { |
557 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | |
561 if (!session_) { | 558 if (!session_) { |
562 LOG(LS_WARNING) << "Failed to protect SRTCP packet: no SRTP Session"; | 559 LOG(LS_WARNING) << "Failed to protect SRTCP packet: no SRTP Session"; |
563 return false; | 560 return false; |
564 } | 561 } |
565 | 562 |
566 int need_len = in_len + sizeof(uint32_t) + rtcp_auth_tag_len_; // NOLINT | 563 int need_len = in_len + sizeof(uint32_t) + rtcp_auth_tag_len_; // NOLINT |
567 if (max_len < need_len) { | 564 if (max_len < need_len) { |
568 LOG(LS_WARNING) << "Failed to protect SRTCP packet: The buffer length " | 565 LOG(LS_WARNING) << "Failed to protect SRTCP packet: The buffer length " |
569 << max_len << " is less than the needed " << need_len; | 566 << max_len << " is less than the needed " << need_len; |
570 return false; | 567 return false; |
571 } | 568 } |
572 | 569 |
573 *out_len = in_len; | 570 *out_len = in_len; |
574 int err = srtp_protect_rtcp(session_, p, out_len); | 571 int err = srtp_protect_rtcp(session_, p, out_len); |
575 srtp_stat_->AddProtectRtcpResult(err); | 572 srtp_stat_->AddProtectRtcpResult(err); |
576 if (err != err_status_ok) { | 573 if (err != err_status_ok) { |
577 LOG(LS_WARNING) << "Failed to protect SRTCP packet, err=" << err; | 574 LOG(LS_WARNING) << "Failed to protect SRTCP packet, err=" << err; |
578 return false; | 575 return false; |
579 } | 576 } |
580 return true; | 577 return true; |
581 } | 578 } |
582 | 579 |
583 bool SrtpSession::UnprotectRtp(void* p, int in_len, int* out_len) { | 580 bool SrtpSession::UnprotectRtp(void* p, int in_len, int* out_len) { |
581 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | |
584 if (!session_) { | 582 if (!session_) { |
585 LOG(LS_WARNING) << "Failed to unprotect SRTP packet: no SRTP Session"; | 583 LOG(LS_WARNING) << "Failed to unprotect SRTP packet: no SRTP Session"; |
586 return false; | 584 return false; |
587 } | 585 } |
588 | 586 |
589 *out_len = in_len; | 587 *out_len = in_len; |
590 int err = srtp_unprotect(session_, p, out_len); | 588 int err = srtp_unprotect(session_, p, out_len); |
591 uint32_t ssrc; | 589 uint32_t ssrc; |
592 if (GetRtpSsrc(p, in_len, &ssrc)) { | 590 if (GetRtpSsrc(p, in_len, &ssrc)) { |
593 srtp_stat_->AddUnprotectRtpResult(ssrc, err); | 591 srtp_stat_->AddUnprotectRtpResult(ssrc, err); |
594 } | 592 } |
595 if (err != err_status_ok) { | 593 if (err != err_status_ok) { |
596 LOG(LS_WARNING) << "Failed to unprotect SRTP packet, err=" << err; | 594 LOG(LS_WARNING) << "Failed to unprotect SRTP packet, err=" << err; |
597 return false; | 595 return false; |
598 } | 596 } |
599 return true; | 597 return true; |
600 } | 598 } |
601 | 599 |
602 bool SrtpSession::UnprotectRtcp(void* p, int in_len, int* out_len) { | 600 bool SrtpSession::UnprotectRtcp(void* p, int in_len, int* out_len) { |
601 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | |
603 if (!session_) { | 602 if (!session_) { |
604 LOG(LS_WARNING) << "Failed to unprotect SRTCP packet: no SRTP Session"; | 603 LOG(LS_WARNING) << "Failed to unprotect SRTCP packet: no SRTP Session"; |
605 return false; | 604 return false; |
606 } | 605 } |
607 | 606 |
608 *out_len = in_len; | 607 *out_len = in_len; |
609 int err = srtp_unprotect_rtcp(session_, p, out_len); | 608 int err = srtp_unprotect_rtcp(session_, p, out_len); |
610 srtp_stat_->AddUnprotectRtcpResult(err); | 609 srtp_stat_->AddUnprotectRtcpResult(err); |
611 if (err != err_status_ok) { | 610 if (err != err_status_ok) { |
612 LOG(LS_WARNING) << "Failed to unprotect SRTCP packet, err=" << err; | 611 LOG(LS_WARNING) << "Failed to unprotect SRTCP packet, err=" << err; |
613 return false; | 612 return false; |
614 } | 613 } |
615 return true; | 614 return true; |
616 } | 615 } |
617 | 616 |
618 bool SrtpSession::GetRtpAuthParams(uint8_t** key, int* key_len, int* tag_len) { | 617 bool SrtpSession::GetRtpAuthParams(uint8_t** key, int* key_len, int* tag_len) { |
619 #if defined(ENABLE_EXTERNAL_AUTH) | 618 #if defined(ENABLE_EXTERNAL_AUTH) |
619 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | |
620 ExternalHmacContext* external_hmac = NULL; | 620 ExternalHmacContext* external_hmac = NULL; |
621 // stream_template will be the reference context for other streams. | 621 // stream_template will be the reference context for other streams. |
622 // Let's use it for getting the keys. | 622 // Let's use it for getting the keys. |
623 srtp_stream_ctx_t* srtp_context = session_->stream_template; | 623 srtp_stream_ctx_t* srtp_context = session_->stream_template; |
624 if (srtp_context && srtp_context->rtp_auth) { | 624 if (srtp_context && srtp_context->rtp_auth) { |
625 external_hmac = reinterpret_cast<ExternalHmacContext*>( | 625 external_hmac = reinterpret_cast<ExternalHmacContext*>( |
626 srtp_context->rtp_auth->state); | 626 srtp_context->rtp_auth->state); |
627 } | 627 } |
628 | 628 |
629 if (!external_hmac) { | 629 if (!external_hmac) { |
630 LOG(LS_ERROR) << "Failed to get auth keys from libsrtp!."; | 630 LOG(LS_ERROR) << "Failed to get auth keys from libsrtp!."; |
631 return false; | 631 return false; |
632 } | 632 } |
633 | 633 |
634 *key = external_hmac->key; | 634 *key = external_hmac->key; |
635 *key_len = external_hmac->key_length; | 635 *key_len = external_hmac->key_length; |
636 *tag_len = rtp_auth_tag_len_; | 636 *tag_len = rtp_auth_tag_len_; |
637 return true; | 637 return true; |
638 #else | 638 #else |
639 return false; | 639 return false; |
640 #endif | 640 #endif |
641 } | 641 } |
642 | 642 |
643 bool SrtpSession::GetSendStreamPacketIndex(void* p, | 643 bool SrtpSession::GetSendStreamPacketIndex(void* p, |
644 int in_len, | 644 int in_len, |
645 int64_t* index) { | 645 int64_t* index) { |
646 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | |
646 srtp_hdr_t* hdr = reinterpret_cast<srtp_hdr_t*>(p); | 647 srtp_hdr_t* hdr = reinterpret_cast<srtp_hdr_t*>(p); |
647 srtp_stream_ctx_t* stream = srtp_get_stream(session_, hdr->ssrc); | 648 srtp_stream_ctx_t* stream = srtp_get_stream(session_, hdr->ssrc); |
648 if (stream == NULL) | 649 if (stream == NULL) |
649 return false; | 650 return false; |
650 | 651 |
651 // Shift packet index, put into network byte order | 652 // Shift packet index, put into network byte order |
652 *index = static_cast<int64_t>( | 653 *index = static_cast<int64_t>( |
653 rtc::NetworkToHost64(rdbx_get_packet_index(&stream->rtp_rdbx) << 16)); | 654 rtc::NetworkToHost64(rdbx_get_packet_index(&stream->rtp_rdbx) << 16)); |
654 return true; | 655 return true; |
655 } | 656 } |
656 | 657 |
657 void SrtpSession::set_signal_silent_time(uint32_t signal_silent_time_in_ms) { | 658 void SrtpSession::set_signal_silent_time(uint32_t signal_silent_time_in_ms) { |
658 srtp_stat_->set_signal_silent_time(signal_silent_time_in_ms); | 659 srtp_stat_->set_signal_silent_time(signal_silent_time_in_ms); |
659 } | 660 } |
660 | 661 |
661 bool SrtpSession::SetKey(int type, | 662 bool SrtpSession::SetKey(int type, |
662 const std::string& cs, | 663 const std::string& cs, |
663 const uint8_t* key, | 664 const uint8_t* key, |
664 int len) { | 665 int len) { |
666 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | |
665 if (session_) { | 667 if (session_) { |
666 LOG(LS_ERROR) << "Failed to create SRTP session: " | 668 LOG(LS_ERROR) << "Failed to create SRTP session: " |
667 << "SRTP session already created"; | 669 << "SRTP session already created"; |
668 return false; | 670 return false; |
669 } | 671 } |
670 | 672 |
671 if (!Init()) { | 673 if (!Init()) { |
672 return false; | 674 return false; |
673 } | 675 } |
674 | 676 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
710 #endif | 712 #endif |
711 policy.next = NULL; | 713 policy.next = NULL; |
712 | 714 |
713 int err = srtp_create(&session_, &policy); | 715 int err = srtp_create(&session_, &policy); |
714 if (err != err_status_ok) { | 716 if (err != err_status_ok) { |
715 session_ = NULL; | 717 session_ = NULL; |
716 LOG(LS_ERROR) << "Failed to create SRTP session, err=" << err; | 718 LOG(LS_ERROR) << "Failed to create SRTP session, err=" << err; |
717 return false; | 719 return false; |
718 } | 720 } |
719 | 721 |
720 | 722 session_->user_data = this; |
721 rtp_auth_tag_len_ = policy.rtp.auth_tag_len; | 723 rtp_auth_tag_len_ = policy.rtp.auth_tag_len; |
722 rtcp_auth_tag_len_ = policy.rtcp.auth_tag_len; | 724 rtcp_auth_tag_len_ = policy.rtcp.auth_tag_len; |
723 return true; | 725 return true; |
724 } | 726 } |
725 | 727 |
726 bool SrtpSession::Init() { | 728 bool SrtpSession::Init() { |
727 rtc::GlobalLockScope ls(&lock_); | 729 rtc::GlobalLockScope ls(&lock_); |
728 | 730 |
729 if (!inited_) { | 731 if (!inited_) { |
730 int err; | 732 int err; |
(...skipping 28 matching lines...) Expand all Loading... | |
759 int err = srtp_shutdown(); | 761 int err = srtp_shutdown(); |
760 if (err) { | 762 if (err) { |
761 LOG(LS_ERROR) << "srtp_shutdown failed. err=" << err; | 763 LOG(LS_ERROR) << "srtp_shutdown failed. err=" << err; |
762 return; | 764 return; |
763 } | 765 } |
764 inited_ = false; | 766 inited_ = false; |
765 } | 767 } |
766 } | 768 } |
767 | 769 |
768 void SrtpSession::HandleEvent(const srtp_event_data_t* ev) { | 770 void SrtpSession::HandleEvent(const srtp_event_data_t* ev) { |
771 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | |
769 switch (ev->event) { | 772 switch (ev->event) { |
770 case event_ssrc_collision: | 773 case event_ssrc_collision: |
771 LOG(LS_INFO) << "SRTP event: SSRC collision"; | 774 LOG(LS_INFO) << "SRTP event: SSRC collision"; |
772 break; | 775 break; |
773 case event_key_soft_limit: | 776 case event_key_soft_limit: |
774 LOG(LS_INFO) << "SRTP event: reached soft key usage limit"; | 777 LOG(LS_INFO) << "SRTP event: reached soft key usage limit"; |
775 break; | 778 break; |
776 case event_key_hard_limit: | 779 case event_key_hard_limit: |
777 LOG(LS_INFO) << "SRTP event: reached hard key usage limit"; | 780 LOG(LS_INFO) << "SRTP event: reached hard key usage limit"; |
778 break; | 781 break; |
779 case event_packet_index_limit: | 782 case event_packet_index_limit: |
780 LOG(LS_INFO) << "SRTP event: reached hard packet limit (2^48 packets)"; | 783 LOG(LS_INFO) << "SRTP event: reached hard packet limit (2^48 packets)"; |
781 break; | 784 break; |
782 default: | 785 default: |
783 LOG(LS_INFO) << "SRTP event: unknown " << ev->event; | 786 LOG(LS_INFO) << "SRTP event: unknown " << ev->event; |
784 break; | 787 break; |
785 } | 788 } |
786 } | 789 } |
787 | 790 |
788 void SrtpSession::HandleEventThunk(srtp_event_data_t* ev) { | 791 void SrtpSession::HandleEventThunk(srtp_event_data_t* ev) { |
789 rtc::GlobalLockScope ls(&lock_); | 792 // Callback will be executed from same thread that calls the "srtp_protect" |
790 | 793 // and "srtp_unprotect" functions. |
791 for (std::list<SrtpSession*>::iterator it = sessions()->begin(); | 794 SrtpSession* session = static_cast<SrtpSession*>(ev->session->user_data); |
792 it != sessions()->end(); ++it) { | 795 if (session) { |
793 if ((*it)->session_ == ev->session) { | 796 session->HandleEvent(ev); |
794 (*it)->HandleEvent(ev); | |
795 break; | |
796 } | |
797 } | 797 } |
798 } | 798 } |
799 | 799 |
800 std::list<SrtpSession*>* SrtpSession::sessions() { | |
801 RTC_DEFINE_STATIC_LOCAL(std::list<SrtpSession*>, sessions, ()); | |
802 return &sessions; | |
803 } | |
804 | |
805 #else // !HAVE_SRTP | 800 #else // !HAVE_SRTP |
806 | 801 |
807 // On some systems, SRTP is not (yet) available. | 802 // On some systems, SRTP is not (yet) available. |
808 | 803 |
809 SrtpSession::SrtpSession() { | 804 SrtpSession::SrtpSession() { |
810 LOG(WARNING) << "SRTP implementation is missing."; | 805 LOG(WARNING) << "SRTP implementation is missing."; |
811 } | 806 } |
812 | 807 |
813 SrtpSession::~SrtpSession() { | 808 SrtpSession::~SrtpSession() { |
814 } | 809 } |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
942 SrtpNotAvailable(__FUNCTION__); | 937 SrtpNotAvailable(__FUNCTION__); |
943 } | 938 } |
944 | 939 |
945 void SrtpStat::HandleSrtpResult(const SrtpStat::FailureKey& key) { | 940 void SrtpStat::HandleSrtpResult(const SrtpStat::FailureKey& key) { |
946 SrtpNotAvailable(__FUNCTION__); | 941 SrtpNotAvailable(__FUNCTION__); |
947 } | 942 } |
948 | 943 |
949 #endif // HAVE_SRTP | 944 #endif // HAVE_SRTP |
950 | 945 |
951 } // namespace cricket | 946 } // namespace cricket |
OLD | NEW |