From 9c4e5361f4b60950b1c2197c69763acd16fd8579 Mon Sep 17 00:00:00 2001 From: PeratX <1215714524@qq.com> Date: Thu, 6 Jul 2017 14:57:43 +0800 Subject: [PATCH] Added support for IPv6 --- .../daedalus/fragment/DNSTestFragment.java | 11 +++- .../daedalus/provider/UdpProvider.java | 8 ++- .../daedalus/service/DaedalusVpnService.java | 60 ++++++++++++------- 3 files changed, 56 insertions(+), 23 deletions(-) diff --git a/app/src/main/java/org/itxtech/daedalus/fragment/DNSTestFragment.java b/app/src/main/java/org/itxtech/daedalus/fragment/DNSTestFragment.java index 0ba94d6..d128329 100644 --- a/app/src/main/java/org/itxtech/daedalus/fragment/DNSTestFragment.java +++ b/app/src/main/java/org/itxtech/daedalus/fragment/DNSTestFragment.java @@ -114,7 +114,7 @@ public class DNSTestFragment extends ToolbarFragment { String servers = Daedalus.getPrefs().getString("dns_test_servers", ""); if (!servers.equals("")) { for (String server : servers.split(",")) { - if (server.contains(":")) { + if (server.contains(".") && server.contains(":")) {//IPv4 String[] pieces = servers.split(":"); int port = AbstractDNSServer.DNS_SERVER_DEFAULT_PORT; try { @@ -123,6 +123,15 @@ public class DNSTestFragment extends ToolbarFragment { Logger.logException(e); } add(new AbstractDNSServer(pieces[0], port)); + } else if (!server.contains(".") && server.contains("|")) {//IPv6 + String[] pieces = servers.split("\\|"); + int port = AbstractDNSServer.DNS_SERVER_DEFAULT_PORT; + try { + port = Integer.parseInt(pieces[1]); + } catch (Exception e) { + Logger.logException(e); + } + add(new AbstractDNSServer(pieces[0], port)); } else { add(new AbstractDNSServer(server, AbstractDNSServer.DNS_SERVER_DEFAULT_PORT)); } diff --git a/app/src/main/java/org/itxtech/daedalus/provider/UdpProvider.java b/app/src/main/java/org/itxtech/daedalus/provider/UdpProvider.java index b1578b4..ec1a881 100644 --- a/app/src/main/java/org/itxtech/daedalus/provider/UdpProvider.java +++ b/app/src/main/java/org/itxtech/daedalus/provider/UdpProvider.java @@ -244,6 +244,12 @@ public class UdpProvider extends Provider { * @param responsePayload The payload of the response */ void handleDnsResponse(IpPacket requestPacket, byte[] responsePayload) { + try { + DNSMessage message = new DNSMessage(responsePayload); + Logger.info(message.toString()); + } catch (IOException e) { + Logger.logException(e); + } UdpPacket udpOutPacket = (UdpPacket) requestPacket.getPayload(); UdpPacket.Builder payLoadBuilder = new UdpPacket.Builder(udpOutPacket) .srcPort(udpOutPacket.getHeader().getDstPort()) @@ -357,7 +363,7 @@ public class UdpProvider extends Provider { builder.addAnswer(new Record<>(dnsQueryName, Record.TYPE.A, 1, 64, new A(ip[0], ip[1], ip[2], ip[3]))); handleDnsResponse(parsedPacket, builder.build().toArray()); } else { - Logger.info("Provider: Resolving " + dnsQueryName + " Sending to " + destAddr); + Logger.info("Provider: Resolving " + dnsQueryName + " Type: " + dnsMsg.getQuestion().type.name() + " Sending to " + destAddr); DatagramPacket outPacket = new DatagramPacket(dnsRawData, 0, dnsRawData.length, destAddr, DNSServerHelper.getPortOrDefault(destAddr, parsedUdp.getHeader().getDstPort().valueAsInt())); forwardPacket(outPacket, parsedPacket); diff --git a/app/src/main/java/org/itxtech/daedalus/service/DaedalusVpnService.java b/app/src/main/java/org/itxtech/daedalus/service/DaedalusVpnService.java index 03d12cc..952f41b 100644 --- a/app/src/main/java/org/itxtech/daedalus/service/DaedalusVpnService.java +++ b/app/src/main/java/org/itxtech/daedalus/service/DaedalusVpnService.java @@ -22,7 +22,10 @@ import org.itxtech.daedalus.util.Logger; import org.itxtech.daedalus.util.RulesResolver; import org.itxtech.daedalus.util.server.DNSServerHelper; +import java.net.Inet4Address; +import java.net.Inet6Address; import java.net.InetAddress; +import java.net.UnknownHostException; import java.util.HashMap; /** @@ -175,11 +178,33 @@ public class DaedalusVpnService extends VpnService implements Runnable { stopThread(); } + private InetAddress addDnsServer(Builder builder, String format, byte[] ipv6Template, InetAddress address) throws UnknownHostException { + int size = dnsServers.size(); + size++; + if (address instanceof Inet4Address) { + String alias = String.format(format, size + 1); + dnsServers.put(alias, address.getHostAddress()); + builder.addRoute(alias, 32); + return InetAddress.getByName(alias); + } else if (address instanceof Inet6Address) { + /*ipv6Template[ipv6Template.length - 1] = (byte) (size + 1); + InetAddress i6addr = Inet6Address.getByAddress(ipv6Template); + dnsServers.put(i6addr.getHostAddress(), address.getHostAddress()); + return i6addr;*/ + return address; + } + return null; + } + @TargetApi(Build.VERSION_CODES.LOLLIPOP) @Override public void run() { try { - Builder builder = new Builder(); + Builder builder = new Builder() + .setSession("Daedalus") + .setConfigureIntent(PendingIntent.getActivity(this, 0, + new Intent(this, MainActivity.class).putExtra(MainActivity.LAUNCH_FRAGMENT, MainActivity.FRAGMENT_SETTINGS), + PendingIntent.FLAG_ONE_SHOT)); String format = null; for (String prefix : new String[]{"10.0.0", "192.0.2", "198.51.100", "203.0.113", "192.168.50"}) { try { @@ -194,34 +219,27 @@ public class DaedalusVpnService extends VpnService implements Runnable { boolean advanced = Daedalus.getPrefs().getBoolean("settings_advanced_switch", false); statisticQuery = Daedalus.getPrefs().getBoolean("settings_count_query_times", false); + byte[] ipv6Template = new byte[]{32, 1, 13, (byte) (184 & 0xFF), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - String aliasPrimary; - String aliasSecondary; + InetAddress aliasPrimary; + InetAddress aliasSecondary; if (advanced) { dnsServers = new HashMap<>(); - aliasPrimary = String.format(format, 2); - dnsServers.put(aliasPrimary, primaryServer); - aliasSecondary = String.format(format, 3); - dnsServers.put(aliasSecondary, secondaryServer); + aliasPrimary = addDnsServer(builder, format, ipv6Template, InetAddress.getByName(primaryServer)); + aliasSecondary = addDnsServer(builder, format, ipv6Template, InetAddress.getByName(secondaryServer)); } else { - aliasPrimary = primaryServer; - aliasSecondary = secondaryServer; + aliasPrimary = InetAddress.getByName(primaryServer); + aliasSecondary = InetAddress.getByName(secondaryServer); } - InetAddress primaryDNSServer = InetAddress.getByName(aliasPrimary); - InetAddress secondaryDNSServer = InetAddress.getByName(aliasSecondary); - Logger.info("Daedalus VPN service is listening on " + primaryDNSServer.getHostAddress() + " and " + secondaryDNSServer.getHostAddress()); - builder.setSession("Daedalus") - .addDnsServer(primaryDNSServer) - .addDnsServer(secondaryDNSServer) - .setConfigureIntent(PendingIntent.getActivity(this, 0, - new Intent(this, MainActivity.class).putExtra(MainActivity.LAUNCH_FRAGMENT, MainActivity.FRAGMENT_SETTINGS), - PendingIntent.FLAG_ONE_SHOT)); + InetAddress primaryDNSServer = aliasPrimary; + InetAddress secondaryDNSServer = aliasSecondary; + Logger.info("Daedalus VPN service is listening on " + primaryServer + " as " + primaryDNSServer.getHostAddress()); + Logger.info("Daedalus VPN service is listening on " + secondaryServer + " as " + secondaryDNSServer.getHostAddress()); + builder.addDnsServer(primaryDNSServer).addDnsServer(secondaryDNSServer); if (advanced) { - builder.addRoute(primaryDNSServer, primaryDNSServer.getAddress().length * 8) - .addRoute(secondaryDNSServer, secondaryDNSServer.getAddress().length * 8) - .setBlocking(true); + builder.setBlocking(true); } descriptor = builder.establish();