Browse Source

rpc: Make sure conn object is always cleaned up

Make sure conn object always gets cleaned up by using a
`boost::shared_ptr`.

This makes valgrind happy - before this commit, one connection object
always leaked at shutdown, as well as can avoid other leaks, when
for example an exception happens.

Also add an explicit Close() to the !ClientAllowed path to make it similar
to the normal path (I'm not sure whether it is needed, but it
can't hurt).
0.10
Wladimir J. van der Laan 11 years ago
parent
commit
1a445225f6
  1. 16
      src/rpcserver.cpp

16
src/rpcserver.cpp

@ -444,7 +444,7 @@ template <typename Protocol, typename SocketAcceptorService>
static void RPCAcceptHandler(boost::shared_ptr< basic_socket_acceptor<Protocol, SocketAcceptorService> > acceptor, static void RPCAcceptHandler(boost::shared_ptr< basic_socket_acceptor<Protocol, SocketAcceptorService> > acceptor,
ssl::context& context, ssl::context& context,
bool fUseSSL, bool fUseSSL,
AcceptedConnection* conn, boost::shared_ptr< AcceptedConnection > conn,
const boost::system::error_code& error); const boost::system::error_code& error);
/** /**
@ -456,7 +456,7 @@ static void RPCListen(boost::shared_ptr< basic_socket_acceptor<Protocol, SocketA
const bool fUseSSL) const bool fUseSSL)
{ {
// Accept connection // Accept connection
AcceptedConnectionImpl<Protocol>* conn = new AcceptedConnectionImpl<Protocol>(acceptor->get_io_service(), context, fUseSSL); boost::shared_ptr< AcceptedConnectionImpl<Protocol> > conn(new AcceptedConnectionImpl<Protocol>(acceptor->get_io_service(), context, fUseSSL));
acceptor->async_accept( acceptor->async_accept(
conn->sslStream.lowest_layer(), conn->sslStream.lowest_layer(),
@ -477,23 +477,20 @@ template <typename Protocol, typename SocketAcceptorService>
static void RPCAcceptHandler(boost::shared_ptr< basic_socket_acceptor<Protocol, SocketAcceptorService> > acceptor, static void RPCAcceptHandler(boost::shared_ptr< basic_socket_acceptor<Protocol, SocketAcceptorService> > acceptor,
ssl::context& context, ssl::context& context,
const bool fUseSSL, const bool fUseSSL,
AcceptedConnection* conn, boost::shared_ptr< AcceptedConnection > conn,
const boost::system::error_code& error) const boost::system::error_code& error)
{ {
// Immediately start accepting new connections, except when we're cancelled or our socket is closed. // Immediately start accepting new connections, except when we're cancelled or our socket is closed.
if (error != asio::error::operation_aborted && acceptor->is_open()) if (error != asio::error::operation_aborted && acceptor->is_open())
RPCListen(acceptor, context, fUseSSL); RPCListen(acceptor, context, fUseSSL);
AcceptedConnectionImpl<ip::tcp>* tcp_conn = dynamic_cast< AcceptedConnectionImpl<ip::tcp>* >(conn); AcceptedConnectionImpl<ip::tcp>* tcp_conn = dynamic_cast< AcceptedConnectionImpl<ip::tcp>* >(conn.get());
// TODO: Actually handle errors
if (error) if (error)
{ {
delete conn;
// TODO: Actually handle errors // TODO: Actually handle errors
LogPrintf("%s: Error: %s\n", __func__, error.message()); LogPrintf("%s: Error: %s\n", __func__, error.message());
} }
// Restrict callers by IP. It is important to // Restrict callers by IP. It is important to
// do this before starting client thread, to filter out // do this before starting client thread, to filter out
// certain DoS and misbehaving clients. // certain DoS and misbehaving clients.
@ -502,12 +499,11 @@ static void RPCAcceptHandler(boost::shared_ptr< basic_socket_acceptor<Protocol,
// Only send a 403 if we're not using SSL to prevent a DoS during the SSL handshake. // Only send a 403 if we're not using SSL to prevent a DoS during the SSL handshake.
if (!fUseSSL) if (!fUseSSL)
conn->stream() << HTTPReply(HTTP_FORBIDDEN, "", false) << std::flush; conn->stream() << HTTPReply(HTTP_FORBIDDEN, "", false) << std::flush;
delete conn; conn->close();
} }
else { else {
ServiceConnection(conn); ServiceConnection(conn.get());
conn->close(); conn->close();
delete conn;
} }
} }

Loading…
Cancel
Save