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, |
(...skipping 15 matching lines...) Expand all Loading... |
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/dtlsidentitystore.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/sslidentity.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 14 matching lines...) Expand all Loading... |
60 MediaSessionOptions::Streams sorted_streams = streams; | 61 MediaSessionOptions::Streams sorted_streams = streams; |
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 }; | 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; |
(...skipping 13 matching lines...) Expand all Loading... |
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::SSLIdentity* identity = |
101 rtc::SSLIdentity::FromPEMStrings(pem_key, pem_cert); | 101 rtc::SSLIdentity::FromPEMStrings(pem_key, pem_cert); |
102 SignalIdentityReady(identity); | 102 SignalIdentityReady(identity); |
103 } | 103 } |
104 | 104 |
105 void WebRtcIdentityRequestObserver::OnSuccessWithIdentityObj( | 105 void WebRtcIdentityRequestObserver::OnSuccess( |
106 rtc::scoped_ptr<rtc::SSLIdentity> identity) { | 106 rtc::scoped_ptr<rtc::SSLIdentity> identity) { |
107 SignalIdentityReady(identity.release()); | 107 SignalIdentityReady(identity.release()); |
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 cricket::ChannelManager* channel_manager, | 131 cricket::ChannelManager* channel_manager, |
132 MediaStreamSignaling* mediastream_signaling, | 132 MediaStreamSignaling* mediastream_signaling, |
133 DTLSIdentityServiceInterface* dtls_identity_service, | 133 rtc::scoped_ptr<DtlsIdentityStoreInterface> dtls_identity_store, |
134 WebRtcSession* session, | 134 WebRtcSession* session, |
135 const std::string& session_id, | 135 const std::string& session_id, |
136 cricket::DataChannelType dct, | 136 cricket::DataChannelType dct, |
137 bool dtls_enabled) | 137 bool dtls_enabled) |
138 : signaling_thread_(signaling_thread), | 138 : signaling_thread_(signaling_thread), |
139 mediastream_signaling_(mediastream_signaling), | 139 mediastream_signaling_(mediastream_signaling), |
140 session_desc_factory_(channel_manager, &transport_desc_factory_), | 140 session_desc_factory_(channel_manager, &transport_desc_factory_), |
141 // RFC 4566 suggested a Network Time Protocol (NTP) format timestamp | 141 // RFC 4566 suggested a Network Time Protocol (NTP) format timestamp |
142 // as the session id and session version. To simplify, it should be fine | 142 // 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 | 143 // to just use a random number as session id and start version from |
144 // |kInitSessionVersion|. | 144 // |kInitSessionVersion|. |
145 session_version_(kInitSessionVersion), | 145 session_version_(kInitSessionVersion), |
146 identity_service_(dtls_identity_service), | 146 dtls_identity_store_(dtls_identity_store.Pass()), |
147 session_(session), | 147 session_(session), |
148 session_id_(session_id), | 148 session_id_(session_id), |
149 data_channel_type_(dct), | 149 data_channel_type_(dct), |
150 identity_request_state_(IDENTITY_NOT_NEEDED) { | 150 identity_request_state_(IDENTITY_NOT_NEEDED) { |
151 transport_desc_factory_.set_protocol(cricket::ICEPROTO_RFC5245); | 151 transport_desc_factory_.set_protocol(cricket::ICEPROTO_RFC5245); |
152 session_desc_factory_.set_add_legacy_streams(false); | 152 session_desc_factory_.set_add_legacy_streams(false); |
153 // SRTP-SDES is disabled if DTLS is on. | 153 // SRTP-SDES is disabled if DTLS is on. |
154 SetSdesPolicy(dtls_enabled ? cricket::SEC_DISABLED : cricket::SEC_REQUIRED); | 154 SetSdesPolicy(dtls_enabled ? cricket::SEC_DISABLED : cricket::SEC_REQUIRED); |
155 | 155 |
156 if (!dtls_enabled) { | 156 // If |dtls_enabled| we must have a |dtls_identity_store_|. |
157 return; | 157 DCHECK(!dtls_enabled || dtls_identity_store_); |
158 } | |
159 | 158 |
160 if (identity_service_.get()) { | 159 if (dtls_enabled && dtls_identity_store_) { |
161 identity_request_observer_ = | 160 identity_request_observer_ = |
162 new rtc::RefCountedObject<WebRtcIdentityRequestObserver>(); | 161 new rtc::RefCountedObject<WebRtcIdentityRequestObserver>(); |
163 | 162 |
164 identity_request_observer_->SignalRequestFailed.connect( | 163 identity_request_observer_->SignalRequestFailed.connect( |
165 this, &WebRtcSessionDescriptionFactory::OnIdentityRequestFailed); | 164 this, &WebRtcSessionDescriptionFactory::OnIdentityRequestFailed); |
166 identity_request_observer_->SignalIdentityReady.connect( | 165 identity_request_observer_->SignalIdentityReady.connect( |
167 this, &WebRtcSessionDescriptionFactory::SetIdentity); | 166 this, &WebRtcSessionDescriptionFactory::SetIdentity); |
168 | 167 |
169 if (identity_service_->RequestIdentity( | 168 LOG(LS_VERBOSE) << "DTLS-SRTP enabled; sending DTLS identity request."; |
170 DtlsIdentityStore::kIdentityName, | |
171 DtlsIdentityStore::kIdentityName, | |
172 identity_request_observer_)) { | |
173 LOG(LS_VERBOSE) << "DTLS-SRTP enabled; sent DTLS identity request."; | |
174 identity_request_state_ = IDENTITY_WAITING; | |
175 } else { | |
176 LOG(LS_ERROR) << "Failed to send DTLS identity request."; | |
177 identity_request_state_ = IDENTITY_FAILED; | |
178 } | |
179 } else { | |
180 identity_request_state_ = IDENTITY_WAITING; | 169 identity_request_state_ = IDENTITY_WAITING; |
181 // Do not generate the identity in the constructor since the caller has | 170 dtls_identity_store_->RequestIdentity(rtc::KT_DEFAULT, |
182 // not got a chance to connect to SignalIdentityReady. | 171 identity_request_observer_); |
183 signaling_thread_->Post(this, MSG_GENERATE_IDENTITY, NULL); | |
184 } | 172 } |
185 } | 173 } |
186 | 174 |
187 WebRtcSessionDescriptionFactory::~WebRtcSessionDescriptionFactory() { | 175 WebRtcSessionDescriptionFactory::~WebRtcSessionDescriptionFactory() { |
188 ASSERT(signaling_thread_->IsCurrent()); | 176 ASSERT(signaling_thread_->IsCurrent()); |
189 | 177 |
190 // Fail any requests that were asked for before identity generation completed. | 178 // Fail any requests that were asked for before identity generation completed. |
191 FailPendingRequests(kFailedDueToSessionShutdown); | 179 FailPendingRequests(kFailedDueToSessionShutdown); |
192 | 180 |
193 // Process all pending notifications in the message queue. If we don't do | 181 // Process all pending notifications in the message queue. If we don't do |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
317 delete param; | 305 delete param; |
318 break; | 306 break; |
319 } | 307 } |
320 case MSG_CREATE_SESSIONDESCRIPTION_FAILED: { | 308 case MSG_CREATE_SESSIONDESCRIPTION_FAILED: { |
321 CreateSessionDescriptionMsg* param = | 309 CreateSessionDescriptionMsg* param = |
322 static_cast<CreateSessionDescriptionMsg*>(msg->pdata); | 310 static_cast<CreateSessionDescriptionMsg*>(msg->pdata); |
323 param->observer->OnFailure(param->error); | 311 param->observer->OnFailure(param->error); |
324 delete param; | 312 delete param; |
325 break; | 313 break; |
326 } | 314 } |
327 case MSG_GENERATE_IDENTITY: { | |
328 LOG(LS_INFO) << "Generating identity."; | |
329 SetIdentity(rtc::SSLIdentity::Generate(DtlsIdentityStore::kIdentityName)); | |
330 break; | |
331 } | |
332 default: | 315 default: |
333 ASSERT(false); | 316 ASSERT(false); |
334 break; | 317 break; |
335 } | 318 } |
336 } | 319 } |
337 | 320 |
338 void WebRtcSessionDescriptionFactory::InternalCreateOffer( | 321 void WebRtcSessionDescriptionFactory::InternalCreateOffer( |
339 CreateSessionDescriptionRequest request) { | 322 CreateSessionDescriptionRequest request) { |
340 cricket::SessionDescription* desc( | 323 cricket::SessionDescription* desc( |
341 session_desc_factory_.CreateOffer( | 324 session_desc_factory_.CreateOffer( |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
466 if (create_session_description_requests_.front().type == | 449 if (create_session_description_requests_.front().type == |
467 CreateSessionDescriptionRequest::kOffer) { | 450 CreateSessionDescriptionRequest::kOffer) { |
468 InternalCreateOffer(create_session_description_requests_.front()); | 451 InternalCreateOffer(create_session_description_requests_.front()); |
469 } else { | 452 } else { |
470 InternalCreateAnswer(create_session_description_requests_.front()); | 453 InternalCreateAnswer(create_session_description_requests_.front()); |
471 } | 454 } |
472 create_session_description_requests_.pop(); | 455 create_session_description_requests_.pop(); |
473 } | 456 } |
474 } | 457 } |
475 } // namespace webrtc | 458 } // namespace webrtc |
OLD | NEW |