OLD | NEW |
1 /* | 1 /* |
2 * libjingle | 2 * libjingle |
3 * Copyright 2015 Google Inc. | 3 * Copyright 2015 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 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
54 class DtlsIdentityStoreImpl::WorkerTask : public sigslot::has_slots<>, | 54 class DtlsIdentityStoreImpl::WorkerTask : public sigslot::has_slots<>, |
55 public rtc::MessageHandler { | 55 public rtc::MessageHandler { |
56 public: | 56 public: |
57 WorkerTask(DtlsIdentityStoreImpl* store, rtc::KeyType key_type) | 57 WorkerTask(DtlsIdentityStoreImpl* store, rtc::KeyType key_type) |
58 : signaling_thread_(rtc::Thread::Current()), | 58 : signaling_thread_(rtc::Thread::Current()), |
59 store_(store), | 59 store_(store), |
60 key_type_(key_type) { | 60 key_type_(key_type) { |
61 store_->SignalDestroyed.connect(this, &WorkerTask::OnStoreDestroyed); | 61 store_->SignalDestroyed.connect(this, &WorkerTask::OnStoreDestroyed); |
62 } | 62 } |
63 | 63 |
64 virtual ~WorkerTask() { DCHECK(signaling_thread_->IsCurrent()); } | 64 virtual ~WorkerTask() { RTC_DCHECK(signaling_thread_->IsCurrent()); } |
65 | 65 |
66 private: | 66 private: |
67 void GenerateIdentity_w() { | 67 void GenerateIdentity_w() { |
68 LOG(LS_INFO) << "Generating identity, using keytype " << key_type_; | 68 LOG(LS_INFO) << "Generating identity, using keytype " << key_type_; |
69 rtc::scoped_ptr<rtc::SSLIdentity> identity( | 69 rtc::scoped_ptr<rtc::SSLIdentity> identity( |
70 rtc::SSLIdentity::Generate(kIdentityName, key_type_)); | 70 rtc::SSLIdentity::Generate(kIdentityName, key_type_)); |
71 | 71 |
72 // Posting to |this| avoids touching |store_| on threads other than | 72 // Posting to |this| avoids touching |store_| on threads other than |
73 // |signaling_thread_| and thus avoids having to use locks. | 73 // |signaling_thread_| and thus avoids having to use locks. |
74 IdentityResultMessageData* msg = new IdentityResultMessageData( | 74 IdentityResultMessageData* msg = new IdentityResultMessageData( |
75 new IdentityResult(key_type_, identity.Pass())); | 75 new IdentityResult(key_type_, identity.Pass())); |
76 signaling_thread_->Post(this, MSG_GENERATE_IDENTITY_RESULT, msg); | 76 signaling_thread_->Post(this, MSG_GENERATE_IDENTITY_RESULT, msg); |
77 } | 77 } |
78 | 78 |
79 void OnMessage(rtc::Message* msg) override { | 79 void OnMessage(rtc::Message* msg) override { |
80 switch (msg->message_id) { | 80 switch (msg->message_id) { |
81 case MSG_GENERATE_IDENTITY: | 81 case MSG_GENERATE_IDENTITY: |
82 // This message always runs on the worker thread. | 82 // This message always runs on the worker thread. |
83 GenerateIdentity_w(); | 83 GenerateIdentity_w(); |
84 | 84 |
85 // Must delete |this|, owned by msg->pdata, on the signaling thread to | 85 // Must delete |this|, owned by msg->pdata, on the signaling thread to |
86 // avoid races on disconnecting the signal. | 86 // avoid races on disconnecting the signal. |
87 signaling_thread_->Post(this, MSG_DESTROY, msg->pdata); | 87 signaling_thread_->Post(this, MSG_DESTROY, msg->pdata); |
88 break; | 88 break; |
89 case MSG_GENERATE_IDENTITY_RESULT: | 89 case MSG_GENERATE_IDENTITY_RESULT: |
90 DCHECK(signaling_thread_->IsCurrent()); | 90 RTC_DCHECK(signaling_thread_->IsCurrent()); |
91 { | 91 { |
92 rtc::scoped_ptr<IdentityResultMessageData> pdata( | 92 rtc::scoped_ptr<IdentityResultMessageData> pdata( |
93 static_cast<IdentityResultMessageData*>(msg->pdata)); | 93 static_cast<IdentityResultMessageData*>(msg->pdata)); |
94 if (store_) { | 94 if (store_) { |
95 store_->OnIdentityGenerated(pdata->data()->key_type_, | 95 store_->OnIdentityGenerated(pdata->data()->key_type_, |
96 pdata->data()->identity_.Pass()); | 96 pdata->data()->identity_.Pass()); |
97 } | 97 } |
98 } | 98 } |
99 break; | 99 break; |
100 case MSG_DESTROY: | 100 case MSG_DESTROY: |
101 DCHECK(signaling_thread_->IsCurrent()); | 101 RTC_DCHECK(signaling_thread_->IsCurrent()); |
102 delete msg->pdata; | 102 delete msg->pdata; |
103 // |this| has now been deleted. Don't touch member variables. | 103 // |this| has now been deleted. Don't touch member variables. |
104 break; | 104 break; |
105 default: | 105 default: |
106 CHECK(false) << "Unexpected message type"; | 106 RTC_CHECK(false) << "Unexpected message type"; |
107 } | 107 } |
108 } | 108 } |
109 | 109 |
110 void OnStoreDestroyed() { | 110 void OnStoreDestroyed() { |
111 DCHECK(signaling_thread_->IsCurrent()); | 111 RTC_DCHECK(signaling_thread_->IsCurrent()); |
112 store_ = nullptr; | 112 store_ = nullptr; |
113 } | 113 } |
114 | 114 |
115 rtc::Thread* const signaling_thread_; | 115 rtc::Thread* const signaling_thread_; |
116 DtlsIdentityStoreImpl* store_; // Only touched on |signaling_thread_|. | 116 DtlsIdentityStoreImpl* store_; // Only touched on |signaling_thread_|. |
117 const rtc::KeyType key_type_; | 117 const rtc::KeyType key_type_; |
118 }; | 118 }; |
119 | 119 |
120 DtlsIdentityStoreImpl::DtlsIdentityStoreImpl(rtc::Thread* signaling_thread, | 120 DtlsIdentityStoreImpl::DtlsIdentityStoreImpl(rtc::Thread* signaling_thread, |
121 rtc::Thread* worker_thread) | 121 rtc::Thread* worker_thread) |
122 : signaling_thread_(signaling_thread), | 122 : signaling_thread_(signaling_thread), |
123 worker_thread_(worker_thread), | 123 worker_thread_(worker_thread), |
124 request_info_() { | 124 request_info_() { |
125 DCHECK(signaling_thread_->IsCurrent()); | 125 RTC_DCHECK(signaling_thread_->IsCurrent()); |
126 // Preemptively generate identities unless the worker thread and signaling | 126 // Preemptively generate identities unless the worker thread and signaling |
127 // thread are the same (only do preemptive work in the background). | 127 // thread are the same (only do preemptive work in the background). |
128 if (worker_thread_ != signaling_thread_) { | 128 if (worker_thread_ != signaling_thread_) { |
129 // Only necessary for RSA. | 129 // Only necessary for RSA. |
130 GenerateIdentity(rtc::KT_RSA, nullptr); | 130 GenerateIdentity(rtc::KT_RSA, nullptr); |
131 } | 131 } |
132 } | 132 } |
133 | 133 |
134 DtlsIdentityStoreImpl::~DtlsIdentityStoreImpl() { | 134 DtlsIdentityStoreImpl::~DtlsIdentityStoreImpl() { |
135 DCHECK(signaling_thread_->IsCurrent()); | 135 RTC_DCHECK(signaling_thread_->IsCurrent()); |
136 SignalDestroyed(); | 136 SignalDestroyed(); |
137 } | 137 } |
138 | 138 |
139 void DtlsIdentityStoreImpl::RequestIdentity( | 139 void DtlsIdentityStoreImpl::RequestIdentity( |
140 rtc::KeyType key_type, | 140 rtc::KeyType key_type, |
141 const rtc::scoped_refptr<webrtc::DtlsIdentityRequestObserver>& observer) { | 141 const rtc::scoped_refptr<webrtc::DtlsIdentityRequestObserver>& observer) { |
142 DCHECK(signaling_thread_->IsCurrent()); | 142 RTC_DCHECK(signaling_thread_->IsCurrent()); |
143 DCHECK(observer); | 143 RTC_DCHECK(observer); |
144 | 144 |
145 GenerateIdentity(key_type, observer); | 145 GenerateIdentity(key_type, observer); |
146 } | 146 } |
147 | 147 |
148 void DtlsIdentityStoreImpl::OnMessage(rtc::Message* msg) { | 148 void DtlsIdentityStoreImpl::OnMessage(rtc::Message* msg) { |
149 DCHECK(signaling_thread_->IsCurrent()); | 149 RTC_DCHECK(signaling_thread_->IsCurrent()); |
150 switch (msg->message_id) { | 150 switch (msg->message_id) { |
151 case MSG_GENERATE_IDENTITY_RESULT: { | 151 case MSG_GENERATE_IDENTITY_RESULT: { |
152 rtc::scoped_ptr<IdentityResultMessageData> pdata( | 152 rtc::scoped_ptr<IdentityResultMessageData> pdata( |
153 static_cast<IdentityResultMessageData*>(msg->pdata)); | 153 static_cast<IdentityResultMessageData*>(msg->pdata)); |
154 OnIdentityGenerated(pdata->data()->key_type_, | 154 OnIdentityGenerated(pdata->data()->key_type_, |
155 pdata->data()->identity_.Pass()); | 155 pdata->data()->identity_.Pass()); |
156 break; | 156 break; |
157 } | 157 } |
158 } | 158 } |
159 } | 159 } |
160 | 160 |
161 bool DtlsIdentityStoreImpl::HasFreeIdentityForTesting( | 161 bool DtlsIdentityStoreImpl::HasFreeIdentityForTesting( |
162 rtc::KeyType key_type) const { | 162 rtc::KeyType key_type) const { |
163 DCHECK(signaling_thread_->IsCurrent()); | 163 RTC_DCHECK(signaling_thread_->IsCurrent()); |
164 return request_info_[key_type].free_identity_.get() != nullptr; | 164 return request_info_[key_type].free_identity_.get() != nullptr; |
165 } | 165 } |
166 | 166 |
167 void DtlsIdentityStoreImpl::GenerateIdentity( | 167 void DtlsIdentityStoreImpl::GenerateIdentity( |
168 rtc::KeyType key_type, | 168 rtc::KeyType key_type, |
169 const rtc::scoped_refptr<webrtc::DtlsIdentityRequestObserver>& observer) { | 169 const rtc::scoped_refptr<webrtc::DtlsIdentityRequestObserver>& observer) { |
170 DCHECK(signaling_thread_->IsCurrent()); | 170 RTC_DCHECK(signaling_thread_->IsCurrent()); |
171 | 171 |
172 // Enqueue observer to be informed when generation of |key_type| is completed. | 172 // Enqueue observer to be informed when generation of |key_type| is completed. |
173 if (observer.get()) { | 173 if (observer.get()) { |
174 request_info_[key_type].request_observers_.push(observer); | 174 request_info_[key_type].request_observers_.push(observer); |
175 | 175 |
176 // Already have a free identity generated? | 176 // Already have a free identity generated? |
177 if (request_info_[key_type].free_identity_.get()) { | 177 if (request_info_[key_type].free_identity_.get()) { |
178 // Return identity async - post even though we are on |signaling_thread_|. | 178 // Return identity async - post even though we are on |signaling_thread_|. |
179 LOG(LS_VERBOSE) << "Using a free DTLS identity."; | 179 LOG(LS_VERBOSE) << "Using a free DTLS identity."; |
180 ++request_info_[key_type].gen_in_progress_counts_; | 180 ++request_info_[key_type].gen_in_progress_counts_; |
(...skipping 17 matching lines...) Expand all Loading... |
198 ++request_info_[key_type].gen_in_progress_counts_; | 198 ++request_info_[key_type].gen_in_progress_counts_; |
199 WorkerTask* task = new WorkerTask(this, key_type); // Post 1 task/request. | 199 WorkerTask* task = new WorkerTask(this, key_type); // Post 1 task/request. |
200 // The WorkerTask is owned by the message data to make sure it will not be | 200 // The WorkerTask is owned by the message data to make sure it will not be |
201 // leaked even if the task does not get run. | 201 // leaked even if the task does not get run. |
202 WorkerTaskMessageData* msg = new WorkerTaskMessageData(task); | 202 WorkerTaskMessageData* msg = new WorkerTaskMessageData(task); |
203 worker_thread_->Post(task, MSG_GENERATE_IDENTITY, msg); | 203 worker_thread_->Post(task, MSG_GENERATE_IDENTITY, msg); |
204 } | 204 } |
205 | 205 |
206 void DtlsIdentityStoreImpl::OnIdentityGenerated( | 206 void DtlsIdentityStoreImpl::OnIdentityGenerated( |
207 rtc::KeyType key_type, rtc::scoped_ptr<rtc::SSLIdentity> identity) { | 207 rtc::KeyType key_type, rtc::scoped_ptr<rtc::SSLIdentity> identity) { |
208 DCHECK(signaling_thread_->IsCurrent()); | 208 RTC_DCHECK(signaling_thread_->IsCurrent()); |
209 | 209 |
210 DCHECK(request_info_[key_type].gen_in_progress_counts_); | 210 RTC_DCHECK(request_info_[key_type].gen_in_progress_counts_); |
211 --request_info_[key_type].gen_in_progress_counts_; | 211 --request_info_[key_type].gen_in_progress_counts_; |
212 | 212 |
213 rtc::scoped_refptr<webrtc::DtlsIdentityRequestObserver> observer; | 213 rtc::scoped_refptr<webrtc::DtlsIdentityRequestObserver> observer; |
214 if (!request_info_[key_type].request_observers_.empty()) { | 214 if (!request_info_[key_type].request_observers_.empty()) { |
215 observer = request_info_[key_type].request_observers_.front(); | 215 observer = request_info_[key_type].request_observers_.front(); |
216 request_info_[key_type].request_observers_.pop(); | 216 request_info_[key_type].request_observers_.pop(); |
217 } | 217 } |
218 | 218 |
219 if (observer.get() == nullptr) { | 219 if (observer.get() == nullptr) { |
220 // No observer - store result in |free_identities_|. | 220 // No observer - store result in |free_identities_|. |
221 DCHECK(!request_info_[key_type].free_identity_.get()); | 221 RTC_DCHECK(!request_info_[key_type].free_identity_.get()); |
222 request_info_[key_type].free_identity_.swap(identity); | 222 request_info_[key_type].free_identity_.swap(identity); |
223 if (request_info_[key_type].free_identity_.get()) | 223 if (request_info_[key_type].free_identity_.get()) |
224 LOG(LS_VERBOSE) << "A free DTLS identity was saved."; | 224 LOG(LS_VERBOSE) << "A free DTLS identity was saved."; |
225 else | 225 else |
226 LOG(LS_WARNING) << "Failed to generate DTLS identity (preemptively)."; | 226 LOG(LS_WARNING) << "Failed to generate DTLS identity (preemptively)."; |
227 } else { | 227 } else { |
228 // Return the result to the observer. | 228 // Return the result to the observer. |
229 if (identity.get()) { | 229 if (identity.get()) { |
230 LOG(LS_VERBOSE) << "A DTLS identity is returned to an observer."; | 230 LOG(LS_VERBOSE) << "A DTLS identity is returned to an observer."; |
231 observer->OnSuccess(identity.Pass()); | 231 observer->OnSuccess(identity.Pass()); |
232 } else { | 232 } else { |
233 LOG(LS_WARNING) << "Failed to generate DTLS identity."; | 233 LOG(LS_WARNING) << "Failed to generate DTLS identity."; |
234 observer->OnFailure(0); | 234 observer->OnFailure(0); |
235 } | 235 } |
236 | 236 |
237 // Preemptively generate another identity of the same type? | 237 // Preemptively generate another identity of the same type? |
238 if (worker_thread_ != signaling_thread_ && // Only do in background thread. | 238 if (worker_thread_ != signaling_thread_ && // Only do in background thread. |
239 key_type == rtc::KT_RSA && // Only necessary for RSA. | 239 key_type == rtc::KT_RSA && // Only necessary for RSA. |
240 !request_info_[key_type].free_identity_.get() && | 240 !request_info_[key_type].free_identity_.get() && |
241 request_info_[key_type].request_observers_.size() <= | 241 request_info_[key_type].request_observers_.size() <= |
242 request_info_[key_type].gen_in_progress_counts_) { | 242 request_info_[key_type].gen_in_progress_counts_) { |
243 GenerateIdentity(key_type, nullptr); | 243 GenerateIdentity(key_type, nullptr); |
244 } | 244 } |
245 } | 245 } |
246 } | 246 } |
247 | 247 |
248 } // namespace webrtc | 248 } // namespace webrtc |
OLD | NEW |