0
0
mirror of https://github.com/OpenVPN/openvpn3.git synced 2024-09-20 04:02:15 +02:00

On iOS with a split-tunnel, and at least one pushed DNS server:

1. route all DNS requests through pushed DNS server if no added
   search domains.

2. route selected DNS requests through pushed DNS server if at
   least one added search domain.

On Android, apparently there is no selective DNS routing, so all
DNS requests will be routed through pushed DNS server, if at least
one exists.

With redirect-gateway on both platforms, all DNS requests are always
routed through the VPN.
This commit is contained in:
James Yonan 2013-01-26 06:53:31 +00:00
parent c2b20bdb3c
commit d24d0b4aef
4 changed files with 68 additions and 96 deletions

View File

@ -61,8 +61,8 @@ public class OpenVPNClientThread extends ClientAPI_OpenVPNClient implements Runn
boolean tun_builder_reroute_gw(String server_address, boolean server_address_ipv6, boolean ipv4, boolean ipv6, long flags);
boolean tun_builder_add_route(String address, int prefix_length, boolean ipv6);
boolean tun_builder_exclude_route(String address, int prefix_length, boolean ipv6);
boolean tun_builder_add_dns_server(String address, boolean ipv6, boolean reroute_dns);
boolean tun_builder_add_search_domain(String domain, boolean reroute_dns);
boolean tun_builder_add_dns_server(String address, boolean ipv6);
boolean tun_builder_add_search_domain(String domain);
boolean tun_builder_set_mtu(int mtu);
boolean tun_builder_set_session_name(String name);
int tun_builder_establish();
@ -290,20 +290,20 @@ public class OpenVPNClientThread extends ClientAPI_OpenVPNClient implements Runn
}
@Override
public boolean tun_builder_add_dns_server(String address, boolean ipv6, boolean reroute_dns) {
public boolean tun_builder_add_dns_server(String address, boolean ipv6) {
TunBuilder tb = tun_builder;
if (tb != null)
return tb.tun_builder_add_dns_server(address, ipv6, reroute_dns);
return tb.tun_builder_add_dns_server(address, ipv6);
else
return false;
}
@Override
public boolean tun_builder_add_search_domain(String domain, boolean reroute_dns)
public boolean tun_builder_add_search_domain(String domain)
{
TunBuilder tb = tun_builder;
if (tb != null)
return tb.tun_builder_add_search_domain(domain, reroute_dns);
return tb.tun_builder_add_search_domain(domain);
else
return false;
}

View File

@ -29,24 +29,15 @@ namespace openvpn {
// Callback to construct a new tun builder
// Should be called first.
virtual bool tun_builder_new()
{
return false;
}
virtual bool tun_builder_new() = 0;
// Callback to set address of remote server
// Never called more than once per tun_builder session.
virtual bool tun_builder_set_remote_address(const std::string& address, bool ipv6)
{
return false;
}
virtual bool tun_builder_set_remote_address(const std::string& address, bool ipv6) = 0;
// Callback to add network address to VPN interface
// May be called more than once per tun_builder session
virtual bool tun_builder_add_address(const std::string& address, int prefix_length, bool ipv6)
{
return false;
}
virtual bool tun_builder_add_address(const std::string& address, int prefix_length, bool ipv6) = 0;
// Callback to reroute default gateway to VPN interface.
// server_address is provided so that the implementation may exclude
@ -56,61 +47,44 @@ namespace openvpn {
// ipv6 is true if the default route to be added should be IPv6.
// flags are defined in RedirectGatewayFlags
// Never called more than once per tun_builder session.
virtual bool tun_builder_reroute_gw(const std::string& server_address, bool server_address_ipv6, bool ipv4, bool ipv6, unsigned int flags)
{
return false;
}
virtual bool tun_builder_reroute_gw(const std::string& server_address, bool server_address_ipv6, bool ipv4, bool ipv6, unsigned int flags) = 0;
// Callback to add route to VPN interface
// May be called more than once per tun_builder session
virtual bool tun_builder_add_route(const std::string& address, int prefix_length, bool ipv6)
{
return false;
}
virtual bool tun_builder_add_route(const std::string& address, int prefix_length, bool ipv6) = 0;
// Callback to exclude route from VPN interface
// May be called more than once per tun_builder session
virtual bool tun_builder_exclude_route(const std::string& address, int prefix_length, bool ipv6)
{
return false;
}
virtual bool tun_builder_exclude_route(const std::string& address, int prefix_length, bool ipv6) = 0;
// Callback to add DNS server to VPN interface
// May be called more than once per tun_builder session
virtual bool tun_builder_add_dns_server(const std::string& address, bool ipv6, bool reroute_dns)
{
return false;
}
// If reroute_dns is true, all DNS traffic should be routed over the
// tunnel, while if false, only DNS traffic that matches an added search
// domain should be routed.
// Guaranteed to be called after tun_builder_reroute_gw.
virtual bool tun_builder_add_dns_server(const std::string& address, bool ipv6) = 0;
// Callback to add search domain to DNS resolver
// May be called more than once per tun_builder session
virtual bool tun_builder_add_search_domain(const std::string& domain, bool reroute_dns)
{
return false;
}
// See tun_builder_add_dns_server above for description of
// reroute_dns parameter.
// Guaranteed to be called after tun_builder_reroute_gw.
virtual bool tun_builder_add_search_domain(const std::string& domain) = 0;
// Callback to set MTU of the VPN interface
// Never called more than once per tun_builder session.
virtual bool tun_builder_set_mtu(int mtu)
{
return false;
}
virtual bool tun_builder_set_mtu(int mtu) = 0;
// Callback to set the session name
// Never called more than once per tun_builder session.
virtual bool tun_builder_set_session_name(const std::string& name)
{
return false;
}
virtual bool tun_builder_set_session_name(const std::string& name) = 0;
// Callback to establish the VPN tunnel, returning a file descriptor
// to the tunnel, which the caller will henceforth own. Returns -1
// if the tunnel could not be established.
// Always called last after tun_builder session has been configured.
virtual int tun_builder_establish()
{
return -1;
}
virtual int tun_builder_establish() = 0;
// Called just before tunnel socket is closed
virtual void tun_builder_teardown()

View File

@ -95,7 +95,18 @@ namespace openvpn {
}
};
TunBuilderCapture() : mtu(1500), reroute_dns(false) {}
TunBuilderCapture() : mtu(1500) {}
virtual bool tun_builder_new()
{
return false;
}
virtual int tun_builder_establish()
{
return -1;
}
virtual bool tun_builder_set_remote_address(const std::string& address, bool ipv6)
{
@ -142,22 +153,20 @@ namespace openvpn {
return true;
}
virtual bool tun_builder_add_dns_server(const std::string& address, bool ipv6, bool reroute_dns)
virtual bool tun_builder_add_dns_server(const std::string& address, bool ipv6)
{
DNSServer dns;
dns.address = address;
dns.ipv6 = ipv6;
dns_servers.push_back(dns);
this->reroute_dns = reroute_dns;
return true;
}
virtual bool tun_builder_add_search_domain(const std::string& domain, bool reroute_dns)
virtual bool tun_builder_add_search_domain(const std::string& domain)
{
SearchDomain dom;
dom.domain = domain;
search_domains.push_back(dom);
this->reroute_dns = reroute_dns;
return true;
}
@ -181,7 +190,6 @@ namespace openvpn {
os << "Remote Address: " << remote_address.to_string() << std::endl;
render_route_list(os, "Tunnel Addresses", tunnel_addresses);
os << "Reroute Gateway: " << reroute_gw.to_string() << std::endl;
os << "Reroute DNS: " << reroute_dns << std::endl;
render_route_list(os, "Add Routes", add_routes);
render_route_list(os, "Exclude Routes", exclude_routes);
{
@ -203,7 +211,6 @@ namespace openvpn {
RemoteAddress remote_address; // real address of server
std::vector<Route> tunnel_addresses; // local tunnel addresses
RerouteGW reroute_gw; // redirect-gateway info for ipv4
bool reroute_dns; // redirect DNS requests through tunnel
std::vector<Route> add_routes; // routes that should be added to tunnel
std::vector<Route> exclude_routes; // routes that should be excluded from tunnel
std::vector<DNSServer> dns_servers; // VPN DNS servers

View File

@ -354,19 +354,14 @@ namespace openvpn {
// add routes
const unsigned int reroute_gw_ver_flags = add_routes(tb, opt, server_addr, ip_ver_flags);
// Should all DNS requests be rerouted through pushed DNS servers?
// (If false, only DNS requests that correspond to pushed domain prefixes
// will be routed).
const bool reroute_dns = should_reroute_dns(opt, reroute_gw_ver_flags, quiet);
// add DNS servers and domain prefixes
const unsigned int add_dns_flags = add_dns(tb, opt, reroute_dns, quiet);
const unsigned int add_dns_flags = add_dns(tb, opt, quiet);
// DNS fallback
if ((reroute_gw_ver_flags & F_IPv4) && !(add_dns_flags & F_ADD_DNS))
{
if (config.google_dns_fallback)
add_google_dns(tb, reroute_dns);
add_google_dns(tb);
else if (stats)
stats->error(Error::REROUTE_GW_NO_DNS);
}
@ -391,31 +386,6 @@ namespace openvpn {
}
}
static bool should_reroute_dns(const OptionList& opt,
const unsigned int reroute_gw_ver_flags,
const bool quiet)
{
bool ret = bool(reroute_gw_ver_flags & F_IPv4);
try {
const std::string& yes_no = opt.get_optional("redirect-dns", 1, 16); // DIRECTIVE
if (!yes_no.empty())
{
if (yes_no == "yes")
ret = true;
else if (yes_no == "no")
ret = false;
else if (!quiet)
OPENVPN_LOG("unknown redirect-dns option: " << yes_no);
}
}
catch (const std::exception& e)
{
if (!quiet)
OPENVPN_LOG("error parsing redirect-dns: " << e.what());
}
return ret;
}
static unsigned int tun_ifconfig(TunBuilderBase* tb, ClientState* state, const OptionList& opt)
{
enum Topology {
@ -620,7 +590,7 @@ namespace openvpn {
return reroute_gw_ver_flags;
}
static unsigned int add_dns(TunBuilderBase* tb, const OptionList& opt, const bool reroute_dns, const bool quiet)
static unsigned int add_dns(TunBuilderBase* tb, const OptionList& opt, const bool quiet)
{
// Example:
// [dhcp-option] [DNS] [172.16.0.23]
@ -642,8 +612,7 @@ namespace openvpn {
o.exact_args(3);
const IP::Addr ip = IP::Addr::from_string(o.get(2, 256), "dns-server-ip");
if (!tb->tun_builder_add_dns_server(ip.to_string(),
ip.version() == IP::Addr::V6,
reroute_dns))
ip.version() == IP::Addr::V6))
throw tun_builder_dhcp_option_error("tun_builder_add_dns_server failed");
flags |= F_ADD_DNS;
}
@ -656,7 +625,7 @@ namespace openvpn {
strvec v = Split::by_space<strvec, StandardLex, SpaceMatch, Split::NullLimit>(o.get(j, 256));
for (size_t k = 0; k < v.size(); ++k)
{
if (!tb->tun_builder_add_search_domain(v[k], reroute_dns))
if (!tb->tun_builder_add_search_domain(v[k]))
throw tun_builder_dhcp_option_error("tun_builder_add_search_domain failed");
}
}
@ -673,10 +642,32 @@ namespace openvpn {
return flags;
}
static void add_google_dns(TunBuilderBase* tb, const bool reroute_dns)
static bool search_domains_exist(const OptionList& opt)
{
if (!tb->tun_builder_add_dns_server("8.8.8.8", false, reroute_dns)
|| !tb->tun_builder_add_dns_server("8.8.4.4", false, reroute_dns))
OptionList::IndexMap::const_iterator dopt = opt.map().find("dhcp-option"); // DIRECTIVE
if (dopt != opt.map().end())
{
for (OptionList::IndexList::const_iterator i = dopt->second.begin(); i != dopt->second.end(); ++i)
{
const Option& o = opt[*i];
try {
const std::string& type = o.get(1, 64);
if (type == "DOMAIN")
return true;
}
catch (const std::exception& e)
{
OPENVPN_THROW(tun_builder_error, "error parsing dhcp-option: " << o.render() << " : " << e.what());
}
}
}
return false;
}
static void add_google_dns(TunBuilderBase* tb)
{
if (!tb->tun_builder_add_dns_server("8.8.8.8", false)
|| !tb->tun_builder_add_dns_server("8.8.4.4", false))
throw tun_builder_dhcp_option_error("tun_builder_add_dns_server failed for Google DNS");
}