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.

This commit is contained in:
Eric Frias 2014-06-01 18:07:56 -04:00
parent 861221098f
commit 9fa6e8a430
2 changed files with 29 additions and 13 deletions

View file

@ -16,7 +16,7 @@ namespace fc {
~tcp_socket(); ~tcp_socket();
void connect_to( const fc::ip::endpoint& remote_endpoint ); 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 enable_keep_alives(const fc::microseconds& interval);
void set_io_hooks(tcp_socket_io_hooks* new_hooks); void set_io_hooks(tcp_socket_io_hooks* new_hooks);
void set_reuse_address(bool enable = true); // set SO_REUSEADDR 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 set_reuse_address(bool enable = true); // set SO_REUSEADDR, call before listen
void listen( uint16_t port ); void listen( uint16_t port );
void listen( const fc::ip::endpoint& ep ); void listen( const fc::ip::endpoint& ep );
fc::ip::endpoint get_local_endpoint() const;
uint16_t get_port()const; uint16_t get_port()const;
private: private:
// non copyable // non copyable

View file

@ -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() ) ); 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 try
{ {
my->_sock.bind(boost::asio::ip::tcp::endpoint(boost::asio::ip::address_v4(local_endpoint.get_address()), my->_sock.bind(boost::asio::ip::tcp::endpoint(boost::asio::ip::address_v4(local_endpoint.get_address()),
local_endpoint.port())); 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())); 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) void tcp_socket::enable_keep_alives(const fc::microseconds& interval)
@ -230,21 +230,36 @@ namespace fc {
{ {
if( !my ) if( !my )
my = new impl; my = new impl;
my->_accept.bind(boost::asio::ip::tcp::endpoint(boost::asio::ip::address_v4(), port)); try
my->_accept.listen(); {
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 ) void tcp_server::listen( const fc::ip::endpoint& ep )
{ {
if( !my ) if( !my )
my = new impl; my = new impl;
my->_accept.bind(boost::asio::ip::tcp::endpoint(boost::asio::ip::address_v4::from_string((string)ep.get_address()), ep.port())); try
my->_accept.listen(); {
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 uint16_t tcp_server::get_port()const
{ {
FC_ASSERT( my != nullptr ); FC_ASSERT( my != nullptr );
return my->_accept.local_endpoint().port(); return my->_accept.local_endpoint().port();
} }