mirror of
https://github.com/M66B/NetGuard.git
synced 2025-03-19 18:25:43 +00:00
Resolve using the database
This commit is contained in:
parent
f8c5a4cf32
commit
4a042339ba
2 changed files with 77 additions and 54 deletions
|
@ -23,6 +23,7 @@ import android.content.ContentValues;
|
|||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.database.sqlite.SQLiteDoneException;
|
||||
import android.database.sqlite.SQLiteOpenHelper;
|
||||
import android.util.Log;
|
||||
|
||||
|
@ -440,6 +441,30 @@ public class DatabaseHelper extends SQLiteOpenHelper {
|
|||
return this;
|
||||
}
|
||||
|
||||
public String getQName(String ip) {
|
||||
SQLiteDatabase db = this.getReadableDatabase();
|
||||
try {
|
||||
return db.compileStatement(
|
||||
"SELECT qname FROM dns WHERE resource = '" + ip.replace("'", "''") + "'")
|
||||
.simpleQueryForString();
|
||||
} catch (SQLiteDoneException ignored) {
|
||||
// Not found
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Cursor getDns() {
|
||||
SQLiteDatabase db = this.getReadableDatabase();
|
||||
|
||||
String query = "SELECT access.uid, dns.resource, access.dport, access.block";
|
||||
query += " FROM access";
|
||||
query += " JOIN dns";
|
||||
query += " ON dns.qname = access.daddr";
|
||||
query += " WHERE access.block >= 0";
|
||||
|
||||
return db.rawQuery(query, new String[]{});
|
||||
}
|
||||
|
||||
public void addLogChangedListener(LogChangedListener listener) {
|
||||
logChangedListeners.add(listener);
|
||||
}
|
||||
|
|
|
@ -103,7 +103,6 @@ public class SinkholeService extends VpnService implements SharedPreferences.OnS
|
|||
private Object subscriptionsChangedListener = null;
|
||||
private ParcelFileDescriptor vpn = null;
|
||||
|
||||
private static final Map<InetAddress, ResourceRecord> mapRR = new HashMap<>();
|
||||
private Map<String, Boolean> mapHostsBlocked = new HashMap<>();
|
||||
private Map<Integer, Boolean> mapUidAllowed = new HashMap<>();
|
||||
private Map<Integer, Map<Integer, Map<InetAddress, Boolean>>> mapUidIPFilters = new HashMap<>();
|
||||
|
@ -668,23 +667,11 @@ public class SinkholeService extends VpnService implements SharedPreferences.OnS
|
|||
boolean notify = prefs.getBoolean("notify_access", false);
|
||||
boolean system = prefs.getBoolean("manage_system", false);
|
||||
|
||||
// Get real name
|
||||
String dname = null;
|
||||
if (filter) {
|
||||
ResourceRecord rr = null;
|
||||
try {
|
||||
rr = reverseDNS(InetAddress.getByName(packet.daddr));
|
||||
if (rr == null)
|
||||
Log.w(TAG, "No revered DNS for " + packet);
|
||||
else
|
||||
dname = rr.QName;
|
||||
} catch (UnknownHostException ex) {
|
||||
Log.e(TAG, ex.toString() + "\n" + Log.getStackTraceString(ex));
|
||||
}
|
||||
}
|
||||
|
||||
DatabaseHelper dh = new DatabaseHelper(SinkholeService.this);
|
||||
|
||||
// Get real name
|
||||
String dname = dh.getQName(packet.daddr);
|
||||
|
||||
// Traffic log
|
||||
if (log)
|
||||
dh.insertLog(packet, dname, (last_connected ? last_metered ? 2 : 1 : 0), last_interactive);
|
||||
|
@ -711,14 +698,7 @@ public class SinkholeService extends VpnService implements SharedPreferences.OnS
|
|||
}
|
||||
|
||||
private void resolved(ResourceRecord rr) {
|
||||
synchronized (mapRR) {
|
||||
try {
|
||||
mapRR.put(InetAddress.getByName(rr.Resource), rr);
|
||||
new DatabaseHelper(SinkholeService.this).insertDns(rr).close();
|
||||
} catch (UnknownHostException ex) {
|
||||
Log.e(TAG, ex.toString() + "\n" + Log.getStackTraceString(ex));
|
||||
}
|
||||
}
|
||||
new DatabaseHelper(SinkholeService.this).insertDns(rr).close();
|
||||
}
|
||||
|
||||
private void set(Intent intent) {
|
||||
|
@ -859,6 +839,7 @@ public class SinkholeService extends VpnService implements SharedPreferences.OnS
|
|||
if (filter) {
|
||||
prepareUidAllowed(listAllowed);
|
||||
prepareHostsBlocked();
|
||||
prepareUidIPFilters();
|
||||
} else
|
||||
unprepare();
|
||||
|
||||
|
@ -869,7 +850,12 @@ public class SinkholeService extends VpnService implements SharedPreferences.OnS
|
|||
|
||||
// Native needs to be started for name resolving
|
||||
if (filter)
|
||||
prepareUidIPFilters();
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
updateUidIPFilters();
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
private void stopNative(ParcelFileDescriptor vpn, boolean clear) {
|
||||
|
@ -934,14 +920,15 @@ public class SinkholeService extends VpnService implements SharedPreferences.OnS
|
|||
Map<Integer, Map<Integer, Map<InetAddress, Boolean>>> map = new HashMap<>();
|
||||
|
||||
DatabaseHelper dh = new DatabaseHelper(SinkholeService.this);
|
||||
Cursor cursor = dh.getAccess();
|
||||
|
||||
Cursor cursor = dh.getDns();
|
||||
int colUid = cursor.getColumnIndex("uid");
|
||||
int colDAddr = cursor.getColumnIndex("daddr");
|
||||
int colResource = cursor.getColumnIndex("resource");
|
||||
int colDPort = cursor.getColumnIndex("dport");
|
||||
int colBlock = cursor.getColumnIndex("block");
|
||||
while (cursor.moveToNext()) {
|
||||
int uid = cursor.getInt(colUid);
|
||||
String daddr = cursor.getString(colDAddr);
|
||||
String dresource = cursor.getString(colResource);
|
||||
int dport = cursor.isNull(colDPort) ? -1 : cursor.getInt(colDPort);
|
||||
boolean block = (cursor.getInt(colBlock) > 0);
|
||||
|
||||
|
@ -950,16 +937,47 @@ public class SinkholeService extends VpnService implements SharedPreferences.OnS
|
|||
if (!map.get(uid).containsKey(dport))
|
||||
map.get(uid).put(dport, new HashMap<InetAddress, Boolean>());
|
||||
|
||||
try {
|
||||
map.get(uid).get(dport).put(InetAddress.getByName(dresource), block);
|
||||
Log.i(TAG, "Set filter uid=" + uid + " " + dresource + "/" + dport + "=" + block);
|
||||
} catch (UnknownHostException ex) {
|
||||
Log.e(TAG, ex.toString() + "\n" + Log.getStackTraceString(ex));
|
||||
}
|
||||
}
|
||||
cursor.close();
|
||||
|
||||
dh.close();
|
||||
|
||||
synchronized (mapUidIPFilters) {
|
||||
mapUidIPFilters = map;
|
||||
}
|
||||
}
|
||||
|
||||
private void updateUidIPFilters() {
|
||||
Map<Integer, Map<Integer, Map<InetAddress, Boolean>>> map = new HashMap<>();
|
||||
|
||||
DatabaseHelper dh = new DatabaseHelper(SinkholeService.this);
|
||||
|
||||
Cursor cursor = dh.getAccess();
|
||||
int colDAddr = cursor.getColumnIndex("daddr");
|
||||
while (cursor.moveToNext()) {
|
||||
String daddr = cursor.getString(colDAddr);
|
||||
try {
|
||||
for (InetAddress iaddr : InetAddress.getAllByName(daddr)) {
|
||||
map.get(uid).get(dport).put(iaddr, block);
|
||||
Log.i(TAG, "Set filter uid=" + uid + " " + iaddr + "/" + dport + "=" + block);
|
||||
ResourceRecord rr = new ResourceRecord();
|
||||
rr.Time = new Date().getTime();
|
||||
rr.QName = daddr;
|
||||
rr.AName = daddr;
|
||||
rr.Resource = iaddr.getHostAddress();
|
||||
rr.TTL = 10 * 60; // Android default
|
||||
dh.insertDns(rr);
|
||||
}
|
||||
} catch (UnknownHostException ex) {
|
||||
Log.e(TAG, ex.toString() + "\n" + Log.getStackTraceString(ex));
|
||||
}
|
||||
}
|
||||
cursor.close();
|
||||
|
||||
dh.close();
|
||||
|
||||
synchronized (mapUidIPFilters) {
|
||||
|
@ -967,6 +985,10 @@ public class SinkholeService extends VpnService implements SharedPreferences.OnS
|
|||
}
|
||||
}
|
||||
|
||||
private void cleanupDNS() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
private List<Rule> getAllowedRules(List<Rule> listRule) {
|
||||
List<Rule> listAllowed = new ArrayList<>();
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
|
@ -1067,30 +1089,6 @@ public class SinkholeService extends VpnService implements SharedPreferences.OnS
|
|||
mServiceHandler.sendMessage(msg);
|
||||
}
|
||||
|
||||
public static ResourceRecord reverseDNS(InetAddress ip) {
|
||||
synchronized (mapRR) {
|
||||
if (mapRR.containsKey(ip))
|
||||
return mapRR.get(ip);
|
||||
else
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private void cleanupDNS() {
|
||||
long now = new Date().getTime();
|
||||
synchronized (mapRR) {
|
||||
List<InetAddress> ips = new ArrayList<>(mapRR.keySet());
|
||||
for (InetAddress ip : ips) {
|
||||
ResourceRecord rr = mapRR.get(ip);
|
||||
if (rr.Time + rr.TTL * 1000L < now &&
|
||||
rr.Time + 10 * 60 * 1000L < now) {
|
||||
mapRR.remove(ip);
|
||||
Log.i(TAG, "Purged " + rr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Called from native code
|
||||
private boolean isDomainBlocked(String name) {
|
||||
return (mapHostsBlocked.containsKey(name) && mapHostsBlocked.get(name));
|
||||
|
|
Loading…
Add table
Reference in a new issue