Implemented DNS over TCP (very slow)
This commit is contained in:
parent
187b21f758
commit
c8ab7ec1aa
@ -38,7 +38,8 @@ import java.util.List;
|
|||||||
* <p>
|
* <p>
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, version 3.
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*/
|
*/
|
||||||
public class Daedalus extends Application {
|
public class Daedalus extends Application {
|
||||||
private static final String SHORTCUT_ID_ACTIVATE = "shortcut_activate";
|
private static final String SHORTCUT_ID_ACTIVATE = "shortcut_activate";
|
||||||
|
@ -21,7 +21,8 @@ import org.itxtech.daedalus.fragment.DnsServerConfigFragment;
|
|||||||
* <p>
|
* <p>
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, version 3.
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*/
|
*/
|
||||||
public class DnsServerConfigActivity extends AppCompatActivity {
|
public class DnsServerConfigActivity extends AppCompatActivity {
|
||||||
public static final String LAUNCH_ACTION_CUSTOM_DNS_SERVER_ID = "org.itxtech.daedalus.activity.DnsServerConfigActivity.LAUNCH_ACTION_CUSTOM_DNS_SERVER_ID";
|
public static final String LAUNCH_ACTION_CUSTOM_DNS_SERVER_ID = "org.itxtech.daedalus.activity.DnsServerConfigActivity.LAUNCH_ACTION_CUSTOM_DNS_SERVER_ID";
|
||||||
|
@ -34,7 +34,8 @@ import org.itxtech.daedalus.fragment.*;
|
|||||||
* <p>
|
* <p>
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, version 3.
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*/
|
*/
|
||||||
public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {
|
public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {
|
||||||
public static final String LAUNCH_ACTION = "org.itxtech.daedalus.activity.MainActivity.LAUNCH_ACTION";
|
public static final String LAUNCH_ACTION = "org.itxtech.daedalus.activity.MainActivity.LAUNCH_ACTION";
|
||||||
|
@ -25,7 +25,8 @@ import java.util.Locale;
|
|||||||
* <p>
|
* <p>
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, version 3.
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*/
|
*/
|
||||||
public class AboutFragment extends Fragment {
|
public class AboutFragment extends Fragment {
|
||||||
private WebView mWebView = null;
|
private WebView mWebView = null;
|
||||||
|
@ -25,7 +25,8 @@ import org.itxtech.daedalus.util.DnsServer;
|
|||||||
* <p>
|
* <p>
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, version 3.
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*/
|
*/
|
||||||
public class DnsServerConfigFragment extends PreferenceFragment implements Toolbar.OnMenuItemClickListener {
|
public class DnsServerConfigFragment extends PreferenceFragment implements Toolbar.OnMenuItemClickListener {
|
||||||
private Intent intent = null;
|
private Intent intent = null;
|
||||||
|
@ -24,7 +24,8 @@ import org.itxtech.daedalus.util.CustomDnsServer;
|
|||||||
* <p>
|
* <p>
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, version 3.
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*/
|
*/
|
||||||
public class DnsServersFragment extends Fragment {
|
public class DnsServersFragment extends Fragment {
|
||||||
private DnsServersFragment.DnsServerAdapter adapter;
|
private DnsServersFragment.DnsServerAdapter adapter;
|
||||||
|
@ -37,7 +37,8 @@ import java.util.Set;
|
|||||||
* <p>
|
* <p>
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, version 3.
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*/
|
*/
|
||||||
public class DnsTestFragment extends Fragment {
|
public class DnsTestFragment extends Fragment {
|
||||||
private static final String TAG = "DServerTest";
|
private static final String TAG = "DServerTest";
|
||||||
|
@ -30,7 +30,8 @@ import java.util.Date;
|
|||||||
* <p>
|
* <p>
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, version 3.
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*/
|
*/
|
||||||
public class HostsFragment extends Fragment {
|
public class HostsFragment extends Fragment {
|
||||||
|
|
||||||
|
@ -26,7 +26,8 @@ import org.itxtech.daedalus.util.DnsServerHelper;
|
|||||||
* <p>
|
* <p>
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, version 3.
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*/
|
*/
|
||||||
public class MainFragment extends Fragment {
|
public class MainFragment extends Fragment {
|
||||||
|
|
||||||
|
@ -21,7 +21,8 @@ import org.itxtech.daedalus.util.DnsServerHelper;
|
|||||||
* <p>
|
* <p>
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, version 3.
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*/
|
*/
|
||||||
public class SettingsFragment extends PreferenceFragment {
|
public class SettingsFragment extends PreferenceFragment {
|
||||||
private View view = null;
|
private View view = null;
|
||||||
|
@ -11,7 +11,8 @@ import org.itxtech.daedalus.service.DaedalusVpnService;
|
|||||||
* <p>
|
* <p>
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, version 3.
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*/
|
*/
|
||||||
public abstract class DnsProvider {
|
public abstract class DnsProvider {
|
||||||
ParcelFileDescriptor descriptor;
|
ParcelFileDescriptor descriptor;
|
||||||
|
@ -0,0 +1,264 @@
|
|||||||
|
package org.itxtech.daedalus.provider;
|
||||||
|
|
||||||
|
import android.annotation.TargetApi;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.os.ParcelFileDescriptor;
|
||||||
|
import android.system.ErrnoException;
|
||||||
|
import android.system.Os;
|
||||||
|
import android.system.OsConstants;
|
||||||
|
import android.system.StructPollfd;
|
||||||
|
import android.util.Log;
|
||||||
|
import de.measite.minidns.DNSMessage;
|
||||||
|
import org.itxtech.daedalus.service.DaedalusVpnService;
|
||||||
|
import org.itxtech.daedalus.util.DnsServerHelper;
|
||||||
|
import org.pcap4j.packet.*;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.net.*;
|
||||||
|
import java.nio.channels.SocketChannel;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author PeratX
|
||||||
|
*/
|
||||||
|
public class TcpDnsProvider extends UdpDnsProvider {
|
||||||
|
|
||||||
|
private static final String TAG = "TcpDnsProvider";
|
||||||
|
|
||||||
|
private final TcpDnsProvider.WospList dnsIn = new TcpDnsProvider.WospList();
|
||||||
|
|
||||||
|
public TcpDnsProvider(ParcelFileDescriptor descriptor, DaedalusVpnService service) {
|
||||||
|
super(descriptor, service);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
||||||
|
public void process() {
|
||||||
|
try {
|
||||||
|
Log.d(TAG, "Starting advanced DNS proxy.");
|
||||||
|
FileDescriptor[] pipes = Os.pipe();
|
||||||
|
mInterruptFd = pipes[0];
|
||||||
|
mBlockFd = pipes[1];
|
||||||
|
FileInputStream inputStream = new FileInputStream(descriptor.getFileDescriptor());
|
||||||
|
FileOutputStream outputStream = new FileOutputStream(descriptor.getFileDescriptor());
|
||||||
|
|
||||||
|
byte[] packet = new byte[32767];
|
||||||
|
while (running) {
|
||||||
|
StructPollfd deviceFd = new StructPollfd();
|
||||||
|
deviceFd.fd = inputStream.getFD();
|
||||||
|
deviceFd.events = (short) OsConstants.POLLIN;
|
||||||
|
StructPollfd blockFd = new StructPollfd();
|
||||||
|
blockFd.fd = mBlockFd;
|
||||||
|
blockFd.events = (short) (OsConstants.POLLHUP | OsConstants.POLLERR);
|
||||||
|
|
||||||
|
if (!deviceWrites.isEmpty())
|
||||||
|
deviceFd.events |= (short) OsConstants.POLLOUT;
|
||||||
|
|
||||||
|
StructPollfd[] polls = new StructPollfd[2 + dnsIn.size()];
|
||||||
|
polls[0] = deviceFd;
|
||||||
|
polls[1] = blockFd;
|
||||||
|
{
|
||||||
|
int i = -1;
|
||||||
|
for (TcpDnsProvider.WaitingOnSocketPacket wosp : dnsIn) {
|
||||||
|
i++;
|
||||||
|
StructPollfd pollFd = polls[2 + i] = new StructPollfd();
|
||||||
|
pollFd.fd = ParcelFileDescriptor.fromSocket(wosp.socket).getFileDescriptor();
|
||||||
|
pollFd.events = (short) OsConstants.POLLIN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.d(TAG, "doOne: Polling " + polls.length + " file descriptors");
|
||||||
|
Os.poll(polls, -1);
|
||||||
|
if (blockFd.revents != 0) {
|
||||||
|
Log.i(TAG, "Told to stop VPN");
|
||||||
|
running = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Need to do this before reading from the device, otherwise a new insertion there could
|
||||||
|
// invalidate one of the sockets we want to read from either due to size or time out
|
||||||
|
// constraints
|
||||||
|
{
|
||||||
|
int i = -1;
|
||||||
|
Iterator<TcpDnsProvider.WaitingOnSocketPacket> iter = dnsIn.iterator();
|
||||||
|
while (iter.hasNext()) {
|
||||||
|
i++;
|
||||||
|
TcpDnsProvider.WaitingOnSocketPacket wosp = iter.next();
|
||||||
|
if ((polls[i + 2].revents & OsConstants.POLLIN) != 0) {
|
||||||
|
Log.d(TAG, "Read from TCP DNS socket" + wosp.socket);
|
||||||
|
iter.remove();
|
||||||
|
handleRawDnsResponse(wosp.packet, wosp.socket);
|
||||||
|
wosp.socket.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((deviceFd.revents & OsConstants.POLLOUT) != 0) {
|
||||||
|
Log.d(TAG, "Write to device");
|
||||||
|
writeToDevice(outputStream);
|
||||||
|
}
|
||||||
|
if ((deviceFd.revents & OsConstants.POLLIN) != 0) {
|
||||||
|
Log.d(TAG, "Read from device");
|
||||||
|
readPacketFromDevice(inputStream, packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
checkCache();
|
||||||
|
|
||||||
|
service.providerLoopCallback();
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte[] processUdpPacket(DatagramPacket outPacket, IpPacket parsedPacket) {
|
||||||
|
if (parsedPacket == null) {
|
||||||
|
return new byte[0];
|
||||||
|
}
|
||||||
|
return outPacket.getData();
|
||||||
|
}
|
||||||
|
|
||||||
|
void forwardPacket(DatagramPacket outPacket, IpPacket parsedPacket) throws DaedalusVpnService.VpnNetworkException {
|
||||||
|
Socket dnsSocket;
|
||||||
|
try {
|
||||||
|
// Packets to be sent to the real DNS server will need to be protected from the VPN
|
||||||
|
dnsSocket = SocketChannel.open().socket();
|
||||||
|
|
||||||
|
Log.d(TAG, String.valueOf(service.protect(dnsSocket)));
|
||||||
|
|
||||||
|
SocketAddress address = new InetSocketAddress(outPacket.getAddress(), DnsServerHelper.getPortOrDefault(outPacket.getAddress(), outPacket.getPort()));
|
||||||
|
dnsSocket.connect(address, 5000);
|
||||||
|
dnsSocket.setSoTimeout(5000);
|
||||||
|
Log.d(TAG, "Sending");
|
||||||
|
DataOutputStream dos = new DataOutputStream(dnsSocket.getOutputStream());
|
||||||
|
byte[] packet = processUdpPacket(outPacket, parsedPacket);
|
||||||
|
dos.writeShort(packet.length);
|
||||||
|
dos.write(packet);
|
||||||
|
dos.flush();
|
||||||
|
|
||||||
|
if (parsedPacket != null) {
|
||||||
|
dnsIn.add(new TcpDnsProvider.WaitingOnSocketPacket(dnsSocket, parsedPacket));
|
||||||
|
} else {
|
||||||
|
dnsSocket.close();
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
if (e.getCause() instanceof ErrnoException) {
|
||||||
|
ErrnoException errnoExc = (ErrnoException) e.getCause();
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleRawDnsResponse(IpPacket parsedPacket, Socket dnsSocket) throws IOException, IllegalRawDataException {
|
||||||
|
if (!dnsSocket.isClosed()) {
|
||||||
|
DataInputStream stream = new DataInputStream(dnsSocket.getInputStream());
|
||||||
|
int length = stream.readUnsignedShort();
|
||||||
|
Log.d(TAG, "Reading length: " + String.valueOf(length));
|
||||||
|
byte[] data = new byte[length];
|
||||||
|
stream.read(data);
|
||||||
|
dnsSocket.close();
|
||||||
|
handleDnsResponse(parsedPacket, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles a responsePayload from an upstream DNS server
|
||||||
|
*
|
||||||
|
* @param requestPacket The original request packet
|
||||||
|
* @param responsePayload The payload of the response
|
||||||
|
*/
|
||||||
|
private void handleDnsResponse(IpPacket requestPacket, byte[] responsePayload) throws IllegalRawDataException, IOException {
|
||||||
|
DNSMessage message = new DNSMessage(responsePayload);
|
||||||
|
Log.d(TAG, message.toString());
|
||||||
|
|
||||||
|
UdpPacket udpOutPacket = (UdpPacket) requestPacket.getPayload();
|
||||||
|
UdpPacket.Builder payLoadBuilder = new UdpPacket.Builder(udpOutPacket)
|
||||||
|
.srcPort(udpOutPacket.getHeader().getDstPort())
|
||||||
|
.dstPort(udpOutPacket.getHeader().getSrcPort())
|
||||||
|
.srcAddr(requestPacket.getHeader().getDstAddr())
|
||||||
|
.dstAddr(requestPacket.getHeader().getSrcAddr())
|
||||||
|
.correctChecksumAtBuild(true)
|
||||||
|
.correctLengthAtBuild(true)
|
||||||
|
.payloadBuilder(
|
||||||
|
new UnknownPacket.Builder()
|
||||||
|
.rawData(responsePayload)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
IpPacket ipOutPacket;
|
||||||
|
if (requestPacket instanceof IpV4Packet) {
|
||||||
|
ipOutPacket = new IpV4Packet.Builder((IpV4Packet) requestPacket)
|
||||||
|
.srcAddr((Inet4Address) requestPacket.getHeader().getDstAddr())
|
||||||
|
.dstAddr((Inet4Address) requestPacket.getHeader().getSrcAddr())
|
||||||
|
.correctChecksumAtBuild(true)
|
||||||
|
.correctLengthAtBuild(true)
|
||||||
|
.payloadBuilder(payLoadBuilder)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
ipOutPacket = new IpV6Packet.Builder((IpV6Packet) requestPacket)
|
||||||
|
.srcAddr((Inet6Address) requestPacket.getHeader().getDstAddr())
|
||||||
|
.dstAddr((Inet6Address) requestPacket.getHeader().getSrcAddr())
|
||||||
|
.correctLengthAtBuild(true)
|
||||||
|
.payloadBuilder(payLoadBuilder)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
queueDeviceWrite(ipOutPacket);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper class holding a socket, the packet we are waiting the answer for, and a time
|
||||||
|
*/
|
||||||
|
private static class WaitingOnSocketPacket {
|
||||||
|
final Socket socket;
|
||||||
|
final IpPacket packet;
|
||||||
|
private final long time;
|
||||||
|
|
||||||
|
WaitingOnSocketPacket(Socket socket, IpPacket packet) {
|
||||||
|
this.socket = socket;
|
||||||
|
this.packet = packet;
|
||||||
|
this.time = System.currentTimeMillis();
|
||||||
|
}
|
||||||
|
|
||||||
|
long ageSeconds() {
|
||||||
|
return (System.currentTimeMillis() - time) / 1000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queue of WaitingOnSocketPacket, bound on time and space.
|
||||||
|
*/
|
||||||
|
private static class WospList implements Iterable<TcpDnsProvider.WaitingOnSocketPacket> {
|
||||||
|
private final LinkedList<TcpDnsProvider.WaitingOnSocketPacket> list = new LinkedList<>();
|
||||||
|
|
||||||
|
void add(TcpDnsProvider.WaitingOnSocketPacket wosp) {
|
||||||
|
try {
|
||||||
|
if (list.size() > 1024) {
|
||||||
|
Log.d(TAG, "Dropping socket due to space constraints: " + list.element().socket);
|
||||||
|
list.element().socket.close();
|
||||||
|
list.remove();
|
||||||
|
}
|
||||||
|
while (!list.isEmpty() && list.element().ageSeconds() > 10) {
|
||||||
|
Log.d(TAG, "Timeout on socket " + list.element().socket);
|
||||||
|
list.element().socket.close();
|
||||||
|
list.remove();
|
||||||
|
}
|
||||||
|
list.add(wosp);
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Iterator<TcpDnsProvider.WaitingOnSocketPacket> iterator() {
|
||||||
|
return list.iterator();
|
||||||
|
}
|
||||||
|
|
||||||
|
int size() {
|
||||||
|
return list.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -37,15 +37,16 @@ import java.util.Queue;
|
|||||||
* <p>
|
* <p>
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, version 3.
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*/
|
*/
|
||||||
public class UdpDnsProvider extends DnsProvider {
|
public class UdpDnsProvider extends DnsProvider {
|
||||||
private static final String TAG = "UdpDnsProvider";
|
private static final String TAG = "UdpDnsProvider";
|
||||||
|
|
||||||
private final WospList dnsIn = new WospList();
|
private final WospList dnsIn = new WospList();
|
||||||
private FileDescriptor mBlockFd = null;
|
FileDescriptor mBlockFd = null;
|
||||||
private FileDescriptor mInterruptFd = null;
|
FileDescriptor mInterruptFd = null;
|
||||||
private final Queue<byte[]> deviceWrites = new LinkedList<>();
|
final Queue<byte[]> deviceWrites = new LinkedList<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Number of iterations since we last cleared the pcap4j cache
|
* Number of iterations since we last cleared the pcap4j cache
|
||||||
@ -73,7 +74,7 @@ public class UdpDnsProvider extends DnsProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void queueDeviceWrite(IpPacket ipOutPacket) {
|
void queueDeviceWrite(IpPacket ipOutPacket) {
|
||||||
dnsQueryTimes++;
|
dnsQueryTimes++;
|
||||||
Log.i(TAG, "QT " + dnsQueryTimes);
|
Log.i(TAG, "QT " + dnsQueryTimes);
|
||||||
deviceWrites.add(ipOutPacket.getRawData());
|
deviceWrites.add(ipOutPacket.getRawData());
|
||||||
@ -132,7 +133,7 @@ public class UdpDnsProvider extends DnsProvider {
|
|||||||
i++;
|
i++;
|
||||||
WaitingOnSocketPacket wosp = iter.next();
|
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 DNS socket" + wosp.socket);
|
Log.d(TAG, "Read from UDP DNS socket" + wosp.socket);
|
||||||
iter.remove();
|
iter.remove();
|
||||||
handleRawDnsResponse(wosp.packet, wosp.socket);
|
handleRawDnsResponse(wosp.packet, wosp.socket);
|
||||||
wosp.socket.close();
|
wosp.socket.close();
|
||||||
@ -148,6 +149,15 @@ public class UdpDnsProvider extends DnsProvider {
|
|||||||
readPacketFromDevice(inputStream, packet);
|
readPacketFromDevice(inputStream, packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
checkCache();
|
||||||
|
service.providerLoopCallback();
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void checkCache() {
|
||||||
// pcap4j has some sort of properties cache in the packet factory. This cache leaks, so
|
// pcap4j has some sort of properties cache in the packet factory. This cache leaks, so
|
||||||
// we need to clean it up.
|
// we need to clean it up.
|
||||||
if (++pcap4jFactoryClearCacheCounter % 1024 == 0) {
|
if (++pcap4jFactoryClearCacheCounter % 1024 == 0) {
|
||||||
@ -164,15 +174,9 @@ public class UdpDnsProvider extends DnsProvider {
|
|||||||
Log.e(TAG, "Cannot get declared loader field", e);
|
Log.e(TAG, "Cannot get declared loader field", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
service.providerLoopCallback();
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void writeToDevice(FileOutputStream outFd) throws DaedalusVpnService.VpnNetworkException {
|
||||||
private void writeToDevice(FileOutputStream outFd) throws DaedalusVpnService.VpnNetworkException {
|
|
||||||
try {
|
try {
|
||||||
outFd.write(deviceWrites.poll());
|
outFd.write(deviceWrites.poll());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
@ -181,7 +185,7 @@ public class UdpDnsProvider extends DnsProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void readPacketFromDevice(FileInputStream inputStream, byte[] packet) throws DaedalusVpnService.VpnNetworkException, SocketException {
|
void readPacketFromDevice(FileInputStream inputStream, byte[] packet) throws DaedalusVpnService.VpnNetworkException, SocketException {
|
||||||
// Read the outgoing packet from the input stream.
|
// Read the outgoing packet from the input stream.
|
||||||
int length;
|
int length;
|
||||||
|
|
||||||
@ -203,7 +207,7 @@ public class UdpDnsProvider extends DnsProvider {
|
|||||||
handleDnsRequest(readPacket);
|
handleDnsRequest(readPacket);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void forwardPacket(DatagramPacket outPacket, IpPacket parsedPacket) throws DaedalusVpnService.VpnNetworkException {
|
void forwardPacket(DatagramPacket outPacket, IpPacket parsedPacket) throws DaedalusVpnService.VpnNetworkException {
|
||||||
DatagramSocket dnsSocket;
|
DatagramSocket dnsSocket;
|
||||||
try {
|
try {
|
||||||
// Packets to be sent to the real DNS server will need to be protected from the VPN
|
// Packets to be sent to the real DNS server will need to be protected from the VPN
|
||||||
|
@ -17,7 +17,8 @@ import org.itxtech.daedalus.util.DnsServerHelper;
|
|||||||
* <p>
|
* <p>
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, version 3.
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*/
|
*/
|
||||||
public class BootBroadcastReceiver extends BroadcastReceiver {
|
public class BootBroadcastReceiver extends BroadcastReceiver {
|
||||||
@Override
|
@Override
|
||||||
|
@ -17,7 +17,8 @@ import java.lang.reflect.Method;
|
|||||||
* <p>
|
* <p>
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, version 3.
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*/
|
*/
|
||||||
public class StatusBarBroadcastReceiver extends BroadcastReceiver {
|
public class StatusBarBroadcastReceiver extends BroadcastReceiver {
|
||||||
public static String STATUS_BAR_BTN_DEACTIVATE_CLICK_ACTION = "org.itxtech.daedalus.receiver.StatusBarBroadcastReceiver.STATUS_BAR_BTN_DEACTIVATE_CLICK_ACTION";
|
public static String STATUS_BAR_BTN_DEACTIVATE_CLICK_ACTION = "org.itxtech.daedalus.receiver.StatusBarBroadcastReceiver.STATUS_BAR_BTN_DEACTIVATE_CLICK_ACTION";
|
||||||
|
@ -16,6 +16,7 @@ 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.DnsProvider;
|
||||||
|
import org.itxtech.daedalus.provider.TcpDnsProvider;
|
||||||
import org.itxtech.daedalus.provider.UdpDnsProvider;
|
import org.itxtech.daedalus.provider.UdpDnsProvider;
|
||||||
import org.itxtech.daedalus.receiver.StatusBarBroadcastReceiver;
|
import org.itxtech.daedalus.receiver.StatusBarBroadcastReceiver;
|
||||||
import org.itxtech.daedalus.util.DnsServerHelper;
|
import org.itxtech.daedalus.util.DnsServerHelper;
|
||||||
@ -31,7 +32,8 @@ import java.net.Inet4Address;
|
|||||||
* <p>
|
* <p>
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, version 3.
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*/
|
*/
|
||||||
public class DaedalusVpnService extends VpnService implements Runnable {
|
public class DaedalusVpnService extends VpnService implements Runnable {
|
||||||
public static final String ACTION_ACTIVATE = "org.itxtech.daedalus.service.DaedalusVpnService.ACTION_ACTIVATE";
|
public static final String ACTION_ACTIVATE = "org.itxtech.daedalus.service.DaedalusVpnService.ACTION_ACTIVATE";
|
||||||
@ -191,7 +193,11 @@ public class DaedalusVpnService extends VpnService implements Runnable {
|
|||||||
ParcelFileDescriptor descriptor = builder.establish();
|
ParcelFileDescriptor descriptor = builder.establish();
|
||||||
|
|
||||||
if (advanced) {
|
if (advanced) {
|
||||||
|
if (Daedalus.getPrefs().getBoolean("settings_dns_over_tcp", false)) {
|
||||||
|
provider = new TcpDnsProvider(descriptor, this);
|
||||||
|
} else {
|
||||||
provider = new UdpDnsProvider(descriptor, this);
|
provider = new UdpDnsProvider(descriptor, this);
|
||||||
|
}
|
||||||
provider.start();
|
provider.start();
|
||||||
provider.process();
|
provider.process();
|
||||||
} else {
|
} else {
|
||||||
|
@ -18,7 +18,8 @@ import java.util.ArrayList;
|
|||||||
* <p>
|
* <p>
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, version 3.
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*/
|
*/
|
||||||
public class Configurations {
|
public class Configurations {
|
||||||
private static final int CUSTOM_DNS_ID_START = 32;
|
private static final int CUSTOM_DNS_ID_START = 32;
|
||||||
|
@ -10,7 +10,8 @@ import org.itxtech.daedalus.Daedalus;
|
|||||||
* <p>
|
* <p>
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, version 3.
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*/
|
*/
|
||||||
public class CustomDnsServer {
|
public class CustomDnsServer {
|
||||||
private String name;
|
private String name;
|
||||||
|
@ -10,7 +10,8 @@ import android.content.Context;
|
|||||||
* <p>
|
* <p>
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, version 3.
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*/
|
*/
|
||||||
public class DnsServer {
|
public class DnsServer {
|
||||||
public static int DNS_SERVER_DEFAULT_PORT = 53;
|
public static int DNS_SERVER_DEFAULT_PORT = 53;
|
||||||
|
@ -15,7 +15,8 @@ import java.util.HashMap;
|
|||||||
* <p>
|
* <p>
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, version 3.
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*/
|
*/
|
||||||
public class DnsServerHelper {
|
public class DnsServerHelper {
|
||||||
private static HashMap<String, Integer> portCache = null;
|
private static HashMap<String, Integer> portCache = null;
|
||||||
|
@ -12,7 +12,8 @@ import java.util.ArrayList;
|
|||||||
* <p>
|
* <p>
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, version 3.
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*/
|
*/
|
||||||
public class HostsProvider {
|
public class HostsProvider {
|
||||||
private String name;
|
private String name;
|
||||||
|
@ -16,7 +16,8 @@ import java.util.HashMap;
|
|||||||
* <p>
|
* <p>
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, version 3.
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*/
|
*/
|
||||||
public class HostsResolver implements Runnable {
|
public class HostsResolver implements Runnable {
|
||||||
private static final String TAG = "DHostsResolver";
|
private static final String TAG = "DHostsResolver";
|
||||||
|
@ -20,7 +20,8 @@ import org.itxtech.daedalus.R;
|
|||||||
* <p>
|
* <p>
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, version 3.
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*/
|
*/
|
||||||
public class ClearAutoCompleteTextView extends AutoCompleteTextView implements View.OnTouchListener, View.OnFocusChangeListener, TextWatcher {
|
public class ClearAutoCompleteTextView extends AutoCompleteTextView implements View.OnTouchListener, View.OnFocusChangeListener, TextWatcher {
|
||||||
|
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
package org.itxtech.daedalus.view;
|
package org.itxtech.daedalus.view;
|
||||||
|
|
||||||
|
import android.annotation.TargetApi;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.os.Build;
|
||||||
import android.preference.ListPreference;
|
import android.preference.ListPreference;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
|
|
||||||
@ -12,10 +14,12 @@ import android.util.AttributeSet;
|
|||||||
* <p>
|
* <p>
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, version 3.
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
*/
|
*/
|
||||||
public class ClickPreference extends ListPreference {
|
public class ClickPreference extends ListPreference {
|
||||||
|
|
||||||
|
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
||||||
public ClickPreference(Context context, AttributeSet attrs, int defStyleAttr) {
|
public ClickPreference(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||||
super(context, attrs, defStyleAttr);
|
super(context, attrs, defStyleAttr);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user