mirror of
https://github.com/emanuele-f/PCAPdroid.git
synced 2026-07-03 21:21:12 +08:00
Hide connections matching whitelist after delay
Some info of the connections, such as the host and the protocol, can become available after the connection has been shown. Such info could determine a match with the whitelist, in which case the connection must be hidden.
This commit is contained in:
parent
3e9680b96c
commit
ca7c8127d9
@ -72,13 +72,15 @@ public class ConnectionsRegister {
|
||||
conns = Arrays.copyOfRange(conns, conns.length - mSize, conns.length);
|
||||
}
|
||||
|
||||
int in_items = Math.min((mSize - mNumItems), conns.length);
|
||||
int out_items = conns.length - in_items;
|
||||
int out_items = conns.length - Math.min((mSize - mNumItems), conns.length);
|
||||
int insert_pos = mNumItems;
|
||||
ConnectionDescriptor []removedItems = null;
|
||||
|
||||
//Log.d(TAG, "newConnections[" + mNumItems + "/" + mSize +"]: insert " + conns.length +
|
||||
// " items at " + mTail + " (removed: " + out_items + " at " + firstPos() + ")");
|
||||
|
||||
if(out_items > 0) {
|
||||
int pos = mTail;
|
||||
int pos = firstPos();
|
||||
removedItems = new ConnectionDescriptor[out_items];
|
||||
|
||||
// update the apps stats
|
||||
@ -128,16 +130,16 @@ public class ConnectionsRegister {
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void connectionsUpdates(ConnectionUpdate[] conns) {
|
||||
public synchronized void connectionsUpdates(ConnectionUpdate[] updates) {
|
||||
int first_pos = firstPos();
|
||||
int first_id = mItemsRing[first_pos].incr_id;
|
||||
int last_id = mItemsRing[lastPos()].incr_id;
|
||||
int []changed_pos = new int[conns.length];
|
||||
int []changed_pos = new int[updates.length];
|
||||
int k = 0;
|
||||
|
||||
Log.d(TAG, "connectionsUpdates: items=" + mNumItems + ", first_id=" + first_id + ", last_id=" + last_id);
|
||||
|
||||
for(ConnectionUpdate update: conns) {
|
||||
for(ConnectionUpdate update: updates) {
|
||||
int id = update.incr_id;
|
||||
|
||||
// ignore updates for untracked items
|
||||
@ -159,10 +161,10 @@ public class ConnectionsRegister {
|
||||
}
|
||||
|
||||
for(ConnectionsListener listener: mListeners) {
|
||||
if(k != conns.length) {
|
||||
if(k != updates.length) {
|
||||
// some untracked items where skipped, shrink the array
|
||||
changed_pos = Arrays.copyOf(changed_pos, k);
|
||||
k = conns.length;
|
||||
k = updates.length;
|
||||
}
|
||||
|
||||
listener.connectionsUpdated(changed_pos);
|
||||
|
||||
@ -43,6 +43,7 @@ import com.emanuelef.remote_capture.Utils;
|
||||
import com.emanuelef.remote_capture.model.Whitelist;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Objects;
|
||||
|
||||
@ -58,7 +59,12 @@ public class ConnectionsAdapter extends RecyclerView.Adapter<ConnectionsAdapter.
|
||||
private int mClickedPosition;
|
||||
private int mNumRemovedItems;
|
||||
public boolean mWhitelistEnabled;
|
||||
|
||||
// maps a connection ID to a position in mFilteredConn. Positions are shifted by mNumRemovedItems
|
||||
// to provide an always increasing position even when items are removed. The correct unshifted
|
||||
// position is returned by getFilteredItemPos.
|
||||
private final HashMap<Integer, Integer> mIdToFilteredPos;
|
||||
|
||||
private ArrayList<ConnectionDescriptor> mFilteredConn;
|
||||
private String mFilter;
|
||||
public final Whitelist mWhitelist;
|
||||
@ -175,8 +181,10 @@ public class ConnectionsAdapter extends RecyclerView.Adapter<ConnectionsAdapter.
|
||||
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
|
||||
ConnectionDescriptor conn = getItem(position);
|
||||
|
||||
if(conn == null)
|
||||
if(conn == null) {
|
||||
Log.w(TAG, "bad position: " + position);
|
||||
return;
|
||||
}
|
||||
|
||||
holder.bindConn(mContext, conn, mApps, mUnknownIcon);
|
||||
}
|
||||
@ -203,6 +211,20 @@ public class ConnectionsAdapter extends RecyclerView.Adapter<ConnectionsAdapter.
|
||||
return(pos - mNumRemovedItems);
|
||||
}
|
||||
|
||||
private void removeItemAt(int pos) {
|
||||
int incr_id = mFilteredConn.get(pos).incr_id;
|
||||
|
||||
mFilteredConn.remove(pos);
|
||||
mIdToFilteredPos.remove(incr_id);
|
||||
notifyItemRemoved(pos);
|
||||
}
|
||||
|
||||
/* Fixes the mappings in mIdToFilteredPos, starting from the provided position */
|
||||
private void fixFilteredPositions(int startPos) {
|
||||
for(int i=startPos; i<mFilteredConn.size(); i++)
|
||||
mIdToFilteredPos.put(mFilteredConn.get(i).incr_id, i + mNumRemovedItems);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connectionsChanges(int num_connetions) {
|
||||
mUnfilteredItemsCount = num_connetions;
|
||||
@ -219,12 +241,12 @@ public class ConnectionsAdapter extends RecyclerView.Adapter<ConnectionsAdapter.
|
||||
}
|
||||
|
||||
int numNew = 0;
|
||||
int vpos = mNumRemovedItems + mFilteredConn.size();
|
||||
int pos = mNumRemovedItems + mFilteredConn.size();
|
||||
|
||||
// Assume that connections are only added at the end of the dataset
|
||||
for(ConnectionDescriptor conn : conns) {
|
||||
if(matches(conn)) {
|
||||
mIdToFilteredPos.put(conn.incr_id, vpos++);
|
||||
mIdToFilteredPos.put(conn.incr_id, pos++);
|
||||
mFilteredConn.add(conn);
|
||||
numNew++;
|
||||
}
|
||||
@ -247,15 +269,14 @@ public class ConnectionsAdapter extends RecyclerView.Adapter<ConnectionsAdapter.
|
||||
if(conn == null)
|
||||
continue;
|
||||
|
||||
int vpos = getFilteredItemPos(conn.incr_id);
|
||||
int pos = getFilteredItemPos(conn.incr_id);
|
||||
|
||||
if(vpos != -1) {
|
||||
// Assume that connections are only remove from the start of the dataset
|
||||
mFilteredConn.remove(0);
|
||||
mIdToFilteredPos.remove(conn.incr_id);
|
||||
if(pos != -1) {
|
||||
// Assume that connections are only removed from the start of the dataset
|
||||
removeItemAt(0);
|
||||
|
||||
// by incrementing mNumRemovedItems we can shift the position of subsequent items
|
||||
mNumRemovedItems++;
|
||||
notifyItemRemoved(vpos);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -269,19 +290,43 @@ public class ConnectionsAdapter extends RecyclerView.Adapter<ConnectionsAdapter.
|
||||
}
|
||||
|
||||
ConnectionsRegister reg = CaptureService.requireConnsRegister();
|
||||
int first_removed_pos = -1;
|
||||
int num_just_removed = 0;
|
||||
|
||||
for(int pos : positions) {
|
||||
ConnectionDescriptor conn = reg.getConn(pos);
|
||||
// Sort order necessary to properly use num_just_removed
|
||||
Arrays.sort(positions);
|
||||
|
||||
for(int reg_pos : positions) {
|
||||
ConnectionDescriptor conn = reg.getConn(reg_pos);
|
||||
|
||||
if(conn != null) {
|
||||
int vpos = getFilteredItemPos(conn.incr_id);
|
||||
int pos = getFilteredItemPos(conn.incr_id);
|
||||
|
||||
if(vpos != -1) {
|
||||
Log.d(TAG, "Changed item " + vpos + ", dataset size: " + getItemCount());
|
||||
notifyItemChanged(pos);
|
||||
if(pos != -1) {
|
||||
pos -= num_just_removed;
|
||||
|
||||
if(matches(conn)) {
|
||||
Log.d(TAG, "Changed item " + pos + ", dataset size: " + getItemCount());
|
||||
notifyItemChanged(pos);
|
||||
} else {
|
||||
Log.d(TAG, "Unmatch item " + pos + ": " + conn.toString());
|
||||
|
||||
// A previously matching connection may not match anymore. This happens, for
|
||||
// example, when its info or protocol is updated. In this case, the connection
|
||||
// must be removed.
|
||||
removeItemAt(pos);
|
||||
num_just_removed++;
|
||||
|
||||
if(first_removed_pos == -1)
|
||||
first_removed_pos = pos;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Need to recalculate the mappings starting at the first removed item
|
||||
if(first_removed_pos != -1)
|
||||
fixFilteredPositions(first_removed_pos);
|
||||
}
|
||||
|
||||
public void refreshFilteredConnections() {
|
||||
@ -295,7 +340,7 @@ public class ConnectionsAdapter extends RecyclerView.Adapter<ConnectionsAdapter.
|
||||
mNumRemovedItems = 0;
|
||||
|
||||
if(hasWhitelistFilter() || (mFilter != null)) {
|
||||
int vpos = 0;
|
||||
int pos = 0;
|
||||
mFilteredConn = new ArrayList<>();
|
||||
|
||||
for(int i=0; i<mUnfilteredItemsCount; i++) {
|
||||
@ -303,7 +348,7 @@ public class ConnectionsAdapter extends RecyclerView.Adapter<ConnectionsAdapter.
|
||||
|
||||
if(matches(conn)) {
|
||||
mFilteredConn.add(conn);
|
||||
mIdToFilteredPos.put(conn.incr_id, vpos++);
|
||||
mIdToFilteredPos.put(conn.incr_id, pos++);
|
||||
}
|
||||
}
|
||||
|
||||
@ -320,8 +365,10 @@ public class ConnectionsAdapter extends RecyclerView.Adapter<ConnectionsAdapter.
|
||||
|
||||
ConnectionsRegister reg = CaptureService.getConnsRegister();
|
||||
|
||||
if((pos < 0) || (pos >= mUnfilteredItemsCount) || (reg == null))
|
||||
if((pos < 0) || (pos >= mUnfilteredItemsCount) || (reg == null)) {
|
||||
Log.w(TAG, "getItem: bad position: " + pos);
|
||||
return null;
|
||||
}
|
||||
|
||||
return reg.getConn(pos);
|
||||
}
|
||||
|
||||
@ -455,7 +455,7 @@ public class ConnectionsFragment extends Fragment implements ConnectionsListener
|
||||
@Override
|
||||
public void connectionsAdded(int start, ConnectionDescriptor []conns) {
|
||||
mHandler.post(() -> {
|
||||
Log.d(TAG, "Added " + conns.length + " connections at " + start);
|
||||
Log.d(TAG, "Add " + conns.length + " connections at " + start);
|
||||
|
||||
mAdapter.connectionsAdded(start, conns);
|
||||
|
||||
|
||||
@ -21,6 +21,8 @@ package com.emanuelef.remote_capture.model;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.emanuelef.remote_capture.AppsResolver;
|
||||
import com.emanuelef.remote_capture.R;
|
||||
|
||||
@ -128,4 +130,10 @@ public class ConnectionDescriptor implements Serializable {
|
||||
app.getPackageName().equals(filter)))
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull String toString() {
|
||||
return "[proto=" + ipproto + "/" + l7proto + "]: " + src_ip + ":" + src_port + " -> " +
|
||||
dst_ip + ":" + dst_port + " [" + uid + "] " + info;
|
||||
}
|
||||
}
|
||||
|
||||
@ -17,6 +17,7 @@
|
||||
* Copyright 2020-21 - Emanuele Faranda
|
||||
*/
|
||||
|
||||
#include <inttypes.h>
|
||||
#include "vpnproxy.h"
|
||||
#include "pcap_utils.h"
|
||||
#include "common/utils.h"
|
||||
@ -38,8 +39,8 @@ static ndpi_protocol_bitmask_struct_t masterProtos;
|
||||
static int dumper_socket;
|
||||
static bool send_header;
|
||||
static int netd_resolve_waiting;
|
||||
static time_t last_connections_dump;
|
||||
static time_t next_connections_dump;
|
||||
static u_int64_t last_connections_dump;
|
||||
static u_int64_t next_connections_dump;
|
||||
static vpnproxy_data_t *global_proxy = NULL;
|
||||
|
||||
/* ******************************************************* */
|
||||
@ -728,7 +729,7 @@ static void sendConnectionsDump(vpnproxy_data_t *proxy) {
|
||||
if((proxy->new_conns.cur_items == 0) && (proxy->conns_updates.cur_items == 0))
|
||||
return;
|
||||
|
||||
log_d("sendConnectionsDump [after %d ms]: new=%d, updates=%d",
|
||||
log_d("sendConnectionsDump [after %" PRIu64 " ms]: new=%d, updates=%d",
|
||||
proxy->now_ms - last_connections_dump,
|
||||
proxy->new_conns.cur_items, proxy->conns_updates.cur_items);
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user