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 38namespace cricket { 39class ChannelManager; 40class TransportDescriptionFactory; 41} // namespace cricket 42 43namespace webrtc { 44class CreateSessionDescriptionObserver; 45class MediaConstraintsInterface; 46class SessionDescriptionInterface; 47class WebRtcSession; 48 49// DTLS identity request callback class. 50class 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 64struct CreateSessionDescriptionRequest { 65 enum Type { 66 kOffer, 67 kAnswer, 68 }; 69 70 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. 88class 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. 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