| 710 | |
| 711 | |
| 712 | void OpenSSLSocketImpl::handle_accept_callback( |
| 713 | const std::shared_ptr<SocketImpl>& socket) |
| 714 | { |
| 715 | // Wrap this new socket up into our SSL wrapper class by releasing |
| 716 | // the FD and creating a new OpenSSLSocketImpl object with the FD. |
| 717 | const std::shared_ptr<OpenSSLSocketImpl> ssl_socket = |
| 718 | std::make_shared<OpenSSLSocketImpl>(socket->release()); |
| 719 | |
| 720 | // Set up SSL object. |
| 721 | SSL* accept_ssl = SSL_new(openssl::context()); |
| 722 | if (accept_ssl == nullptr) { |
| 723 | accept_queue.put(Failure("Accept failed, SSL_new")); |
| 724 | return; |
| 725 | } |
| 726 | |
| 727 | Try<Address> peer_address = network::peer(ssl_socket->get()); |
| 728 | if (!peer_address.isSome()) { |
| 729 | SSL_free(accept_ssl); |
| 730 | accept_queue.put( |
| 731 | Failure("Failed to determine peer IP: " + peer_address.error())); |
| 732 | return; |
| 733 | } |
| 734 | |
| 735 | // NOTE: Right now, `openssl::configure_socket` does not do anything |
| 736 | // in server mode, but we still pass the correct peer address to |
| 737 | // enable modules to implement application-level logic in the future. |
| 738 | Try<Nothing> configured = openssl::configure_socket( |
| 739 | accept_ssl, Mode::SERVER, peer_address.get(), None()); |
| 740 | |
| 741 | if (configured.isError()) { |
| 742 | SSL_free(accept_ssl); |
| 743 | accept_queue.put( |
| 744 | Failure("Failed to openssl::configure_socket for " + |
| 745 | stringify(*peer_address) + ": " + configured.error())); |
| 746 | return; |
| 747 | } |
| 748 | |
| 749 | // Set the SSL context in server mode. |
| 750 | SSL_set_accept_state(accept_ssl); |
| 751 | |
| 752 | // Hold a weak pointer since we do not want this accept function to extend |
| 753 | // the lifetime of `this` unnecessarily. |
| 754 | std::weak_ptr<OpenSSLSocketImpl> weak_self(shared(this)); |
| 755 | |
| 756 | // Pass ownership of `accept_ssl` to the newly accepted socket, |
| 757 | // and start the SSL handshake. When the SSL handshake completes, |
| 758 | // the listening socket will place the result (failure or success) |
| 759 | // onto the listening socket's `accept_queue`. |
| 760 | // |
| 761 | // TODO(josephw): Add a timeout to catch/close incoming sockets which |
| 762 | // never finish the SSL handshake. |
| 763 | ssl_socket->set_ssl_and_do_handshake(accept_ssl) |
| 764 | .onAny([weak_self, ssl_socket](Future<size_t> result) { |
| 765 | std::shared_ptr<OpenSSLSocketImpl> self(weak_self.lock()); |
| 766 | |
| 767 | if (self == nullptr) { |
| 768 | return; |
| 769 | } |
no test coverage detected