 Chromium Code Reviews
 Chromium Code Reviews Issue 2915243002:
  Fixing SSL error that occurs when underlying socket is blocked.  (Closed)
    
  
    Issue 2915243002:
  Fixing SSL error that occurs when underlying socket is blocked.  (Closed) 
  | OLD | NEW | 
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 | 
| OLD | NEW |