Chromium Code Reviews| 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 316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 327 | 327 |
| 328 ssl_ = SSL_new(ssl_ctx_); | 328 ssl_ = SSL_new(ssl_ctx_); |
| 329 if (!ssl_) { | 329 if (!ssl_) { |
| 330 err = -1; | 330 err = -1; |
| 331 goto ssl_error; | 331 goto ssl_error; |
| 332 } | 332 } |
| 333 | 333 |
| 334 SSL_set_app_data(ssl_, this); | 334 SSL_set_app_data(ssl_, this); |
| 335 | 335 |
| 336 SSL_set_bio(ssl_, bio, bio); | 336 SSL_set_bio(ssl_, bio, bio); |
| 337 // SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER allows different buffers to be passed | |
| 338 // into SSL_write when a record could only be partially transmitted (and thus | |
| 339 // requires another call to SSL_write to finish transmission). This allows us | |
| 340 // to copy the data into our own buffer when this occurs, since the original | |
| 341 // buffer can't safely be accessed after control exits Send. | |
| 337 SSL_set_mode(ssl_, SSL_MODE_ENABLE_PARTIAL_WRITE | | 342 SSL_set_mode(ssl_, SSL_MODE_ENABLE_PARTIAL_WRITE | |
| 338 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); | 343 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); |
|
juberti1
2017/06/02 05:35:44
From the chat with davidben, I'm not sure we want
Taylor Brandstetter
2017/06/02 06:49:13
Probably. But it's unrelated to this CL so I'll le
| |
| 339 | 344 |
| 340 // the SSL object owns the bio now | 345 // the SSL object owns the bio now |
| 341 bio = nullptr; | 346 bio = nullptr; |
| 342 | 347 |
| 343 // Do the connect | 348 // Do the connect |
| 344 err = ContinueSSL(); | 349 err = ContinueSSL(); |
| 345 if (err != 0) | 350 if (err != 0) |
| 346 goto ssl_error; | 351 goto ssl_error; |
| 347 | 352 |
| 348 return err; | 353 return err; |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 417 if (signal) | 422 if (signal) |
| 418 AsyncSocketAdapter::OnCloseEvent(this, err); | 423 AsyncSocketAdapter::OnCloseEvent(this, err); |
| 419 } | 424 } |
| 420 | 425 |
| 421 void | 426 void |
| 422 OpenSSLAdapter::Cleanup() { | 427 OpenSSLAdapter::Cleanup() { |
| 423 LOG(LS_INFO) << "Cleanup"; | 428 LOG(LS_INFO) << "Cleanup"; |
| 424 | 429 |
| 425 state_ = SSL_NONE; | 430 state_ = SSL_NONE; |
| 426 ssl_read_needs_write_ = false; | 431 ssl_read_needs_write_ = false; |
| 427 ssl_write_needs_read_ = false; | 432 ssl_write_needs_read_ = false; |
|
pthatcher1
2017/06/02 04:58:21
Should this also clear pending_write_ and pending_
Taylor Brandstetter
2017/06/02 06:49:13
I'll do it for consistency, but I don't see a way
| |
| 428 custom_verification_succeeded_ = false; | 433 custom_verification_succeeded_ = false; |
| 429 | 434 |
| 430 if (ssl_) { | 435 if (ssl_) { |
| 431 SSL_free(ssl_); | 436 SSL_free(ssl_); |
| 432 ssl_ = nullptr; | 437 ssl_ = nullptr; |
| 433 } | 438 } |
| 434 | 439 |
| 435 if (ssl_ctx_) { | 440 if (ssl_ctx_) { |
| 436 SSL_CTX_free(ssl_ctx_); | 441 SSL_CTX_free(ssl_ctx_); |
| 437 ssl_ctx_ = nullptr; | 442 ssl_ctx_ = nullptr; |
| 438 } | 443 } |
| 439 | 444 |
| 440 // Clear the DTLS timer | 445 // Clear the DTLS timer |
| 441 Thread::Current()->Clear(this, MSG_TIMEOUT); | 446 Thread::Current()->Clear(this, MSG_TIMEOUT); |
| 442 } | 447 } |
| 443 | 448 |
| 449 int OpenSSLAdapter::DoSslWrite(const void* pv, size_t cb) { | |
| 450 // If we're in "pending write" mode, we should only be calling SSL_write with | |
| 451 // the pending data. | |
| 452 RTC_DCHECK(!pending_write_ || pv == pending_data_.data()); | |
| 453 | |
| 454 ssl_write_needs_read_ = false; | |
| 455 int ret = SSL_write(ssl_, pv, checked_cast<int>(cb)); | |
| 456 int error = SSL_get_error(ssl_, ret); | |
| 457 switch (error) { | |
| 458 case SSL_ERROR_SSL: | |
| 459 // Walk down the error stack to find the SSL error. | |
| 460 uint32_t error_code; | |
|
juberti1
2017/06/02 05:35:44
This feels like it should be factored into a funct
Taylor Brandstetter
2017/06/02 06:49:13
Done.
| |
| 461 const char* file; | |
| 462 int line; | |
| 463 do { | |
| 464 error_code = ERR_get_error_line(&file, &line); | |
| 465 if (ERR_GET_LIB(error_code) == ERR_LIB_SSL) { | |
| 466 LOG(LS_ERROR) << "ERR_LIB_SSL: " << error_code << ", " << file << ":" | |
| 467 << line; | |
| 468 break; | |
| 469 } | |
| 470 } while (error_code != 0); | |
| 471 Error("SSL_write", ret ? ret : -1, false); | |
| 472 break; | |
| 473 case SSL_ERROR_NONE: | |
| 474 // Success! | |
|
juberti1
2017/06/02 05:35:44
Maybe this case should come first?
Taylor Brandstetter
2017/06/02 06:49:13
Done.
| |
| 475 return ret; | |
| 476 case SSL_ERROR_WANT_READ: | |
| 477 LOG(LS_INFO) << " -- error want read"; | |
| 478 ssl_write_needs_read_ = true; | |
| 479 SetError(EWOULDBLOCK); | |
| 480 break; | |
| 481 case SSL_ERROR_WANT_WRITE: | |
| 482 LOG(LS_INFO) << " -- error want write"; | |
| 483 SetError(EWOULDBLOCK); | |
| 484 break; | |
| 485 case SSL_ERROR_ZERO_RETURN: | |
| 486 // LOG(LS_INFO) << " -- remote side closed"; | |
| 487 SetError(EWOULDBLOCK); | |
| 488 // do we need to signal closure? | |
| 489 break; | |
| 490 default: | |
| 491 LOG(LS_WARNING) << "Unknown error from SSL_write: " << error; | |
| 492 Error("SSL_write", ret ? ret : -1, false); | |
| 493 break; | |
| 494 } | |
| 495 | |
| 496 // If SSL_write fails with SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE, this | |
| 497 // means the underlying socket is blocked on reading or (more typically) | |
| 498 // writing. When this happens, OpenSSL requires that the next call to | |
| 499 // SSL_write uses the same arguments (though, with | |
| 500 // SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER, the actual buffer pointer may be | |
| 501 // different). | |
| 502 // | |
| 503 // However, after Send exits, we will have lost access to data the user of | |
| 504 // this class is trying to send, and there's no guarantee that the user of | |
| 505 // this class will call Send with the same arguements when it fails. So, we | |
| 506 // buffer the data ourselves. When we know the underlying socket is writable | |
| 507 // again from OnWriteEvent (or if Send is called again before that happens), | |
| 508 // we'll retry sending this buffered data. | |
| 509 if ((error == SSL_ERROR_WANT_READ || error == SSL_ERROR_WANT_WRITE) && | |
|
juberti1
2017/06/02 05:35:43
It seems like this should be a low-level routine -
Taylor Brandstetter
2017/06/02 06:49:13
Ok. Somehow the fact that the write failed due to
| |
| 510 !pending_write_) { | |
| 511 LOG(LS_WARNING) | |
| 512 << "SSL_write couldn't write to the underlying socket; buffering data."; | |
| 513 pending_write_ = true; | |
| 514 pending_data_.SetData(static_cast<const uint8_t*>(pv), cb); | |
| 515 // Since we're taking responsibility for sending this data, return its full | |
| 516 // size. The user of this class can consider it sent. | |
| 517 return cb; | |
| 518 } | |
| 519 | |
| 520 return SOCKET_ERROR; | |
| 521 } | |
| 522 | |
| 444 // | 523 // |
| 445 // AsyncSocket Implementation | 524 // AsyncSocket Implementation |
| 446 // | 525 // |
| 447 | 526 |
| 448 int | 527 int |
| 449 OpenSSLAdapter::Send(const void* pv, size_t cb) { | 528 OpenSSLAdapter::Send(const void* pv, size_t cb) { |
| 450 //LOG(LS_INFO) << "OpenSSLAdapter::Send(" << cb << ")"; | 529 //LOG(LS_INFO) << "OpenSSLAdapter::Send(" << cb << ")"; |
| 451 | 530 |
| 452 switch (state_) { | 531 switch (state_) { |
| 453 case SSL_NONE: | 532 case SSL_NONE: |
| 454 return AsyncSocketAdapter::Send(pv, cb); | 533 return AsyncSocketAdapter::Send(pv, cb); |
| 455 | 534 |
| 456 case SSL_WAIT: | 535 case SSL_WAIT: |
| 457 case SSL_CONNECTING: | 536 case SSL_CONNECTING: |
| 458 SetError(ENOTCONN); | 537 SetError(ENOTCONN); |
| 459 return SOCKET_ERROR; | 538 return SOCKET_ERROR; |
| 460 | 539 |
| 461 case SSL_CONNECTED: | 540 case SSL_CONNECTED: |
| 462 break; | 541 break; |
| 463 | 542 |
| 464 case SSL_ERROR: | 543 case SSL_ERROR: |
| 465 default: | 544 default: |
| 466 return SOCKET_ERROR; | 545 return SOCKET_ERROR; |
| 467 } | 546 } |
| 468 | 547 |
| 548 if (pending_write_) { | |
| 549 int ret = DoSslWrite(pending_data_.data(), pending_data_.size()); | |
| 550 if (ret == static_cast<int>(pending_data_.size())) { | |
| 551 // We completed sending the data previously passed into SSL_write! Now | |
| 552 // we're allowed to send more data. | |
| 553 pending_write_ = false; | |
| 554 } else { | |
| 555 // We couldn't finish sending the pending data, so we definitely can't | |
| 556 // send any more data. Return with an EWOULDBLOCK error. | |
| 557 SetError(EWOULDBLOCK); | |
| 558 return -1; | |
|
pthatcher1
2017/06/02 04:58:21
return SOCKET_ERROR
or just:
return ret;
Taylor Brandstetter
2017/06/02 06:49:13
Done.
| |
| 559 } | |
|
pthatcher1
2017/06/02 04:58:21
Might be more clear with an early return:
if (pen
Taylor Brandstetter
2017/06/02 06:49:13
I don't like "MaybeRetrySslWrite" because it's not
| |
| 560 } | |
| 561 | |
| 469 // OpenSSL will return an error if we try to write zero bytes | 562 // OpenSSL will return an error if we try to write zero bytes |
| 470 if (cb == 0) | 563 if (cb == 0) |
| 471 return 0; | 564 return 0; |
| 472 | 565 |
| 473 ssl_write_needs_read_ = false; | 566 return DoSslWrite(pv, cb); |
| 474 | |
| 475 int code = SSL_write(ssl_, pv, checked_cast<int>(cb)); | |
| 476 switch (SSL_get_error(ssl_, code)) { | |
| 477 case SSL_ERROR_NONE: | |
| 478 //LOG(LS_INFO) << " -- success"; | |
| 479 return code; | |
| 480 case SSL_ERROR_WANT_READ: | |
| 481 //LOG(LS_INFO) << " -- error want read"; | |
| 482 ssl_write_needs_read_ = true; | |
| 483 SetError(EWOULDBLOCK); | |
| 484 break; | |
| 485 case SSL_ERROR_WANT_WRITE: | |
| 486 //LOG(LS_INFO) << " -- error want write"; | |
| 487 SetError(EWOULDBLOCK); | |
| 488 break; | |
| 489 case SSL_ERROR_ZERO_RETURN: | |
| 490 //LOG(LS_INFO) << " -- remote side closed"; | |
| 491 SetError(EWOULDBLOCK); | |
| 492 // do we need to signal closure? | |
| 493 break; | |
| 494 default: | |
| 495 //LOG(LS_INFO) << " -- error " << code; | |
| 496 Error("SSL_write", (code ? code : -1), false); | |
| 497 break; | |
| 498 } | |
| 499 | |
| 500 return SOCKET_ERROR; | |
| 501 } | 567 } |
| 502 | 568 |
| 503 int | 569 int |
| 504 OpenSSLAdapter::SendTo(const void* pv, size_t cb, const SocketAddress& addr) { | 570 OpenSSLAdapter::SendTo(const void* pv, size_t cb, const SocketAddress& addr) { |
| 505 if (socket_->GetState() == Socket::CS_CONNECTED && | 571 if (socket_->GetState() == Socket::CS_CONNECTED && |
| 506 addr == socket_->GetRemoteAddress()) { | 572 addr == socket_->GetRemoteAddress()) { |
| 507 return Send(pv, cb); | 573 return Send(pv, cb); |
| 508 } | 574 } |
| 509 | 575 |
| 510 SetError(ENOTCONN); | 576 SetError(ENOTCONN); |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 535 // Don't trust OpenSSL with zero byte reads | 601 // Don't trust OpenSSL with zero byte reads |
| 536 if (cb == 0) | 602 if (cb == 0) |
| 537 return 0; | 603 return 0; |
| 538 | 604 |
| 539 ssl_read_needs_write_ = false; | 605 ssl_read_needs_write_ = false; |
| 540 | 606 |
| 541 int code = SSL_read(ssl_, pv, checked_cast<int>(cb)); | 607 int code = SSL_read(ssl_, pv, checked_cast<int>(cb)); |
| 542 switch (SSL_get_error(ssl_, code)) { | 608 switch (SSL_get_error(ssl_, code)) { |
| 543 case SSL_ERROR_NONE: | 609 case SSL_ERROR_NONE: |
| 544 //LOG(LS_INFO) << " -- success"; | 610 //LOG(LS_INFO) << " -- success"; |
| 545 return code; | 611 return code; |
|
pthatcher1
2017/06/02 04:58:21
Should we check for SSL_ERROR_SSL here as well?
Taylor Brandstetter
2017/06/02 06:49:13
Done.
| |
| 546 case SSL_ERROR_WANT_READ: | 612 case SSL_ERROR_WANT_READ: |
| 547 //LOG(LS_INFO) << " -- error want read"; | 613 //LOG(LS_INFO) << " -- error want read"; |
| 548 SetError(EWOULDBLOCK); | 614 SetError(EWOULDBLOCK); |
| 549 break; | 615 break; |
| 550 case SSL_ERROR_WANT_WRITE: | 616 case SSL_ERROR_WANT_WRITE: |
| 551 //LOG(LS_INFO) << " -- error want write"; | 617 //LOG(LS_INFO) << " -- error want write"; |
| 552 ssl_read_needs_write_ = true; | 618 ssl_read_needs_write_ = true; |
| 553 SetError(EWOULDBLOCK); | 619 SetError(EWOULDBLOCK); |
| 554 break; | 620 break; |
| 555 case SSL_ERROR_ZERO_RETURN: | 621 case SSL_ERROR_ZERO_RETURN: |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 675 return; | 741 return; |
| 676 | 742 |
| 677 // Don't let ourselves go away during the callbacks | 743 // Don't let ourselves go away during the callbacks |
| 678 //PRefPtr<OpenSSLAdapter> lock(this); // TODO: fix this | 744 //PRefPtr<OpenSSLAdapter> lock(this); // TODO: fix this |
| 679 | 745 |
| 680 if (ssl_read_needs_write_) { | 746 if (ssl_read_needs_write_) { |
| 681 //LOG(LS_INFO) << " -- onStreamReadable"; | 747 //LOG(LS_INFO) << " -- onStreamReadable"; |
| 682 AsyncSocketAdapter::OnReadEvent(socket); | 748 AsyncSocketAdapter::OnReadEvent(socket); |
| 683 } | 749 } |
| 684 | 750 |
| 751 // If a previous SSL_write failed due to the underlying socket being blocked, | |
| 752 // this will attempt finishing the write operation. | |
| 753 if (pending_write_) { | |
| 754 if (DoSslWrite(pending_data_.data(), pending_data_.size()) == | |
| 755 static_cast<int>(pending_data_.size())) { | |
| 756 pending_write_ = false; | |
|
pthatcher1
2017/06/02 04:58:21
Shouldn't we clear the pending_data_?
Taylor Brandstetter
2017/06/02 06:49:13
Would have been pointless before, but since I got
| |
| 757 } | |
| 758 } | |
|
pthatcher1
2017/06/02 04:58:21
With the helper method, this could just be:
Maybe
| |
| 759 | |
| 685 //LOG(LS_INFO) << " -- onStreamWriteable"; | 760 //LOG(LS_INFO) << " -- onStreamWriteable"; |
| 686 AsyncSocketAdapter::OnWriteEvent(socket); | 761 AsyncSocketAdapter::OnWriteEvent(socket); |
| 687 } | 762 } |
| 688 | 763 |
| 689 void | 764 void |
| 690 OpenSSLAdapter::OnCloseEvent(AsyncSocket* socket, int err) { | 765 OpenSSLAdapter::OnCloseEvent(AsyncSocket* socket, int err) { |
| 691 LOG(LS_INFO) << "OpenSSLAdapter::OnCloseEvent(" << err << ")"; | 766 LOG(LS_INFO) << "OpenSSLAdapter::OnCloseEvent(" << err << ")"; |
| 692 AsyncSocketAdapter::OnCloseEvent(socket, err); | 767 AsyncSocketAdapter::OnCloseEvent(socket, err); |
| 693 } | 768 } |
| 694 | 769 |
| (...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"); | 981 SSL_CTX_set_cipher_list(ctx, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH"); |
| 907 | 982 |
| 908 if (ssl_mode_ == SSL_MODE_DTLS) { | 983 if (ssl_mode_ == SSL_MODE_DTLS) { |
| 909 SSL_CTX_set_read_ahead(ctx, 1); | 984 SSL_CTX_set_read_ahead(ctx, 1); |
| 910 } | 985 } |
| 911 | 986 |
| 912 return ctx; | 987 return ctx; |
| 913 } | 988 } |
| 914 | 989 |
| 915 } // namespace rtc | 990 } // namespace rtc |
| OLD | NEW |