OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2011 The WebRTC Project Authors. All rights reserved. | 2 * Copyright 2011 The WebRTC Project Authors. All rights reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
87 } | 87 } |
88 | 88 |
89 DtlsTransportChannelWrapper::DtlsTransportChannelWrapper( | 89 DtlsTransportChannelWrapper::DtlsTransportChannelWrapper( |
90 Transport* transport, | 90 Transport* transport, |
91 TransportChannelImpl* channel) | 91 TransportChannelImpl* channel) |
92 : TransportChannelImpl(channel->transport_name(), channel->component()), | 92 : TransportChannelImpl(channel->transport_name(), channel->component()), |
93 transport_(transport), | 93 transport_(transport), |
94 worker_thread_(rtc::Thread::Current()), | 94 worker_thread_(rtc::Thread::Current()), |
95 channel_(channel), | 95 channel_(channel), |
96 downward_(NULL), | 96 downward_(NULL), |
97 dtls_state_(STATE_NONE), | |
98 ssl_role_(rtc::SSL_CLIENT), | 97 ssl_role_(rtc::SSL_CLIENT), |
99 ssl_max_version_(rtc::SSL_PROTOCOL_DTLS_10) { | 98 ssl_max_version_(rtc::SSL_PROTOCOL_DTLS_10) { |
100 channel_->SignalWritableState.connect(this, | 99 channel_->SignalWritableState.connect(this, |
101 &DtlsTransportChannelWrapper::OnWritableState); | 100 &DtlsTransportChannelWrapper::OnWritableState); |
102 channel_->SignalReadPacket.connect(this, | 101 channel_->SignalReadPacket.connect(this, |
103 &DtlsTransportChannelWrapper::OnReadPacket); | 102 &DtlsTransportChannelWrapper::OnReadPacket); |
104 channel_->SignalSentPacket.connect( | 103 channel_->SignalSentPacket.connect( |
105 this, &DtlsTransportChannelWrapper::OnSentPacket); | 104 this, &DtlsTransportChannelWrapper::OnSentPacket); |
106 channel_->SignalReadyToSend.connect(this, | 105 channel_->SignalReadyToSend.connect(this, |
107 &DtlsTransportChannelWrapper::OnReadyToSend); | 106 &DtlsTransportChannelWrapper::OnReadyToSend); |
108 channel_->SignalGatheringState.connect( | 107 channel_->SignalGatheringState.connect( |
109 this, &DtlsTransportChannelWrapper::OnGatheringState); | 108 this, &DtlsTransportChannelWrapper::OnGatheringState); |
110 channel_->SignalCandidateGathered.connect( | 109 channel_->SignalCandidateGathered.connect( |
111 this, &DtlsTransportChannelWrapper::OnCandidateGathered); | 110 this, &DtlsTransportChannelWrapper::OnCandidateGathered); |
112 channel_->SignalRoleConflict.connect(this, | 111 channel_->SignalRoleConflict.connect(this, |
113 &DtlsTransportChannelWrapper::OnRoleConflict); | 112 &DtlsTransportChannelWrapper::OnRoleConflict); |
114 channel_->SignalRouteChange.connect(this, | 113 channel_->SignalRouteChange.connect(this, |
115 &DtlsTransportChannelWrapper::OnRouteChange); | 114 &DtlsTransportChannelWrapper::OnRouteChange); |
116 channel_->SignalConnectionRemoved.connect(this, | 115 channel_->SignalConnectionRemoved.connect(this, |
117 &DtlsTransportChannelWrapper::OnConnectionRemoved); | 116 &DtlsTransportChannelWrapper::OnConnectionRemoved); |
118 channel_->SignalReceivingState.connect(this, | 117 channel_->SignalReceivingState.connect(this, |
119 &DtlsTransportChannelWrapper::OnReceivingState); | 118 &DtlsTransportChannelWrapper::OnReceivingState); |
120 } | 119 } |
121 | 120 |
122 DtlsTransportChannelWrapper::~DtlsTransportChannelWrapper() { | 121 DtlsTransportChannelWrapper::~DtlsTransportChannelWrapper() { |
123 } | 122 } |
124 | 123 |
125 void DtlsTransportChannelWrapper::Connect() { | 124 void DtlsTransportChannelWrapper::Connect() { |
126 // We should only get a single call to Connect. | 125 // We should only get a single call to Connect. |
127 ASSERT(dtls_state_ == STATE_NONE || | 126 ASSERT(dtls_state() == DTLS_TRANSPORT_NEW); |
128 dtls_state_ == STATE_OFFERED || | |
129 dtls_state_ == STATE_ACCEPTED); | |
130 channel_->Connect(); | 127 channel_->Connect(); |
131 } | 128 } |
132 | 129 |
133 bool DtlsTransportChannelWrapper::SetLocalCertificate( | 130 bool DtlsTransportChannelWrapper::SetLocalCertificate( |
134 const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) { | 131 const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) { |
135 if (dtls_state_ != STATE_NONE) { | 132 if (dtls_active_) { |
136 if (certificate == local_certificate_) { | 133 if (certificate == local_certificate_) { |
137 // This may happen during renegotiation. | 134 // This may happen during renegotiation. |
138 LOG_J(LS_INFO, this) << "Ignoring identical DTLS identity"; | 135 LOG_J(LS_INFO, this) << "Ignoring identical DTLS identity"; |
139 return true; | 136 return true; |
140 } else { | 137 } else { |
141 LOG_J(LS_ERROR, this) << "Can't change DTLS local identity in this state"; | 138 LOG_J(LS_ERROR, this) << "Can't change DTLS local identity in this state"; |
142 return false; | 139 return false; |
143 } | 140 } |
144 } | 141 } |
145 | 142 |
146 if (certificate) { | 143 if (certificate) { |
147 local_certificate_ = certificate; | 144 local_certificate_ = certificate; |
148 dtls_state_ = STATE_OFFERED; | 145 dtls_active_ = true; |
149 } else { | 146 } else { |
150 LOG_J(LS_INFO, this) << "NULL DTLS identity supplied. Not doing DTLS"; | 147 LOG_J(LS_INFO, this) << "NULL DTLS identity supplied. Not doing DTLS"; |
151 } | 148 } |
152 | 149 |
153 return true; | 150 return true; |
154 } | 151 } |
155 | 152 |
156 rtc::scoped_refptr<rtc::RTCCertificate> | 153 rtc::scoped_refptr<rtc::RTCCertificate> |
157 DtlsTransportChannelWrapper::GetLocalCertificate() const { | 154 DtlsTransportChannelWrapper::GetLocalCertificate() const { |
158 return local_certificate_; | 155 return local_certificate_; |
159 } | 156 } |
160 | 157 |
161 bool DtlsTransportChannelWrapper::SetSslMaxProtocolVersion( | 158 bool DtlsTransportChannelWrapper::SetSslMaxProtocolVersion( |
162 rtc::SSLProtocolVersion version) { | 159 rtc::SSLProtocolVersion version) { |
163 if (dtls_state_ != STATE_NONE) { | 160 if (dtls_active_) { |
164 LOG(LS_ERROR) << "Not changing max. protocol version " | 161 LOG(LS_ERROR) << "Not changing max. protocol version " |
165 << "while DTLS is negotiating"; | 162 << "while DTLS is negotiating"; |
166 return false; | 163 return false; |
167 } | 164 } |
168 | 165 |
169 ssl_max_version_ = version; | 166 ssl_max_version_ = version; |
170 return true; | 167 return true; |
171 } | 168 } |
172 | 169 |
173 bool DtlsTransportChannelWrapper::SetSslRole(rtc::SSLRole role) { | 170 bool DtlsTransportChannelWrapper::SetSslRole(rtc::SSLRole role) { |
174 if (dtls_state_ == STATE_OPEN) { | 171 if (dtls_state() == DTLS_TRANSPORT_CONNECTED) { |
175 if (ssl_role_ != role) { | 172 if (ssl_role_ != role) { |
176 LOG(LS_ERROR) << "SSL Role can't be reversed after the session is setup."; | 173 LOG(LS_ERROR) << "SSL Role can't be reversed after the session is setup."; |
177 return false; | 174 return false; |
178 } | 175 } |
179 return true; | 176 return true; |
180 } | 177 } |
181 | 178 |
182 ssl_role_ = role; | 179 ssl_role_ = role; |
183 return true; | 180 return true; |
184 } | 181 } |
185 | 182 |
186 bool DtlsTransportChannelWrapper::GetSslRole(rtc::SSLRole* role) const { | 183 bool DtlsTransportChannelWrapper::GetSslRole(rtc::SSLRole* role) const { |
187 *role = ssl_role_; | 184 *role = ssl_role_; |
188 return true; | 185 return true; |
189 } | 186 } |
190 | 187 |
191 bool DtlsTransportChannelWrapper::GetSslCipherSuite(int* cipher) { | 188 bool DtlsTransportChannelWrapper::GetSslCipherSuite(int* cipher) { |
192 if (dtls_state_ != STATE_OPEN) { | 189 if (dtls_state() != DTLS_TRANSPORT_CONNECTED) { |
193 return false; | 190 return false; |
194 } | 191 } |
195 | 192 |
196 return dtls_->GetSslCipherSuite(cipher); | 193 return dtls_->GetSslCipherSuite(cipher); |
197 } | 194 } |
198 | 195 |
199 bool DtlsTransportChannelWrapper::SetRemoteFingerprint( | 196 bool DtlsTransportChannelWrapper::SetRemoteFingerprint( |
200 const std::string& digest_alg, | 197 const std::string& digest_alg, |
201 const uint8_t* digest, | 198 const uint8_t* digest, |
202 size_t digest_len) { | 199 size_t digest_len) { |
203 rtc::Buffer remote_fingerprint_value(digest, digest_len); | 200 rtc::Buffer remote_fingerprint_value(digest, digest_len); |
204 | 201 |
205 if (dtls_state_ != STATE_NONE && | 202 if (dtls_active_ && remote_fingerprint_value_ == remote_fingerprint_value && |
206 remote_fingerprint_value_ == remote_fingerprint_value && | |
207 !digest_alg.empty()) { | 203 !digest_alg.empty()) { |
208 // This may happen during renegotiation. | 204 // This may happen during renegotiation. |
209 LOG_J(LS_INFO, this) << "Ignoring identical remote DTLS fingerprint"; | 205 LOG_J(LS_INFO, this) << "Ignoring identical remote DTLS fingerprint"; |
210 return true; | 206 return true; |
211 } | 207 } |
212 | 208 |
213 // Allow SetRemoteFingerprint with a NULL digest even if SetLocalCertificate | 209 // Allow SetRemoteFingerprint with a NULL digest even if SetLocalCertificate |
214 // hasn't been called. | 210 // hasn't been called. |
215 if (dtls_state_ > STATE_OFFERED || | 211 if (dtls_ || (!dtls_active_ && !digest_alg.empty())) { |
216 (dtls_state_ == STATE_NONE && !digest_alg.empty())) { | |
217 LOG_J(LS_ERROR, this) << "Can't set DTLS remote settings in this state."; | 212 LOG_J(LS_ERROR, this) << "Can't set DTLS remote settings in this state."; |
218 return false; | 213 return false; |
219 } | 214 } |
220 | 215 |
221 if (digest_alg.empty()) { | 216 if (digest_alg.empty()) { |
222 LOG_J(LS_INFO, this) << "Other side didn't support DTLS."; | 217 LOG_J(LS_INFO, this) << "Other side didn't support DTLS."; |
223 dtls_state_ = STATE_NONE; | 218 dtls_active_ = false; |
224 return true; | 219 return true; |
225 } | 220 } |
226 | 221 |
227 // At this point we know we are doing DTLS | 222 // At this point we know we are doing DTLS |
228 remote_fingerprint_value_ = remote_fingerprint_value.Pass(); | 223 remote_fingerprint_value_ = remote_fingerprint_value.Pass(); |
229 remote_fingerprint_algorithm_ = digest_alg; | 224 remote_fingerprint_algorithm_ = digest_alg; |
230 | 225 |
231 if (!SetupDtls()) { | 226 if (!SetupDtls()) { |
232 dtls_state_ = STATE_CLOSED; | 227 set_dtls_state(DTLS_TRANSPORT_FAILED); |
233 return false; | 228 return false; |
234 } | 229 } |
235 | 230 |
236 dtls_state_ = STATE_ACCEPTED; | |
237 return true; | 231 return true; |
238 } | 232 } |
239 | 233 |
240 bool DtlsTransportChannelWrapper::GetRemoteSSLCertificate( | 234 bool DtlsTransportChannelWrapper::GetRemoteSSLCertificate( |
241 rtc::SSLCertificate** cert) const { | 235 rtc::SSLCertificate** cert) const { |
242 if (!dtls_) | 236 if (!dtls_) { |
243 return false; | 237 return false; |
| 238 } |
244 | 239 |
245 return dtls_->GetPeerCertificate(cert); | 240 return dtls_->GetPeerCertificate(cert); |
246 } | 241 } |
247 | 242 |
248 bool DtlsTransportChannelWrapper::SetupDtls() { | 243 bool DtlsTransportChannelWrapper::SetupDtls() { |
249 StreamInterfaceChannel* downward = new StreamInterfaceChannel(channel_); | 244 StreamInterfaceChannel* downward = new StreamInterfaceChannel(channel_); |
250 | 245 |
251 dtls_.reset(rtc::SSLStreamAdapter::Create(downward)); | 246 dtls_.reset(rtc::SSLStreamAdapter::Create(downward)); |
252 if (!dtls_) { | 247 if (!dtls_) { |
253 LOG_J(LS_ERROR, this) << "Failed to create DTLS adapter."; | 248 LOG_J(LS_ERROR, this) << "Failed to create DTLS adapter."; |
(...skipping 16 matching lines...) Expand all Loading... |
270 return false; | 265 return false; |
271 } | 266 } |
272 | 267 |
273 // Set up DTLS-SRTP, if it's been enabled. | 268 // Set up DTLS-SRTP, if it's been enabled. |
274 if (!srtp_ciphers_.empty()) { | 269 if (!srtp_ciphers_.empty()) { |
275 if (!dtls_->SetDtlsSrtpCiphers(srtp_ciphers_)) { | 270 if (!dtls_->SetDtlsSrtpCiphers(srtp_ciphers_)) { |
276 LOG_J(LS_ERROR, this) << "Couldn't set DTLS-SRTP ciphers."; | 271 LOG_J(LS_ERROR, this) << "Couldn't set DTLS-SRTP ciphers."; |
277 return false; | 272 return false; |
278 } | 273 } |
279 } else { | 274 } else { |
280 LOG_J(LS_INFO, this) << "Not using DTLS."; | 275 LOG_J(LS_INFO, this) << "Not using DTLS-SRTP."; |
281 } | 276 } |
282 | 277 |
283 LOG_J(LS_INFO, this) << "DTLS setup complete."; | 278 LOG_J(LS_INFO, this) << "DTLS setup complete."; |
284 return true; | 279 return true; |
285 } | 280 } |
286 | 281 |
287 bool DtlsTransportChannelWrapper::SetSrtpCiphers( | 282 bool DtlsTransportChannelWrapper::SetSrtpCiphers( |
288 const std::vector<std::string>& ciphers) { | 283 const std::vector<std::string>& ciphers) { |
289 if (srtp_ciphers_ == ciphers) | 284 if (srtp_ciphers_ == ciphers) { |
290 return true; | 285 return true; |
| 286 } |
291 | 287 |
292 if (dtls_state_ == STATE_STARTED) { | 288 if (dtls_state() == DTLS_TRANSPORT_CONNECTING) { |
293 LOG(LS_WARNING) << "Ignoring new SRTP ciphers while DTLS is negotiating"; | 289 LOG(LS_WARNING) << "Ignoring new SRTP ciphers while DTLS is negotiating"; |
294 return true; | 290 return true; |
295 } | 291 } |
296 | 292 |
297 if (dtls_state_ == STATE_OPEN) { | 293 if (dtls_state() == DTLS_TRANSPORT_CONNECTED) { |
298 // We don't support DTLS renegotiation currently. If new set of srtp ciphers | 294 // We don't support DTLS renegotiation currently. If new set of srtp ciphers |
299 // are different than what's being used currently, we will not use it. | 295 // are different than what's being used currently, we will not use it. |
300 // So for now, let's be happy (or sad) with a warning message. | 296 // So for now, let's be happy (or sad) with a warning message. |
301 std::string current_srtp_cipher; | 297 std::string current_srtp_cipher; |
302 if (!dtls_->GetDtlsSrtpCipher(¤t_srtp_cipher)) { | 298 if (!dtls_->GetDtlsSrtpCipher(¤t_srtp_cipher)) { |
303 LOG(LS_ERROR) << "Failed to get the current SRTP cipher for DTLS channel"; | 299 LOG(LS_ERROR) << "Failed to get the current SRTP cipher for DTLS channel"; |
304 return false; | 300 return false; |
305 } | 301 } |
306 const std::vector<std::string>::const_iterator iter = | 302 const std::vector<std::string>::const_iterator iter = |
307 std::find(ciphers.begin(), ciphers.end(), current_srtp_cipher); | 303 std::find(ciphers.begin(), ciphers.end(), current_srtp_cipher); |
308 if (iter == ciphers.end()) { | 304 if (iter == ciphers.end()) { |
309 std::string requested_str; | 305 std::string requested_str; |
310 for (size_t i = 0; i < ciphers.size(); ++i) { | 306 for (size_t i = 0; i < ciphers.size(); ++i) { |
311 requested_str.append(" "); | 307 requested_str.append(" "); |
312 requested_str.append(ciphers[i]); | 308 requested_str.append(ciphers[i]); |
313 requested_str.append(" "); | 309 requested_str.append(" "); |
314 } | 310 } |
315 LOG(LS_WARNING) << "Ignoring new set of SRTP ciphers, as DTLS " | 311 LOG(LS_WARNING) << "Ignoring new set of SRTP ciphers, as DTLS " |
316 << "renegotiation is not supported currently " | 312 << "renegotiation is not supported currently " |
317 << "current cipher = " << current_srtp_cipher << " and " | 313 << "current cipher = " << current_srtp_cipher << " and " |
318 << "requested = " << "[" << requested_str << "]"; | 314 << "requested = " << "[" << requested_str << "]"; |
319 } | 315 } |
320 return true; | 316 return true; |
321 } | 317 } |
322 | 318 |
323 if (dtls_state_ != STATE_NONE && | 319 if (!VERIFY(dtls_state() == DTLS_TRANSPORT_NEW)) { |
324 dtls_state_ != STATE_OFFERED && | |
325 dtls_state_ != STATE_ACCEPTED) { | |
326 ASSERT(false); | |
327 return false; | 320 return false; |
328 } | 321 } |
329 | 322 |
330 srtp_ciphers_ = ciphers; | 323 srtp_ciphers_ = ciphers; |
331 return true; | 324 return true; |
332 } | 325 } |
333 | 326 |
334 bool DtlsTransportChannelWrapper::GetSrtpCryptoSuite(std::string* cipher) { | 327 bool DtlsTransportChannelWrapper::GetSrtpCryptoSuite(std::string* cipher) { |
335 if (dtls_state_ != STATE_OPEN) { | 328 if (dtls_state() != DTLS_TRANSPORT_CONNECTED) { |
336 return false; | 329 return false; |
337 } | 330 } |
338 | 331 |
339 return dtls_->GetDtlsSrtpCipher(cipher); | 332 return dtls_->GetDtlsSrtpCipher(cipher); |
340 } | 333 } |
341 | 334 |
342 | 335 |
343 // Called from upper layers to send a media packet. | 336 // Called from upper layers to send a media packet. |
344 int DtlsTransportChannelWrapper::SendPacket( | 337 int DtlsTransportChannelWrapper::SendPacket( |
345 const char* data, size_t size, | 338 const char* data, size_t size, |
346 const rtc::PacketOptions& options, int flags) { | 339 const rtc::PacketOptions& options, int flags) { |
347 int result = -1; | 340 if (!dtls_active_) { |
| 341 // Not doing DTLS. |
| 342 return channel_->SendPacket(data, size, options); |
| 343 } |
348 | 344 |
349 switch (dtls_state_) { | 345 switch (dtls_state()) { |
350 case STATE_OFFERED: | 346 case DTLS_TRANSPORT_NEW: |
351 // We don't know if we are doing DTLS yet, so we can't send a packet. | 347 // Can't send data until the connection is active. |
352 // TODO(ekr@rtfm.com): assert here? | 348 // TODO(ekr@rtfm.com): assert here if dtls_ is NULL? |
353 result = -1; | 349 return -1; |
354 break; | 350 case DTLS_TRANSPORT_CONNECTING: |
355 | 351 // Can't send data until the connection is active. |
356 case STATE_STARTED: | 352 return -1; |
357 case STATE_ACCEPTED: | 353 case DTLS_TRANSPORT_CONNECTED: |
358 // Can't send data until the connection is active | |
359 result = -1; | |
360 break; | |
361 | |
362 case STATE_OPEN: | |
363 if (flags & PF_SRTP_BYPASS) { | 354 if (flags & PF_SRTP_BYPASS) { |
364 ASSERT(!srtp_ciphers_.empty()); | 355 ASSERT(!srtp_ciphers_.empty()); |
365 if (!IsRtpPacket(data, size)) { | 356 if (!IsRtpPacket(data, size)) { |
366 result = -1; | 357 return -1; |
367 break; | |
368 } | 358 } |
369 | 359 |
370 result = channel_->SendPacket(data, size, options); | 360 return channel_->SendPacket(data, size, options); |
371 } else { | 361 } else { |
372 result = (dtls_->WriteAll(data, size, NULL, NULL) == | 362 return (dtls_->WriteAll(data, size, NULL, NULL) == rtc::SR_SUCCESS) |
373 rtc::SR_SUCCESS) ? static_cast<int>(size) : -1; | 363 ? static_cast<int>(size) |
| 364 : -1; |
374 } | 365 } |
375 break; | 366 case DTLS_TRANSPORT_FAILED: |
376 // Not doing DTLS. | 367 case DTLS_TRANSPORT_CLOSED: |
377 case STATE_NONE: | 368 // Can't send anything when we're closed. |
378 result = channel_->SendPacket(data, size, options); | 369 return -1; |
379 break; | 370 default: |
380 | 371 ASSERT(false); |
381 case STATE_CLOSED: // Can't send anything when we're closed. | |
382 return -1; | 372 return -1; |
383 } | 373 } |
384 | |
385 return result; | |
386 } | 374 } |
387 | 375 |
388 // The state transition logic here is as follows: | 376 // The state transition logic here is as follows: |
389 // (1) If we're not doing DTLS-SRTP, then the state is just the | 377 // (1) If we're not doing DTLS-SRTP, then the state is just the |
390 // state of the underlying impl() | 378 // state of the underlying impl() |
391 // (2) If we're doing DTLS-SRTP: | 379 // (2) If we're doing DTLS-SRTP: |
392 // - Prior to the DTLS handshake, the state is neither receiving nor | 380 // - Prior to the DTLS handshake, the state is neither receiving nor |
393 // writable | 381 // writable |
394 // - When the impl goes writable for the first time we | 382 // - When the impl goes writable for the first time we |
395 // start the DTLS handshake | 383 // start the DTLS handshake |
396 // - Once the DTLS handshake completes, the state is that of the | 384 // - Once the DTLS handshake completes, the state is that of the |
397 // impl again | 385 // impl again |
398 void DtlsTransportChannelWrapper::OnWritableState(TransportChannel* channel) { | 386 void DtlsTransportChannelWrapper::OnWritableState(TransportChannel* channel) { |
399 ASSERT(rtc::Thread::Current() == worker_thread_); | 387 ASSERT(rtc::Thread::Current() == worker_thread_); |
400 ASSERT(channel == channel_); | 388 ASSERT(channel == channel_); |
401 LOG_J(LS_VERBOSE, this) | 389 LOG_J(LS_VERBOSE, this) |
402 << "DTLSTransportChannelWrapper: channel writable state changed to " | 390 << "DTLSTransportChannelWrapper: channel writable state changed to " |
403 << channel_->writable(); | 391 << channel_->writable(); |
404 | 392 |
405 switch (dtls_state_) { | 393 if (!dtls_active_) { |
406 case STATE_NONE: | 394 // Not doing DTLS. |
407 case STATE_OPEN: | 395 // Note: SignalWritableState fired by set_writable. |
| 396 set_writable(channel_->writable()); |
| 397 return; |
| 398 } |
| 399 |
| 400 switch (dtls_state()) { |
| 401 case DTLS_TRANSPORT_NEW: |
| 402 // This should never fail: |
| 403 // Because we are operating in a nonblocking mode and all |
| 404 // incoming packets come in via OnReadPacket(), which rejects |
| 405 // packets in this state, the incoming queue must be empty. We |
| 406 // ignore write errors, thus any errors must be because of |
| 407 // configuration and therefore are our fault. |
| 408 // Note that in non-debug configurations, failure in |
| 409 // MaybeStartDtls() changes the state to DTLS_TRANSPORT_FAILED. |
| 410 VERIFY(MaybeStartDtls()); |
| 411 break; |
| 412 case DTLS_TRANSPORT_CONNECTED: |
| 413 // Note: SignalWritableState fired by set_writable. |
408 set_writable(channel_->writable()); | 414 set_writable(channel_->writable()); |
409 // Note: SignalWritableState fired by set_writable. | |
410 break; | 415 break; |
411 | 416 case DTLS_TRANSPORT_CONNECTING: |
412 case STATE_OFFERED: | 417 // Do nothing. |
413 // Do nothing | |
414 break; | 418 break; |
415 | 419 case DTLS_TRANSPORT_FAILED: |
416 case STATE_ACCEPTED: | 420 case DTLS_TRANSPORT_CLOSED: |
417 if (!MaybeStartDtls()) { | 421 // Should not happen. Do nothing. |
418 // This should never happen: | |
419 // Because we are operating in a nonblocking mode and all | |
420 // incoming packets come in via OnReadPacket(), which rejects | |
421 // packets in this state, the incoming queue must be empty. We | |
422 // ignore write errors, thus any errors must be because of | |
423 // configuration and therefore are our fault. | |
424 // Note that in non-debug configurations, failure in | |
425 // MaybeStartDtls() changes the state to STATE_CLOSED. | |
426 ASSERT(false); | |
427 } | |
428 break; | |
429 | |
430 case STATE_STARTED: | |
431 // Do nothing | |
432 break; | |
433 | |
434 case STATE_CLOSED: | |
435 // Should not happen. Do nothing | |
436 break; | 422 break; |
437 } | 423 } |
438 } | 424 } |
439 | 425 |
440 void DtlsTransportChannelWrapper::OnReceivingState(TransportChannel* channel) { | 426 void DtlsTransportChannelWrapper::OnReceivingState(TransportChannel* channel) { |
441 ASSERT(rtc::Thread::Current() == worker_thread_); | 427 ASSERT(rtc::Thread::Current() == worker_thread_); |
442 ASSERT(channel == channel_); | 428 ASSERT(channel == channel_); |
443 LOG_J(LS_VERBOSE, this) | 429 LOG_J(LS_VERBOSE, this) |
444 << "DTLSTransportChannelWrapper: channel receiving state changed to " | 430 << "DTLSTransportChannelWrapper: channel receiving state changed to " |
445 << channel_->receiving(); | 431 << channel_->receiving(); |
446 if (dtls_state_ == STATE_NONE || dtls_state_ == STATE_OPEN) { | 432 if (!dtls_active_ || dtls_state() == DTLS_TRANSPORT_CONNECTED) { |
447 // Note: SignalReceivingState fired by set_receiving. | 433 // Note: SignalReceivingState fired by set_receiving. |
448 set_receiving(channel_->receiving()); | 434 set_receiving(channel_->receiving()); |
449 } | 435 } |
450 } | 436 } |
451 | 437 |
452 void DtlsTransportChannelWrapper::OnReadPacket( | 438 void DtlsTransportChannelWrapper::OnReadPacket( |
453 TransportChannel* channel, const char* data, size_t size, | 439 TransportChannel* channel, const char* data, size_t size, |
454 const rtc::PacketTime& packet_time, int flags) { | 440 const rtc::PacketTime& packet_time, int flags) { |
455 ASSERT(rtc::Thread::Current() == worker_thread_); | 441 ASSERT(rtc::Thread::Current() == worker_thread_); |
456 ASSERT(channel == channel_); | 442 ASSERT(channel == channel_); |
457 ASSERT(flags == 0); | 443 ASSERT(flags == 0); |
458 | 444 |
459 switch (dtls_state_) { | 445 if (!dtls_active_) { |
460 case STATE_NONE: | 446 // Not doing DTLS. |
461 // We are not doing DTLS | 447 SignalReadPacket(this, data, size, packet_time, 0); |
462 SignalReadPacket(this, data, size, packet_time, 0); | 448 return; |
| 449 } |
| 450 |
| 451 switch (dtls_state()) { |
| 452 case DTLS_TRANSPORT_NEW: |
| 453 if (dtls_) { |
| 454 // Drop packets received before DTLS has actually started. |
| 455 LOG_J(LS_INFO, this) << "Dropping packet received before DTLS started."; |
| 456 } else { |
| 457 // Currently drop the packet, but we might in future |
| 458 // decide to take this as evidence that the other |
| 459 // side is ready to do DTLS and start the handshake |
| 460 // on our end. |
| 461 LOG_J(LS_WARNING, this) << "Received packet before we know if we are " |
| 462 << "doing DTLS or not; dropping."; |
| 463 } |
463 break; | 464 break; |
464 | 465 |
465 case STATE_OFFERED: | 466 case DTLS_TRANSPORT_CONNECTING: |
466 // Currently drop the packet, but we might in future | 467 case DTLS_TRANSPORT_CONNECTED: |
467 // decide to take this as evidence that the other | |
468 // side is ready to do DTLS and start the handshake | |
469 // on our end | |
470 LOG_J(LS_WARNING, this) << "Received packet before we know if we are " | |
471 << "doing DTLS or not; dropping."; | |
472 break; | |
473 | |
474 case STATE_ACCEPTED: | |
475 // Drop packets received before DTLS has actually started | |
476 LOG_J(LS_INFO, this) << "Dropping packet received before DTLS started."; | |
477 break; | |
478 | |
479 case STATE_STARTED: | |
480 case STATE_OPEN: | |
481 // We should only get DTLS or SRTP packets; STUN's already been demuxed. | 468 // We should only get DTLS or SRTP packets; STUN's already been demuxed. |
482 // Is this potentially a DTLS packet? | 469 // Is this potentially a DTLS packet? |
483 if (IsDtlsPacket(data, size)) { | 470 if (IsDtlsPacket(data, size)) { |
484 if (!HandleDtlsPacket(data, size)) { | 471 if (!HandleDtlsPacket(data, size)) { |
485 LOG_J(LS_ERROR, this) << "Failed to handle DTLS packet."; | 472 LOG_J(LS_ERROR, this) << "Failed to handle DTLS packet."; |
486 return; | 473 return; |
487 } | 474 } |
488 } else { | 475 } else { |
489 // Not a DTLS packet; our handshake should be complete by now. | 476 // Not a DTLS packet; our handshake should be complete by now. |
490 if (dtls_state_ != STATE_OPEN) { | 477 if (dtls_state() != DTLS_TRANSPORT_CONNECTED) { |
491 LOG_J(LS_ERROR, this) << "Received non-DTLS packet before DTLS " | 478 LOG_J(LS_ERROR, this) << "Received non-DTLS packet before DTLS " |
492 << "complete."; | 479 << "complete."; |
493 return; | 480 return; |
494 } | 481 } |
495 | 482 |
496 // And it had better be a SRTP packet. | 483 // And it had better be a SRTP packet. |
497 if (!IsRtpPacket(data, size)) { | 484 if (!IsRtpPacket(data, size)) { |
498 LOG_J(LS_ERROR, this) << "Received unexpected non-DTLS packet."; | 485 LOG_J(LS_ERROR, this) << "Received unexpected non-DTLS packet."; |
499 return; | 486 return; |
500 } | 487 } |
501 | 488 |
502 // Sanity check. | 489 // Sanity check. |
503 ASSERT(!srtp_ciphers_.empty()); | 490 ASSERT(!srtp_ciphers_.empty()); |
504 | 491 |
505 // Signal this upwards as a bypass packet. | 492 // Signal this upwards as a bypass packet. |
506 SignalReadPacket(this, data, size, packet_time, PF_SRTP_BYPASS); | 493 SignalReadPacket(this, data, size, packet_time, PF_SRTP_BYPASS); |
507 } | 494 } |
508 break; | 495 break; |
509 case STATE_CLOSED: | 496 case DTLS_TRANSPORT_FAILED: |
510 // This shouldn't be happening. Drop the packet | 497 case DTLS_TRANSPORT_CLOSED: |
| 498 // This shouldn't be happening. Drop the packet. |
511 break; | 499 break; |
512 } | 500 } |
513 } | 501 } |
514 | 502 |
515 void DtlsTransportChannelWrapper::OnSentPacket( | 503 void DtlsTransportChannelWrapper::OnSentPacket( |
516 TransportChannel* channel, | 504 TransportChannel* channel, |
517 const rtc::SentPacket& sent_packet) { | 505 const rtc::SentPacket& sent_packet) { |
518 ASSERT(rtc::Thread::Current() == worker_thread_); | 506 ASSERT(rtc::Thread::Current() == worker_thread_); |
519 | 507 |
520 SignalSentPacket(this, sent_packet); | 508 SignalSentPacket(this, sent_packet); |
521 } | 509 } |
522 | 510 |
523 void DtlsTransportChannelWrapper::OnReadyToSend(TransportChannel* channel) { | 511 void DtlsTransportChannelWrapper::OnReadyToSend(TransportChannel* channel) { |
524 if (writable()) { | 512 if (writable()) { |
525 SignalReadyToSend(this); | 513 SignalReadyToSend(this); |
526 } | 514 } |
527 } | 515 } |
528 | 516 |
529 void DtlsTransportChannelWrapper::OnDtlsEvent(rtc::StreamInterface* dtls, | 517 void DtlsTransportChannelWrapper::OnDtlsEvent(rtc::StreamInterface* dtls, |
530 int sig, int err) { | 518 int sig, int err) { |
531 ASSERT(rtc::Thread::Current() == worker_thread_); | 519 ASSERT(rtc::Thread::Current() == worker_thread_); |
532 ASSERT(dtls == dtls_.get()); | 520 ASSERT(dtls == dtls_.get()); |
533 if (sig & rtc::SE_OPEN) { | 521 if (sig & rtc::SE_OPEN) { |
534 // This is the first time. | 522 // This is the first time. |
535 LOG_J(LS_INFO, this) << "DTLS handshake complete."; | 523 LOG_J(LS_INFO, this) << "DTLS handshake complete."; |
536 if (dtls_->GetState() == rtc::SS_OPEN) { | 524 if (dtls_->GetState() == rtc::SS_OPEN) { |
537 // The check for OPEN shouldn't be necessary but let's make | 525 // The check for OPEN shouldn't be necessary but let's make |
538 // sure we don't accidentally frob the state if it's closed. | 526 // sure we don't accidentally frob the state if it's closed. |
539 dtls_state_ = STATE_OPEN; | 527 set_dtls_state(DTLS_TRANSPORT_CONNECTED); |
540 set_writable(true); | 528 set_writable(true); |
541 } | 529 } |
542 } | 530 } |
543 if (sig & rtc::SE_READ) { | 531 if (sig & rtc::SE_READ) { |
544 char buf[kMaxDtlsPacketLen]; | 532 char buf[kMaxDtlsPacketLen]; |
545 size_t read; | 533 size_t read; |
546 if (dtls_->Read(buf, sizeof(buf), &read, NULL) == rtc::SR_SUCCESS) { | 534 if (dtls_->Read(buf, sizeof(buf), &read, NULL) == rtc::SR_SUCCESS) { |
547 SignalReadPacket(this, buf, read, rtc::CreatePacketTime(0), 0); | 535 SignalReadPacket(this, buf, read, rtc::CreatePacketTime(0), 0); |
548 } | 536 } |
549 } | 537 } |
550 if (sig & rtc::SE_CLOSE) { | 538 if (sig & rtc::SE_CLOSE) { |
551 ASSERT(sig == rtc::SE_CLOSE); // SE_CLOSE should be by itself. | 539 ASSERT(sig == rtc::SE_CLOSE); // SE_CLOSE should be by itself. |
| 540 set_writable(false); |
552 if (!err) { | 541 if (!err) { |
553 LOG_J(LS_INFO, this) << "DTLS channel closed"; | 542 LOG_J(LS_INFO, this) << "DTLS channel closed"; |
| 543 set_dtls_state(DTLS_TRANSPORT_CLOSED); |
554 } else { | 544 } else { |
555 LOG_J(LS_INFO, this) << "DTLS channel error, code=" << err; | 545 LOG_J(LS_INFO, this) << "DTLS channel error, code=" << err; |
| 546 set_dtls_state(DTLS_TRANSPORT_FAILED); |
556 } | 547 } |
557 set_writable(false); | |
558 dtls_state_ = STATE_CLOSED; | |
559 } | 548 } |
560 } | 549 } |
561 | 550 |
562 bool DtlsTransportChannelWrapper::MaybeStartDtls() { | 551 bool DtlsTransportChannelWrapper::MaybeStartDtls() { |
563 if (channel_->writable()) { | 552 if (dtls_ && channel_->writable()) { |
564 if (dtls_->StartSSLWithPeer()) { | 553 if (dtls_->StartSSLWithPeer()) { |
565 LOG_J(LS_ERROR, this) << "Couldn't start DTLS handshake"; | 554 LOG_J(LS_ERROR, this) << "Couldn't start DTLS handshake"; |
566 dtls_state_ = STATE_CLOSED; | 555 set_dtls_state(DTLS_TRANSPORT_FAILED); |
567 return false; | 556 return false; |
568 } | 557 } |
569 LOG_J(LS_INFO, this) | 558 LOG_J(LS_INFO, this) |
570 << "DtlsTransportChannelWrapper: Started DTLS handshake"; | 559 << "DtlsTransportChannelWrapper: Started DTLS handshake"; |
571 | 560 set_dtls_state(DTLS_TRANSPORT_CONNECTING); |
572 dtls_state_ = STATE_STARTED; | |
573 } | 561 } |
574 return true; | 562 return true; |
575 } | 563 } |
576 | 564 |
577 // Called from OnReadPacket when a DTLS packet is received. | 565 // Called from OnReadPacket when a DTLS packet is received. |
578 bool DtlsTransportChannelWrapper::HandleDtlsPacket(const char* data, | 566 bool DtlsTransportChannelWrapper::HandleDtlsPacket(const char* data, |
579 size_t size) { | 567 size_t size) { |
580 // Sanity check we're not passing junk that | 568 // Sanity check we're not passing junk that |
581 // just looks like DTLS. | 569 // just looks like DTLS. |
582 const uint8_t* tmp_data = reinterpret_cast<const uint8_t*>(data); | 570 const uint8_t* tmp_data = reinterpret_cast<const uint8_t*>(data); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
623 SignalRouteChange(this, candidate); | 611 SignalRouteChange(this, candidate); |
624 } | 612 } |
625 | 613 |
626 void DtlsTransportChannelWrapper::OnConnectionRemoved( | 614 void DtlsTransportChannelWrapper::OnConnectionRemoved( |
627 TransportChannelImpl* channel) { | 615 TransportChannelImpl* channel) { |
628 ASSERT(channel == channel_); | 616 ASSERT(channel == channel_); |
629 SignalConnectionRemoved(this); | 617 SignalConnectionRemoved(this); |
630 } | 618 } |
631 | 619 |
632 } // namespace cricket | 620 } // namespace cricket |
OLD | NEW |