14#ifndef OPENVPN_TUN_CLIENT_TUNPROP_H
15#define OPENVPN_TUN_CLIENT_TUNPROP_H
57#if defined(OPENVPN_PLATFORM_WIN) || defined(OPENVPN_PLATFORM_MAC) || defined(OPENVPN_PLATFORM_LINUX) || defined(OPENVPN_PLATFORM_IPHONE)
78 struct State :
public RC<thread_unsafe_refcount>
115 throw tun_prop_error(
"one of ifconfig or ifconfig-ipv6 must be specified");
128 if (
config.allow_local_lan_access)
137 excludedRoutesOptions.
add_item(
Option{
"route", exRoute,
"",
"net_gateway"});
142 excludedRoutesOptions.
add_item(
Option{
"route-ipv6", exRoute,
"net_gateway"});
145 add_routes(tb, excludedRoutesOptions, ipv, eer.
get(), quiet);
153 if (eer && server_addr.
defined())
157 eer->add_default_routes(ipv.
rgv4(), ipv.
rgv6());
159 eer->emulate(tb, ipv, server_addr);
165 throw tun_prop_route_error(
"tun_builder_reroute_gw for redirect-gateway failed");
169 bool dns_option_added =
add_dns_options(tb, opt, quiet,
config.dhcp_search_domains_as_split_domains);
182 if (ipv.
rgv4() && !dns_option_added)
184 if (
config.google_dns_fallback)
198 throw tun_prop_error(
"tun_builder_set_remote_address failed");
202 throw tun_prop_error(
"tun_builder_set_layer failed");
208 if (!
config.session_name.empty())
211 throw tun_prop_error(
"tun_builder_set_session_name failed");
227 throw tun_prop_error(
"route-metric is out of range");
229 throw tun_prop_error(
"tun_builder_set_route_metric_default failed");
232 catch (
const std::exception &e)
235 OPENVPN_LOG(
"exception processing route-metric: " << e.what());
247 throw tun_prop_error(
"route-gateway is not IPv4 (IPv6 route-gateway is passed with ifconfig-ipv6 directive)");
263 bool status = parse_number_validate<decltype(tun_mtu)>(o->
get(1, 16),
271 throw option_error(ERR_INVALID_OPTION_VAL,
"tun-mtu parse/range issue");
280 throw tun_prop_error(
"tun_builder_set_mtu failed");
297 Topology top = NET30;
302 const std::string &topstr = o->
get(1, 16);
303 if (topstr ==
"subnet")
305 else if (topstr ==
"net30")
308 throw option_error(ERR_INVALID_OPTION_VAL,
"only topology 'subnet' and 'net30' supported");
323 throw tun_prop_error(
"ifconfig address is not IPv4 (topology subnet)");
329 throw tun_prop_error(
"tun_builder_add_address IPv4 failed (topology subnet)");
337 else if (top == NET30)
343 throw tun_prop_error(
"ifconfig address is not IPv4 (topology net30)");
344 if ((local & netmask) != (remote & netmask))
345 throw tun_prop_error(
"ifconfig addresses are not in the same /30 subnet (topology net30)");
351 throw tun_prop_error(
"tun_builder_add_address IPv4 failed (topology net30)");
360 throw option_error(ERR_INVALID_OPTION_VAL,
"internal topology error");
363 o = opt.
get_ptr(
"ifconfig-ipv6");
369 throw tun_prop_error(
"ifconfig-ipv6 address is not IPv6");
370 std::string gateway_str;
375 throw tun_prop_error(
"ifconfig-ipv6 gateway is not IPv6");
385 throw tun_prop_error(
"tun_builder_add_address IPv6 failed");
403 const std::string addr_str = addr.
to_string();
409 throw tun_prop_route_error(
"tun_builder_add_route failed");
414 throw tun_prop_route_error(
"tun_builder_exclude_route failed");
422 if (o.
size() >= (target_index + 1))
424 const std::string &target = o.
ref(target_index);
425 if (target ==
"vpn_gateway")
427 else if (target ==
"net_gateway")
430 throw tun_prop_route_error(
"route destinations other than vpn_gateway or net_gateway are not supported");
445 OptionList::IndexMap::const_iterator dopt = opt.
map().find(
"route");
446 if (dopt != opt.
map().end())
448 for (OptionList::IndexList::const_iterator i = dopt->second.begin(); i != dopt->second.end(); ++i)
450 const Option &o = opt[*i];
456 throw tun_prop_error(
"route is not canonical");
458 throw tun_prop_error(
"route is not IPv4");
462 catch (
const std::exception &e)
474 OptionList::IndexMap::const_iterator dopt = opt.
map().find(
"route-ipv6");
475 if (dopt != opt.
map().end())
477 for (OptionList::IndexList::const_iterator i = dopt->second.begin(); i != dopt->second.end(); ++i)
479 const Option &o = opt[*i];
485 throw tun_prop_error(
"route is not canonical");
487 throw tun_prop_error(
"route is not IPv6");
491 catch (
const std::exception &e)
509 for (IP::AddrList::const_iterator i = addrlist.begin(); i != addrlist.end(); ++i)
512 if (addr != server_addr)
519 catch (
const std::exception &e)
546 throw tun_prop_dns_option_error(
"tun_builder_set_dns_options failed");
550 catch (
const std::exception &e)
579 OptionList::IndexMap::const_iterator dopt = opt.
map().find(
"dhcp-option");
580 if (dopt != opt.
map().end())
582 std::string auto_config_url;
583 std::string http_host;
584 unsigned int http_port = 0;
585 std::string https_host;
586 unsigned int https_port = 0;
587 for (OptionList::IndexList::const_iterator i = dopt->second.begin(); i != dopt->second.end(); ++i)
589 const Option &o = opt[*i];
592 const std::string &type = o.
get(1, 64);
593 if (type ==
"DNS" || type ==
"DNS6" || type ==
"DOMAIN" || type ==
"DOMAIN-SEARCH" || type ==
"ADAPTER_DOMAIN_SUFFIX")
598 else if (type ==
"PROXY_BYPASS")
601 for (
size_t j = 2; j < o.
size(); ++j)
603 typedef std::vector<std::string> strvec;
604 strvec v = Split::by_space<strvec, StandardLex, SpaceMatch, Split::NullLimit>(o.
get(j, 256));
605 for (
size_t k = 0; k < v.size(); ++k)
608 throw tun_prop_dhcp_option_error(ERR_INVALID_OPTION_PUSHED,
"tun_builder_add_proxy_bypass");
612 else if (type ==
"PROXY_AUTO_CONFIG_URL")
615 auto_config_url = o.
get(2, 256);
617 else if (type ==
"PROXY_HTTP")
620 http_host = o.
get(2, 256);
623 else if (type ==
"PROXY_HTTPS")
626 https_host = o.
get(2, 256);
629 else if (type ==
"WINS")
634 throw tun_prop_dhcp_option_error(ERR_INVALID_OPTION_PUSHED,
"WINS addresses must be IPv4");
636 throw tun_prop_dhcp_option_error(ERR_INVALID_OPTION_PUSHED,
"tun_builder_add_wins_server failed");
641 catch (
const std::exception &e)
649 if (!http_host.empty())
652 throw tun_prop_dhcp_option_error(ERR_INVALID_OPTION_PUSHED,
"tun_builder_set_proxy_http");
654 if (!https_host.empty())
657 throw tun_prop_dhcp_option_error(ERR_INVALID_OPTION_PUSHED,
"tun_builder_set_proxy_https");
659 if (!auto_config_url.empty())
662 throw tun_prop_dhcp_option_error(ERR_INVALID_OPTION_PUSHED,
"tun_builder_set_proxy_auto_config_url");
665 catch (
const std::exception &e)
668 OPENVPN_LOG(
"exception setting dhcp-option for proxy: " << e.what());
675 OptionList::IndexMap::const_iterator dopt = opt.
map().find(
"dhcp-option");
676 if (dopt != opt.
map().end())
678 for (OptionList::IndexList::const_iterator i = dopt->second.begin(); i != dopt->second.end(); ++i)
680 const Option &o = opt[*i];
683 const std::string &type = o.
get(1, 64);
684 if (type ==
"DOMAIN")
687 catch (
const std::exception &e)
701 server.
addresses = {{{
"8.8.8.8"}, 0}, {{
"8.8.4.4"}, 0}};
702 google_dns.
servers[0] = std::move(server);
704 throw tun_prop_dns_option_error(ERR_INVALID_OPTION_PUSHED,
"tun_builder_set_dns_options failed for Google DNS");
unsigned int api_flags() const
static Addr from_string(const std::string &ipstr, const TITLE &title, const Version required_version)
std::string to_string() const
unsigned int prefix_len() const
static unsigned int version_size(Version v)
const IndexMap & map() const
void add_item(const Option &opt)
const Option * get_ptr(const std::string &name) const
bool exists(const std::string &name) const
void exact_args(const size_t n) const
std::string get_optional(const size_t index, const size_t max_len) const
const std::string & get(const size_t index, const size_t max_len) const
T get_num(const size_t idx) const
void min_args(const size_t n) const
const std::string & ref(const size_t i) const
std::string render(const unsigned int flags) const
T * get() const noexcept
Returns the raw pointer to the object T, or nullptr.
Reference count base class for objects tracked by RCPtr. Disallows copying and assignment.
void cached_ip_address_list(IP::AddrList &addrlist) const
virtual void error(const size_t type, const std::string *text=nullptr)
TunBuilder methods, loosely based on the Android VpnService.Builder abstraction.
virtual bool tun_builder_set_dns_options(const DnsOptions &dns)
Callback to set DNS related options to VPN interface.
virtual bool tun_builder_add_address(const std::string &address, int prefix_length, const std::string &gateway, bool ipv6, bool net30)
Callback to add a network address to the VPN interface.
virtual bool tun_builder_add_route(const std::string &address, int prefix_length, int metric, bool ipv6)
Callback to add a route to the VPN interface.
virtual bool tun_builder_set_route_metric_default(int metric)
Optional callback to set default value for route metric.
virtual bool tun_builder_set_proxy_http(const std::string &host, int port)
Callback to set the HTTP proxy.
virtual bool tun_builder_reroute_gw(bool ipv4, bool ipv6, unsigned int flags)
Callback to reroute the default gateway to the VPN interface.
virtual bool tun_builder_add_wins_server(const std::string &address)
Callback to add a Windows WINS server to the VPN interface.
virtual bool tun_builder_set_layer(int layer)
Optional callback that indicates OSI layer to be used.
virtual std::vector< std::string > tun_builder_get_local_networks(bool ipv6)
Retrieves a list of local networks to exclude from the VPN network.
virtual bool tun_builder_add_proxy_bypass(const std::string &bypass_host)
Callback to add a host which should bypass the proxy.
virtual bool tun_builder_set_allow_family(int af, bool allow)
Indicates whether traffic of a certain address family (AF_INET or AF_INET6) should be blocked or allo...
virtual bool tun_builder_set_proxy_https(const std::string &host, int port)
Set the HTTPS proxy for the TunBuilder session.
virtual bool tun_builder_exclude_route(const std::string &address, int prefix_length, int metric, bool ipv6)
Callback to exclude route from VPN interface.
virtual bool tun_builder_set_allow_local_dns(bool allow)
Optional callback that indicates whether local DNS traffic should be blocked or allowed to prevent DN...
virtual bool tun_builder_set_mtu(int mtu)
Callback to set the MTU of the VPN interface.
virtual bool tun_builder_set_remote_address(const std::string &address, bool ipv6)
Callback to set the address of the remote server.
virtual bool tun_builder_set_proxy_auto_config_url(const std::string &url)
Callback to set the proxy "Auto Config URL".
virtual bool tun_builder_set_session_name(const std::string &name)
Sets the session name for the TunBuilder.
static void configure_builder(TunBuilderBase *tb, State *state, SessionStats *stats, const IP::Addr &server_addr, const Config &config, const OptionList &opt, const EmulateExcludeRouteFactory *eer_factory, const bool quiet)
OPENVPN_UNTAGGED_EXCEPTION_INHERIT(option_error, tun_prop_dns_option_error)
static void add_route_tunbuilder(TunBuilderBase *tb, bool add, const IP::Addr &addr, int prefix_length, int metric, bool ipv6, EmulateExcludeRoute *eer)
static IP::Addr route_gateway(const OptionList &opt)
OPENVPN_EXCEPTION(tun_prop_error)
static void add_google_dns(TunBuilderBase *tb)
static void add_remote_bypass_routes(TunBuilderBase *tb, const RemoteList &remote_list, const IP::Addr &server_addr, EmulateExcludeRoute *eer, const bool quiet)
static void tun_mtu(TunBuilderBase *tb, State *state, const OptionList &opt, int config_mtu, int config_mtu_max)
static void add_route_metric_default(TunBuilderBase *tb, const OptionList &opt, const bool quiet)
static bool route_target(const Option &o, const size_t target_index)
OPENVPN_UNTAGGED_EXCEPTION_INHERIT(option_error, tun_prop_dhcp_option_error)
static bool search_domains_exist(const OptionList &opt, const bool quiet)
static constexpr int MAX_ROUTE_METRIC
OPENVPN_EXCEPTION(tun_prop_route_error)
static bool add_dns_options(TunBuilderBase *tb, const OptionList &opt, bool quiet, bool use_dhcp_search_domains_as_split_domains)
Configure tun builder to use DNS related options if defined.
static void add_routes(TunBuilderBase *tb, const OptionList &opt, const IPVerFlags &ipv, EmulateExcludeRoute *eer, const bool quiet)
static IP::Addr::VersionMask tun_ifconfig(TunBuilderBase *tb, State *state, const OptionList &opt)
static void add_dhcp_options(TunBuilderBase *tb, const OptionList &opt, const bool quiet)
Parse options for WINS and HTTP Proxy –dhcp-option(s) and add them to the tunbuilder (tb) passed.
#define OPENVPN_LOG(args)
void validate_port(const std::string &port, const std::string &title, unsigned int *value=nullptr)
constexpr std::uint32_t INVALID_ADAPTER_INDEX
All DNS options set with the –dns or –dhcp-option directive.
std::map< int, DnsServer > servers
DNS settings for a name server.
std::vector< DnsAddress > addresses
virtual EmulateExcludeRoute::Ptr new_obj() const =0
virtual void add_route(const bool add, const IP::Addr &addr, const int prefix_len)=0
bool is_canonical() const
static AddrMaskPair from_string(const std::string &s1, const std::string &s2, const char *title=nullptr)
Addr::Version version() const
RemoteList::Ptr remote_list
bool dhcp_search_domains_as_split_domains
bool allow_local_lan_access
std::uint32_t vpn_interface_index
std::vector< TunBuilderCapture::Route > add_routes
static const char config[]
static void add(const Time &t1, const Time::Duration &d1)