From 9fa6e8a43082b7325b32d240bf9da6379f281ae4 Mon Sep 17 00:00:00 2001 From: Eric Frias Date: Sun, 1 Jun 2014 18:07:56 -0400 Subject: [PATCH] Separate the 'bind' operation for tcp_sockets from the 'connect_to' operation so we can tell which operation is throwing an exception in client code. convert a few boost exceptions into fc::exceptions. --- include/fc/network/tcp_socket.hpp | 3 ++- src/network/tcp_socket.cpp | 39 +++++++++++++++++++++---------- 2 files changed, 29 insertions(+), 13 deletions(-) diff --git a/include/fc/network/tcp_socket.hpp b/include/fc/network/tcp_socket.hpp index a2fc8f4..2fd235e 100644 --- a/include/fc/network/tcp_socket.hpp +++ b/include/fc/network/tcp_socket.hpp @@ -16,7 +16,7 @@ namespace fc { ~tcp_socket(); void connect_to( const fc::ip::endpoint& remote_endpoint ); - void connect_to( const fc::ip::endpoint& remote_endpoint, const fc::ip::endpoint& local_endpoint ); + void bind( const fc::ip::endpoint& local_endpoint ); void enable_keep_alives(const fc::microseconds& interval); void set_io_hooks(tcp_socket_io_hooks* new_hooks); void set_reuse_address(bool enable = true); // set SO_REUSEADDR @@ -68,6 +68,7 @@ namespace fc { void set_reuse_address(bool enable = true); // set SO_REUSEADDR, call before listen void listen( uint16_t port ); void listen( const fc::ip::endpoint& ep ); + fc::ip::endpoint get_local_endpoint() const; uint16_t get_port()const; private: // non copyable diff --git a/src/network/tcp_socket.cpp b/src/network/tcp_socket.cpp index 1363347..2a53c14 100644 --- a/src/network/tcp_socket.cpp +++ b/src/network/tcp_socket.cpp @@ -93,18 +93,18 @@ namespace fc { fc::asio::tcp::connect(my->_sock, fc::asio::tcp::endpoint( boost::asio::ip::address_v4(remote_endpoint.get_address()), remote_endpoint.port() ) ); } - void tcp_socket::connect_to( const fc::ip::endpoint& remote_endpoint, const fc::ip::endpoint& local_endpoint ) { + void tcp_socket::bind(const fc::ip::endpoint& local_endpoint) + { try { - my->_sock.bind(boost::asio::ip::tcp::endpoint(boost::asio::ip::address_v4(local_endpoint.get_address()), - local_endpoint.port())); + my->_sock.bind(boost::asio::ip::tcp::endpoint(boost::asio::ip::address_v4(local_endpoint.get_address()), + local_endpoint.port())); } - catch (std::exception& except) + catch (const std::exception& except) { elog("Exception binding outgoing connection to desired local endpoint: ${what}", ("what", except.what())); - throw; + FC_THROW("error binding to ${endpoint}: ${what}", ("endpoint", local_endpoint)("what", except.what())); } - fc::asio::tcp::connect(my->_sock, fc::asio::tcp::endpoint(boost::asio::ip::address_v4(remote_endpoint.get_address()), remote_endpoint.port())); } void tcp_socket::enable_keep_alives(const fc::microseconds& interval) @@ -230,21 +230,36 @@ namespace fc { { if( !my ) my = new impl; - my->_accept.bind(boost::asio::ip::tcp::endpoint(boost::asio::ip::address_v4(), port)); - my->_accept.listen(); + try + { + my->_accept.bind(boost::asio::ip::tcp::endpoint(boost::asio::ip::address_v4(), port)); + my->_accept.listen(); + } + FC_RETHROW_EXCEPTIONS(warn, "error listening on socket"); } void tcp_server::listen( const fc::ip::endpoint& ep ) { if( !my ) my = new impl; - my->_accept.bind(boost::asio::ip::tcp::endpoint(boost::asio::ip::address_v4::from_string((string)ep.get_address()), ep.port())); - my->_accept.listen(); + try + { + my->_accept.bind(boost::asio::ip::tcp::endpoint(boost::asio::ip::address_v4::from_string((string)ep.get_address()), ep.port())); + my->_accept.listen(); + } + FC_RETHROW_EXCEPTIONS(warn, "error listening on socket"); + } + + fc::ip::endpoint tcp_server::get_local_endpoint() const + { + FC_ASSERT( my != nullptr ); + return fc::ip::endpoint(my->_accept.local_endpoint().address().to_v4().to_ulong(), + my->_accept.local_endpoint().port() ); } uint16_t tcp_server::get_port()const { - FC_ASSERT( my != nullptr ); - return my->_accept.local_endpoint().port(); + FC_ASSERT( my != nullptr ); + return my->_accept.local_endpoint().port(); }