@@ -762,6 +762,43 @@ SSLNetVConnection::SSLNetVConnection()
762762{
763763}
764764
765+ void
766+ SSLNetVConnection::do_io_close (int lerrno)
767+ {
768+ if (this ->ssl != NULL && sslHandShakeComplete) {
769+ int new_shutdown_mode = 0 , shutdown_mode = 0 ;
770+ if (this ->lerrno < 0 ) {
771+ new_shutdown_mode = SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN;
772+ } else {
773+ shutdown_mode = SSL_get_shutdown (ssl);
774+ Debug (" ssl-shutdown" , " previous shutdown state 0x%x" , shutdown_mode);
775+ new_shutdown_mode = shutdown_mode | SSL_RECEIVED_SHUTDOWN;
776+ }
777+ if (new_shutdown_mode != shutdown_mode) {
778+ // We do not need to sit around and wait for the client's close-notify if
779+ // they have not already sent it. We will still be standards compliant
780+ Debug (" ssl-shutdown" , " new SSL_set_shutdown 0x%x" , new_shutdown_mode);
781+ SSL_set_shutdown (ssl, new_shutdown_mode);
782+ }
783+
784+ // If the peer has already sent a FIN, don't bother with the shutdown
785+ // They will just send us a RST for our troubles
786+ // This test is not foolproof. The client's fin could be on the wire
787+ // at the same time we send the close-notify. If so, the client will likely
788+ // send RST anyway
789+ char c;
790+ ssize_t x = recv (this ->con .fd , &c, 1 , MSG_PEEK);
791+ // x < 0 means error. x == 0 means fin sent
792+ if (x != 0 ) {
793+ // Send the close-notify
794+ int ret = SSL_shutdown (ssl);
795+ Debug (" ssl-shutdown" , " SSL_shutdown %s" , (ret)?" success" :" failed" );
796+ }
797+ }
798+ // Go on and do the unix socket cleanups
799+ super::do_io_close (lerrno);
800+ }
801+
765802void
766803SSLNetVConnection::free (EThread *t)
767804{
@@ -780,8 +817,6 @@ SSLNetVConnection::free(EThread *t)
780817 closed = 0 ;
781818 ink_assert (con.fd == NO_FD);
782819 if (ssl != NULL ) {
783- /* if (sslHandShakeComplete)
784- SSL_set_shutdown(ssl, SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN); */
785820 SSL_free (ssl);
786821 ssl = NULL ;
787822 }
0 commit comments