Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * libjingle | 2 * libjingle |
| 3 * Copyright 2013 Google Inc. | 3 * Copyright 2013 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, |
| 11 * this list of conditions and the following disclaimer in the documentation | 11 * this list of conditions and the following disclaimer in the documentation |
| 12 * and/or other materials provided with the distribution. | 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 | 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. | 14 * derived from this software without specific prior written permission. |
| 15 * | 15 * |
| 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED | 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 | 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
| 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO | 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO |
| 19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| 20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | 20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
| 21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; | 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, | 22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |
| 23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR | 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 | 24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF |
| 25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 26 */ | 26 */ |
| 27 | 27 |
| 28 #include "talk/app/webrtc/webrtcsessiondescriptionfactory.h" | 28 #include "talk/app/webrtc/webrtcsessiondescriptionfactory.h" |
| 29 | 29 |
| 30 #include "talk/app/webrtc/dtlsidentitystore.h" | 30 #include "talk/app/webrtc/dtlsidentityservice.h" |
| 31 #include "talk/app/webrtc/jsep.h" | 31 #include "talk/app/webrtc/jsep.h" |
| 32 #include "talk/app/webrtc/jsepsessiondescription.h" | 32 #include "talk/app/webrtc/jsepsessiondescription.h" |
| 33 #include "talk/app/webrtc/mediaconstraintsinterface.h" | 33 #include "talk/app/webrtc/mediaconstraintsinterface.h" |
| 34 #include "talk/app/webrtc/mediastreamsignaling.h" | 34 #include "talk/app/webrtc/mediastreamsignaling.h" |
| 35 #include "talk/app/webrtc/webrtcsession.h" | 35 #include "talk/app/webrtc/webrtcsession.h" |
| 36 | 36 |
| 37 using cricket::MediaSessionOptions; | 37 using cricket::MediaSessionOptions; |
| 38 | 38 |
| 39 namespace webrtc { | 39 namespace webrtc { |
| 40 namespace { | 40 namespace { |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 61 std::sort(sorted_streams.begin(), sorted_streams.end(), CompareStream); | 61 std::sort(sorted_streams.begin(), sorted_streams.end(), CompareStream); |
| 62 MediaSessionOptions::Streams::iterator it = | 62 MediaSessionOptions::Streams::iterator it = |
| 63 std::adjacent_find(sorted_streams.begin(), sorted_streams.end(), | 63 std::adjacent_find(sorted_streams.begin(), sorted_streams.end(), |
| 64 SameId); | 64 SameId); |
| 65 return it == sorted_streams.end(); | 65 return it == sorted_streams.end(); |
| 66 } | 66 } |
| 67 | 67 |
| 68 enum { | 68 enum { |
| 69 MSG_CREATE_SESSIONDESCRIPTION_SUCCESS, | 69 MSG_CREATE_SESSIONDESCRIPTION_SUCCESS, |
| 70 MSG_CREATE_SESSIONDESCRIPTION_FAILED, | 70 MSG_CREATE_SESSIONDESCRIPTION_FAILED, |
| 71 MSG_GENERATE_IDENTITY, | 71 MSG_USE_CONSTRUCTOR_CERTIFICATE |
| 72 }; | 72 }; |
| 73 | 73 |
| 74 struct CreateSessionDescriptionMsg : public rtc::MessageData { | 74 struct CreateSessionDescriptionMsg : public rtc::MessageData { |
| 75 explicit CreateSessionDescriptionMsg( | 75 explicit CreateSessionDescriptionMsg( |
| 76 webrtc::CreateSessionDescriptionObserver* observer) | 76 webrtc::CreateSessionDescriptionObserver* observer) |
| 77 : observer(observer) { | 77 : observer(observer) { |
| 78 } | 78 } |
| 79 | 79 |
| 80 rtc::scoped_refptr<webrtc::CreateSessionDescriptionObserver> observer; | 80 rtc::scoped_refptr<webrtc::CreateSessionDescriptionObserver> observer; |
| 81 std::string error; | 81 std::string error; |
| 82 rtc::scoped_ptr<webrtc::SessionDescriptionInterface> description; | 82 rtc::scoped_ptr<webrtc::SessionDescriptionInterface> description; |
| 83 }; | 83 }; |
| 84 } // namespace | 84 } // namespace |
| 85 | 85 |
| 86 void WebRtcIdentityRequestObserver::OnFailure(int error) { | 86 void WebRtcIdentityRequestObserver::OnFailure(int error) { |
| 87 SignalRequestFailed(error); | 87 SignalRequestFailed(error); |
| 88 } | 88 } |
| 89 | 89 |
| 90 void WebRtcIdentityRequestObserver::OnSuccess( | 90 void WebRtcIdentityRequestObserver::OnSuccess( |
| 91 const std::string& der_cert, const std::string& der_private_key) { | 91 const std::string& der_cert, const std::string& der_private_key) { |
| 92 std::string pem_cert = rtc::SSLIdentity::DerToPem( | 92 std::string pem_cert = rtc::SSLIdentity::DerToPem( |
| 93 rtc::kPemTypeCertificate, | 93 rtc::kPemTypeCertificate, |
| 94 reinterpret_cast<const unsigned char*>(der_cert.data()), | 94 reinterpret_cast<const unsigned char*>(der_cert.data()), |
| 95 der_cert.length()); | 95 der_cert.length()); |
| 96 std::string pem_key = rtc::SSLIdentity::DerToPem( | 96 std::string pem_key = rtc::SSLIdentity::DerToPem( |
| 97 rtc::kPemTypeRsaPrivateKey, | 97 rtc::kPemTypeRsaPrivateKey, |
| 98 reinterpret_cast<const unsigned char*>(der_private_key.data()), | 98 reinterpret_cast<const unsigned char*>(der_private_key.data()), |
| 99 der_private_key.length()); | 99 der_private_key.length()); |
| 100 rtc::SSLIdentity* identity = | 100 rtc::scoped_ptr<rtc::SSLIdentity> identity( |
| 101 rtc::SSLIdentity::FromPEMStrings(pem_key, pem_cert); | 101 rtc::SSLIdentity::FromPEMStrings(pem_key, pem_cert)); |
| 102 SignalIdentityReady(identity); | 102 SignalCertificateReady(DtlsCertificate::Create(identity.Pass())); |
| 103 } | 103 } |
| 104 | 104 |
| 105 void WebRtcIdentityRequestObserver::OnSuccessWithIdentityObj( | 105 void WebRtcIdentityRequestObserver::OnSuccessWithIdentityObj( |
| 106 rtc::scoped_ptr<rtc::SSLIdentity> identity) { | 106 rtc::scoped_ptr<rtc::SSLIdentity> identity) { |
| 107 SignalIdentityReady(identity.release()); | 107 SignalCertificateReady(DtlsCertificate::Create(identity.Pass())); |
| 108 } | 108 } |
| 109 | 109 |
| 110 // static | 110 // static |
| 111 void WebRtcSessionDescriptionFactory::CopyCandidatesFromSessionDescription( | 111 void WebRtcSessionDescriptionFactory::CopyCandidatesFromSessionDescription( |
| 112 const SessionDescriptionInterface* source_desc, | 112 const SessionDescriptionInterface* source_desc, |
| 113 SessionDescriptionInterface* dest_desc) { | 113 SessionDescriptionInterface* dest_desc) { |
| 114 if (!source_desc) | 114 if (!source_desc) |
| 115 return; | 115 return; |
| 116 for (size_t m = 0; m < source_desc->number_of_mediasections() && | 116 for (size_t m = 0; m < source_desc->number_of_mediasections() && |
| 117 m < dest_desc->number_of_mediasections(); ++m) { | 117 m < dest_desc->number_of_mediasections(); ++m) { |
| 118 const IceCandidateCollection* source_candidates = | 118 const IceCandidateCollection* source_candidates = |
| 119 source_desc->candidates(m); | 119 source_desc->candidates(m); |
| 120 const IceCandidateCollection* dest_candidates = dest_desc->candidates(m); | 120 const IceCandidateCollection* dest_candidates = dest_desc->candidates(m); |
| 121 for (size_t n = 0; n < source_candidates->count(); ++n) { | 121 for (size_t n = 0; n < source_candidates->count(); ++n) { |
| 122 const IceCandidateInterface* new_candidate = source_candidates->at(n); | 122 const IceCandidateInterface* new_candidate = source_candidates->at(n); |
| 123 if (!dest_candidates->HasCandidate(new_candidate)) | 123 if (!dest_candidates->HasCandidate(new_candidate)) |
| 124 dest_desc->AddCandidate(source_candidates->at(n)); | 124 dest_desc->AddCandidate(source_candidates->at(n)); |
| 125 } | 125 } |
| 126 } | 126 } |
| 127 } | 127 } |
| 128 | 128 |
| 129 WebRtcSessionDescriptionFactory::WebRtcSessionDescriptionFactory( | 129 WebRtcSessionDescriptionFactory::WebRtcSessionDescriptionFactory( |
| 130 rtc::Thread* signaling_thread, | 130 rtc::Thread* signaling_thread, |
| 131 rtc::Thread* worker_thread, | |
| 131 cricket::ChannelManager* channel_manager, | 132 cricket::ChannelManager* channel_manager, |
| 132 MediaStreamSignaling* mediastream_signaling, | 133 MediaStreamSignaling* mediastream_signaling, |
| 133 DTLSIdentityServiceInterface* dtls_identity_service, | 134 DTLSIdentityServiceInterface* dtls_identity_service, |
| 135 rtc::scoped_refptr<DtlsCertificate> certificate, | |
| 134 WebRtcSession* session, | 136 WebRtcSession* session, |
| 135 const std::string& session_id, | 137 const std::string& session_id, |
| 136 cricket::DataChannelType dct, | 138 cricket::DataChannelType dct, |
| 137 bool dtls_enabled) | 139 bool dtls_enabled) |
| 138 : signaling_thread_(signaling_thread), | 140 : signaling_thread_(signaling_thread), |
| 141 worker_thread_(worker_thread), | |
| 139 mediastream_signaling_(mediastream_signaling), | 142 mediastream_signaling_(mediastream_signaling), |
| 140 session_desc_factory_(channel_manager, &transport_desc_factory_), | 143 session_desc_factory_(channel_manager, &transport_desc_factory_), |
| 141 // RFC 4566 suggested a Network Time Protocol (NTP) format timestamp | 144 // RFC 4566 suggested a Network Time Protocol (NTP) format timestamp |
| 142 // as the session id and session version. To simplify, it should be fine | 145 // as the session id and session version. To simplify, it should be fine |
| 143 // to just use a random number as session id and start version from | 146 // to just use a random number as session id and start version from |
| 144 // |kInitSessionVersion|. | 147 // |kInitSessionVersion|. |
| 145 session_version_(kInitSessionVersion), | 148 session_version_(kInitSessionVersion), |
| 146 identity_service_(dtls_identity_service), | 149 identity_service_(dtls_identity_service), |
| 150 certificate_(certificate), | |
| 147 session_(session), | 151 session_(session), |
| 148 session_id_(session_id), | 152 session_id_(session_id), |
| 149 data_channel_type_(dct), | 153 data_channel_type_(dct), |
| 150 identity_request_state_(IDENTITY_NOT_NEEDED) { | 154 certificate_request_state_(CERTIFICATE_NOT_NEEDED) { |
| 151 transport_desc_factory_.set_protocol(cricket::ICEPROTO_RFC5245); | 155 transport_desc_factory_.set_protocol(cricket::ICEPROTO_RFC5245); |
| 152 session_desc_factory_.set_add_legacy_streams(false); | 156 session_desc_factory_.set_add_legacy_streams(false); |
| 153 // SRTP-SDES is disabled if DTLS is on. | 157 // SRTP-SDES is disabled if DTLS is on. |
| 154 SetSdesPolicy(dtls_enabled ? cricket::SEC_DISABLED : cricket::SEC_REQUIRED); | 158 SetSdesPolicy(dtls_enabled ? cricket::SEC_DISABLED : cricket::SEC_REQUIRED); |
| 155 | 159 |
| 156 if (!dtls_enabled) { | 160 if (!dtls_enabled) { |
| 157 return; | 161 return; |
| 158 } | 162 } |
| 159 | 163 |
| 160 if (identity_service_.get()) { | 164 certificate_request_state_ = CERTIFICATE_WAITING; |
| 165 if (certificate_.get()) { | |
| 166 LOG(LS_VERBOSE) << "DTLS-SRTP enabled; using DTLS certificate."; | |
| 167 // We already have a certificate but we wait to do SetCertificate; if we do | |
| 168 // it in the constructor then the caller has not had a chance to connect to | |
| 169 // SignalCertificateReady. | |
| 170 signaling_thread_->Post(this, MSG_USE_CONSTRUCTOR_CERTIFICATE, NULL); | |
|
Henrik Grunell WebRTC
2015/08/06 14:06:52
As discussed, pass the certificate here.
hbos
2015/08/10 15:10:18
Acknowledged.
| |
| 171 } else { | |
| 172 // No certificate provided, time to generate a new certificate. | |
| 173 | |
| 174 // Create observer and connect callback functions. | |
|
Henrik Grunell WebRTC
2015/08/06 14:06:52
Remove this comment, its clear from the code what
hbos
2015/08/10 15:10:18
Acknowledged.
| |
| 161 identity_request_observer_ = | 175 identity_request_observer_ = |
| 162 new rtc::RefCountedObject<WebRtcIdentityRequestObserver>(); | 176 new rtc::RefCountedObject<WebRtcIdentityRequestObserver>(); |
| 163 | |
| 164 identity_request_observer_->SignalRequestFailed.connect( | 177 identity_request_observer_->SignalRequestFailed.connect( |
| 165 this, &WebRtcSessionDescriptionFactory::OnIdentityRequestFailed); | 178 this, &WebRtcSessionDescriptionFactory::OnIdentityRequestFailed); |
| 166 identity_request_observer_->SignalIdentityReady.connect( | 179 identity_request_observer_->SignalCertificateReady.connect( |
| 167 this, &WebRtcSessionDescriptionFactory::SetIdentity); | 180 this, &WebRtcSessionDescriptionFactory::SetCertificate); |
| 168 | 181 |
| 169 if (identity_service_->RequestIdentity( | 182 // If an |identity_service_| was not provided we default to using |
| 170 DtlsIdentityStore::kIdentityName, | 183 // DtlsIdentityStore and DtlsIdentityService. |
| 171 DtlsIdentityStore::kIdentityName, | 184 if (!identity_service_.get()) { |
| 172 identity_request_observer_)) { | 185 identity_store_.reset( |
| 173 LOG(LS_VERBOSE) << "DTLS-SRTP enabled; sent DTLS identity request."; | 186 new DtlsIdentityStore(signaling_thread_, worker_thread_)); |
| 174 identity_request_state_ = IDENTITY_WAITING; | 187 identity_service_.reset(new DtlsIdentityService(identity_store_.get())); |
| 188 } | |
| 189 | |
| 190 // Request identity. This happens asynchronously, so the caller will have a | |
| 191 // chance to connect to SignalCertificateReady. | |
| 192 if (identity_service_->RequestIdentity(DtlsIdentityStore::kIdentityName, | |
| 193 DtlsIdentityStore::kIdentityName, | |
| 194 identity_request_observer_)) { | |
| 195 LOG(LS_VERBOSE) << "DTLS-SRTP enabled but no certificate supplied, sent " | |
| 196 << "DTLS identity request."; | |
| 175 } else { | 197 } else { |
| 176 LOG(LS_ERROR) << "Failed to send DTLS identity request."; | 198 certificate_request_state_ = CERTIFICATE_FAILED; |
| 177 identity_request_state_ = IDENTITY_FAILED; | 199 LOG(LS_VERBOSE) << "DTLS-SRTP enabled but no certificate supplied, " |
| 200 << "FAILED to send DTLS identity request."; | |
| 178 } | 201 } |
| 179 } else { | |
| 180 identity_request_state_ = IDENTITY_WAITING; | |
| 181 // Do not generate the identity in the constructor since the caller has | |
| 182 // not got a chance to connect to SignalIdentityReady. | |
| 183 signaling_thread_->Post(this, MSG_GENERATE_IDENTITY, NULL); | |
| 184 } | 202 } |
| 185 } | 203 } |
| 186 | 204 |
| 187 WebRtcSessionDescriptionFactory::~WebRtcSessionDescriptionFactory() { | 205 WebRtcSessionDescriptionFactory::~WebRtcSessionDescriptionFactory() { |
| 188 ASSERT(signaling_thread_->IsCurrent()); | 206 ASSERT(signaling_thread_->IsCurrent()); |
| 189 | 207 |
| 190 // Fail any requests that were asked for before identity generation completed. | 208 // Fail any requests that were asked for before identity generation completed. |
| 191 FailPendingRequests(kFailedDueToSessionShutdown); | 209 FailPendingRequests(kFailedDueToSessionShutdown); |
| 192 | 210 |
| 193 // Process all pending notifications in the message queue. If we don't do | 211 // Process all pending notifications in the message queue. If we don't do |
| 194 // this, requests will linger and not know they succeeded or failed. | 212 // this, requests will linger and not know they succeeded or failed. |
| 195 rtc::MessageList list; | 213 rtc::MessageList list; |
| 196 signaling_thread_->Clear(this, rtc::MQID_ANY, &list); | 214 signaling_thread_->Clear(this, rtc::MQID_ANY, &list); |
| 197 for (auto& msg : list) | 215 for (auto& msg : list) |
| 198 OnMessage(&msg); | 216 OnMessage(&msg); |
| 199 | 217 |
| 200 transport_desc_factory_.set_identity(NULL); | 218 transport_desc_factory_.set_identity(NULL); |
| 201 } | 219 } |
| 202 | 220 |
| 203 void WebRtcSessionDescriptionFactory::CreateOffer( | 221 void WebRtcSessionDescriptionFactory::CreateOffer( |
| 204 CreateSessionDescriptionObserver* observer, | 222 CreateSessionDescriptionObserver* observer, |
| 205 const PeerConnectionInterface::RTCOfferAnswerOptions& options) { | 223 const PeerConnectionInterface::RTCOfferAnswerOptions& options) { |
| 206 cricket::MediaSessionOptions session_options; | 224 cricket::MediaSessionOptions session_options; |
| 207 | 225 |
| 208 std::string error = "CreateOffer"; | 226 std::string error = "CreateOffer"; |
| 209 if (identity_request_state_ == IDENTITY_FAILED) { | 227 if (certificate_request_state_ == CERTIFICATE_FAILED) { |
| 210 error += kFailedDueToIdentityFailed; | 228 error += kFailedDueToIdentityFailed; |
| 211 LOG(LS_ERROR) << error; | 229 LOG(LS_ERROR) << error; |
| 212 PostCreateSessionDescriptionFailed(observer, error); | 230 PostCreateSessionDescriptionFailed(observer, error); |
| 213 return; | 231 return; |
| 214 } | 232 } |
| 215 | 233 |
| 216 if (!mediastream_signaling_->GetOptionsForOffer(options, | 234 if (!mediastream_signaling_->GetOptionsForOffer(options, |
| 217 &session_options)) { | 235 &session_options)) { |
| 218 error += " called with invalid options."; | 236 error += " called with invalid options."; |
| 219 LOG(LS_ERROR) << error; | 237 LOG(LS_ERROR) << error; |
| 220 PostCreateSessionDescriptionFailed(observer, error); | 238 PostCreateSessionDescriptionFailed(observer, error); |
| 221 return; | 239 return; |
| 222 } | 240 } |
| 223 | 241 |
| 224 if (!ValidStreams(session_options.streams)) { | 242 if (!ValidStreams(session_options.streams)) { |
| 225 error += " called with invalid media streams."; | 243 error += " called with invalid media streams."; |
| 226 LOG(LS_ERROR) << error; | 244 LOG(LS_ERROR) << error; |
| 227 PostCreateSessionDescriptionFailed(observer, error); | 245 PostCreateSessionDescriptionFailed(observer, error); |
| 228 return; | 246 return; |
| 229 } | 247 } |
| 230 | 248 |
| 231 if (data_channel_type_ == cricket::DCT_SCTP && | 249 if (data_channel_type_ == cricket::DCT_SCTP && |
| 232 mediastream_signaling_->HasDataChannels()) { | 250 mediastream_signaling_->HasDataChannels()) { |
| 233 session_options.data_channel_type = cricket::DCT_SCTP; | 251 session_options.data_channel_type = cricket::DCT_SCTP; |
| 234 } | 252 } |
| 235 | 253 |
| 236 CreateSessionDescriptionRequest request( | 254 CreateSessionDescriptionRequest request( |
| 237 CreateSessionDescriptionRequest::kOffer, observer, session_options); | 255 CreateSessionDescriptionRequest::kOffer, observer, session_options); |
| 238 if (identity_request_state_ == IDENTITY_WAITING) { | 256 if (certificate_request_state_ == CERTIFICATE_WAITING) { |
| 239 create_session_description_requests_.push(request); | 257 create_session_description_requests_.push(request); |
| 240 } else { | 258 } else { |
| 241 ASSERT(identity_request_state_ == IDENTITY_SUCCEEDED || | 259 ASSERT(certificate_request_state_ == CERTIFICATE_SUCCEEDED || |
| 242 identity_request_state_ == IDENTITY_NOT_NEEDED); | 260 certificate_request_state_ == CERTIFICATE_NOT_NEEDED); |
| 243 InternalCreateOffer(request); | 261 InternalCreateOffer(request); |
| 244 } | 262 } |
| 245 } | 263 } |
| 246 | 264 |
| 247 void WebRtcSessionDescriptionFactory::CreateAnswer( | 265 void WebRtcSessionDescriptionFactory::CreateAnswer( |
| 248 CreateSessionDescriptionObserver* observer, | 266 CreateSessionDescriptionObserver* observer, |
| 249 const MediaConstraintsInterface* constraints) { | 267 const MediaConstraintsInterface* constraints) { |
| 250 std::string error = "CreateAnswer"; | 268 std::string error = "CreateAnswer"; |
| 251 if (identity_request_state_ == IDENTITY_FAILED) { | 269 if (certificate_request_state_ == CERTIFICATE_FAILED) { |
| 252 error += kFailedDueToIdentityFailed; | 270 error += kFailedDueToIdentityFailed; |
| 253 LOG(LS_ERROR) << error; | 271 LOG(LS_ERROR) << error; |
| 254 PostCreateSessionDescriptionFailed(observer, error); | 272 PostCreateSessionDescriptionFailed(observer, error); |
| 255 return; | 273 return; |
| 256 } | 274 } |
| 257 if (!session_->remote_description()) { | 275 if (!session_->remote_description()) { |
| 258 error += " can't be called before SetRemoteDescription."; | 276 error += " can't be called before SetRemoteDescription."; |
| 259 LOG(LS_ERROR) << error; | 277 LOG(LS_ERROR) << error; |
| 260 PostCreateSessionDescriptionFailed(observer, error); | 278 PostCreateSessionDescriptionFailed(observer, error); |
| 261 return; | 279 return; |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 283 } | 301 } |
| 284 // RTP data channel is handled in MediaSessionOptions::AddStream. SCTP streams | 302 // RTP data channel is handled in MediaSessionOptions::AddStream. SCTP streams |
| 285 // are not signaled in the SDP so does not go through that path and must be | 303 // are not signaled in the SDP so does not go through that path and must be |
| 286 // handled here. | 304 // handled here. |
| 287 if (data_channel_type_ == cricket::DCT_SCTP) { | 305 if (data_channel_type_ == cricket::DCT_SCTP) { |
| 288 options.data_channel_type = cricket::DCT_SCTP; | 306 options.data_channel_type = cricket::DCT_SCTP; |
| 289 } | 307 } |
| 290 | 308 |
| 291 CreateSessionDescriptionRequest request( | 309 CreateSessionDescriptionRequest request( |
| 292 CreateSessionDescriptionRequest::kAnswer, observer, options); | 310 CreateSessionDescriptionRequest::kAnswer, observer, options); |
| 293 if (identity_request_state_ == IDENTITY_WAITING) { | 311 if (certificate_request_state_ == CERTIFICATE_WAITING) { |
| 294 create_session_description_requests_.push(request); | 312 create_session_description_requests_.push(request); |
| 295 } else { | 313 } else { |
| 296 ASSERT(identity_request_state_ == IDENTITY_SUCCEEDED || | 314 ASSERT(certificate_request_state_ == CERTIFICATE_SUCCEEDED || |
| 297 identity_request_state_ == IDENTITY_NOT_NEEDED); | 315 certificate_request_state_ == CERTIFICATE_NOT_NEEDED); |
| 298 InternalCreateAnswer(request); | 316 InternalCreateAnswer(request); |
| 299 } | 317 } |
| 300 } | 318 } |
| 301 | 319 |
| 302 void WebRtcSessionDescriptionFactory::SetSdesPolicy( | 320 void WebRtcSessionDescriptionFactory::SetSdesPolicy( |
| 303 cricket::SecurePolicy secure_policy) { | 321 cricket::SecurePolicy secure_policy) { |
| 304 session_desc_factory_.set_secure(secure_policy); | 322 session_desc_factory_.set_secure(secure_policy); |
| 305 } | 323 } |
| 306 | 324 |
| 307 cricket::SecurePolicy WebRtcSessionDescriptionFactory::SdesPolicy() const { | 325 cricket::SecurePolicy WebRtcSessionDescriptionFactory::SdesPolicy() const { |
| 308 return session_desc_factory_.secure(); | 326 return session_desc_factory_.secure(); |
| 309 } | 327 } |
| 310 | 328 |
| 311 void WebRtcSessionDescriptionFactory::OnMessage(rtc::Message* msg) { | 329 void WebRtcSessionDescriptionFactory::OnMessage(rtc::Message* msg) { |
| 312 switch (msg->message_id) { | 330 switch (msg->message_id) { |
| 313 case MSG_CREATE_SESSIONDESCRIPTION_SUCCESS: { | 331 case MSG_CREATE_SESSIONDESCRIPTION_SUCCESS: { |
| 314 CreateSessionDescriptionMsg* param = | 332 CreateSessionDescriptionMsg* param = |
| 315 static_cast<CreateSessionDescriptionMsg*>(msg->pdata); | 333 static_cast<CreateSessionDescriptionMsg*>(msg->pdata); |
| 316 param->observer->OnSuccess(param->description.release()); | 334 param->observer->OnSuccess(param->description.release()); |
| 317 delete param; | 335 delete param; |
| 318 break; | 336 break; |
| 319 } | 337 } |
| 320 case MSG_CREATE_SESSIONDESCRIPTION_FAILED: { | 338 case MSG_CREATE_SESSIONDESCRIPTION_FAILED: { |
| 321 CreateSessionDescriptionMsg* param = | 339 CreateSessionDescriptionMsg* param = |
| 322 static_cast<CreateSessionDescriptionMsg*>(msg->pdata); | 340 static_cast<CreateSessionDescriptionMsg*>(msg->pdata); |
| 323 param->observer->OnFailure(param->error); | 341 param->observer->OnFailure(param->error); |
| 324 delete param; | 342 delete param; |
| 325 break; | 343 break; |
| 326 } | 344 } |
| 327 case MSG_GENERATE_IDENTITY: { | 345 case MSG_USE_CONSTRUCTOR_CERTIFICATE: { |
| 328 LOG(LS_INFO) << "Generating identity."; | 346 LOG(LS_INFO) << "Using certificate supplied to constructor."; |
| 329 SetIdentity(rtc::SSLIdentity::Generate(DtlsIdentityStore::kIdentityName)); | 347 DCHECK(certificate_.get()); |
| 348 SetCertificate(certificate_); | |
| 330 break; | 349 break; |
| 331 } | 350 } |
| 332 default: | 351 default: |
| 333 ASSERT(false); | 352 ASSERT(false); |
| 334 break; | 353 break; |
| 335 } | 354 } |
| 336 } | 355 } |
| 337 | 356 |
| 338 void WebRtcSessionDescriptionFactory::InternalCreateOffer( | 357 void WebRtcSessionDescriptionFactory::InternalCreateOffer( |
| 339 CreateSessionDescriptionRequest request) { | 358 CreateSessionDescriptionRequest request) { |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 440 SessionDescriptionInterface* description) { | 459 SessionDescriptionInterface* description) { |
| 441 CreateSessionDescriptionMsg* msg = new CreateSessionDescriptionMsg(observer); | 460 CreateSessionDescriptionMsg* msg = new CreateSessionDescriptionMsg(observer); |
| 442 msg->description.reset(description); | 461 msg->description.reset(description); |
| 443 signaling_thread_->Post(this, MSG_CREATE_SESSIONDESCRIPTION_SUCCESS, msg); | 462 signaling_thread_->Post(this, MSG_CREATE_SESSIONDESCRIPTION_SUCCESS, msg); |
| 444 } | 463 } |
| 445 | 464 |
| 446 void WebRtcSessionDescriptionFactory::OnIdentityRequestFailed(int error) { | 465 void WebRtcSessionDescriptionFactory::OnIdentityRequestFailed(int error) { |
| 447 ASSERT(signaling_thread_->IsCurrent()); | 466 ASSERT(signaling_thread_->IsCurrent()); |
| 448 | 467 |
| 449 LOG(LS_ERROR) << "Async identity request failed: error = " << error; | 468 LOG(LS_ERROR) << "Async identity request failed: error = " << error; |
| 450 identity_request_state_ = IDENTITY_FAILED; | 469 certificate_request_state_ = CERTIFICATE_FAILED; |
| 451 | 470 |
| 452 FailPendingRequests(kFailedDueToIdentityFailed); | 471 FailPendingRequests(kFailedDueToIdentityFailed); |
| 453 } | 472 } |
| 454 | 473 |
| 455 void WebRtcSessionDescriptionFactory::SetIdentity( | 474 void WebRtcSessionDescriptionFactory::SetCertificate( |
| 456 rtc::SSLIdentity* identity) { | 475 rtc::scoped_refptr<DtlsCertificate> certificate) { |
| 457 LOG(LS_VERBOSE) << "Setting new identity"; | 476 LOG(LS_VERBOSE) << "Setting new identity"; |
| 458 | 477 |
| 459 identity_request_state_ = IDENTITY_SUCCEEDED; | 478 certificate_ = certificate; |
| 460 SignalIdentityReady(identity); | 479 DCHECK(certificate_.get()); |
| 461 | 480 |
| 462 transport_desc_factory_.set_identity(identity); | 481 certificate_request_state_ = CERTIFICATE_SUCCEEDED; |
| 482 SignalCertificateReady(certificate_); | |
| 483 | |
| 484 transport_desc_factory_.set_identity(certificate->identity()); | |
| 463 transport_desc_factory_.set_secure(cricket::SEC_ENABLED); | 485 transport_desc_factory_.set_secure(cricket::SEC_ENABLED); |
| 464 | 486 |
| 465 while (!create_session_description_requests_.empty()) { | 487 while (!create_session_description_requests_.empty()) { |
| 466 if (create_session_description_requests_.front().type == | 488 if (create_session_description_requests_.front().type == |
| 467 CreateSessionDescriptionRequest::kOffer) { | 489 CreateSessionDescriptionRequest::kOffer) { |
| 468 InternalCreateOffer(create_session_description_requests_.front()); | 490 InternalCreateOffer(create_session_description_requests_.front()); |
| 469 } else { | 491 } else { |
| 470 InternalCreateAnswer(create_session_description_requests_.front()); | 492 InternalCreateAnswer(create_session_description_requests_.front()); |
| 471 } | 493 } |
| 472 create_session_description_requests_.pop(); | 494 create_session_description_requests_.pop(); |
| 473 } | 495 } |
| 474 } | 496 } |
| 475 } // namespace webrtc | 497 } // namespace webrtc |
| OLD | NEW |