Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(9)

Side by Side Diff: webrtc/p2p/base/dtlstransportchannel.cc

Issue 1414363002: Exposing DTLS transport state from TransportChannel. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Fixing Windows compiler warning. Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « webrtc/p2p/base/dtlstransportchannel.h ('k') | webrtc/p2p/base/transport.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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(&current_srtp_cipher)) { 298 if (!dtls_->GetDtlsSrtpCipher(&current_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
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
OLDNEW
« no previous file with comments | « webrtc/p2p/base/dtlstransportchannel.h ('k') | webrtc/p2p/base/transport.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698