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 rtc::scoped_refptr<DtlsCertificate> certificate, |
134 WebRtcSession* session, | 135 WebRtcSession* session, |
135 const std::string& session_id, | 136 const std::string& session_id, |
136 cricket::DataChannelType dct, | 137 cricket::DataChannelType dct, |
137 bool dtls_enabled) | 138 bool dtls_enabled) |
138 : signaling_thread_(signaling_thread), | 139 : signaling_thread_(signaling_thread), |
| 140 worker_thread_(worker_thread), |
139 mediastream_signaling_(mediastream_signaling), | 141 mediastream_signaling_(mediastream_signaling), |
140 session_desc_factory_(channel_manager, &transport_desc_factory_), | 142 session_desc_factory_(channel_manager, &transport_desc_factory_), |
141 // RFC 4566 suggested a Network Time Protocol (NTP) format timestamp | 143 // RFC 4566 suggested a Network Time Protocol (NTP) format timestamp |
142 // as the session id and session version. To simplify, it should be fine | 144 // 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 | 145 // to just use a random number as session id and start version from |
144 // |kInitSessionVersion|. | 146 // |kInitSessionVersion|. |
145 session_version_(kInitSessionVersion), | 147 session_version_(kInitSessionVersion), |
146 identity_service_(dtls_identity_service), | 148 certificate_(certificate), |
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); |
155 | 157 |
156 if (!dtls_enabled) { | 158 if (!dtls_enabled) { |
157 return; | 159 return; |
158 } | 160 } |
159 | 161 |
160 if (identity_service_.get()) { | 162 certificate_request_state_ = CERTIFICATE_WAITING; |
| 163 if (certificate_.get()) { |
| 164 LOG(LS_VERBOSE) << "DTLS-SRTP enabled; using DTLS certificate."; |
| 165 // We already have a certificate but we wait to do SetCertificate; if we do |
| 166 // it in the constructor the caller has not had a chance to connect to |
| 167 // SignalCertificateReady. |
| 168 signaling_thread_->Post(this, MSG_USE_CONSTRUCTOR_CERTIFICATE, NULL); |
| 169 } else { |
| 170 // We generate a new certificate with our own service. |
161 identity_request_observer_ = | 171 identity_request_observer_ = |
162 new rtc::RefCountedObject<WebRtcIdentityRequestObserver>(); | 172 new rtc::RefCountedObject<WebRtcIdentityRequestObserver>(); |
163 | 173 |
164 identity_request_observer_->SignalRequestFailed.connect( | 174 identity_request_observer_->SignalRequestFailed.connect( |
165 this, &WebRtcSessionDescriptionFactory::OnIdentityRequestFailed); | 175 this, &WebRtcSessionDescriptionFactory::OnIdentityRequestFailed); |
166 identity_request_observer_->SignalIdentityReady.connect( | 176 identity_request_observer_->SignalCertificateReady.connect( |
167 this, &WebRtcSessionDescriptionFactory::SetIdentity); | 177 this, &WebRtcSessionDescriptionFactory::SetCertificate); |
168 | 178 |
169 if (identity_service_->RequestIdentity( | 179 identity_store_.reset( |
170 DtlsIdentityStore::kIdentityName, | 180 new DtlsIdentityStore(signaling_thread_, worker_thread_)); |
171 DtlsIdentityStore::kIdentityName, | 181 identity_service_.reset(new DtlsIdentityService(identity_store_.get())); |
172 identity_request_observer_)) { | 182 if (identity_service_->RequestIdentity(DtlsIdentityStore::kIdentityName, |
173 LOG(LS_VERBOSE) << "DTLS-SRTP enabled; sent DTLS identity request."; | 183 DtlsIdentityStore::kIdentityName, |
174 identity_request_state_ = IDENTITY_WAITING; | 184 identity_request_observer_)) { |
| 185 LOG(LS_VERBOSE) << "DTLS-SRTP enabled but no certificate supplied, sent " |
| 186 << "DTLS identity request."; |
175 } else { | 187 } else { |
176 LOG(LS_ERROR) << "Failed to send DTLS identity request."; | 188 certificate_request_state_ = CERTIFICATE_FAILED; |
177 identity_request_state_ = IDENTITY_FAILED; | 189 LOG(LS_VERBOSE) << "DTLS-SRTP enabled but no certificate supplied, " |
| 190 << "FAILED to send DTLS identity request."; |
178 } | 191 } |
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 } | 192 } |
185 } | 193 } |
186 | 194 |
187 WebRtcSessionDescriptionFactory::~WebRtcSessionDescriptionFactory() { | 195 WebRtcSessionDescriptionFactory::~WebRtcSessionDescriptionFactory() { |
188 ASSERT(signaling_thread_->IsCurrent()); | 196 ASSERT(signaling_thread_->IsCurrent()); |
189 | 197 |
190 // Fail any requests that were asked for before identity generation completed. | 198 // Fail any requests that were asked for before identity generation completed. |
191 FailPendingRequests(kFailedDueToSessionShutdown); | 199 FailPendingRequests(kFailedDueToSessionShutdown); |
192 | 200 |
193 // Process all pending notifications in the message queue. If we don't do | 201 // 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. | 202 // this, requests will linger and not know they succeeded or failed. |
195 rtc::MessageList list; | 203 rtc::MessageList list; |
196 signaling_thread_->Clear(this, rtc::MQID_ANY, &list); | 204 signaling_thread_->Clear(this, rtc::MQID_ANY, &list); |
197 for (auto& msg : list) | 205 for (auto& msg : list) |
198 OnMessage(&msg); | 206 OnMessage(&msg); |
199 | 207 |
200 transport_desc_factory_.set_identity(NULL); | 208 transport_desc_factory_.set_identity(NULL); |
201 } | 209 } |
202 | 210 |
203 void WebRtcSessionDescriptionFactory::CreateOffer( | 211 void WebRtcSessionDescriptionFactory::CreateOffer( |
204 CreateSessionDescriptionObserver* observer, | 212 CreateSessionDescriptionObserver* observer, |
205 const PeerConnectionInterface::RTCOfferAnswerOptions& options) { | 213 const PeerConnectionInterface::RTCOfferAnswerOptions& options) { |
206 cricket::MediaSessionOptions session_options; | 214 cricket::MediaSessionOptions session_options; |
207 | 215 |
208 std::string error = "CreateOffer"; | 216 std::string error = "CreateOffer"; |
209 if (identity_request_state_ == IDENTITY_FAILED) { | 217 if (certificate_request_state_ == CERTIFICATE_FAILED) { |
210 error += kFailedDueToIdentityFailed; | 218 error += kFailedDueToIdentityFailed; |
211 LOG(LS_ERROR) << error; | 219 LOG(LS_ERROR) << error; |
212 PostCreateSessionDescriptionFailed(observer, error); | 220 PostCreateSessionDescriptionFailed(observer, error); |
213 return; | 221 return; |
214 } | 222 } |
215 | 223 |
216 if (!mediastream_signaling_->GetOptionsForOffer(options, | 224 if (!mediastream_signaling_->GetOptionsForOffer(options, |
217 &session_options)) { | 225 &session_options)) { |
218 error += " called with invalid options."; | 226 error += " called with invalid options."; |
219 LOG(LS_ERROR) << error; | 227 LOG(LS_ERROR) << error; |
220 PostCreateSessionDescriptionFailed(observer, error); | 228 PostCreateSessionDescriptionFailed(observer, error); |
221 return; | 229 return; |
222 } | 230 } |
223 | 231 |
224 if (!ValidStreams(session_options.streams)) { | 232 if (!ValidStreams(session_options.streams)) { |
225 error += " called with invalid media streams."; | 233 error += " called with invalid media streams."; |
226 LOG(LS_ERROR) << error; | 234 LOG(LS_ERROR) << error; |
227 PostCreateSessionDescriptionFailed(observer, error); | 235 PostCreateSessionDescriptionFailed(observer, error); |
228 return; | 236 return; |
229 } | 237 } |
230 | 238 |
231 if (data_channel_type_ == cricket::DCT_SCTP && | 239 if (data_channel_type_ == cricket::DCT_SCTP && |
232 mediastream_signaling_->HasDataChannels()) { | 240 mediastream_signaling_->HasDataChannels()) { |
233 session_options.data_channel_type = cricket::DCT_SCTP; | 241 session_options.data_channel_type = cricket::DCT_SCTP; |
234 } | 242 } |
235 | 243 |
236 CreateSessionDescriptionRequest request( | 244 CreateSessionDescriptionRequest request( |
237 CreateSessionDescriptionRequest::kOffer, observer, session_options); | 245 CreateSessionDescriptionRequest::kOffer, observer, session_options); |
238 if (identity_request_state_ == IDENTITY_WAITING) { | 246 if (certificate_request_state_ == CERTIFICATE_WAITING) { |
239 create_session_description_requests_.push(request); | 247 create_session_description_requests_.push(request); |
240 } else { | 248 } else { |
241 ASSERT(identity_request_state_ == IDENTITY_SUCCEEDED || | 249 ASSERT(certificate_request_state_ == CERTIFICATE_SUCCEEDED || |
242 identity_request_state_ == IDENTITY_NOT_NEEDED); | 250 certificate_request_state_ == CERTIFICATE_NOT_NEEDED); |
243 InternalCreateOffer(request); | 251 InternalCreateOffer(request); |
244 } | 252 } |
245 } | 253 } |
246 | 254 |
247 void WebRtcSessionDescriptionFactory::CreateAnswer( | 255 void WebRtcSessionDescriptionFactory::CreateAnswer( |
248 CreateSessionDescriptionObserver* observer, | 256 CreateSessionDescriptionObserver* observer, |
249 const MediaConstraintsInterface* constraints) { | 257 const MediaConstraintsInterface* constraints) { |
250 std::string error = "CreateAnswer"; | 258 std::string error = "CreateAnswer"; |
251 if (identity_request_state_ == IDENTITY_FAILED) { | 259 if (certificate_request_state_ == CERTIFICATE_FAILED) { |
252 error += kFailedDueToIdentityFailed; | 260 error += kFailedDueToIdentityFailed; |
253 LOG(LS_ERROR) << error; | 261 LOG(LS_ERROR) << error; |
254 PostCreateSessionDescriptionFailed(observer, error); | 262 PostCreateSessionDescriptionFailed(observer, error); |
255 return; | 263 return; |
256 } | 264 } |
257 if (!session_->remote_description()) { | 265 if (!session_->remote_description()) { |
258 error += " can't be called before SetRemoteDescription."; | 266 error += " can't be called before SetRemoteDescription."; |
259 LOG(LS_ERROR) << error; | 267 LOG(LS_ERROR) << error; |
260 PostCreateSessionDescriptionFailed(observer, error); | 268 PostCreateSessionDescriptionFailed(observer, error); |
261 return; | 269 return; |
(...skipping 21 matching lines...) Expand all Loading... |
283 } | 291 } |
284 // RTP data channel is handled in MediaSessionOptions::AddStream. SCTP streams | 292 // 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 | 293 // are not signaled in the SDP so does not go through that path and must be |
286 // handled here. | 294 // handled here. |
287 if (data_channel_type_ == cricket::DCT_SCTP) { | 295 if (data_channel_type_ == cricket::DCT_SCTP) { |
288 options.data_channel_type = cricket::DCT_SCTP; | 296 options.data_channel_type = cricket::DCT_SCTP; |
289 } | 297 } |
290 | 298 |
291 CreateSessionDescriptionRequest request( | 299 CreateSessionDescriptionRequest request( |
292 CreateSessionDescriptionRequest::kAnswer, observer, options); | 300 CreateSessionDescriptionRequest::kAnswer, observer, options); |
293 if (identity_request_state_ == IDENTITY_WAITING) { | 301 if (certificate_request_state_ == CERTIFICATE_WAITING) { |
294 create_session_description_requests_.push(request); | 302 create_session_description_requests_.push(request); |
295 } else { | 303 } else { |
296 ASSERT(identity_request_state_ == IDENTITY_SUCCEEDED || | 304 ASSERT(certificate_request_state_ == CERTIFICATE_SUCCEEDED || |
297 identity_request_state_ == IDENTITY_NOT_NEEDED); | 305 certificate_request_state_ == CERTIFICATE_NOT_NEEDED); |
298 InternalCreateAnswer(request); | 306 InternalCreateAnswer(request); |
299 } | 307 } |
300 } | 308 } |
301 | 309 |
302 void WebRtcSessionDescriptionFactory::SetSdesPolicy( | 310 void WebRtcSessionDescriptionFactory::SetSdesPolicy( |
303 cricket::SecurePolicy secure_policy) { | 311 cricket::SecurePolicy secure_policy) { |
304 session_desc_factory_.set_secure(secure_policy); | 312 session_desc_factory_.set_secure(secure_policy); |
305 } | 313 } |
306 | 314 |
307 cricket::SecurePolicy WebRtcSessionDescriptionFactory::SdesPolicy() const { | 315 cricket::SecurePolicy WebRtcSessionDescriptionFactory::SdesPolicy() const { |
308 return session_desc_factory_.secure(); | 316 return session_desc_factory_.secure(); |
309 } | 317 } |
310 | 318 |
311 void WebRtcSessionDescriptionFactory::OnMessage(rtc::Message* msg) { | 319 void WebRtcSessionDescriptionFactory::OnMessage(rtc::Message* msg) { |
312 switch (msg->message_id) { | 320 switch (msg->message_id) { |
313 case MSG_CREATE_SESSIONDESCRIPTION_SUCCESS: { | 321 case MSG_CREATE_SESSIONDESCRIPTION_SUCCESS: { |
314 CreateSessionDescriptionMsg* param = | 322 CreateSessionDescriptionMsg* param = |
315 static_cast<CreateSessionDescriptionMsg*>(msg->pdata); | 323 static_cast<CreateSessionDescriptionMsg*>(msg->pdata); |
316 param->observer->OnSuccess(param->description.release()); | 324 param->observer->OnSuccess(param->description.release()); |
317 delete param; | 325 delete param; |
318 break; | 326 break; |
319 } | 327 } |
320 case MSG_CREATE_SESSIONDESCRIPTION_FAILED: { | 328 case MSG_CREATE_SESSIONDESCRIPTION_FAILED: { |
321 CreateSessionDescriptionMsg* param = | 329 CreateSessionDescriptionMsg* param = |
322 static_cast<CreateSessionDescriptionMsg*>(msg->pdata); | 330 static_cast<CreateSessionDescriptionMsg*>(msg->pdata); |
323 param->observer->OnFailure(param->error); | 331 param->observer->OnFailure(param->error); |
324 delete param; | 332 delete param; |
325 break; | 333 break; |
326 } | 334 } |
327 case MSG_GENERATE_IDENTITY: { | 335 case MSG_USE_CONSTRUCTOR_CERTIFICATE: { |
328 LOG(LS_INFO) << "Generating identity."; | 336 LOG(LS_INFO) << "Using certificate supplied to constructor."; |
329 SetIdentity(rtc::SSLIdentity::Generate(DtlsIdentityStore::kIdentityName)); | 337 DCHECK(certificate_.get()); |
| 338 SetCertificate(certificate_); |
330 break; | 339 break; |
331 } | 340 } |
332 default: | 341 default: |
333 ASSERT(false); | 342 ASSERT(false); |
334 break; | 343 break; |
335 } | 344 } |
336 } | 345 } |
337 | 346 |
338 void WebRtcSessionDescriptionFactory::InternalCreateOffer( | 347 void WebRtcSessionDescriptionFactory::InternalCreateOffer( |
339 CreateSessionDescriptionRequest request) { | 348 CreateSessionDescriptionRequest request) { |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
440 SessionDescriptionInterface* description) { | 449 SessionDescriptionInterface* description) { |
441 CreateSessionDescriptionMsg* msg = new CreateSessionDescriptionMsg(observer); | 450 CreateSessionDescriptionMsg* msg = new CreateSessionDescriptionMsg(observer); |
442 msg->description.reset(description); | 451 msg->description.reset(description); |
443 signaling_thread_->Post(this, MSG_CREATE_SESSIONDESCRIPTION_SUCCESS, msg); | 452 signaling_thread_->Post(this, MSG_CREATE_SESSIONDESCRIPTION_SUCCESS, msg); |
444 } | 453 } |
445 | 454 |
446 void WebRtcSessionDescriptionFactory::OnIdentityRequestFailed(int error) { | 455 void WebRtcSessionDescriptionFactory::OnIdentityRequestFailed(int error) { |
447 ASSERT(signaling_thread_->IsCurrent()); | 456 ASSERT(signaling_thread_->IsCurrent()); |
448 | 457 |
449 LOG(LS_ERROR) << "Async identity request failed: error = " << error; | 458 LOG(LS_ERROR) << "Async identity request failed: error = " << error; |
450 identity_request_state_ = IDENTITY_FAILED; | 459 certificate_request_state_ = CERTIFICATE_FAILED; |
451 | 460 |
452 FailPendingRequests(kFailedDueToIdentityFailed); | 461 FailPendingRequests(kFailedDueToIdentityFailed); |
453 } | 462 } |
454 | 463 |
455 void WebRtcSessionDescriptionFactory::SetIdentity( | 464 void WebRtcSessionDescriptionFactory::SetCertificate( |
456 rtc::SSLIdentity* identity) { | 465 rtc::scoped_refptr<DtlsCertificate> certificate) { |
457 LOG(LS_VERBOSE) << "Setting new identity"; | 466 LOG(LS_VERBOSE) << "Setting new identity"; |
458 | 467 |
459 identity_request_state_ = IDENTITY_SUCCEEDED; | 468 certificate_ = certificate; |
460 SignalIdentityReady(identity); | 469 DCHECK(certificate_.get()); |
461 | 470 |
462 transport_desc_factory_.set_identity(identity); | 471 certificate_request_state_ = CERTIFICATE_SUCCEEDED; |
| 472 SignalCertificateReady(certificate_); |
| 473 |
| 474 transport_desc_factory_.set_identity(certificate->identity()); |
463 transport_desc_factory_.set_secure(cricket::SEC_ENABLED); | 475 transport_desc_factory_.set_secure(cricket::SEC_ENABLED); |
464 | 476 |
465 while (!create_session_description_requests_.empty()) { | 477 while (!create_session_description_requests_.empty()) { |
466 if (create_session_description_requests_.front().type == | 478 if (create_session_description_requests_.front().type == |
467 CreateSessionDescriptionRequest::kOffer) { | 479 CreateSessionDescriptionRequest::kOffer) { |
468 InternalCreateOffer(create_session_description_requests_.front()); | 480 InternalCreateOffer(create_session_description_requests_.front()); |
469 } else { | 481 } else { |
470 InternalCreateAnswer(create_session_description_requests_.front()); | 482 InternalCreateAnswer(create_session_description_requests_.front()); |
471 } | 483 } |
472 create_session_description_requests_.pop(); | 484 create_session_description_requests_.pop(); |
473 } | 485 } |
474 } | 486 } |
475 } // namespace webrtc | 487 } // namespace webrtc |
OLD | NEW |