Skip to content

Commit

Permalink
Implement dns responses live log for VPN mode.
Browse files Browse the repository at this point in the history
  • Loading branch information
Gedsh committed Jan 17, 2020
1 parent b866bee commit f6bb165
Show file tree
Hide file tree
Showing 5 changed files with 206 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,17 @@

import android.annotation.SuppressLint;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.content.SharedPreferences;
import android.os.Bundle;
import androidx.fragment.app.Fragment;
import androidx.preference.PreferenceManager;

import android.os.IBinder;
import android.text.Html;
import android.text.method.ScrollingMovementMethod;
import android.util.Log;
Expand All @@ -41,7 +45,9 @@
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Objects;
import java.util.Timer;
import java.util.TimerTask;
Expand All @@ -58,6 +64,8 @@
import pan.alexander.tordnscrypt.utils.Verifier;
import pan.alexander.tordnscrypt.utils.enums.ModuleState;
import pan.alexander.tordnscrypt.modules.ModulesStatus;
import pan.alexander.tordnscrypt.vpn.ResourceRecord;
import pan.alexander.tordnscrypt.vpn.service.ServiceVPN;
import pan.alexander.tordnscrypt.vpn.service.ServiceVPNHelper;

import static pan.alexander.tordnscrypt.TopFragment.DNSCryptVersion;
Expand All @@ -72,6 +80,7 @@
import static pan.alexander.tordnscrypt.utils.enums.ModuleState.STOPPED;
import static pan.alexander.tordnscrypt.utils.enums.ModuleState.STOPPING;
import static pan.alexander.tordnscrypt.utils.enums.OperationMode.ROOT_MODE;
import static pan.alexander.tordnscrypt.utils.enums.OperationMode.VPN_MODE;


