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 #include "webrtc/base/messagequeue.h" | |
36 | 37 |
37 using cricket::MediaSessionOptions; | 38 using cricket::MediaSessionOptions; |
38 | 39 |
39 namespace webrtc { | 40 namespace webrtc { |
40 namespace { | 41 namespace { |
41 static const char kFailedDueToIdentityFailed[] = | 42 static const char kFailedDueToIdentityFailed[] = |
42 " failed because DTLS identity request failed"; | 43 " failed because DTLS identity request failed"; |
43 static const char kFailedDueToSessionShutdown[] = | 44 static const char kFailedDueToSessionShutdown[] = |
44 " failed because the session was shut down"; | 45 " failed because the session was shut down"; |
45 | 46 |
(...skipping 15 matching lines...) Expand all Loading... | |
61 std::sort(sorted_streams.begin(), sorted_streams.end(), CompareStream); | 62 std::sort(sorted_streams.begin(), sorted_streams.end(), CompareStream); |
62 MediaSessionOptions::Streams::iterator it = | 63 MediaSessionOptions::Streams::iterator it = |
63 std::adjacent_find(sorted_streams.begin(), sorted_streams.end(), | 64 std::adjacent_find(sorted_streams.begin(), sorted_streams.end(), |
64 SameId); | 65 SameId); |
65 return it == sorted_streams.end(); | 66 return it == sorted_streams.end(); |
66 } | 67 } |
67 | 68 |
68 enum { | 69 enum { |
69 MSG_CREATE_SESSIONDESCRIPTION_SUCCESS, | 70 MSG_CREATE_SESSIONDESCRIPTION_SUCCESS, |
70 MSG_CREATE_SESSIONDESCRIPTION_FAILED, | 71 MSG_CREATE_SESSIONDESCRIPTION_FAILED, |
71 MSG_GENERATE_IDENTITY, | 72 MSG_USE_CONSTRUCTOR_CERTIFICATE |
72 }; | 73 }; |
73 | 74 |
74 struct CreateSessionDescriptionMsg : public rtc::MessageData { | 75 struct CreateSessionDescriptionMsg : public rtc::MessageData { |
75 explicit CreateSessionDescriptionMsg( | 76 explicit CreateSessionDescriptionMsg( |
76 webrtc::CreateSessionDescriptionObserver* observer) | 77 webrtc::CreateSessionDescriptionObserver* observer) |
77 : observer(observer) { | 78 : observer(observer) { |
78 } | 79 } |
79 | 80 |
80 rtc::scoped_refptr<webrtc::CreateSessionDescriptionObserver> observer; | 81 rtc::scoped_refptr<webrtc::CreateSessionDescriptionObserver> observer; |
81 std::string error; | 82 std::string error; |
82 rtc::scoped_ptr<webrtc::SessionDescriptionInterface> description; | 83 rtc::scoped_ptr<webrtc::SessionDescriptionInterface> description; |
83 }; | 84 }; |
84 } // namespace | 85 } // namespace |
85 | 86 |
86 void WebRtcIdentityRequestObserver::OnFailure(int error) { | 87 void WebRtcIdentityRequestObserver::OnFailure(int error) { |
87 SignalRequestFailed(error); | 88 SignalRequestFailed(error); |
88 } | 89 } |
89 | 90 |
90 void WebRtcIdentityRequestObserver::OnSuccess( | 91 void WebRtcIdentityRequestObserver::OnSuccess( |
91 const std::string& der_cert, const std::string& der_private_key) { | 92 const std::string& der_cert, const std::string& der_private_key) { |
92 std::string pem_cert = rtc::SSLIdentity::DerToPem( | 93 std::string pem_cert = rtc::SSLIdentity::DerToPem( |
93 rtc::kPemTypeCertificate, | 94 rtc::kPemTypeCertificate, |
94 reinterpret_cast<const unsigned char*>(der_cert.data()), | 95 reinterpret_cast<const unsigned char*>(der_cert.data()), |
95 der_cert.length()); | 96 der_cert.length()); |
96 std::string pem_key = rtc::SSLIdentity::DerToPem( | 97 std::string pem_key = rtc::SSLIdentity::DerToPem( |
97 rtc::kPemTypeRsaPrivateKey, | 98 rtc::kPemTypeRsaPrivateKey, |
98 reinterpret_cast<const unsigned char*>(der_private_key.data()), | 99 reinterpret_cast<const unsigned char*>(der_private_key.data()), |
99 der_private_key.length()); | 100 der_private_key.length()); |
100 rtc::SSLIdentity* identity = | 101 rtc::scoped_ptr<rtc::SSLIdentity> identity( |
101 rtc::SSLIdentity::FromPEMStrings(pem_key, pem_cert); | 102 rtc::SSLIdentity::FromPEMStrings(pem_key, pem_cert)); |
102 SignalIdentityReady(identity); | 103 SignalCertificateReady(DtlsCertificate::Create(identity.Pass())); |
103 } | 104 } |
104 | 105 |
105 void WebRtcIdentityRequestObserver::OnSuccessWithIdentityObj( | 106 void WebRtcIdentityRequestObserver::OnSuccessWithIdentityObj( |
106 rtc::scoped_ptr<rtc::SSLIdentity> identity) { | 107 rtc::scoped_ptr<rtc::SSLIdentity> identity) { |
107 SignalIdentityReady(identity.release()); | 108 SignalCertificateReady(DtlsCertificate::Create(identity.Pass())); |
108 } | 109 } |
109 | 110 |
110 // static | 111 // static |
111 void WebRtcSessionDescriptionFactory::CopyCandidatesFromSessionDescription( | 112 void WebRtcSessionDescriptionFactory::CopyCandidatesFromSessionDescription( |
112 const SessionDescriptionInterface* source_desc, | 113 const SessionDescriptionInterface* source_desc, |
113 SessionDescriptionInterface* dest_desc) { | 114 SessionDescriptionInterface* dest_desc) { |
114 if (!source_desc) | 115 if (!source_desc) |
115 return; | 116 return; |
116 for (size_t m = 0; m < source_desc->number_of_mediasections() && | 117 for (size_t m = 0; m < source_desc->number_of_mediasections() && |
117 m < dest_desc->number_of_mediasections(); ++m) { | 118 m < dest_desc->number_of_mediasections(); ++m) { |
118 const IceCandidateCollection* source_candidates = | 119 const IceCandidateCollection* source_candidates = |
119 source_desc->candidates(m); | 120 source_desc->candidates(m); |
120 const IceCandidateCollection* dest_candidates = dest_desc->candidates(m); | 121 const IceCandidateCollection* dest_candidates = dest_desc->candidates(m); |
121 for (size_t n = 0; n < source_candidates->count(); ++n) { | 122 for (size_t n = 0; n < source_candidates->count(); ++n) { |
122 const IceCandidateInterface* new_candidate = source_candidates->at(n); | 123 const IceCandidateInterface* new_candidate = source_candidates->at(n); |
123 if (!dest_candidates->HasCandidate(new_candidate)) | 124 if (!dest_candidates->HasCandidate(new_candidate)) |
124 dest_desc->AddCandidate(source_candidates->at(n)); | 125 dest_desc->AddCandidate(source_candidates->at(n)); |
125 } | 126 } |
126 } | 127 } |
127 } | 128 } |
128 | 129 |
130 // Private constructor called by other constructors. | |
129 WebRtcSessionDescriptionFactory::WebRtcSessionDescriptionFactory( | 131 WebRtcSessionDescriptionFactory::WebRtcSessionDescriptionFactory( |
130 rtc::Thread* signaling_thread, | 132 rtc::Thread* signaling_thread, |
133 rtc::Thread* worker_thread, | |
131 cricket::ChannelManager* channel_manager, | 134 cricket::ChannelManager* channel_manager, |
132 MediaStreamSignaling* mediastream_signaling, | 135 MediaStreamSignaling* mediastream_signaling, |
133 DTLSIdentityServiceInterface* dtls_identity_service, | |
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), | |
147 session_(session), | 149 session_(session), |
148 session_id_(session_id), | 150 session_id_(session_id), |
149 data_channel_type_(dct), | 151 data_channel_type_(dct), |
150 identity_request_state_(IDENTITY_NOT_NEEDED) { | 152 certificate_request_state_(CERTIFICATE_NOT_NEEDED) { |
151 transport_desc_factory_.set_protocol(cricket::ICEPROTO_RFC5245); | 153 transport_desc_factory_.set_protocol(cricket::ICEPROTO_RFC5245); |
152 session_desc_factory_.set_add_legacy_streams(false); | 154 session_desc_factory_.set_add_legacy_streams(false); |
153 // SRTP-SDES is disabled if DTLS is on. | 155 // SRTP-SDES is disabled if DTLS is on. |
154 SetSdesPolicy(dtls_enabled ? cricket::SEC_DISABLED : cricket::SEC_REQUIRED); | 156 SetSdesPolicy(dtls_enabled ? cricket::SEC_DISABLED : cricket::SEC_REQUIRED); |
157 } | |
155 | 158 |
156 if (!dtls_enabled) { | 159 WebRtcSessionDescriptionFactory::WebRtcSessionDescriptionFactory( |
157 return; | 160 rtc::Thread* signaling_thread, |
161 rtc::Thread* worker_thread, | |
162 cricket::ChannelManager* channel_manager, | |
163 MediaStreamSignaling* mediastream_signaling, | |
164 WebRtcSession* session, | |
165 const std::string& session_id, | |
166 cricket::DataChannelType dct) | |
167 : WebRtcSessionDescriptionFactory(signaling_thread, worker_thread, | |
168 channel_manager, mediastream_signaling, | |
169 session, session_id, dct, false) { | |
170 } | |
171 | |
172 WebRtcSessionDescriptionFactory::WebRtcSessionDescriptionFactory( | |
173 rtc::Thread* signaling_thread, | |
174 rtc::Thread* worker_thread, | |
175 cricket::ChannelManager* channel_manager, | |
176 MediaStreamSignaling* mediastream_signaling, | |
177 DTLSIdentityServiceInterface* dtls_identity_service, | |
178 WebRtcSession* session, | |
179 const std::string& session_id, | |
180 cricket::DataChannelType dct) | |
181 : WebRtcSessionDescriptionFactory(signaling_thread, worker_thread, | |
182 channel_manager, mediastream_signaling, | |
183 session, session_id, dct, true) { | |
184 identity_service_.reset(dtls_identity_service); | |
185 | |
186 // Generate certificate. | |
187 certificate_request_state_ = CERTIFICATE_WAITING; | |
188 | |
189 identity_request_observer_ = | |
190 new rtc::RefCountedObject<WebRtcIdentityRequestObserver>(); | |
191 identity_request_observer_->SignalRequestFailed.connect( | |
192 this, &WebRtcSessionDescriptionFactory::OnIdentityRequestFailed); | |
193 identity_request_observer_->SignalCertificateReady.connect( | |
194 this, &WebRtcSessionDescriptionFactory::SetCertificate); | |
195 | |
196 // If an |identity_service_| was not provided we default to using | |
197 // DtlsIdentityStore and DtlsIdentityService. | |
198 if (!identity_service_.get()) { | |
199 identity_store_.reset( | |
200 new DtlsIdentityStore(signaling_thread_, worker_thread_)); | |
201 identity_service_.reset(new DtlsIdentityService(identity_store_.get())); | |
158 } | 202 } |
159 | 203 |
160 if (identity_service_.get()) { | 204 // Request identity. This happens asynchronously, so the caller will have a |
161 identity_request_observer_ = | 205 // chance to connect to SignalCertificateReady. |
162 new rtc::RefCountedObject<WebRtcIdentityRequestObserver>(); | 206 if (identity_service_->RequestIdentity(DtlsIdentityStore::kIdentityName, |
207 DtlsIdentityStore::kIdentityName, | |
208 identity_request_observer_)) { | |
209 LOG(LS_VERBOSE) << "DTLS-SRTP enabled, sent DTLS identity request."; | |
210 } else { | |
211 certificate_request_state_ = CERTIFICATE_FAILED; | |
212 LOG(LS_VERBOSE) << "DTLS-SRTP enabled, DTLS identity request FAILED."; | |
213 } | |
214 } | |
163 | 215 |
164 identity_request_observer_->SignalRequestFailed.connect( | 216 WebRtcSessionDescriptionFactory::WebRtcSessionDescriptionFactory( |
165 this, &WebRtcSessionDescriptionFactory::OnIdentityRequestFailed); | 217 rtc::Thread* signaling_thread, |
166 identity_request_observer_->SignalIdentityReady.connect( | 218 rtc::Thread* worker_thread, |
167 this, &WebRtcSessionDescriptionFactory::SetIdentity); | 219 cricket::ChannelManager* channel_manager, |
220 MediaStreamSignaling* mediastream_signaling, | |
221 rtc::scoped_refptr<DtlsCertificate> certificate, | |
222 WebRtcSession* session, | |
223 const std::string& session_id, | |
224 cricket::DataChannelType dct) | |
225 : WebRtcSessionDescriptionFactory(signaling_thread, worker_thread, | |
226 channel_manager, mediastream_signaling, | |
227 session, session_id, dct, true) { | |
228 DCHECK(certificate.get()); | |
168 | 229 |
169 if (identity_service_->RequestIdentity( | 230 LOG(LS_VERBOSE) << "DTLS-SRTP enabled; using DTLS certificate."; |
170 DtlsIdentityStore::kIdentityName, | 231 // We already have a certificate but we wait to do SetCertificate; if we do |
171 DtlsIdentityStore::kIdentityName, | 232 // it in the constructor then the caller has not had a chance to connect to |
172 identity_request_observer_)) { | 233 // SignalCertificateReady. |
173 LOG(LS_VERBOSE) << "DTLS-SRTP enabled; sent DTLS identity request."; | 234 certificate_request_state_ = CERTIFICATE_WAITING; |
174 identity_request_state_ = IDENTITY_WAITING; | 235 signaling_thread_->Post(this, MSG_USE_CONSTRUCTOR_CERTIFICATE, |
175 } else { | 236 new rtc::ScopedRefMessageData<DtlsCertificate>( |
176 LOG(LS_ERROR) << "Failed to send DTLS identity request."; | 237 certificate)); |
177 identity_request_state_ = IDENTITY_FAILED; | |
178 } | |
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 } | |
185 } | 238 } |
186 | 239 |
187 WebRtcSessionDescriptionFactory::~WebRtcSessionDescriptionFactory() { | 240 WebRtcSessionDescriptionFactory::~WebRtcSessionDescriptionFactory() { |
188 ASSERT(signaling_thread_->IsCurrent()); | 241 ASSERT(signaling_thread_->IsCurrent()); |
189 | 242 |
190 // Fail any requests that were asked for before identity generation completed. | 243 // Fail any requests that were asked for before identity generation completed. |
191 FailPendingRequests(kFailedDueToSessionShutdown); | 244 FailPendingRequests(kFailedDueToSessionShutdown); |
192 | 245 |
193 // Process all pending notifications in the message queue. If we don't do | 246 // 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. | 247 // this, requests will linger and not know they succeeded or failed. |
195 rtc::MessageList list; | 248 rtc::MessageList list; |
196 signaling_thread_->Clear(this, rtc::MQID_ANY, &list); | 249 signaling_thread_->Clear(this, rtc::MQID_ANY, &list); |
197 for (auto& msg : list) | 250 for (auto& msg : list) |
198 OnMessage(&msg); | 251 OnMessage(&msg); |
199 | 252 |
200 transport_desc_factory_.set_identity(NULL); | 253 transport_desc_factory_.set_certificate(nullptr); |
201 } | 254 } |
202 | 255 |
203 void WebRtcSessionDescriptionFactory::CreateOffer( | 256 void WebRtcSessionDescriptionFactory::CreateOffer( |
204 CreateSessionDescriptionObserver* observer, | 257 CreateSessionDescriptionObserver* observer, |
205 const PeerConnectionInterface::RTCOfferAnswerOptions& options) { | 258 const PeerConnectionInterface::RTCOfferAnswerOptions& options) { |
206 cricket::MediaSessionOptions session_options; | 259 cricket::MediaSessionOptions session_options; |
207 | 260 |
208 std::string error = "CreateOffer"; | 261 std::string error = "CreateOffer"; |
209 if (identity_request_state_ == IDENTITY_FAILED) { | 262 if (certificate_request_state_ == CERTIFICATE_FAILED) { |
210 error += kFailedDueToIdentityFailed; | 263 error += kFailedDueToIdentityFailed; |
211 LOG(LS_ERROR) << error; | 264 LOG(LS_ERROR) << error; |
212 PostCreateSessionDescriptionFailed(observer, error); | 265 PostCreateSessionDescriptionFailed(observer, error); |
213 return; | 266 return; |
214 } | 267 } |
215 | 268 |
216 if (!mediastream_signaling_->GetOptionsForOffer(options, | 269 if (!mediastream_signaling_->GetOptionsForOffer(options, |
217 &session_options)) { | 270 &session_options)) { |
218 error += " called with invalid options."; | 271 error += " called with invalid options."; |
219 LOG(LS_ERROR) << error; | 272 LOG(LS_ERROR) << error; |
220 PostCreateSessionDescriptionFailed(observer, error); | 273 PostCreateSessionDescriptionFailed(observer, error); |
221 return; | 274 return; |
222 } | 275 } |
223 | 276 |
224 if (!ValidStreams(session_options.streams)) { | 277 if (!ValidStreams(session_options.streams)) { |
225 error += " called with invalid media streams."; | 278 error += " called with invalid media streams."; |
226 LOG(LS_ERROR) << error; | 279 LOG(LS_ERROR) << error; |
227 PostCreateSessionDescriptionFailed(observer, error); | 280 PostCreateSessionDescriptionFailed(observer, error); |
228 return; | 281 return; |
229 } | 282 } |
230 | 283 |
231 if (data_channel_type_ == cricket::DCT_SCTP && | 284 if (data_channel_type_ == cricket::DCT_SCTP && |
232 mediastream_signaling_->HasDataChannels()) { | 285 mediastream_signaling_->HasDataChannels()) { |
233 session_options.data_channel_type = cricket::DCT_SCTP; | 286 session_options.data_channel_type = cricket::DCT_SCTP; |
234 } | 287 } |
235 | 288 |
236 CreateSessionDescriptionRequest request( | 289 CreateSessionDescriptionRequest request( |
237 CreateSessionDescriptionRequest::kOffer, observer, session_options); | 290 CreateSessionDescriptionRequest::kOffer, observer, session_options); |
238 if (identity_request_state_ == IDENTITY_WAITING) { | 291 if (certificate_request_state_ == CERTIFICATE_WAITING) { |
239 create_session_description_requests_.push(request); | 292 create_session_description_requests_.push(request); |
240 } else { | 293 } else { |
241 ASSERT(identity_request_state_ == IDENTITY_SUCCEEDED || | 294 ASSERT(certificate_request_state_ == CERTIFICATE_SUCCEEDED || |
242 identity_request_state_ == IDENTITY_NOT_NEEDED); | 295 certificate_request_state_ == CERTIFICATE_NOT_NEEDED); |
243 InternalCreateOffer(request); | 296 InternalCreateOffer(request); |
244 } | 297 } |
245 } | 298 } |
246 | 299 |
247 void WebRtcSessionDescriptionFactory::CreateAnswer( | 300 void WebRtcSessionDescriptionFactory::CreateAnswer( |
248 CreateSessionDescriptionObserver* observer, | 301 CreateSessionDescriptionObserver* observer, |
249 const MediaConstraintsInterface* constraints) { | 302 const MediaConstraintsInterface* constraints) { |
250 std::string error = "CreateAnswer"; | 303 std::string error = "CreateAnswer"; |
251 if (identity_request_state_ == IDENTITY_FAILED) { | 304 if (certificate_request_state_ == CERTIFICATE_FAILED) { |
252 error += kFailedDueToIdentityFailed; | 305 error += kFailedDueToIdentityFailed; |
253 LOG(LS_ERROR) << error; | 306 LOG(LS_ERROR) << error; |
254 PostCreateSessionDescriptionFailed(observer, error); | 307 PostCreateSessionDescriptionFailed(observer, error); |
255 return; | 308 return; |
256 } | 309 } |
257 if (!session_->remote_description()) { | 310 if (!session_->remote_description()) { |
258 error += " can't be called before SetRemoteDescription."; | 311 error += " can't be called before SetRemoteDescription."; |
259 LOG(LS_ERROR) << error; | 312 LOG(LS_ERROR) << error; |
260 PostCreateSessionDescriptionFailed(observer, error); | 313 PostCreateSessionDescriptionFailed(observer, error); |
261 return; | 314 return; |
(...skipping 21 matching lines...) Expand all Loading... | |
283 } | 336 } |
284 // RTP data channel is handled in MediaSessionOptions::AddStream. SCTP streams | 337 // 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 | 338 // are not signaled in the SDP so does not go through that path and must be |
286 // handled here. | 339 // handled here. |
287 if (data_channel_type_ == cricket::DCT_SCTP) { | 340 if (data_channel_type_ == cricket::DCT_SCTP) { |
288 options.data_channel_type = cricket::DCT_SCTP; | 341 options.data_channel_type = cricket::DCT_SCTP; |
289 } | 342 } |
290 | 343 |
291 CreateSessionDescriptionRequest request( | 344 CreateSessionDescriptionRequest request( |
292 CreateSessionDescriptionRequest::kAnswer, observer, options); | 345 CreateSessionDescriptionRequest::kAnswer, observer, options); |
293 if (identity_request_state_ == IDENTITY_WAITING) { | 346 if (certificate_request_state_ == CERTIFICATE_WAITING) { |
294 create_session_description_requests_.push(request); | 347 create_session_description_requests_.push(request); |
295 } else { | 348 } else { |
296 ASSERT(identity_request_state_ == IDENTITY_SUCCEEDED || | 349 ASSERT(certificate_request_state_ == CERTIFICATE_SUCCEEDED || |
297 identity_request_state_ == IDENTITY_NOT_NEEDED); | 350 certificate_request_state_ == CERTIFICATE_NOT_NEEDED); |
298 InternalCreateAnswer(request); | 351 InternalCreateAnswer(request); |
299 } | 352 } |
300 } | 353 } |
301 | 354 |
302 void WebRtcSessionDescriptionFactory::SetSdesPolicy( | 355 void WebRtcSessionDescriptionFactory::SetSdesPolicy( |
303 cricket::SecurePolicy secure_policy) { | 356 cricket::SecurePolicy secure_policy) { |
304 session_desc_factory_.set_secure(secure_policy); | 357 session_desc_factory_.set_secure(secure_policy); |
305 } | 358 } |
306 | 359 |
307 cricket::SecurePolicy WebRtcSessionDescriptionFactory::SdesPolicy() const { | 360 cricket::SecurePolicy WebRtcSessionDescriptionFactory::SdesPolicy() const { |
308 return session_desc_factory_.secure(); | 361 return session_desc_factory_.secure(); |
309 } | 362 } |
310 | 363 |
311 void WebRtcSessionDescriptionFactory::OnMessage(rtc::Message* msg) { | 364 void WebRtcSessionDescriptionFactory::OnMessage(rtc::Message* msg) { |
312 switch (msg->message_id) { | 365 switch (msg->message_id) { |
313 case MSG_CREATE_SESSIONDESCRIPTION_SUCCESS: { | 366 case MSG_CREATE_SESSIONDESCRIPTION_SUCCESS: { |
314 CreateSessionDescriptionMsg* param = | 367 CreateSessionDescriptionMsg* param = |
315 static_cast<CreateSessionDescriptionMsg*>(msg->pdata); | 368 static_cast<CreateSessionDescriptionMsg*>(msg->pdata); |
316 param->observer->OnSuccess(param->description.release()); | 369 param->observer->OnSuccess(param->description.release()); |
317 delete param; | 370 delete param; |
318 break; | 371 break; |
319 } | 372 } |
320 case MSG_CREATE_SESSIONDESCRIPTION_FAILED: { | 373 case MSG_CREATE_SESSIONDESCRIPTION_FAILED: { |
321 CreateSessionDescriptionMsg* param = | 374 CreateSessionDescriptionMsg* param = |
322 static_cast<CreateSessionDescriptionMsg*>(msg->pdata); | 375 static_cast<CreateSessionDescriptionMsg*>(msg->pdata); |
323 param->observer->OnFailure(param->error); | 376 param->observer->OnFailure(param->error); |
324 delete param; | 377 delete param; |
325 break; | 378 break; |
326 } | 379 } |
327 case MSG_GENERATE_IDENTITY: { | 380 case MSG_USE_CONSTRUCTOR_CERTIFICATE: { |
328 LOG(LS_INFO) << "Generating identity."; | 381 rtc::ScopedRefMessageData<DtlsCertificate>* param = |
329 SetIdentity(rtc::SSLIdentity::Generate(DtlsIdentityStore::kIdentityName)); | 382 static_cast<rtc::ScopedRefMessageData<DtlsCertificate>*>(msg->pdata); |
383 LOG(LS_INFO) << "Using certificate supplied to constructor."; | |
384 SetCertificate(param->data()); | |
385 delete param; | |
330 break; | 386 break; |
331 } | 387 } |
332 default: | 388 default: |
333 ASSERT(false); | 389 ASSERT(false); |
334 break; | 390 break; |
335 } | 391 } |
336 } | 392 } |
337 | 393 |
338 void WebRtcSessionDescriptionFactory::InternalCreateOffer( | 394 void WebRtcSessionDescriptionFactory::InternalCreateOffer( |
339 CreateSessionDescriptionRequest request) { | 395 CreateSessionDescriptionRequest request) { |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
440 SessionDescriptionInterface* description) { | 496 SessionDescriptionInterface* description) { |
441 CreateSessionDescriptionMsg* msg = new CreateSessionDescriptionMsg(observer); | 497 CreateSessionDescriptionMsg* msg = new CreateSessionDescriptionMsg(observer); |
442 msg->description.reset(description); | 498 msg->description.reset(description); |
443 signaling_thread_->Post(this, MSG_CREATE_SESSIONDESCRIPTION_SUCCESS, msg); | 499 signaling_thread_->Post(this, MSG_CREATE_SESSIONDESCRIPTION_SUCCESS, msg); |
444 } | 500 } |
445 | 501 |
446 void WebRtcSessionDescriptionFactory::OnIdentityRequestFailed(int error) { | 502 void WebRtcSessionDescriptionFactory::OnIdentityRequestFailed(int error) { |
447 ASSERT(signaling_thread_->IsCurrent()); | 503 ASSERT(signaling_thread_->IsCurrent()); |
448 | 504 |
449 LOG(LS_ERROR) << "Async identity request failed: error = " << error; | 505 LOG(LS_ERROR) << "Async identity request failed: error = " << error; |
450 identity_request_state_ = IDENTITY_FAILED; | 506 certificate_request_state_ = CERTIFICATE_FAILED; |
451 | 507 |
452 FailPendingRequests(kFailedDueToIdentityFailed); | 508 FailPendingRequests(kFailedDueToIdentityFailed); |
453 } | 509 } |
454 | 510 |
455 void WebRtcSessionDescriptionFactory::SetIdentity( | 511 void WebRtcSessionDescriptionFactory::SetCertificate( |
456 rtc::SSLIdentity* identity) { | 512 rtc::scoped_refptr<DtlsCertificate> certificate) { |
tommi (sloooow) - chröme
2015/08/10 16:10:16
this should be passed by const &
hbos
2015/08/12 08:55:15
Acknowledged.
| |
457 LOG(LS_VERBOSE) << "Setting new identity"; | 513 LOG(LS_VERBOSE) << "Setting new certificate"; |
458 | 514 |
459 identity_request_state_ = IDENTITY_SUCCEEDED; | 515 DCHECK(certificate); |
460 SignalIdentityReady(identity); | |
461 | 516 |
462 transport_desc_factory_.set_identity(identity); | 517 certificate_request_state_ = CERTIFICATE_SUCCEEDED; |
518 SignalCertificateReady(certificate); | |
519 | |
520 transport_desc_factory_.set_certificate(certificate); | |
463 transport_desc_factory_.set_secure(cricket::SEC_ENABLED); | 521 transport_desc_factory_.set_secure(cricket::SEC_ENABLED); |
464 | 522 |
465 while (!create_session_description_requests_.empty()) { | 523 while (!create_session_description_requests_.empty()) { |
466 if (create_session_description_requests_.front().type == | 524 if (create_session_description_requests_.front().type == |
467 CreateSessionDescriptionRequest::kOffer) { | 525 CreateSessionDescriptionRequest::kOffer) { |
468 InternalCreateOffer(create_session_description_requests_.front()); | 526 InternalCreateOffer(create_session_description_requests_.front()); |
469 } else { | 527 } else { |
470 InternalCreateAnswer(create_session_description_requests_.front()); | 528 InternalCreateAnswer(create_session_description_requests_.front()); |
471 } | 529 } |
472 create_session_description_requests_.pop(); | 530 create_session_description_requests_.pop(); |
473 } | 531 } |
474 } | 532 } |
475 } // namespace webrtc | 533 } // namespace webrtc |
OLD | NEW |