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

Side by Side Diff: webrtc/base/openssladapter.cc

Issue 2915243002: Fixing SSL error that occurs when underlying socket is blocked. (Closed)
Patch Set: Send an additional message while socket is blocked. Created 3 years, 6 months 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/base/openssladapter.h ('k') | webrtc/base/ssladapter_unittest.cc » ('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 2008 The WebRTC Project Authors. All rights reserved. 2 * Copyright 2008 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 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
147 case BIO_CTRL_WPENDING: 147 case BIO_CTRL_WPENDING:
148 case BIO_CTRL_PENDING: 148 case BIO_CTRL_PENDING:
149 return 0; 149 return 0;
150 case BIO_CTRL_FLUSH: 150 case BIO_CTRL_FLUSH:
151 return 1; 151 return 1;
152 default: 152 default:
153 return 0; 153 return 0;
154 } 154 }
155 } 155 }
156 156
157 static void LogSslError() {
158 // Walk down the error stack to find the SSL error.
159 uint32_t error_code;
160 const char* file;
161 int line;
162 do {
163 error_code = ERR_get_error_line(&file, &line);
164 if (ERR_GET_LIB(error_code) == ERR_LIB_SSL) {
165 LOG(LS_ERROR) << "ERR_LIB_SSL: " << error_code << ", " << file << ":"
166 << line;
167 break;
168 }
169 } while (error_code != 0);
170 }
171
157 ///////////////////////////////////////////////////////////////////////////// 172 /////////////////////////////////////////////////////////////////////////////
158 // OpenSSLAdapter 173 // OpenSSLAdapter
159 ///////////////////////////////////////////////////////////////////////////// 174 /////////////////////////////////////////////////////////////////////////////
160 175
161 namespace rtc { 176 namespace rtc {
162 177
163 #ifndef OPENSSL_IS_BORINGSSL 178 #ifndef OPENSSL_IS_BORINGSSL
164 179
165 // This array will store all of the mutexes available to OpenSSL. 180 // This array will store all of the mutexes available to OpenSSL.
166 static MUTEX_TYPE* mutex_buf = nullptr; 181 static MUTEX_TYPE* mutex_buf = nullptr;
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
327 342
328 ssl_ = SSL_new(ssl_ctx_); 343 ssl_ = SSL_new(ssl_ctx_);
329 if (!ssl_) { 344 if (!ssl_) {
330 err = -1; 345 err = -1;
331 goto ssl_error; 346 goto ssl_error;
332 } 347 }
333 348
334 SSL_set_app_data(ssl_, this); 349 SSL_set_app_data(ssl_, this);
335 350
336 SSL_set_bio(ssl_, bio, bio); 351 SSL_set_bio(ssl_, bio, bio);
352 // SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER allows different buffers to be passed
353 // into SSL_write when a record could only be partially transmitted (and thus
354 // requires another call to SSL_write to finish transmission). This allows us
355 // to copy the data into our own buffer when this occurs, since the original
356 // buffer can't safely be accessed after control exits Send.
357 // TODO(deadbeef): Do we want SSL_MODE_ENABLE_PARTIAL_WRITE? It doesn't
358 // appear Send handles partial writes properly, though maybe we never notice
359 // since we never send more than 16KB at once..
337 SSL_set_mode(ssl_, SSL_MODE_ENABLE_PARTIAL_WRITE | 360 SSL_set_mode(ssl_, SSL_MODE_ENABLE_PARTIAL_WRITE |
338 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); 361 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
339 362
340 // the SSL object owns the bio now 363 // the SSL object owns the bio now
341 bio = nullptr; 364 bio = nullptr;
342 365
343 // Do the connect 366 // Do the connect
344 err = ContinueSSL(); 367 err = ContinueSSL();
345 if (err != 0) 368 if (err != 0)
346 goto ssl_error; 369 goto ssl_error;
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
419 } 442 }
420 443
421 void 444 void
422 OpenSSLAdapter::Cleanup() { 445 OpenSSLAdapter::Cleanup() {
423 LOG(LS_INFO) << "Cleanup"; 446 LOG(LS_INFO) << "Cleanup";
424 447
425 state_ = SSL_NONE; 448 state_ = SSL_NONE;
426 ssl_read_needs_write_ = false; 449 ssl_read_needs_write_ = false;
427 ssl_write_needs_read_ = false; 450 ssl_write_needs_read_ = false;
428 custom_verification_succeeded_ = false; 451 custom_verification_succeeded_ = false;
452 pending_data_.Clear();
429 453
430 if (ssl_) { 454 if (ssl_) {
431 SSL_free(ssl_); 455 SSL_free(ssl_);
432 ssl_ = nullptr; 456 ssl_ = nullptr;
433 } 457 }
434 458
435 if (ssl_ctx_) { 459 if (ssl_ctx_) {
436 SSL_CTX_free(ssl_ctx_); 460 SSL_CTX_free(ssl_ctx_);
437 ssl_ctx_ = nullptr; 461 ssl_ctx_ = nullptr;
438 } 462 }
439 463
440 // Clear the DTLS timer 464 // Clear the DTLS timer
441 Thread::Current()->Clear(this, MSG_TIMEOUT); 465 Thread::Current()->Clear(this, MSG_TIMEOUT);
442 } 466 }
443 467
468 int OpenSSLAdapter::DoSslWrite(const void* pv, size_t cb, int* error) {
469 // If we have pending data (that was previously only partially written by
470 // SSL_write), we shouldn't be attempting to write anything else.
471 RTC_DCHECK(pending_data_.empty() || pv == pending_data_.data());
472 RTC_DCHECK(error != nullptr);
473
474 ssl_write_needs_read_ = false;
475 int ret = SSL_write(ssl_, pv, checked_cast<int>(cb));
476 *error = SSL_get_error(ssl_, ret);
477 switch (*error) {
478 case SSL_ERROR_NONE:
479 // Success!
480 return ret;
481 case SSL_ERROR_WANT_READ:
482 LOG(LS_INFO) << " -- error want read";
483 ssl_write_needs_read_ = true;
484 SetError(EWOULDBLOCK);
485 break;
486 case SSL_ERROR_WANT_WRITE:
487 LOG(LS_INFO) << " -- error want write";
488 SetError(EWOULDBLOCK);
489 break;
490 case SSL_ERROR_ZERO_RETURN:
491 // LOG(LS_INFO) << " -- remote side closed";
492 SetError(EWOULDBLOCK);
493 // do we need to signal closure?
494 break;
495 case SSL_ERROR_SSL:
496 LogSslError();
497 Error("SSL_write", ret ? ret : -1, false);
498 break;
499 default:
500 LOG(LS_WARNING) << "Unknown error from SSL_write: " << *error;
501 Error("SSL_write", ret ? ret : -1, false);
502 break;
503 }
504
505 return SOCKET_ERROR;
506 }
507
444 // 508 //
445 // AsyncSocket Implementation 509 // AsyncSocket Implementation
446 // 510 //
447 511
448 int 512 int
449 OpenSSLAdapter::Send(const void* pv, size_t cb) { 513 OpenSSLAdapter::Send(const void* pv, size_t cb) {
450 //LOG(LS_INFO) << "OpenSSLAdapter::Send(" << cb << ")"; 514 //LOG(LS_INFO) << "OpenSSLAdapter::Send(" << cb << ")";
451 515
452 switch (state_) { 516 switch (state_) {
453 case SSL_NONE: 517 case SSL_NONE:
454 return AsyncSocketAdapter::Send(pv, cb); 518 return AsyncSocketAdapter::Send(pv, cb);
455 519
456 case SSL_WAIT: 520 case SSL_WAIT:
457 case SSL_CONNECTING: 521 case SSL_CONNECTING:
458 SetError(ENOTCONN); 522 SetError(ENOTCONN);
459 return SOCKET_ERROR; 523 return SOCKET_ERROR;
460 524
461 case SSL_CONNECTED: 525 case SSL_CONNECTED:
462 break; 526 break;
463 527
464 case SSL_ERROR: 528 case SSL_ERROR:
465 default: 529 default:
466 return SOCKET_ERROR; 530 return SOCKET_ERROR;
467 } 531 }
468 532
533 int ret;
534 int error;
535
536 if (!pending_data_.empty()) {
537 ret = DoSslWrite(pending_data_.data(), pending_data_.size(), &error);
538 if (ret != static_cast<int>(pending_data_.size())) {
539 // We couldn't finish sending the pending data, so we definitely can't
540 // send any more data. Return with an EWOULDBLOCK error.
541 SetError(EWOULDBLOCK);
542 return SOCKET_ERROR;
543 }
544 // We completed sending the data previously passed into SSL_write! Now
545 // we're allowed to send more data.
546 pending_data_.Clear();
547 }
548
469 // OpenSSL will return an error if we try to write zero bytes 549 // OpenSSL will return an error if we try to write zero bytes
470 if (cb == 0) 550 if (cb == 0)
471 return 0; 551 return 0;
472 552
473 ssl_write_needs_read_ = false; 553 ret = DoSslWrite(pv, cb, &error);
474 554
475 int code = SSL_write(ssl_, pv, checked_cast<int>(cb)); 555 // If SSL_write fails with SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE, this
476 switch (SSL_get_error(ssl_, code)) { 556 // means the underlying socket is blocked on reading or (more typically)
477 case SSL_ERROR_NONE: 557 // writing. When this happens, OpenSSL requires that the next call to
478 //LOG(LS_INFO) << " -- success"; 558 // SSL_write uses the same arguments (though, with
479 return code; 559 // SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER, the actual buffer pointer may be
480 case SSL_ERROR_WANT_READ: 560 // different).
481 //LOG(LS_INFO) << " -- error want read"; 561 //
482 ssl_write_needs_read_ = true; 562 // However, after Send exits, we will have lost access to data the user of
483 SetError(EWOULDBLOCK); 563 // this class is trying to send, and there's no guarantee that the user of
484 break; 564 // this class will call Send with the same arguements when it fails. So, we
485 case SSL_ERROR_WANT_WRITE: 565 // buffer the data ourselves. When we know the underlying socket is writable
486 //LOG(LS_INFO) << " -- error want write"; 566 // again from OnWriteEvent (or if Send is called again before that happens),
487 SetError(EWOULDBLOCK); 567 // we'll retry sending this buffered data.
488 break; 568 if ((error == SSL_ERROR_WANT_READ || error == SSL_ERROR_WANT_WRITE) &&
489 case SSL_ERROR_ZERO_RETURN: 569 pending_data_.empty()) {
juberti1 2017/06/02 17:47:22 Is it possible for pending_data_ to *not* be empty
Taylor Brandstetter 2017/06/02 18:18:42 Oh, it isn't possible now that this code was shuff
490 //LOG(LS_INFO) << " -- remote side closed"; 570 LOG(LS_WARNING)
491 SetError(EWOULDBLOCK); 571 << "SSL_write couldn't write to the underlying socket; buffering data.";
492 // do we need to signal closure? 572 pending_data_.SetData(static_cast<const uint8_t*>(pv), cb);
493 break; 573 // Since we're taking responsibility for sending this data, return its full
494 default: 574 // size. The user of this class can consider it sent.
495 //LOG(LS_INFO) << " -- error " << code; 575 return cb;
496 Error("SSL_write", (code ? code : -1), false);
497 break;
498 } 576 }
499 577
500 return SOCKET_ERROR; 578 return ret;
501 } 579 }
502 580
503 int 581 int
504 OpenSSLAdapter::SendTo(const void* pv, size_t cb, const SocketAddress& addr) { 582 OpenSSLAdapter::SendTo(const void* pv, size_t cb, const SocketAddress& addr) {
505 if (socket_->GetState() == Socket::CS_CONNECTED && 583 if (socket_->GetState() == Socket::CS_CONNECTED &&
506 addr == socket_->GetRemoteAddress()) { 584 addr == socket_->GetRemoteAddress()) {
507 return Send(pv, cb); 585 return Send(pv, cb);
508 } 586 }
509 587
510 SetError(ENOTCONN); 588 SetError(ENOTCONN);
(...skipping 21 matching lines...) Expand all
532 return SOCKET_ERROR; 610 return SOCKET_ERROR;
533 } 611 }
534 612
535 // Don't trust OpenSSL with zero byte reads 613 // Don't trust OpenSSL with zero byte reads
536 if (cb == 0) 614 if (cb == 0)
537 return 0; 615 return 0;
538 616
539 ssl_read_needs_write_ = false; 617 ssl_read_needs_write_ = false;
540 618
541 int code = SSL_read(ssl_, pv, checked_cast<int>(cb)); 619 int code = SSL_read(ssl_, pv, checked_cast<int>(cb));
542 switch (SSL_get_error(ssl_, code)) { 620 int error = SSL_get_error(ssl_, code);
543 case SSL_ERROR_NONE: 621 switch (error) {
544 //LOG(LS_INFO) << " -- success"; 622 case SSL_ERROR_NONE:
545 return code; 623 // LOG(LS_INFO) << " -- success";
546 case SSL_ERROR_WANT_READ: 624 return code;
547 //LOG(LS_INFO) << " -- error want read"; 625 case SSL_ERROR_WANT_READ:
548 SetError(EWOULDBLOCK); 626 // LOG(LS_INFO) << " -- error want read";
549 break; 627 SetError(EWOULDBLOCK);
550 case SSL_ERROR_WANT_WRITE: 628 break;
551 //LOG(LS_INFO) << " -- error want write"; 629 case SSL_ERROR_WANT_WRITE:
552 ssl_read_needs_write_ = true; 630 // LOG(LS_INFO) << " -- error want write";
553 SetError(EWOULDBLOCK); 631 ssl_read_needs_write_ = true;
554 break; 632 SetError(EWOULDBLOCK);
555 case SSL_ERROR_ZERO_RETURN: 633 break;
556 //LOG(LS_INFO) << " -- remote side closed"; 634 case SSL_ERROR_ZERO_RETURN:
557 SetError(EWOULDBLOCK); 635 // LOG(LS_INFO) << " -- remote side closed";
558 // do we need to signal closure? 636 SetError(EWOULDBLOCK);
559 break; 637 // do we need to signal closure?
560 default: 638 break;
561 //LOG(LS_INFO) << " -- error " << code; 639 case SSL_ERROR_SSL:
562 Error("SSL_read", (code ? code : -1), false); 640 LogSslError();
563 break; 641 Error("SSL_read", (code ? code : -1), false);
642 break;
643 default:
644 LOG(LS_WARNING) << "Unknown error from SSL_read: " << error;
645 Error("SSL_read", (code ? code : -1), false);
646 break;
564 } 647 }
565 648
566 return SOCKET_ERROR; 649 return SOCKET_ERROR;
567 } 650 }
568 651
569 int OpenSSLAdapter::RecvFrom(void* pv, 652 int OpenSSLAdapter::RecvFrom(void* pv,
570 size_t cb, 653 size_t cb,
571 SocketAddress* paddr, 654 SocketAddress* paddr,
572 int64_t* timestamp) { 655 int64_t* timestamp) {
573 if (socket_->GetState() == Socket::CS_CONNECTED) { 656 if (socket_->GetState() == Socket::CS_CONNECTED) {
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
675 return; 758 return;
676 759
677 // Don't let ourselves go away during the callbacks 760 // Don't let ourselves go away during the callbacks
678 //PRefPtr<OpenSSLAdapter> lock(this); // TODO: fix this 761 //PRefPtr<OpenSSLAdapter> lock(this); // TODO: fix this
679 762
680 if (ssl_read_needs_write_) { 763 if (ssl_read_needs_write_) {
681 //LOG(LS_INFO) << " -- onStreamReadable"; 764 //LOG(LS_INFO) << " -- onStreamReadable";
682 AsyncSocketAdapter::OnReadEvent(socket); 765 AsyncSocketAdapter::OnReadEvent(socket);
683 } 766 }
684 767
768 // If a previous SSL_write failed due to the underlying socket being blocked,
769 // this will attempt finishing the write operation.
770 if (!pending_data_.empty()) {
771 int error;
772 if (DoSslWrite(pending_data_.data(), pending_data_.size(), &error) ==
773 static_cast<int>(pending_data_.size())) {
774 pending_data_.Clear();
775 }
776 }
777
685 //LOG(LS_INFO) << " -- onStreamWriteable"; 778 //LOG(LS_INFO) << " -- onStreamWriteable";
686 AsyncSocketAdapter::OnWriteEvent(socket); 779 AsyncSocketAdapter::OnWriteEvent(socket);
687 } 780 }
688 781
689 void 782 void
690 OpenSSLAdapter::OnCloseEvent(AsyncSocket* socket, int err) { 783 OpenSSLAdapter::OnCloseEvent(AsyncSocket* socket, int err) {
691 LOG(LS_INFO) << "OpenSSLAdapter::OnCloseEvent(" << err << ")"; 784 LOG(LS_INFO) << "OpenSSLAdapter::OnCloseEvent(" << err << ")";
692 AsyncSocketAdapter::OnCloseEvent(socket, err); 785 AsyncSocketAdapter::OnCloseEvent(socket, err);
693 } 786 }
694 787
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
906 SSL_CTX_set_cipher_list(ctx, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH"); 999 SSL_CTX_set_cipher_list(ctx, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
907 1000
908 if (ssl_mode_ == SSL_MODE_DTLS) { 1001 if (ssl_mode_ == SSL_MODE_DTLS) {
909 SSL_CTX_set_read_ahead(ctx, 1); 1002 SSL_CTX_set_read_ahead(ctx, 1);
910 } 1003 }
911 1004
912 return ctx; 1005 return ctx;
913 } 1006 }
914 1007
915 } // namespace rtc 1008 } // namespace rtc
OLDNEW
« no previous file with comments | « webrtc/base/openssladapter.h ('k') | webrtc/base/ssladapter_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698