1 /* 2 * libjingle 3 * Copyright 2013 Google Inc. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 3. The name of the author may not be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 #ifndef TALK_APP_WEBRTC_WEBRTCSESSIONDESCRIPTIONFACTORY_H_ 29 #define TALK_APP_WEBRTC_WEBRTCSESSIONDESCRIPTIONFACTORY_H_ 30 31 #include "talk/app/webrtc/dtlsidentitystore.h" 32 #include "talk/app/webrtc/peerconnectioninterface.h" 33 #include "talk/session/media/mediasession.h" 34 #include "webrtc/p2p/base/transportdescriptionfactory.h" 35 #include "webrtc/base/messagehandler.h" 36 #include "webrtc/base/rtccertificate.h" 37 38 namespace cricket { 39 class ChannelManager; 40 class TransportDescriptionFactory; 41 } // namespace cricket 42 43 namespace webrtc { 44 class CreateSessionDescriptionObserver; 45 class MediaConstraintsInterface; 46 class SessionDescriptionInterface; 47 class WebRtcSession; 48 49 // DTLS identity request callback class. 50 class WebRtcIdentityRequestObserver : public DtlsIdentityRequestObserver, 51 public sigslot::has_slots<> { 52 public: 53 // DtlsIdentityRequestObserver overrides. 54 void OnFailure(int error) override; 55 void OnSuccess(const std::string& der_cert, 56 const std::string& der_private_key) override; 57 void OnSuccess(rtc::scoped_ptr<rtc::SSLIdentity> identity) override; 58 59 sigslot::signal1<int> SignalRequestFailed; 60 sigslot::signal1<const rtc::scoped_refptr<rtc::RTCCertificate>&> 61 SignalCertificateReady; 62 }; 63 64 struct CreateSessionDescriptionRequest { 65 enum Type { 66 kOffer, 67 kAnswer, 68 }; 69 CreateSessionDescriptionRequestCreateSessionDescriptionRequest70 CreateSessionDescriptionRequest( 71 Type type, 72 CreateSessionDescriptionObserver* observer, 73 const cricket::MediaSessionOptions& options) 74 : type(type), 75 observer(observer), 76 options(options) {} 77 78 Type type; 79 rtc::scoped_refptr<CreateSessionDescriptionObserver> observer; 80 cricket::MediaSessionOptions options; 81 }; 82 83 // This class is used to create offer/answer session description with regards to 84 // the async DTLS identity generation for WebRtcSession. 85 // It queues the create offer/answer request until the DTLS identity 86 // request has completed, i.e. when OnIdentityRequestFailed or OnIdentityReady 87 // is called. 88 class WebRtcSessionDescriptionFactory : public rtc::MessageHandler, 89 public sigslot::has_slots<> { 90 public: 91 // Construct with DTLS disabled. 92 WebRtcSessionDescriptionFactory(rtc::Thread* signaling_thread, 93 cricket::ChannelManager* channel_manager, 94 WebRtcSession* session, 95 const std::string& session_id); 96 97 // Construct with DTLS enabled using the specified |dtls_identity_store| to 98 // generate a certificate. 99 WebRtcSessionDescriptionFactory( 100 rtc::Thread* signaling_thread, 101 cricket::ChannelManager* channel_manager, 102 rtc::scoped_ptr<DtlsIdentityStoreInterface> dtls_identity_store, 103 WebRtcSession* session, 104 const std::string& session_id); 105 106 // Construct with DTLS enabled using the specified (already generated) 107 // |certificate|. 108 WebRtcSessionDescriptionFactory( 109 rtc::Thread* signaling_thread, 110 cricket::ChannelManager* channel_manager, 111 const rtc::scoped_refptr<rtc::RTCCertificate>& certificate, 112 WebRtcSession* session, 113 const std::string& session_id); 114 virtual ~WebRtcSessionDescriptionFactory(); 115 116 static void CopyCandidatesFromSessionDescription( 117 const SessionDescriptionInterface* source_desc, 118 SessionDescriptionInterface* dest_desc); 119 120 void CreateOffer( 121 CreateSessionDescriptionObserver* observer, 122 const PeerConnectionInterface::RTCOfferAnswerOptions& options, 123 const cricket::MediaSessionOptions& session_options); 124 void CreateAnswer(CreateSessionDescriptionObserver* observer, 125 const MediaConstraintsInterface* constraints, 126 const cricket::MediaSessionOptions& session_options); 127 128 void SetSdesPolicy(cricket::SecurePolicy secure_policy); 129 cricket::SecurePolicy SdesPolicy() const; 130 131 sigslot::signal1<const rtc::scoped_refptr<rtc::RTCCertificate>&> 132 SignalCertificateReady; 133 134 // For testing. waiting_for_certificate_for_testing()135 bool waiting_for_certificate_for_testing() const { 136 return certificate_request_state_ == CERTIFICATE_WAITING; 137 } 138 139 private: 140 enum CertificateRequestState { 141 CERTIFICATE_NOT_NEEDED, 142 CERTIFICATE_WAITING, 143 CERTIFICATE_SUCCEEDED, 144 CERTIFICATE_FAILED, 145 }; 146 147 WebRtcSessionDescriptionFactory( 148 rtc::Thread* signaling_thread, 149 cricket::ChannelManager* channel_manager, 150 rtc::scoped_ptr<DtlsIdentityStoreInterface> dtls_identity_store, 151 const rtc::scoped_refptr<WebRtcIdentityRequestObserver>& 152 identity_request_observer, 153 WebRtcSession* session, 154 const std::string& session_id, 155 bool dtls_enabled); 156 157 // MessageHandler implementation. 158 virtual void OnMessage(rtc::Message* msg); 159 160 void InternalCreateOffer(CreateSessionDescriptionRequest request); 161 void InternalCreateAnswer(CreateSessionDescriptionRequest request); 162 // Posts failure notifications for all pending session description requests. 163 void FailPendingRequests(const std::string& reason); 164 void PostCreateSessionDescriptionFailed( 165 CreateSessionDescriptionObserver* observer, 166 const std::string& error); 167 void PostCreateSessionDescriptionSucceeded( 168 CreateSessionDescriptionObserver* observer, 169 SessionDescriptionInterface* description); 170 171 void OnIdentityRequestFailed(int error); 172 void SetCertificate( 173 const rtc::scoped_refptr<rtc::RTCCertificate>& certificate); 174 175 std::queue<CreateSessionDescriptionRequest> 176 create_session_description_requests_; 177 rtc::Thread* const signaling_thread_; 178 cricket::TransportDescriptionFactory transport_desc_factory_; 179 cricket::MediaSessionDescriptionFactory session_desc_factory_; 180 uint64_t session_version_; 181 const rtc::scoped_ptr<DtlsIdentityStoreInterface> dtls_identity_store_; 182 const rtc::scoped_refptr<WebRtcIdentityRequestObserver> 183 identity_request_observer_; 184 // TODO(jiayl): remove the dependency on session once bug 2264 is fixed. 185 WebRtcSession* const session_; 186 const std::string session_id_; 187 CertificateRequestState certificate_request_state_; 188 189 RTC_DISALLOW_COPY_AND_ASSIGN(WebRtcSessionDescriptionFactory); 190 }; 191 } // namespace webrtc 192 193 #endif // TALK_APP_WEBRTC_WEBRTCSESSIONDESCRIPTIONFACTORY_H_ 194