Return original packet immediately when network unreachable

This commit is contained in:
PeratX 2017-06-13 19:12:24 +08:00
parent 1a3eb4a376
commit 384c1dafcd
11 changed files with 42 additions and 54 deletions

View File

@ -13,7 +13,7 @@ import android.view.View;
import org.itxtech.daedalus.Daedalus; import org.itxtech.daedalus.Daedalus;
import org.itxtech.daedalus.R; import org.itxtech.daedalus.R;
import org.itxtech.daedalus.fragment.ConfigFragment; import org.itxtech.daedalus.fragment.ConfigFragment;
import org.itxtech.daedalus.fragment.DnsServerConfigFragment; import org.itxtech.daedalus.fragment.DNSServerConfigFragment;
import org.itxtech.daedalus.fragment.RuleConfigFragment; import org.itxtech.daedalus.fragment.RuleConfigFragment;
/** /**
@ -43,13 +43,13 @@ public class ConfigActivity extends AppCompatActivity {
ConfigFragment fragment; ConfigFragment fragment;
switch (getIntent().getIntExtra(LAUNCH_ACTION_FRAGMENT, LAUNCH_FRAGMENT_DNS_SERVER)) { switch (getIntent().getIntExtra(LAUNCH_ACTION_FRAGMENT, LAUNCH_FRAGMENT_DNS_SERVER)) {
case LAUNCH_FRAGMENT_DNS_SERVER: case LAUNCH_FRAGMENT_DNS_SERVER:
fragment = new DnsServerConfigFragment(); fragment = new DNSServerConfigFragment();
break; break;
case LAUNCH_FRAGMENT_RULE: case LAUNCH_FRAGMENT_RULE:
fragment = new RuleConfigFragment(); fragment = new RuleConfigFragment();
break; break;
default://should never reach this default://should never reach this
fragment = new DnsServerConfigFragment(); fragment = new DNSServerConfigFragment();
break; break;
} }

View File

@ -211,10 +211,10 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
switchFragment(new AboutFragment()); switchFragment(new AboutFragment());
break; break;
case FRAGMENT_DNS_SERVERS: case FRAGMENT_DNS_SERVERS:
switchFragment(new DnsServersFragment()); switchFragment(new DNSServersFragment());
break; break;
case FRAGMENT_DNS_TEST: case FRAGMENT_DNS_TEST:
switchFragment(new DnsTestFragment()); switchFragment(new DNSTestFragment());
break; break;
case FRAGMENT_MAIN: case FRAGMENT_MAIN:
switchFragment(new MainFragment()); switchFragment(new MainFragment());
@ -244,10 +244,10 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On
switchFragment(new AboutFragment()); switchFragment(new AboutFragment());
break; break;
case R.id.nav_dns_server: case R.id.nav_dns_server:
switchFragment(new DnsServersFragment()); switchFragment(new DNSServersFragment());
break; break;
case R.id.nav_dns_test: case R.id.nav_dns_test:
switchFragment(new DnsTestFragment()); switchFragment(new DNSTestFragment());
break; break;
case R.id.nav_github: case R.id.nav_github:
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://github.com/iTXTech/Daedalus"))); startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://github.com/iTXTech/Daedalus")));

View File

@ -27,7 +27,7 @@ import org.itxtech.daedalus.util.server.DNSServer;
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
*/ */
public class DnsServerConfigFragment extends ConfigFragment { public class DNSServerConfigFragment extends ConfigFragment {
private int index; private int index;
@Override @Override

View File

@ -28,8 +28,8 @@ import org.itxtech.daedalus.util.server.DNSServerHelper;
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
*/ */
public class DnsServersFragment extends ToolbarFragment { public class DNSServersFragment extends ToolbarFragment {
private DnsServersFragment.DnsServerAdapter adapter; private DNSServerAdapter adapter;
private CustomDNSServer server = null; private CustomDNSServer server = null;
@Override @Override
@ -38,7 +38,7 @@ public class DnsServersFragment extends ToolbarFragment {
RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.recyclerView_dns_servers); RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.recyclerView_dns_servers);
LinearLayoutManager manager = new LinearLayoutManager(getActivity()); LinearLayoutManager manager = new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(manager); recyclerView.setLayoutManager(manager);
adapter = new DnsServerAdapter(); adapter = new DNSServerAdapter();
recyclerView.setAdapter(adapter); recyclerView.setAdapter(adapter);
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(new ItemTouchHelper.Callback() { ItemTouchHelper itemTouchHelper = new ItemTouchHelper(new ItemTouchHelper.Callback() {
@Override @Override
@ -119,7 +119,7 @@ public class DnsServersFragment extends ToolbarFragment {
adapter.notifyDataSetChanged(); adapter.notifyDataSetChanged();
} }
private class DnsServerAdapter extends RecyclerView.Adapter<ViewHolder> { private class DNSServerAdapter extends RecyclerView.Adapter<ViewHolder> {
@Override @Override
public void onBindViewHolder(ViewHolder holder, int position) { public void onBindViewHolder(ViewHolder holder, int position) {
CustomDNSServer server = Daedalus.configurations.getCustomDNSServers().get(position); CustomDNSServer server = Daedalus.configurations.getCustomDNSServers().get(position);

View File

@ -35,7 +35,7 @@ import java.util.Random;
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
*/ */
public class DnsTestFragment extends ToolbarFragment { public class DNSTestFragment extends ToolbarFragment {
private class Type { private class Type {
private Record.TYPE type; private Record.TYPE type;
private String name; private String name;

View File

@ -86,7 +86,7 @@ public class RuleConfigFragment extends ConfigFragment {
}); });
final ListPreference ruleType = (ListPreference) findPreference("ruleType"); final ListPreference ruleType = (ListPreference) findPreference("ruleType");
final String[] entries = {"hosts", "DNSMasq"}; final String[] entries = {"Hosts", "DNSMasq"};
String[] values = {"0", "1"}; String[] values = {"0", "1"};
ruleType.setEntries(entries); ruleType.setEntries(entries);
ruleType.setEntryValues(values); ruleType.setEntryValues(values);

View File

@ -14,13 +14,13 @@ import org.itxtech.daedalus.service.DaedalusVpnService;
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
*/ */
public abstract class DnsProvider { public abstract class Provider {
ParcelFileDescriptor descriptor; ParcelFileDescriptor descriptor;
DaedalusVpnService service; DaedalusVpnService service;
boolean running = false; boolean running = false;
static long dnsQueryTimes = 0; static long dnsQueryTimes = 0;
DnsProvider(ParcelFileDescriptor descriptor, DaedalusVpnService service) { Provider(ParcelFileDescriptor descriptor, DaedalusVpnService service) {
this.descriptor = descriptor; this.descriptor = descriptor;
this.service = service; this.service = service;
dnsQueryTimes = 0; dnsQueryTimes = 0;

View File

@ -33,13 +33,13 @@ import java.util.LinkedList;
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
*/ */
public class TcpDnsProvider extends UdpDnsProvider { public class TcpProvider extends UdpProvider {
private static final String TAG = "TcpDnsProvider"; private static final String TAG = "TcpProvider";
private final TcpDnsProvider.WospList dnsIn = new TcpDnsProvider.WospList(); private final TcpProvider.WospList dnsIn = new TcpProvider.WospList();
public TcpDnsProvider(ParcelFileDescriptor descriptor, DaedalusVpnService service) { public TcpProvider(ParcelFileDescriptor descriptor, DaedalusVpnService service) {
super(descriptor, service); super(descriptor, service);
} }
@ -70,7 +70,7 @@ public class TcpDnsProvider extends UdpDnsProvider {
polls[1] = blockFd; polls[1] = blockFd;
{ {
int i = -1; int i = -1;
for (TcpDnsProvider.WaitingOnSocketPacket wosp : dnsIn) { for (TcpProvider.WaitingOnSocketPacket wosp : dnsIn) {
i++; i++;
StructPollfd pollFd = polls[2 + i] = new StructPollfd(); StructPollfd pollFd = polls[2 + i] = new StructPollfd();
pollFd.fd = ParcelFileDescriptor.fromSocket(wosp.socket).getFileDescriptor(); pollFd.fd = ParcelFileDescriptor.fromSocket(wosp.socket).getFileDescriptor();
@ -91,10 +91,10 @@ public class TcpDnsProvider extends UdpDnsProvider {
// constraints // constraints
{ {
int i = -1; int i = -1;
Iterator<TcpDnsProvider.WaitingOnSocketPacket> iter = dnsIn.iterator(); Iterator<TcpProvider.WaitingOnSocketPacket> iter = dnsIn.iterator();
while (iter.hasNext()) { while (iter.hasNext()) {
i++; i++;
TcpDnsProvider.WaitingOnSocketPacket wosp = iter.next(); TcpProvider.WaitingOnSocketPacket wosp = iter.next();
if ((polls[i + 2].revents & OsConstants.POLLIN) != 0) { if ((polls[i + 2].revents & OsConstants.POLLIN) != 0) {
Log.d(TAG, "Read from TCP DNS socket" + wosp.socket); Log.d(TAG, "Read from TCP DNS socket" + wosp.socket);
iter.remove(); iter.remove();
@ -139,7 +139,7 @@ public class TcpDnsProvider extends UdpDnsProvider {
SocketAddress address = new InetSocketAddress(outPacket.getAddress(), DNSServerHelper.getPortOrDefault(outPacket.getAddress(), outPacket.getPort())); SocketAddress address = new InetSocketAddress(outPacket.getAddress(), DNSServerHelper.getPortOrDefault(outPacket.getAddress(), outPacket.getPort()));
dnsSocket.connect(address, 5000); dnsSocket.connect(address, 5000);
dnsSocket.setSoTimeout(5000); dnsSocket.setSoTimeout(5000);
Logger.info("TcpDnsProvider: Sending DNS query request"); Logger.info("TcpProvider: Sending DNS query request");
DataOutputStream dos = new DataOutputStream(dnsSocket.getOutputStream()); DataOutputStream dos = new DataOutputStream(dnsSocket.getOutputStream());
byte[] packet = processUdpPacket(outPacket, parsedPacket); byte[] packet = processUdpPacket(outPacket, parsedPacket);
dos.writeShort(packet.length); dos.writeShort(packet.length);
@ -147,7 +147,7 @@ public class TcpDnsProvider extends UdpDnsProvider {
dos.flush(); dos.flush();
if (parsedPacket != null) { if (parsedPacket != null) {
dnsIn.add(new TcpDnsProvider.WaitingOnSocketPacket(dnsSocket, parsedPacket)); dnsIn.add(new TcpProvider.WaitingOnSocketPacket(dnsSocket, parsedPacket));
} else { } else {
dnsSocket.close(); dnsSocket.close();
} }
@ -198,10 +198,10 @@ public class TcpDnsProvider extends UdpDnsProvider {
/** /**
* Queue of WaitingOnSocketPacket, bound on time and space. * Queue of WaitingOnSocketPacket, bound on time and space.
*/ */
private static class WospList implements Iterable<TcpDnsProvider.WaitingOnSocketPacket> { private static class WospList implements Iterable<TcpProvider.WaitingOnSocketPacket> {
private final LinkedList<TcpDnsProvider.WaitingOnSocketPacket> list = new LinkedList<>(); private final LinkedList<TcpProvider.WaitingOnSocketPacket> list = new LinkedList<>();
void add(TcpDnsProvider.WaitingOnSocketPacket wosp) { void add(TcpProvider.WaitingOnSocketPacket wosp) {
try { try {
if (list.size() > 1024) { if (list.size() > 1024) {
Log.d(TAG, "Dropping socket due to space constraints: " + list.element().socket); Log.d(TAG, "Dropping socket due to space constraints: " + list.element().socket);
@ -218,7 +218,7 @@ public class TcpDnsProvider extends UdpDnsProvider {
} }
} }
public Iterator<TcpDnsProvider.WaitingOnSocketPacket> iterator() { public Iterator<TcpProvider.WaitingOnSocketPacket> iterator() {
return list.iterator(); return list.iterator();
} }

View File

@ -3,7 +3,6 @@ package org.itxtech.daedalus.provider;
import android.annotation.TargetApi; import android.annotation.TargetApi;
import android.os.Build; import android.os.Build;
import android.os.ParcelFileDescriptor; import android.os.ParcelFileDescriptor;
import android.system.ErrnoException;
import android.system.Os; import android.system.Os;
import android.system.OsConstants; import android.system.OsConstants;
import android.system.StructPollfd; import android.system.StructPollfd;
@ -42,8 +41,8 @@ import java.util.Queue;
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
*/ */
public class UdpDnsProvider extends DnsProvider { public class UdpProvider extends Provider {
private static final String TAG = "UdpDnsProvider"; private static final String TAG = "UdpProvider";
private final WospList dnsIn = new WospList(); private final WospList dnsIn = new WospList();
FileDescriptor mBlockFd = null; FileDescriptor mBlockFd = null;
@ -55,7 +54,7 @@ public class UdpDnsProvider extends DnsProvider {
*/ */
private int pcap4jFactoryClearCacheCounter = 0; private int pcap4jFactoryClearCacheCounter = 0;
public UdpDnsProvider(ParcelFileDescriptor descriptor, DaedalusVpnService service) { public UdpProvider(ParcelFileDescriptor descriptor, DaedalusVpnService service) {
super(descriptor, service); super(descriptor, service);
} }
@ -224,13 +223,8 @@ public class UdpDnsProvider extends DnsProvider {
dnsSocket.close(); dnsSocket.close();
} }
} catch (IOException e) { } catch (IOException e) {
if (e.getCause() instanceof ErrnoException) { handleDnsResponse(parsedPacket, outPacket.getData());
ErrnoException errnoExc = (ErrnoException) e.getCause(); Logger.warning("DNSProvider: Could not send packet to upstream, forwarding packet directly");
if ((errnoExc.errno == OsConstants.ENETUNREACH) || (errnoExc.errno == OsConstants.EPERM)) {
throw new DaedalusVpnService.VpnNetworkException("Cannot send message:", e);
}
}
Log.w(TAG, "handleDnsRequest: Could not send packet to upstream", e);
} }
} }
@ -350,7 +344,7 @@ public class UdpDnsProvider extends DnsProvider {
response = RulesResolver.resolve(dnsQueryName); response = RulesResolver.resolve(dnsQueryName);
} }
if (response != null) { if (response != null) {
Logger.info("DnsProvider: Resolved " + dnsQueryName + " Local resolver response: " + response); Logger.info("Provider: Resolved " + dnsQueryName + " Local resolver response: " + response);
DNSMessage.Builder builder = dnsMsg.asBuilder(); DNSMessage.Builder builder = dnsMsg.asBuilder();
int[] ip = new int[4]; int[] ip = new int[4];
byte i = 0; byte i = 0;
@ -361,7 +355,7 @@ public class UdpDnsProvider extends DnsProvider {
builder.addAnswer(new Record<>(dnsQueryName, Record.TYPE.A, 1, 64, new A(ip[0], ip[1], ip[2], ip[3]))); 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()); handleDnsResponse(parsedPacket, builder.build().toArray());
} else { } else {
Logger.info("DnsProvider: Resolving " + dnsQueryName + " Sending to " + destAddr); Logger.info("Provider: Resolving " + dnsQueryName + " Sending to " + destAddr);
DatagramPacket outPacket = new DatagramPacket(dnsRawData, 0, dnsRawData.length, destAddr, DatagramPacket outPacket = new DatagramPacket(dnsRawData, 0, dnsRawData.length, destAddr,
DNSServerHelper.getPortOrDefault(destAddr, parsedUdp.getHeader().getDstPort().valueAsInt())); DNSServerHelper.getPortOrDefault(destAddr, parsedUdp.getHeader().getDstPort().valueAsInt()));
forwardPacket(outPacket, parsedPacket); forwardPacket(outPacket, parsedPacket);

View File

@ -14,9 +14,9 @@ import android.util.Log;
import org.itxtech.daedalus.Daedalus; import org.itxtech.daedalus.Daedalus;
import org.itxtech.daedalus.R; import org.itxtech.daedalus.R;
import org.itxtech.daedalus.activity.MainActivity; import org.itxtech.daedalus.activity.MainActivity;
import org.itxtech.daedalus.provider.DnsProvider; import org.itxtech.daedalus.provider.Provider;
import org.itxtech.daedalus.provider.TcpDnsProvider; import org.itxtech.daedalus.provider.TcpProvider;
import org.itxtech.daedalus.provider.UdpDnsProvider; import org.itxtech.daedalus.provider.UdpProvider;
import org.itxtech.daedalus.receiver.StatusBarBroadcastReceiver; import org.itxtech.daedalus.receiver.StatusBarBroadcastReceiver;
import org.itxtech.daedalus.util.Logger; import org.itxtech.daedalus.util.Logger;
import org.itxtech.daedalus.util.RulesResolver; import org.itxtech.daedalus.util.RulesResolver;
@ -52,7 +52,7 @@ public class DaedalusVpnService extends VpnService implements Runnable {
private boolean running = false; private boolean running = false;
private long lastUpdate = 0; private long lastUpdate = 0;
private boolean statisticQuery; private boolean statisticQuery;
private DnsProvider provider; private Provider provider;
private ParcelFileDescriptor descriptor; private ParcelFileDescriptor descriptor;
private Thread mThread = null; private Thread mThread = null;
@ -229,9 +229,9 @@ public class DaedalusVpnService extends VpnService implements Runnable {
if (advanced) { if (advanced) {
if (Daedalus.getPrefs().getBoolean("settings_dns_over_tcp", false)) { if (Daedalus.getPrefs().getBoolean("settings_dns_over_tcp", false)) {
provider = new TcpDnsProvider(descriptor, this); provider = new TcpProvider(descriptor, this);
} else { } else {
provider = new UdpDnsProvider(descriptor, this); provider = new UdpProvider(descriptor, this);
} }
provider.start(); provider.start();
provider.process(); provider.process();

View File

@ -28,7 +28,6 @@ public class Configurations {
private static File file; private static File file;
private ArrayList<CustomDNSServer> customDNSServers; private ArrayList<CustomDNSServer> customDNSServers;
private ArrayList<CustomDNSServer> customDnsServers;
private ArrayList<Rule> hostsRules; private ArrayList<Rule> hostsRules;
private ArrayList<Rule> dnsmasqRules; private ArrayList<Rule> dnsmasqRules;
@ -61,11 +60,6 @@ public class Configurations {
} }
public ArrayList<CustomDNSServer> getCustomDNSServers() { public ArrayList<CustomDNSServer> getCustomDNSServers() {
//TODO: remove this after 1.10
if (customDnsServers != null && customDnsServers.size() > 0) {
customDNSServers = customDnsServers;
customDnsServers = null;
}
if (customDNSServers == null) { if (customDNSServers == null) {
customDNSServers = new ArrayList<>(); customDNSServers = new ArrayList<>();
} }