I have a server that accepts ssl connections on port 443. I am using the boost libraries for the server implementation. Below is the code snippet:
    ssl_socket socket_;
{
   // Open the acceptor with the option to reuse the address (i.e.
 SO_REUSEADDR).
     boost::asio::ip::tcp::resolver resolver(io_service_);
     boost::asio::ip::tcp::resolver::query query(address, port);
     boost::asio::ip::tcp::endpoint endpoint = *resolver.resolve(query);
     acceptor_.open(endpoint.protocol());
     acceptor_.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
     acceptor_.bind(endpoint);
     acceptor_.listen(1000);
      start_accept();
}

void server::start_accept() {
        new_connection_.reset(
                        new connection(io_service_, connection_manager_, request_handler_,
                                        context_));
        acceptor_.async_accept(new_connection_->socket(),
                        boost::bind(&server::handle_accept, this,
                                        boost::asio::placeholders::error));
}

void server::handle_accept(const boost::system::error_code& e) {
        // Check whether the server was stopped by a signal before this completion
        // handler had a chance to run.
        if (!acceptor_.is_open()) {
                return;
        } else {
                 start();
        }
         start_accept();
}


void server::start() {
        
        socket_.async_handshake(boost::asio::ssl::stream_base::server,
                        boost::bind(&connection::handle_handshake, this,
                                        boost::asio::placeholders::error));
        if (boost::asio::placeholders::error) {
        //      printf("Error is there. Check it\n");
        }
}

void connection::handle_handshake(const boost::system::error_code& error) {
        
        if (!error) {
                DEBUG("async read some");
                socket_.async_read_some(boost::asio::buffer(buffer_),
                                boost::bind(&connection::handle_read, shared_from_this(),
                                                boost::asio::placeholders::error,
                                                boost::asio::placeholders::bytes_transferred));
        } else {
                std::cout << "Error number: " << error.value();
                std::cout << " Error message: " << error.message();
                std::cout << " Error category: " << error.category().name() << std::endl;
                delete this;
        }
}

When I initiate multiple clients to connect to the server, most of the time the connection succeeds i.e TCP handshake followed by SSL handshake succeeds and I am able to do data transfer. However, there are times when the TCP handshake succeeds (as seen by wireshark) but the SSL request isn't responded to by my server. I am able to see the SSL handshake request coming from the client onto my server, but the server doesn't respond, neither is my handle_accept() function gets called. When I check the output of netstat, I see a lot of data pending in the Recv-Q.

Below is the output of netstat -atn command on the server during one such scenario:

Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State
tcp       15      0 0.0.0.0:443             0.0.0.0:*               LISTEN
tcp        0    213 10.110.112.1:443        10.110.112.2:52363      ESTABLISHED
tcp      180      0 10.110.112.1:443        10.110.112.2:52624      ESTABLISHED
tcp      180      0 10.110.112.1:443        10.110.112.2:52581      ESTABLISHED
tcp      180      0 10.110.112.1:443        10.110.112.2:52646      ESTABLISHED
tcp      180      0 10.110.112.1:443        10.110.112.2:52749      ESTABLISHED
tcp      180      0 10.110.112.1:443        10.110.112.2:52824      ESTABLISHED
tcp      180      0 10.110.112.1:443        10.110.112.2:52805      ESTABLISHED
tcp      180      0 10.110.112.1:443        10.110.112.2:52645      ESTABLISHED
tcp        0    471 10.110.112.1:443        10.110.112.2:52362      ESTABLISHED
tcp        1      0 10.110.112.1:443        10.110.112.3:39129      CLOSE_WAIT
tcp      183      0 10.110.112.1:443        10.110.112.3:39130      CLOSE_WAIT
tcp      180      0 10.110.112.1:443        10.110.112.2:52595      ESTABLISHED
tcp      183      0 10.110.112.1:443        10.110.112.3:39131      CLOSE_WAIT

Upon further debugging, I see that the call to ssl socket member function shutdown() blocks sometimes forever and sometimes for at least 5 - 10 minutes due to which no further data is taken in and the recv-q indicates pending bytes. This is how my write handler is. Any help on where I am going wrong would be greatly appreciated:

void connection::handle_write(const boost::system::error_code& e) {
           if (!e) {
                boost::system::error_code ec;
                socket_.shutdown(ec); //Code blocks here indefinitely
        }
}

Any reasons why the socket_.shutdown( ) blocks. How could I specify a timeout such that the shutdown( ) returns back after some time? Any other way of handling this? ( I know there is async_shutdown( ) but I prefer using shutdown( ) blocking handler)


Any help would be greatly appreciated.


Regards,

Fariya