From 9f5cfc465a19edf50359db952d22986c85491bc0 Mon Sep 17 00:00:00 2001 From: James Yonan Date: Fri, 17 Feb 2012 20:30:08 +0000 Subject: [PATCH] Implement error handling if socket_protect() call fails. --- openvpn/common/exception.hpp | 10 ++++++++++ openvpn/error/error.hpp | 2 ++ openvpn/transport/client/tcpcli.hpp | 14 ++++++++++++-- openvpn/transport/client/udpcli.hpp | 12 +++++++++++- 4 files changed, 35 insertions(+), 3 deletions(-) diff --git a/openvpn/common/exception.hpp b/openvpn/common/exception.hpp index a73fb483..c83a34cc 100644 --- a/openvpn/common/exception.hpp +++ b/openvpn/common/exception.hpp @@ -81,6 +81,16 @@ namespace openvpn { throw exc(_ovpn_exc.str()); \ } while (0) + // properly rethrow an exception that might be derived from Exception + inline void throw_ref(const std::exception& e) + { + const Exception* ex = dynamic_cast(&e); + if (ex) + throw *ex; + else + throw e; + } + } // namespace openvpn #endif // OPENVPN_COMMON_EXCEPTION_H diff --git a/openvpn/error/error.hpp b/openvpn/error/error.hpp index 4f8efcf9..8de011be 100644 --- a/openvpn/error/error.hpp +++ b/openvpn/error/error.hpp @@ -15,6 +15,7 @@ namespace openvpn { BAD_SRC_ADDR, // packet from unknown source address COMPRESS_ERROR, // compress/decompress errors on data channel RESOLVE_ERROR, // DNS resolution error + SOCKET_PROTECT_ERROR, // Error calling protect() method on socket TUN_ERROR, // errors on tun/tap interface TCP_OVERFLOW, // TCP output queue overflow TCP_SIZE_ERROR, // bad embedded uint16_t TCP packet size @@ -42,6 +43,7 @@ namespace openvpn { "BAD_SRC_ADDR", "COMPRESS_ERROR", "RESOLVE_ERROR", + "SOCKET_PROTECT_ERROR", "TUN_ERROR", "TCP_OVERFLOW", "TCP_SIZE_ERROR", diff --git a/openvpn/transport/client/tcpcli.hpp b/openvpn/transport/client/tcpcli.hpp index 10583f05..05bed330 100644 --- a/openvpn/transport/client/tcpcli.hpp +++ b/openvpn/transport/client/tcpcli.hpp @@ -15,6 +15,7 @@ namespace openvpn { OPENVPN_EXCEPTION(tcp_transport_resolve_error); OPENVPN_EXCEPTION(tcp_transport_error); + OPENVPN_SIMPLE_EXCEPTION(tcp_transport_socket_protect_error); class ClientConfig : public TransportClientFactory { @@ -145,7 +146,7 @@ namespace openvpn { parent.transport_recv(buf); } - void tcp_error_handler(const char *error) + void tcp_error_handler(const char *error) // called by LinkImpl { std::ostringstream os; os << "Transport error on '" << config->server_host << ": " << error; @@ -197,7 +198,16 @@ namespace openvpn { socket.open(server_endpoint.protocol()); #ifdef OPENVPN_PLATFORM_TYPE_UNIX if (config->socket_protect) - config->socket_protect->socket_protect(socket.native_handle()); + { + if (!config->socket_protect->socket_protect(socket.native_handle())) + { + config->stats->error(Error::SOCKET_PROTECT_ERROR); + stop(); + tcp_transport_socket_protect_error err; + parent.transport_error(err); + return; + } + } #endif socket.set_option(boost::asio::ip::tcp::no_delay(true)); socket.async_connect(server_endpoint, asio_dispatch_connect(&Client::start_impl_, this)); diff --git a/openvpn/transport/client/udpcli.hpp b/openvpn/transport/client/udpcli.hpp index 8ff69bcc..b2b08c8d 100644 --- a/openvpn/transport/client/udpcli.hpp +++ b/openvpn/transport/client/udpcli.hpp @@ -14,6 +14,7 @@ namespace openvpn { namespace UDPTransport { OPENVPN_EXCEPTION(udp_transport_resolve_error); + OPENVPN_SIMPLE_EXCEPTION(udp_transport_socket_protect_error); class ClientConfig : public TransportClientFactory { @@ -178,7 +179,16 @@ namespace openvpn { socket.open(server_endpoint.protocol()); #ifdef OPENVPN_PLATFORM_TYPE_UNIX if (config->socket_protect) - config->socket_protect->socket_protect(socket.native_handle()); + { + if (!config->socket_protect->socket_protect(socket.native_handle())) + { + config->stats->error(Error::SOCKET_PROTECT_ERROR); + stop(); + udp_transport_socket_protect_error err; + parent.transport_error(err); + return; + } + } #endif socket.connect(server_endpoint); impl.reset(new LinkImpl(this,