OLD | NEW |
1 // Copyright (c) 2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2008 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/base/ssl_client_socket_mac.h" | 5 #include "net/base/ssl_client_socket_mac.h" |
6 | 6 |
7 #include "base/singleton.h" | 7 #include "base/singleton.h" |
8 #include "base/string_util.h" | 8 #include "base/string_util.h" |
9 #include "net/base/net_errors.h" | 9 #include "net/base/net_errors.h" |
10 #include "net/base/ssl_info.h" | 10 #include "net/base/ssl_info.h" |
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
342 // Unlike IsConnected, this method doesn't return a false positive. | 342 // Unlike IsConnected, this method doesn't return a false positive. |
343 // | 343 // |
344 // Strictly speaking, we should check if we have received the close_notify | 344 // Strictly speaking, we should check if we have received the close_notify |
345 // alert message from the server, and return false in that case. Although | 345 // alert message from the server, and return false in that case. Although |
346 // the close_notify alert message means EOF in the SSL layer, it is just | 346 // the close_notify alert message means EOF in the SSL layer, it is just |
347 // bytes to the transport layer below, so transport_->IsConnectedAndIdle() | 347 // bytes to the transport layer below, so transport_->IsConnectedAndIdle() |
348 // returns the desired false when we receive close_notify. | 348 // returns the desired false when we receive close_notify. |
349 return completed_handshake_ && transport_->IsConnectedAndIdle(); | 349 return completed_handshake_ && transport_->IsConnectedAndIdle(); |
350 } | 350 } |
351 | 351 |
352 int SSLClientSocketMac::Read(char* buf, int buf_len, | 352 int SSLClientSocketMac::Read(IOBuffer* buf, int buf_len, |
353 CompletionCallback* callback) { | 353 CompletionCallback* callback) { |
354 DCHECK(completed_handshake_); | 354 DCHECK(completed_handshake_); |
355 DCHECK(next_state_ == STATE_NONE); | 355 DCHECK(next_state_ == STATE_NONE); |
356 DCHECK(!user_callback_); | 356 DCHECK(!user_callback_); |
| 357 DCHECK(!user_buf_); |
357 | 358 |
358 user_buf_ = buf; | 359 user_buf_ = buf; |
359 user_buf_len_ = buf_len; | 360 user_buf_len_ = buf_len; |
360 | 361 |
361 next_state_ = STATE_PAYLOAD_READ; | 362 next_state_ = STATE_PAYLOAD_READ; |
362 int rv = DoLoop(OK); | 363 int rv = DoLoop(OK); |
363 if (rv == ERR_IO_PENDING) | 364 if (rv == ERR_IO_PENDING) { |
364 user_callback_ = callback; | 365 user_callback_ = callback; |
| 366 } else { |
| 367 user_buf_ = NULL; |
| 368 } |
365 return rv; | 369 return rv; |
366 } | 370 } |
367 | 371 |
368 int SSLClientSocketMac::Write(const char* buf, int buf_len, | 372 int SSLClientSocketMac::Write(IOBuffer* buf, int buf_len, |
369 CompletionCallback* callback) { | 373 CompletionCallback* callback) { |
370 DCHECK(completed_handshake_); | 374 DCHECK(completed_handshake_); |
371 DCHECK(next_state_ == STATE_NONE); | 375 DCHECK(next_state_ == STATE_NONE); |
372 DCHECK(!user_callback_); | 376 DCHECK(!user_callback_); |
| 377 DCHECK(!user_buf_); |
373 | 378 |
374 user_buf_ = const_cast<char*>(buf); | 379 user_buf_ = buf; |
375 user_buf_len_ = buf_len; | 380 user_buf_len_ = buf_len; |
376 | 381 |
377 next_state_ = STATE_PAYLOAD_WRITE; | 382 next_state_ = STATE_PAYLOAD_WRITE; |
378 int rv = DoLoop(OK); | 383 int rv = DoLoop(OK); |
379 if (rv == ERR_IO_PENDING) | 384 if (rv == ERR_IO_PENDING) { |
380 user_callback_ = callback; | 385 user_callback_ = callback; |
| 386 } else { |
| 387 user_buf_ = NULL; |
| 388 } |
381 return rv; | 389 return rv; |
382 } | 390 } |
383 | 391 |
384 void SSLClientSocketMac::GetSSLInfo(SSLInfo* ssl_info) { | 392 void SSLClientSocketMac::GetSSLInfo(SSLInfo* ssl_info) { |
385 DCHECK(completed_handshake_); | 393 DCHECK(completed_handshake_); |
386 OSStatus status; | 394 OSStatus status; |
387 | 395 |
388 ssl_info->Reset(); | 396 ssl_info->Reset(); |
389 | 397 |
390 // set cert | 398 // set cert |
(...skipping 21 matching lines...) Expand all Loading... |
412 ssl_info->security_bits = KeySizeOfCipherSuite(suite); | 420 ssl_info->security_bits = KeySizeOfCipherSuite(suite); |
413 } | 421 } |
414 | 422 |
415 void SSLClientSocketMac::DoCallback(int rv) { | 423 void SSLClientSocketMac::DoCallback(int rv) { |
416 DCHECK(rv != ERR_IO_PENDING); | 424 DCHECK(rv != ERR_IO_PENDING); |
417 DCHECK(user_callback_); | 425 DCHECK(user_callback_); |
418 | 426 |
419 // since Run may result in Read being called, clear user_callback_ up front. | 427 // since Run may result in Read being called, clear user_callback_ up front. |
420 CompletionCallback* c = user_callback_; | 428 CompletionCallback* c = user_callback_; |
421 user_callback_ = NULL; | 429 user_callback_ = NULL; |
| 430 user_buf_ = NULL; |
422 c->Run(rv); | 431 c->Run(rv); |
423 } | 432 } |
424 | 433 |
425 void SSLClientSocketMac::OnIOComplete(int result) { | 434 void SSLClientSocketMac::OnIOComplete(int result) { |
426 if (next_io_state_ != STATE_NONE) { | 435 if (next_io_state_ != STATE_NONE) { |
427 State next_state = next_state_; | 436 State next_state = next_state_; |
428 next_state_ = next_io_state_; | 437 next_state_ = next_io_state_; |
429 next_io_state_ = STATE_NONE; | 438 next_io_state_ = STATE_NONE; |
430 result = DoLoop(result); | 439 result = DoLoop(result); |
431 next_state_ = next_state; | 440 next_state_ = next_state; |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
491 | 500 |
492 // TODO(wtc): for now, always check revocation. | 501 // TODO(wtc): for now, always check revocation. |
493 server_cert_status_ = CERT_STATUS_REV_CHECKING_ENABLED; | 502 server_cert_status_ = CERT_STATUS_REV_CHECKING_ENABLED; |
494 if (net_error) | 503 if (net_error) |
495 server_cert_status_ |= MapNetErrorToCertStatus(net_error); | 504 server_cert_status_ |= MapNetErrorToCertStatus(net_error); |
496 | 505 |
497 return net_error; | 506 return net_error; |
498 } | 507 } |
499 | 508 |
500 int SSLClientSocketMac::DoReadComplete(int result) { | 509 int SSLClientSocketMac::DoReadComplete(int result) { |
501 if (result < 0) | 510 if (result < 0) { |
| 511 read_io_buf_ = NULL; |
502 return result; | 512 return result; |
| 513 } |
| 514 |
| 515 char* buffer = &recv_buffer_[recv_buffer_.size() - recv_buffer_tail_slop_]; |
| 516 memcpy(buffer, read_io_buf_->data(), result); |
| 517 read_io_buf_ = NULL; |
503 | 518 |
504 recv_buffer_tail_slop_ -= result; | 519 recv_buffer_tail_slop_ -= result; |
505 | 520 |
506 return result; | 521 return result; |
507 } | 522 } |
508 | 523 |
509 void SSLClientSocketMac::OnWriteComplete(int result) { | 524 void SSLClientSocketMac::OnWriteComplete(int result) { |
510 if (result < 0) { | 525 if (result < 0) { |
511 pending_send_error_ = result; | 526 pending_send_error_ = result; |
512 return; | 527 return; |
513 } | 528 } |
514 | 529 |
515 send_buffer_.erase(send_buffer_.begin(), | 530 send_buffer_.erase(send_buffer_.begin(), |
516 send_buffer_.begin() + result); | 531 send_buffer_.begin() + result); |
517 | 532 |
518 if (!send_buffer_.empty()) | 533 if (!send_buffer_.empty()) |
519 SSLWriteCallback(this, NULL, NULL); | 534 SSLWriteCallback(this, NULL, NULL); |
520 } | 535 } |
521 | 536 |
522 int SSLClientSocketMac::DoPayloadRead() { | 537 int SSLClientSocketMac::DoPayloadRead() { |
523 size_t processed; | 538 size_t processed; |
524 OSStatus status = SSLRead(ssl_context_, | 539 OSStatus status = SSLRead(ssl_context_, |
525 user_buf_, | 540 user_buf_->data(), |
526 user_buf_len_, | 541 user_buf_len_, |
527 &processed); | 542 &processed); |
528 | 543 |
529 // There's a subtle difference here in semantics of the "would block" errors. | 544 // There's a subtle difference here in semantics of the "would block" errors. |
530 // In our code, ERR_IO_PENDING means the whole operation is async, while | 545 // In our code, ERR_IO_PENDING means the whole operation is async, while |
531 // errSSLWouldBlock means that the stream isn't ending (and is often returned | 546 // errSSLWouldBlock means that the stream isn't ending (and is often returned |
532 // along with partial data). So even though "would block" is returned, if we | 547 // along with partial data). So even though "would block" is returned, if we |
533 // have data, let's just return it. | 548 // have data, let's just return it. |
534 | 549 |
535 if (processed > 0) { | 550 if (processed > 0) { |
536 next_state_ = STATE_NONE; | 551 next_state_ = STATE_NONE; |
537 return processed; | 552 return processed; |
538 } | 553 } |
539 | 554 |
540 if (status == errSSLWouldBlock) { | 555 if (status == errSSLWouldBlock) { |
541 next_state_ = STATE_PAYLOAD_READ; | 556 next_state_ = STATE_PAYLOAD_READ; |
542 } | 557 } |
543 | 558 |
544 return NetErrorFromOSStatus(status); | 559 return NetErrorFromOSStatus(status); |
545 } | 560 } |
546 | 561 |
547 int SSLClientSocketMac::DoPayloadWrite() { | 562 int SSLClientSocketMac::DoPayloadWrite() { |
548 size_t processed; | 563 size_t processed; |
549 OSStatus status = SSLWrite(ssl_context_, | 564 OSStatus status = SSLWrite(ssl_context_, |
550 user_buf_, | 565 user_buf_->data(), |
551 user_buf_len_, | 566 user_buf_len_, |
552 &processed); | 567 &processed); |
553 | 568 |
554 if (processed > 0) | 569 if (processed > 0) |
555 return processed; | 570 return processed; |
556 | 571 |
557 return NetErrorFromOSStatus(status); | 572 return NetErrorFromOSStatus(status); |
558 } | 573 } |
559 | 574 |
560 // Handling the reading from the network is one of those things that should be | 575 // Handling the reading from the network is one of those things that should be |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
653 | 668 |
654 // Resize the buffer if needed | 669 // Resize the buffer if needed |
655 | 670 |
656 if (us->recv_buffer_.size() - us->recv_buffer_head_slop_ < *data_length) { | 671 if (us->recv_buffer_.size() - us->recv_buffer_head_slop_ < *data_length) { |
657 us->recv_buffer_.resize(us->recv_buffer_head_slop_ + *data_length); | 672 us->recv_buffer_.resize(us->recv_buffer_head_slop_ + *data_length); |
658 us->recv_buffer_tail_slop_ = *data_length - total_read; | 673 us->recv_buffer_tail_slop_ = *data_length - total_read; |
659 } | 674 } |
660 | 675 |
661 int rv = 1; // any old value to spin the loop below | 676 int rv = 1; // any old value to spin the loop below |
662 while (rv > 0 && total_read < *data_length) { | 677 while (rv > 0 && total_read < *data_length) { |
663 rv = us->transport_->Read(&us->recv_buffer_[us->recv_buffer_head_slop_ + | 678 char* buffer = &us->recv_buffer_[us->recv_buffer_head_slop_ + total_read]; |
664 total_read], | 679 us->read_io_buf_ = new IOBuffer(*data_length - total_read); |
665 us->recv_buffer_tail_slop_, | 680 rv = us->transport_->Read(us->read_io_buf_, |
| 681 *data_length - total_read, |
666 &us->io_callback_); | 682 &us->io_callback_); |
667 | 683 |
668 if (rv > 0) { | 684 if (rv >= 0) { |
| 685 memcpy(buffer, us->read_io_buf_->data(), rv); |
| 686 us->read_io_buf_ = NULL; |
669 total_read += rv; | 687 total_read += rv; |
670 us->recv_buffer_tail_slop_ -= rv; | 688 us->recv_buffer_tail_slop_ -= rv; |
671 } | 689 } |
672 } | 690 } |
673 | 691 |
674 *data_length = total_read; | 692 *data_length = total_read; |
675 if (total_read) { | 693 if (total_read) { |
676 memcpy(data, &us->recv_buffer_[us->recv_buffer_head_slop_], total_read); | 694 memcpy(data, &us->recv_buffer_[us->recv_buffer_head_slop_], total_read); |
677 if (rv == ERR_IO_PENDING) { | 695 if (rv == ERR_IO_PENDING) { |
678 // We have I/O in flight which is going to land in our buffer. We can't | 696 // We have I/O in flight which is going to land in our buffer. We can't |
679 // shuffle things around, so we need to just fiddle with pointers. | 697 // shuffle things around, so we need to just fiddle with pointers. |
680 us->recv_buffer_head_slop_ += total_read; | 698 us->recv_buffer_head_slop_ += total_read; |
681 } else { | 699 } else { |
682 us->recv_buffer_.erase(us->recv_buffer_.begin(), | 700 us->recv_buffer_.erase(us->recv_buffer_.begin(), |
683 us->recv_buffer_.begin() + | 701 us->recv_buffer_.begin() + |
684 total_read + | 702 total_read + |
685 us->recv_buffer_head_slop_); | 703 us->recv_buffer_head_slop_); |
686 us->recv_buffer_head_slop_ = 0; | 704 us->recv_buffer_head_slop_ = 0; |
687 } | 705 } |
688 } | 706 } |
689 | 707 |
690 if (rv == ERR_IO_PENDING) { | 708 if (rv == ERR_IO_PENDING) { |
691 us->next_io_state_ = STATE_READ_COMPLETE; | 709 us->next_io_state_ = STATE_READ_COMPLETE; |
| 710 } else { |
| 711 us->read_io_buf_ = NULL; |
692 } | 712 } |
693 | 713 |
694 if (rv < 0) | 714 if (rv < 0) |
695 return OSStatusFromNetError(rv); | 715 return OSStatusFromNetError(rv); |
696 | 716 |
697 return noErr; | 717 return noErr; |
698 } | 718 } |
699 | 719 |
700 // static | 720 // static |
701 OSStatus SSLClientSocketMac::SSLWriteCallback(SSLConnectionRef connection, | 721 OSStatus SSLClientSocketMac::SSLWriteCallback(SSLConnectionRef connection, |
702 const void* data, | 722 const void* data, |
703 size_t* data_length) { | 723 size_t* data_length) { |
704 SSLClientSocketMac* us = | 724 SSLClientSocketMac* us = |
705 const_cast<SSLClientSocketMac*>( | 725 const_cast<SSLClientSocketMac*>( |
706 static_cast<const SSLClientSocketMac*>(connection)); | 726 static_cast<const SSLClientSocketMac*>(connection)); |
707 | 727 |
708 if (us->pending_send_error_ != OK) { | 728 if (us->pending_send_error_ != OK) { |
709 OSStatus status = OSStatusFromNetError(us->pending_send_error_); | 729 OSStatus status = OSStatusFromNetError(us->pending_send_error_); |
710 us->pending_send_error_ = OK; | 730 us->pending_send_error_ = OK; |
711 return status; | 731 return status; |
712 } | 732 } |
713 | 733 |
714 if (data) | 734 if (data) |
715 us->send_buffer_.insert(us->send_buffer_.end(), | 735 us->send_buffer_.insert(us->send_buffer_.end(), |
716 static_cast<const char*>(data), | 736 static_cast<const char*>(data), |
717 static_cast<const char*>(data) + *data_length); | 737 static_cast<const char*>(data) + *data_length); |
718 int rv; | 738 int rv; |
719 do { | 739 do { |
720 rv = us->transport_->Write(&us->send_buffer_[0], | 740 scoped_refptr<IOBuffer> buffer = new IOBuffer(us->send_buffer_.size()); |
| 741 memcpy(buffer->data(), &us->send_buffer_[0], us->send_buffer_.size()); |
| 742 rv = us->transport_->Write(buffer, |
721 us->send_buffer_.size(), | 743 us->send_buffer_.size(), |
722 &us->write_callback_); | 744 &us->write_callback_); |
723 if (rv > 0) { | 745 if (rv > 0) { |
724 us->send_buffer_.erase(us->send_buffer_.begin(), | 746 us->send_buffer_.erase(us->send_buffer_.begin(), |
725 us->send_buffer_.begin() + rv); | 747 us->send_buffer_.begin() + rv); |
726 | 748 |
727 } | 749 } |
728 } while (rv > 0 && !us->send_buffer_.empty()); | 750 } while (rv > 0 && !us->send_buffer_.empty()); |
729 | 751 |
730 if (rv < 0 && rv != ERR_IO_PENDING) { | 752 if (rv < 0 && rv != ERR_IO_PENDING) { |
731 return OSStatusFromNetError(rv); | 753 return OSStatusFromNetError(rv); |
732 } | 754 } |
733 | 755 |
734 // always lie to our caller | 756 // always lie to our caller |
735 return noErr; | 757 return noErr; |
736 } | 758 } |
737 | 759 |
738 } // namespace net | 760 } // namespace net |
OLD | NEW |