| 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 |