From 429215400ee7d8668e34b45cbd97124dcf3ea31b Mon Sep 17 00:00:00 2001 From: emanuele-f Date: Wed, 24 Mar 2021 00:52:21 +0100 Subject: [PATCH] Refresh connection details activity --- .../remote_capture/ConnectionsRegister.java | 19 +++ .../activities/ConnectionDetailsActivity.java | 151 +++++++++++++++--- .../model/ConnectionDescriptor.java | 1 + app/src/main/res/values-it/strings.xml | 4 +- 4 files changed, 147 insertions(+), 28 deletions(-) diff --git a/app/src/main/java/com/emanuelef/remote_capture/ConnectionsRegister.java b/app/src/main/java/com/emanuelef/remote_capture/ConnectionsRegister.java index d72060cd..5f597195 100644 --- a/app/src/main/java/com/emanuelef/remote_capture/ConnectionsRegister.java +++ b/app/src/main/java/com/emanuelef/remote_capture/ConnectionsRegister.java @@ -182,10 +182,14 @@ public class ConnectionsRegister { // Send the first update to sync it listener.connectionsChanges(num_items); + + Log.d(TAG, "(add) new connections listeners size: " + mListeners.size()); } public synchronized void removeListener(ConnectionsListener listener) { mListeners.remove(listener); + + Log.d(TAG, "(remove) new connections listeners size: " + mListeners.size()); } public int getConnCount() { @@ -224,6 +228,21 @@ public class ConnectionsRegister { return null; } + public synchronized int getConnPositionByIncrId(int incr_id) { + int first = firstPos(); + + for(int i = 0; i < num_items; i++) { + int pos = (first + i) % size; + ConnectionDescriptor item = items_ring[pos]; + + if((item != null) && (item.incr_id == incr_id)) { + return pos; + } + } + + return -1; + } + public synchronized List getAppsStats() { ArrayList rv = new ArrayList<>(mAppsStats.size()); diff --git a/app/src/main/java/com/emanuelef/remote_capture/activities/ConnectionDetailsActivity.java b/app/src/main/java/com/emanuelef/remote_capture/activities/ConnectionDetailsActivity.java index 7cc6d85a..883ca7dd 100644 --- a/app/src/main/java/com/emanuelef/remote_capture/activities/ConnectionDetailsActivity.java +++ b/app/src/main/java/com/emanuelef/remote_capture/activities/ConnectionDetailsActivity.java @@ -25,6 +25,9 @@ import android.content.ClipData; import android.content.ClipboardManager; import android.content.Intent; import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; +import android.util.Log; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; @@ -32,11 +35,14 @@ import android.view.View; import android.widget.TableLayout; import android.widget.TextView; +import com.emanuelef.remote_capture.CaptureService; +import com.emanuelef.remote_capture.ConnectionsRegister; import com.emanuelef.remote_capture.R; import com.emanuelef.remote_capture.Utils; +import com.emanuelef.remote_capture.interfaces.ConnectionsListener; import com.emanuelef.remote_capture.model.ConnectionDescriptor; -public class ConnectionDetailsActivity extends BaseActivity { +public class ConnectionDetailsActivity extends BaseActivity implements ConnectionsListener { private static final String TAG = "ConnectionDetails"; public static final String CONN_EXTRA_KEY = "conn_descriptor"; public static final String APP_NAME_EXTRA_KEY = "app_name"; @@ -44,10 +50,13 @@ public class ConnectionDetailsActivity extends BaseActivity { private TextView mBytesView; private TextView mPacketsView; private TextView mDurationView; - private ConnectionDescriptor conn; + private ConnectionDescriptor mConn; private TextView mStatus; private TextView mFirstSeen; private TextView mLastSeen; + private Handler mHandler; + private int mConnPos; + private boolean mListenerSet; @Override protected void onCreate(Bundle savedInstanceState) { @@ -55,7 +64,9 @@ public class ConnectionDetailsActivity extends BaseActivity { setTitle(R.string.connection_details); setContentView(R.layout.activity_connection_details); - conn = (ConnectionDescriptor) getIntent().getSerializableExtra(CONN_EXTRA_KEY); + mConn = (ConnectionDescriptor) getIntent().getSerializableExtra(CONN_EXTRA_KEY); + mHandler = new Handler(Looper.getMainLooper()); + mConnPos = -1; String app_name = getIntent().getStringExtra(APP_NAME_EXTRA_KEY); TextView app = findViewById(R.id.detail_app); @@ -75,41 +86,95 @@ public class ConnectionDetailsActivity extends BaseActivity { mFirstSeen = findViewById(R.id.first_seen); mLastSeen = findViewById(R.id.last_seen); - String l4proto = Utils.proto2str(conn.ipproto); + String l4proto = Utils.proto2str(mConn.ipproto); - if(conn != null) { - if(!conn.l7proto.equals(l4proto)) - proto.setText(String.format(getResources().getString(R.string.app_and_proto), conn.l7proto, l4proto)); + if(mConn != null) { + if(!mConn.l7proto.equals(l4proto)) + proto.setText(String.format(getResources().getString(R.string.app_and_proto), mConn.l7proto, l4proto)); else - proto.setText(conn.l7proto); + proto.setText(mConn.l7proto); - source.setText(String.format(getResources().getString(R.string.ip_and_port), conn.src_ip, conn.src_port)); - destination.setText(String.format(getResources().getString(R.string.ip_and_port), conn.dst_ip, conn.dst_port)); + source.setText(String.format(getResources().getString(R.string.ip_and_port), mConn.src_ip, mConn.src_port)); + destination.setText(String.format(getResources().getString(R.string.ip_and_port), mConn.dst_ip, mConn.dst_port)); - if((conn.info != null) && (!conn.info.isEmpty())) { - if(conn.l7proto.equals("DNS")) + if((mConn.info != null) && (!mConn.info.isEmpty())) { + if(mConn.l7proto.equals("DNS")) info_label.setText(R.string.query); - else if(conn.l7proto.equals("HTTP")) + else if(mConn.l7proto.equals("HTTP")) info_label.setText(R.string.host); - info.setText(conn.info); + info.setText(mConn.info); } else info_row.setVisibility(View.GONE); - updateStats(); + if(app_name != null) + app.setText(String.format(getResources().getString(R.string.app_and_proto), app_name, Integer.toString(mConn.uid))); + else + app.setText(Integer.toString(mConn.uid)); + + if(!mConn.url.isEmpty()) + url.setText(mConn.url); + else + url_row.setVisibility(View.GONE); + + updateStats(mConn); } - - if(app_name != null) - app.setText(String.format(getResources().getString(R.string.app_and_proto), app_name, Integer.toString(conn.uid))); - else - app.setText(Integer.toString(conn.uid)); - - if(!conn.url.isEmpty()) - url.setText(conn.url); - else - url_row.setVisibility(View.GONE); } - private void updateStats() { + @Override + public void onResume() { + super.onResume(); + mConnPos = -1; + + // Closed connections won't be updated + if(mConn.status < ConnectionDescriptor.CONN_STATUS_CLOSED) + registerConnsListener(); + } + + @Override + public void onPause() { + super.onPause(); + + unregisterConnsListener(); + } + + private void registerConnsListener() { + ConnectionsRegister reg = CaptureService.getConnsRegister(); + + if((reg != null) && !mListenerSet) { + mConnPos = reg.getConnPositionByIncrId(mConn.incr_id); + + if(mConnPos != -1) { + ConnectionDescriptor conn = reg.getConn(mConnPos); + + if(conn != null) { + if(conn.status < ConnectionDescriptor.CONN_STATUS_CLOSED) { + Log.d(TAG, "Adding connections listener"); + reg.addListener(this); + mListenerSet = true; + } + + updateStats(conn); + } + } + } + } + + private void unregisterConnsListener() { + if(mListenerSet) { + ConnectionsRegister reg = CaptureService.getConnsRegister(); + + if(reg != null) { + Log.d(TAG, "Removing connections listener"); + reg.removeListener(this); + } + + mListenerSet = false; + } + + mConnPos = -1; + } + + private void updateStats(ConnectionDescriptor conn) { if(conn != null) { mBytesView.setText(String.format(getResources().getString(R.string.up_and_down), Utils.formatBytes(conn.rcvd_bytes), Utils.formatBytes(conn.sent_bytes))); mPacketsView.setText(String.format(getResources().getString(R.string.up_and_down), Utils.formatPkts(conn.rcvd_pkts), Utils.formatPkts(conn.sent_pkts))); @@ -117,6 +182,9 @@ public class ConnectionDetailsActivity extends BaseActivity { mFirstSeen.setText(Utils.formatEpochFull(this, conn.first_seen)); mLastSeen.setText(Utils.formatEpochFull(this, conn.last_seen)); mStatus.setText(conn.getStatusLabel(this)); + + if(conn.status >= ConnectionDescriptor.CONN_STATUS_CLOSED) + unregisterConnsListener(); } } @@ -156,4 +224,35 @@ public class ConnectionDetailsActivity extends BaseActivity { return super.onOptionsItemSelected(item); } + + @Override + public void connectionsChanges(int num_connetions) {} + + @Override + public void connectionsAdded(int start, int count) {} + + @Override + public void connectionsRemoved(int start, int count) {} + + @Override + public void connectionsUpdated(int[] positions) { + ConnectionsRegister reg = CaptureService.getConnsRegister(); + + if((reg == null) || (mConnPos < 0)) + return; + + for(int pos : positions) { + if(pos == mConnPos) { + ConnectionDescriptor conn = reg.getConn(pos); + + // Double check the incr_id + if((conn != null) && (conn.incr_id == mConn.incr_id)) + mHandler.post(() -> updateStats(conn)); + else + unregisterConnsListener(); + + break; + } + } + } } diff --git a/app/src/main/java/com/emanuelef/remote_capture/model/ConnectionDescriptor.java b/app/src/main/java/com/emanuelef/remote_capture/model/ConnectionDescriptor.java index 726e76c3..29b18210 100644 --- a/app/src/main/java/com/emanuelef/remote_capture/model/ConnectionDescriptor.java +++ b/app/src/main/java/com/emanuelef/remote_capture/model/ConnectionDescriptor.java @@ -97,6 +97,7 @@ public class ConnectionDescriptor implements Serializable { if(status >= CONN_STATUS_CLOSED) { switch(status) { case CONN_STATUS_CLOSED: + case CONN_STATUS_RESET: resid = R.string.conn_status_closed; break; case CONN_STATUS_UNREACHABLE: diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index e1238f22..8c4899d4 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -81,10 +81,10 @@ %1$s catturati, %2$s connessioni Nessun filtro app impostato %1$s, %2$d - Aperta + Attiva Inizio Fine - Chiusa + Terminata Copia negli appunti Copiato negli appunti! IPProto,SrcIP,SrcPort,DstIp,DstPort,Uid,App,Proto,Status,Info,BytesSent,BytesRcvd,PktsSent,PktsRcvd,FirstSeen,LastSeen