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 |