diff --git a/app/src/main/java/com/emanuelef/remote_capture/activities/StatsActivity.java b/app/src/main/java/com/emanuelef/remote_capture/activities/StatsActivity.java index 942c0696..f82f390c 100644 --- a/app/src/main/java/com/emanuelef/remote_capture/activities/StatsActivity.java +++ b/app/src/main/java/com/emanuelef/remote_capture/activities/StatsActivity.java @@ -24,8 +24,6 @@ import androidx.appcompat.app.ActionBar; import androidx.localbroadcastmanager.content.LocalBroadcastManager; import android.content.BroadcastReceiver; -import android.content.ClipData; -import android.content.ClipboardManager; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; @@ -51,6 +49,7 @@ public class StatsActivity extends BaseActivity { private TextView mPacketsRcvd; private TextView mActiveConns; private TextView mDroppedConns; + private TextView mDroppedPkts; private TextView mTotConns; private TextView mMaxFd; private TextView mOpenSocks; @@ -71,6 +70,7 @@ public class StatsActivity extends BaseActivity { mPacketsRcvd = findViewById(R.id.packets_rcvd); mActiveConns = findViewById(R.id.active_connections); mDroppedConns = findViewById(R.id.dropped_connections); + mDroppedPkts = findViewById(R.id.pkts_dropped); mTotConns = findViewById(R.id.tot_connections); mMaxFd = findViewById(R.id.max_fd); mOpenSocks = findViewById(R.id.open_sockets); @@ -82,7 +82,9 @@ public class StatsActivity extends BaseActivity { findViewById(R.id.dns_queries_row).setVisibility(View.GONE); findViewById(R.id.open_sockets_row).setVisibility(View.GONE); findViewById(R.id.max_fd_row).setVisibility(View.GONE); - } + findViewById(R.id.row_dropped_connections).setVisibility(View.GONE); + } else + findViewById(R.id.row_pkts_dropped).setVisibility(View.GONE); mReceiver = new BroadcastReceiver() { @Override @@ -121,6 +123,7 @@ public class StatsActivity extends BaseActivity { mPacketsRcvd.setText(Utils.formatPkts(stats.pkts_rcvd)); mActiveConns.setText(Utils.formatNumber(this, stats.active_conns)); mDroppedConns.setText(Utils.formatNumber(this, stats.num_dropped_conns)); + mDroppedPkts.setText(Utils.formatNumber(this, stats.pkts_dropped)); mTotConns.setText(Utils.formatNumber(this, stats.tot_conns)); mMaxFd.setText(Utils.formatNumber(this, stats.max_fd)); mOpenSocks.setText(Utils.formatNumber(this, stats.num_open_sockets)); diff --git a/app/src/main/java/com/emanuelef/remote_capture/model/VPNStats.java b/app/src/main/java/com/emanuelef/remote_capture/model/VPNStats.java index 3559f980..71063fd7 100644 --- a/app/src/main/java/com/emanuelef/remote_capture/model/VPNStats.java +++ b/app/src/main/java/com/emanuelef/remote_capture/model/VPNStats.java @@ -26,6 +26,7 @@ public class VPNStats implements Serializable { public long bytes_rcvd; public int pkts_sent; public int pkts_rcvd; + public int pkts_dropped; public int num_dropped_conns; public int num_open_sockets; public int max_fd; @@ -35,12 +36,13 @@ public class VPNStats implements Serializable { /* Invoked by native code */ public void setData(long _bytes_sent, long _bytes_rcvd, int _pkts_sent, int _pkts_rcvd, - int _num_dropped_conns, int _num_open_sockets, int _max_fd, - int _active_conns, int _tot_conns, int _num_dns_queries) { + int _pkts_dropped, int _num_dropped_conns, int _num_open_sockets, + int _max_fd, int _active_conns, int _tot_conns, int _num_dns_queries) { bytes_sent = _bytes_sent; bytes_rcvd = _bytes_rcvd; pkts_sent = _pkts_sent; pkts_rcvd = _pkts_rcvd; + pkts_dropped = _pkts_dropped; num_dropped_conns = _num_dropped_conns; num_open_sockets = _num_open_sockets; max_fd = _max_fd; diff --git a/app/src/main/jni/pcapd/pcapd.c b/app/src/main/jni/pcapd/pcapd.c index b71c562d..1852a567 100644 --- a/app/src/main/jni/pcapd/pcapd.c +++ b/app/src/main/jni/pcapd/pcapd.c @@ -490,8 +490,10 @@ static int is_tx_packet(pcapd_runtime_t *rt, const u_char *pkt, u_int16_t len) { static int run_pcap_dump(int uid_filter) { int rv = -1; + struct pcap_stat stats = {0}; pcapd_runtime_t rt = {0}; time_t next_interface_recheck = 0; + time_t next_stats_update = 0; uid_resolver_t *resolver = NULL; uid_lru_t *lru = NULL; @@ -575,6 +577,7 @@ static int run_pcap_dump(int uid_filter) { if((uid_filter == -1) || (uid_filter == uid)) { phdr.ts = hdr->ts; phdr.len = hdr->caplen; + phdr.pkt_drops = stats.ps_drop; phdr.uid = uid; phdr.flags = is_tx ? PCAPD_FLAG_TX : 0; @@ -591,9 +594,14 @@ static int run_pcap_dump(int uid_filter) { } } - if((rt.pd == NULL) && (time(NULL) >= next_interface_recheck)) { + time_t now = time(NULL); + + if((rt.pd == NULL) && (now >= next_interface_recheck)) { check_capture_interface(&rt); - next_interface_recheck = time(NULL) + 5; + next_interface_recheck = now + 5; + } else if((now >= next_stats_update)) { + pcap_stats(rt.pd, &stats); + next_stats_update = now + 3; } } diff --git a/app/src/main/jni/pcapd/pcapd.h b/app/src/main/jni/pcapd/pcapd.h index 4ed52184..8a30d958 100644 --- a/app/src/main/jni/pcapd/pcapd.h +++ b/app/src/main/jni/pcapd/pcapd.h @@ -31,6 +31,7 @@ typedef struct { struct timeval ts; + u_int pkt_drops; uid_t uid; uint16_t len; uint8_t flags; diff --git a/app/src/main/jni/vpnproxy-jni/capture_root.c b/app/src/main/jni/vpnproxy-jni/capture_root.c index 253c3b93..b7111334 100644 --- a/app/src/main/jni/vpnproxy-jni/capture_root.c +++ b/app/src/main/jni/vpnproxy-jni/capture_root.c @@ -358,6 +358,7 @@ int run_root(vpnproxy_data_t *proxy) { goto cleanup; } + proxy->num_dropped_pkts = hdr.pkt_drops; handle_packet(proxy, &connections, &hdr, buffer); housekeeping: diff --git a/app/src/main/jni/vpnproxy-jni/vpnproxy.c b/app/src/main/jni/vpnproxy-jni/vpnproxy.c index 48b1f1ad..1e2c6727 100644 --- a/app/src/main/jni/vpnproxy-jni/vpnproxy.c +++ b/app/src/main/jni/vpnproxy-jni/vpnproxy.c @@ -734,7 +734,7 @@ static void sendStatsDump(const vpnproxy_data_t *proxy, const zdtun_statistics_t (*env)->CallVoidMethod(env, stats_obj, mids.statsSetData, capstats->sent_bytes, capstats->rcvd_bytes, capstats->sent_pkts, capstats->rcvd_pkts, - proxy->num_dropped_connections, + min(proxy->num_dropped_pkts, INT_MAX), proxy->num_dropped_connections, stats->num_open_sockets, stats->all_max_fd, active_conns, tot_conns, proxy->num_dns_requests); if(!jniCheckException(env)) { @@ -967,7 +967,7 @@ static int run_tun(JNIEnv *env, jclass vpn, int tunfd, jint sdk) { /* NOTE: must match ConnectionDescriptor::setData */ "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;IIIIIJJJJIIII)V"); mids.statsInit = jniGetMethodID(env, cls.stats, "", "()V"); - mids.statsSetData = jniGetMethodID(env, cls.stats, "setData", "(JJIIIIIIII)V"); + mids.statsSetData = jniGetMethodID(env, cls.stats, "setData", "(JJIIIIIIIII)V"); vpnproxy_data_t proxy = { .tunfd = tunfd, diff --git a/app/src/main/jni/vpnproxy-jni/vpnproxy.h b/app/src/main/jni/vpnproxy-jni/vpnproxy.h index 314ab2db..1832d2fa 100644 --- a/app/src/main/jni/vpnproxy-jni/vpnproxy.h +++ b/app/src/main/jni/vpnproxy-jni/vpnproxy.h @@ -101,6 +101,7 @@ typedef struct vpnproxy_data { uid_resolver_t *resolver; ip_lru_t *ip_to_host; uint64_t now_ms; + u_int num_dropped_pkts; u_int32_t num_dropped_connections; u_int32_t num_dns_requests; conn_array_t new_conns; diff --git a/app/src/main/res/layout/activity_stats.xml b/app/src/main/res/layout/activity_stats.xml index c8a68484..dd86388c 100644 --- a/app/src/main/res/layout/activity_stats.xml +++ b/app/src/main/res/layout/activity_stats.xml @@ -82,6 +82,25 @@ android:layout_height="fill_parent"> android:textIsSelectable="true" /> + + + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 2acfbb0e..c67d98cc 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -158,5 +158,6 @@ Permissions This is a system daemon. \"Unknown\" marks connections whose app could not be determined + Packets Dropped