diff --git a/openvpn/client/cliconnect.hpp b/openvpn/client/cliconnect.hpp index 9275e3ed..d06f407a 100644 --- a/openvpn/client/cliconnect.hpp +++ b/openvpn/client/cliconnect.hpp @@ -334,6 +334,14 @@ namespace openvpn { stop(); } break; + case Error::TUN_IFACE_DISABLED: + { + ClientEvent::Base::Ptr ev = new ClientEvent::TunIfaceDisabled(client->fatal_reason()); + client_options->events().add_event(ev); + client_options->stats().error(Error::TUN_IFACE_DISABLED); + stop(); + } + break; case Error::PROXY_ERROR: { ClientEvent::Base::Ptr ev = new ClientEvent::ProxyError(client->fatal_reason()); diff --git a/openvpn/client/clievent.hpp b/openvpn/client/clievent.hpp index df7f477b..831768ed 100644 --- a/openvpn/client/clievent.hpp +++ b/openvpn/client/clievent.hpp @@ -49,6 +49,7 @@ namespace openvpn { PROXY_ERROR, TUN_SETUP_FAILED, TUN_IFACE_CREATE, + TUN_IFACE_DISABLED, EPKI_ERROR, // EPKI refers to External PKI errors, i.e. errors in accessing external EPKI_INVALID_ALIAS, // certificates or keys. @@ -86,6 +87,7 @@ namespace openvpn { "PROXY_ERROR", "TUN_SETUP_FAILED", "TUN_IFACE_CREATE", + "TUN_IFACE_DISABLED", "EPKI_ERROR", "EPKI_INVALID_ALIAS", }; @@ -294,6 +296,11 @@ namespace openvpn { TunIfaceCreate(const std::string& reason) : ReasonBase(TUN_IFACE_CREATE, reason) {} }; + struct TunIfaceDisabled : public ReasonBase + { + TunIfaceDisabled(const std::string& reason) : ReasonBase(TUN_IFACE_DISABLED, reason) {} + }; + struct EpkiError : public ReasonBase { EpkiError(const std::string& reason) : ReasonBase(EPKI_ERROR, reason) {} diff --git a/openvpn/error/error.hpp b/openvpn/error/error.hpp index aba4c297..d1bc2ef6 100644 --- a/openvpn/error/error.hpp +++ b/openvpn/error/error.hpp @@ -32,6 +32,7 @@ namespace openvpn { TUN_FRAMING_ERROR, // error with tun PF_INET/PF_INET6 prefix TUN_SETUP_FAILED, // error setting up tun/tap interface TUN_IFACE_CREATE, // error creating tun/tap interface + TUN_IFACE_DISABLED, // tun/tap interface is disabled TAP_NOT_SUPPORTED, // dev tap is present in profile but not supported REROUTE_GW_NO_DNS, // redirect-gateway specified without alt DNS servers TCP_OVERFLOW, // TCP output queue overflow @@ -99,6 +100,7 @@ namespace openvpn { "TUN_FRAMING_ERROR", "TUN_SETUP_FAILED", "TUN_IFACE_CREATE", + "TUN_IFACE_DISABLED", "TAP_NOT_SUPPORTED", "REROUTE_GW_NO_DNS", "TCP_OVERFLOW", diff --git a/openvpn/tun/builder/client.hpp b/openvpn/tun/builder/client.hpp index 377ecaff..6be812b3 100644 --- a/openvpn/tun/builder/client.hpp +++ b/openvpn/tun/builder/client.hpp @@ -235,6 +235,11 @@ namespace openvpn { parent.tun_recv(pfp->buf); } + void tun_error_handler(const Error::Type errtype, // called by TunImpl + const boost::system::error_code* error) + { + } + void stop_() { if (!halt) diff --git a/openvpn/tun/linux/client/tuncli.hpp b/openvpn/tun/linux/client/tuncli.hpp index 236e5712..876b9e44 100644 --- a/openvpn/tun/linux/client/tuncli.hpp +++ b/openvpn/tun/linux/client/tuncli.hpp @@ -139,6 +139,11 @@ namespace openvpn { parent.tun_recv(pfp->buf); } + void tun_error_handler(const Error::Type errtype, // called by TunImpl + const boost::system::error_code* error) + { + } + void stop_() { if (!halt) diff --git a/openvpn/tun/mac/client/tuncli.hpp b/openvpn/tun/mac/client/tuncli.hpp index 921b4bf3..240af2fa 100644 --- a/openvpn/tun/mac/client/tuncli.hpp +++ b/openvpn/tun/mac/client/tuncli.hpp @@ -133,6 +133,11 @@ namespace openvpn { parent.tun_recv(pfp->buf); } + void tun_error_handler(const Error::Type errtype, // called by TunImpl + const boost::system::error_code* error) + { + } + void stop_() { if (!halt) diff --git a/openvpn/tun/tunio.hpp b/openvpn/tun/tunio.hpp index 3ebfc5c6..644501ac 100644 --- a/openvpn/tun/tunio.hpp +++ b/openvpn/tun/tunio.hpp @@ -68,14 +68,14 @@ namespace openvpn { break; default: OPENVPN_LOG_TUN_ERROR("TUN write error: cannot identify IP version for prefix"); - stats->error(Error::TUN_FRAMING_ERROR); + tun_error(Error::TUN_FRAMING_ERROR, NULL); return false; } } else { OPENVPN_LOG_TUN_ERROR("TUN write error: cannot write prefix"); - stats->error(Error::TUN_FRAMING_ERROR); + tun_error(Error::TUN_FRAMING_ERROR, NULL); return false; } } @@ -89,14 +89,14 @@ namespace openvpn { else { OPENVPN_LOG_TUN_ERROR("TUN partial write error"); - stats->error(Error::TUN_WRITE_ERROR); + tun_error(Error::TUN_WRITE_ERROR, NULL); return false; } } catch (boost::system::system_error& e) { OPENVPN_LOG_TUN_ERROR("TUN write error: " << e.what()); - stats->error(Error::TUN_WRITE_ERROR); + tun_error(Error::TUN_WRITE_ERROR, &e.code()); return false; } } @@ -182,18 +182,25 @@ namespace openvpn { else { OPENVPN_LOG_TUN_ERROR("TUN Read Error: cannot read prefix"); - stats->error(Error::TUN_READ_ERROR); + tun_error(Error::TUN_READ_ERROR, NULL); } } else { OPENVPN_LOG_TUN_ERROR("TUN Read Error: " << error.message()); - stats->error(Error::TUN_READ_ERROR); + tun_error(Error::TUN_READ_ERROR, &error); } - queue_read(pfp.release()); // reuse buffer if still available + if (!halt) + queue_read(pfp.release()); // reuse buffer if still available } } + void tun_error(const Error::Type errtype, const boost::system::error_code* error) + { + stats->error(errtype); + read_handler->tun_error_handler(errtype, error); + } + // should be set by derived class constructor std::string name_; STREAM *stream; diff --git a/openvpn/tun/win/client/tuncli.hpp b/openvpn/tun/win/client/tuncli.hpp index f02d72f2..5235fea6 100644 --- a/openvpn/tun/win/client/tuncli.hpp +++ b/openvpn/tun/win/client/tuncli.hpp @@ -495,6 +495,13 @@ namespace openvpn { #endif } + void tun_error_handler(const Error::Type errtype, // called by TunImpl + const boost::system::error_code* error) + { + if (errtype == Error::TUN_READ_ERROR && error && error->value() == 995) + parent.tun_error(Error::TUN_IFACE_DISABLED, "TAP adapter is disabled"); + } + void stop_() { if (!halt)