public class DNSCryptRunFragment extends Fragment implements View.OnClickListener {
Expand All @@ -93,6 +102,11 @@ public class DNSCryptRunFragment extends Fragment implements View.OnClickListene
private ModuleState fixedModuleState;
private int displayLogPeriod = -1;

private ServiceConnection serviceConnection;
private ServiceVPN serviceVPN;
private boolean bound;
private ArrayList<ResourceRecord> savedResourceRecords;


public DNSCryptRunFragment() {
}
Expand Down Expand Up @@ -144,7 +158,7 @@ public void onReceive(Context context, Intent intent) {

if (sb.toString().contains("DNSCrypt_version")) {
String[] strArr = sb.toString().split("DNSCrypt_version");
if (strArr.length > 1 && strArr[1].trim().matches("\\d+\\.\\d+\\.\\d+")) {
if (getActivity() != null && strArr.length > 1 && strArr[1].trim().matches("\\d+\\.\\d+\\.\\d+")) {
DNSCryptVersion = strArr[1].trim();
new PrefManager(getActivity()).setStrPref("DNSCryptVersion", DNSCryptVersion);

Expand Down Expand Up @@ -181,9 +195,7 @@ public void onReceive(Context context, Intent intent) {
setDnsCryptSomethingWrong();
}

}

if (action.equals(TOP_BROADCAST)) {
} else if (action.equals(TOP_BROADCAST)) {
if (TOP_BROADCAST.contains("TOP_BROADCAST")) {
Log.i(LOG_TAG, "DNSCryptRunFragment onReceive TOP_BROADCAST");

Expand Down Expand Up @@ -266,6 +278,8 @@ public void onResume() {

modulesStatus = ModulesStatus.getInstance();

savedResourceRecords = new ArrayList<>();

logFile = new OwnFileReader(getActivity(), appDataDir + "/logs/DnsCrypt.log");

if (isDNSCryptInstalled()) {
Expand Down Expand Up @@ -318,6 +332,7 @@ public void onResume() {
public void onStop() {
super.onStop();
try {
unbindVPNService(getActivity());
stopDisplayLog();
if (br != null) Objects.requireNonNull(getActivity()).unregisterReceiver(br);
} catch (Exception e) {
Expand Down Expand Up @@ -474,6 +489,10 @@ private void refreshDNSCryptState() {

displayLog(5000);

if (modulesStatus.getMode() == VPN_MODE && !bound) {
bindToVPNService(getActivity());
}

} else if (currentModuleState == STOPPED) {

if (isSavedDNSStatusRunning()) {
Expand Down Expand Up @@ -628,24 +647,25 @@ public void run() {
displayLog(10000);
}

getActivity().runOnUiThread(new Runnable() {
displayDnsResponses(lastLines);

@Override
public void run() {
getActivity().runOnUiThread(() -> {

refreshDNSCryptState();
refreshDNSCryptState();

if (!previousLastLines.contentEquals(lastLines)) {
if (!previousLastLines.contentEquals(lastLines)) {

dnsCryptStartedSuccessfully(lastLines);
dnsCryptStartedSuccessfully(lastLines);

dnsCryptStartedWithError(lastLines);
dnsCryptStartedWithError(lastLines);

if (!previousLastLines.isEmpty()) {
tvDNSCryptLog.setText(Html.fromHtml(lastLines));
previousLastLines = lastLines;
}

previousLastLines = lastLines;
}

});

}
Expand Down Expand Up @@ -743,4 +763,93 @@ private void cleanLogFileNoRootMethod() {
}
}

private void bindToVPNService(Context context) {
serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
serviceVPN = ((ServiceVPN.VPNBinder) service).getService();
bound = true;
}

@Override
public void onServiceDisconnected(ComponentName name) {
bound = false;
}
};

if (context != null) {
Intent intent = new Intent(context, ServiceVPN.class);
context.bindService(intent, serviceConnection, 0);
}
}

private void unbindVPNService(Context context) {
if (bound && serviceConnection != null && context != null) {
context.unbindService(serviceConnection);
bound = false;
}
}

private LinkedList<ResourceRecord> getResourceRecords() {
if (serviceVPN != null) {
return serviceVPN.getResourceRecords();
}
return new LinkedList<>();
}

private void displayDnsResponses(String savedLines) {
if (modulesStatus.getMode() != VPN_MODE) {
if (!savedResourceRecords.isEmpty() && getActivity() != null) {
savedResourceRecords.clear();
getActivity().runOnUiThread(() -> tvDNSCryptLog.setText(Html.fromHtml(logFile.readLastLines())));
}
return;
} else if (getActivity() != null && modulesStatus.getMode() == VPN_MODE && !bound) {
bindToVPNService(getActivity());
}

ArrayList<ResourceRecord> resourceRecords = new ArrayList<>(getResourceRecords());

if (resourceRecords.equals(savedResourceRecords) || resourceRecords.isEmpty()) {
return;
}

savedResourceRecords = resourceRecords;

ResourceRecord rr;
StringBuilder line = new StringBuilder();

line.append(savedLines);

line.append("<br />");

for (int i = 0; i < savedResourceRecords.size(); i++) {
rr = savedResourceRecords.get(i);

if (rr.Resource.equals("0.0.0.0") || rr.HInfo.contains("dnscrypt") || rr.Rcode != 0) {
if (!rr.AName.isEmpty()) {
line.append("<font color=#f08080>").append(rr.AName);

if (rr.HInfo.contains("block_ipv6")) {
line.append(" ipv6");
}

line.append("</font>");
} else {
line.append("<font color=#f08080>").append(rr.QName).append("</font>");
}
} else {
line.append("<font color=#0f7f7f>").append(rr.AName).append("</font>");
}

if (i < savedResourceRecords.size() - 1) {
line.append("<br />");
}
}

if (getActivity() != null) {
getActivity().runOnUiThread(() -> tvDNSCryptLog.setText(Html.fromHtml(line.toString())));
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,20 @@

import androidx.annotation.NonNull;

import java.io.Serializable;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Objects;

public class ResourceRecord {
public class ResourceRecord implements Serializable {
public long Time;
public String QName;
public String AName;
public String CName;
public String HInfo;
public String Resource;
public int TTL;
public int Rcode;

private static DateFormat formatter = SimpleDateFormat.getDateTimeInstance();

Expand All @@ -40,7 +42,6 @@ public ResourceRecord() {

private String trimToNotASCIISymbols(String line) {
StringBuilder result = new StringBuilder();
int i = 0;
for (char ch : line.toCharArray()) {
if (ch < 128) {
result.append(ch);
Expand All @@ -52,6 +53,43 @@ private String trimToNotASCIISymbols(String line) {
return result.toString();
}

private String rCodeToString(int Rcode) {
String result = "";
switch (Rcode) {
case 0:
result = "DNS Query completed successfully";
break;
case 1:
result = "DNS Query Format Error";
break;
case 2:
result = "Server failed to complete the DNS request";
break;
case 3:
result = "Domain name does not exist";
break;
case 4:
result = "Function not implemented";
break;
case 5:
result = "The server refused to answer for the query";
break;
case 6:
result = "Name that should not exist, does exist";
break;
case 7:
result = "RRset that should not exist, does exist";
break;
case 8:
result = "Server not authoritative for the zone";
break;
case 9:
result = "Name not in zone";
break;
}
return result;
}

@NonNull
@Override
public String toString() {
Expand All @@ -62,24 +100,39 @@ public String toString() {
" QName " + QName +
" AName " + AName +
" CName " + CName +
" TTL " + TTL +
" " + formatter.format(new Date(Time + TTL * 1000L).getTime());
" " + rCodeToString(Rcode);
} else if (!Resource.isEmpty()){
result = formatter.format(new Date(Time).getTime()) +
" QName " + QName +
" AName " + AName +
" Resource " + Resource +
" TTL " + TTL +
" " + formatter.format(new Date(Time + TTL * 1000L).getTime());
" " + rCodeToString(Rcode);
} else if (!HInfo.isEmpty()){
result = formatter.format(new Date(Time).getTime()) +
" QName " + QName +
" AName " + AName +
" HINFO " + trimToNotASCIISymbols(HInfo)+
" TTL " + TTL +
" " + formatter.format(new Date(Time + TTL * 1000L).getTime());
" " + rCodeToString(Rcode);
}

return result;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ResourceRecord that = (ResourceRecord) o;
return Time == that.Time &&
Rcode == that.Rcode &&
QName.equals(that.QName) &&
AName.equals(that.AName) &&
CName.equals(that.CName) &&
HInfo.equals(that.HInfo);
}

@Override
public int hashCode() {
return Objects.hash(Time, QName, AName, CName, HInfo, Rcode);
}
}
Loading

0 comments on commit f6bb165

Please sign in to comment.