Make recent remote interfaces a list

Storing every rpcapd host ever connected to in recent_common seems
unwise. Change it to a list, so we can have a max count and order.
Store the most recent 20. Maybe this could be a pref eventually.

Related to #17484.
This commit is contained in:
John Thacker 2023-11-19 09:24:37 -05:00 committed by AndersBroman
parent ad6947eb71
commit 2fa48bbbd5
4 changed files with 116 additions and 59 deletions

View File

@ -73,17 +73,16 @@ enum {
#if 0
#ifdef HAVE_PCAP_REMOTE
static void populateExistingRemotes(gpointer key, gpointer value, gpointer user_data)
static void populateExistingRemotes(gpointer value, gpointer user_data)
{
ManageInterfacesDialog *dialog = (ManageInterfacesDialog*)user_data;
const gchar *host = (const gchar *)key;
struct remote_host *remote_host = (struct remote_host *)value;
remote_options global_remote_opts;
int err;
gchar *err_str;
global_remote_opts.src_type = CAPTURE_IFREMOTE;
global_remote_opts.remote_host_opts.remote_host = g_strdup(host);
global_remote_opts.remote_host_opts.remote_host = g_strdup(remote_host->r_host);
global_remote_opts.remote_host_opts.remote_port = g_strdup(remote_host->remote_port);
global_remote_opts.remote_host_opts.auth_type = remote_host->auth_type;
global_remote_opts.remote_host_opts.auth_username = g_strdup(remote_host->auth_username);
@ -101,6 +100,13 @@ static void populateExistingRemotes(gpointer key, gpointer value, gpointer user_
global_remote_opts.remote_host_opts.auth_username,
global_remote_opts.remote_host_opts.auth_password,
&err, &err_str);
// XXX: A host that is in the recent list but is unavailable will cause
// the warning pop-up when opening Manage Interfaces, won't be added, and
// the process will repeat even if Wireshark is quit and restarted. The
// only way to remove hosts (besides editing the recent_common file) is
// to click on adding a remote host and clear the list of recent hosts.
// Should these errors provide an option to remove the failed host from
// the list, or at least a hint that that's how to remove them?
if (rlist == NULL) {
switch (err) {
case 0:

View File

@ -13,6 +13,7 @@
#ifdef HAVE_PCAP_REMOTE
#include <glib.h>
#include <ui/qt/utils/qt_ui_utils.h>
#include <ui/qt/utils/variant_pointer.h>
#include "ui/capture_globals.h"
#include "remote_capture_dialog.h"
#include <ui_remote_capture_dialog.h>
@ -49,7 +50,11 @@ void RemoteCaptureDialog::hostChanged(const QString host)
recent_free_remote_host_list();
ui->hostCombo->clear();
} else {
struct remote_host *rh = recent_get_remote_host(host.toUtf8().constData());
const struct remote_host *rh = nullptr;
int index = ui->hostCombo->findText(host);
if (index != -1) {
rh = VariantPointer<const struct remote_host>::asPtr(ui->hostCombo->itemData(index));
}
if (rh) {
ui->portText->setText(QString(rh->remote_port));
if (rh->auth_type == CAPTURE_AUTH_NULL) {
@ -62,10 +67,11 @@ void RemoteCaptureDialog::hostChanged(const QString host)
}
static void fillBox(gpointer key, gpointer, gpointer user_data)
static void fillBox(gpointer value, gpointer user_data)
{
QComboBox *cb = (QComboBox *)user_data;
cb->addItem(QString((gchar*)key));
struct remote_host* rh = (struct remote_host*)value;
cb->addItem(QString((gchar*)rh->r_host), VariantPointer<const struct remote_host>::asQVariant(rh));
}
void RemoteCaptureDialog::fillComboBox()
@ -88,6 +94,9 @@ void RemoteCaptureDialog::apply_remote()
remote_options global_remote_opts;
QString host = ui->hostCombo->currentText();
if (host.isEmpty()) {
return;
}
global_remote_opts.src_type = CAPTURE_IFREMOTE;
global_remote_opts.remote_host_opts.remote_host = qstring_strdup(host);
QString port = ui->portText->text();
@ -126,24 +135,28 @@ void RemoteCaptureDialog::apply_remote()
QMessageBox::critical(this, tr("Error"), "Unknown error");
return;
}
if (ui->hostCombo->count() == 0) {
ui->hostCombo->addItem("");
ui->hostCombo->addItem(host);
ui->hostCombo->insertSeparator(2);
ui->hostCombo->addItem(QString(tr("Clear list")));
} else {
ui->hostCombo->insertItem(0, host);
}
struct remote_host *rh = recent_get_remote_host(host.toUtf8().constData());
if (!rh) {
rh = (struct remote_host *)g_malloc (sizeof (*rh));
rh->r_host = qstring_strdup(host);
rh->remote_port = qstring_strdup(port);
rh->auth_type = global_remote_opts.remote_host_opts.auth_type;
rh->auth_password = g_strdup("");
rh->auth_username = g_strdup("");
recent_add_remote_host(global_remote_opts.remote_host_opts.remote_host, rh);
}
// Add the remote host even if it already exists, to update the port and
// auth type and move it to the front.
struct remote_host* rh;
rh = (struct remote_host *)g_malloc (sizeof (*rh));
rh->r_host = qstring_strdup(host);
rh->remote_port = qstring_strdup(port);
rh->auth_type = global_remote_opts.remote_host_opts.auth_type;
rh->auth_password = g_strdup("");
rh->auth_username = g_strdup("");
recent_add_remote_host(global_remote_opts.remote_host_opts.remote_host, rh);
// We don't need to add the new entry to hostCombo since we only call
// this when accepting the dialog.
// Tell the parent ManageInterfacesDialog we added this.
// XXX: If the remote hostname already exists in ManageInterfacesDialog,
// this doesn't remove it. Most of the time it won't, but there is the
// corner case of a host existing with empty (hence default, 2002) port,
// and then adding it a second time explicitly starting port 2002.
// Someone could bind rpcapd to multiple ports on the same host for
// some reason too, I suppose.
emit remoteAdded(rlist, &global_remote_opts);
}

View File

@ -462,7 +462,13 @@ recent_add_cfilter(const gchar *ifname, const gchar *s)
}
#ifdef HAVE_PCAP_REMOTE
static GHashTable *remote_host_list=NULL;
/* XXX: use a preference for this setting! */
/* N.B.: If we use a pref, we will read the recent_common file
* before the pref, so don't truncate the list when reading
* (see the similar #16782 for the recent files.)
*/
static guint remote_host_max_recent = 20;
static GList *remote_host_list = NULL;
int recent_get_remote_host_list_size(void)
{
@ -470,40 +476,62 @@ int recent_get_remote_host_list_size(void)
/* No entries exist. */
return 0;
}
return g_hash_table_size (remote_host_list);
return g_list_length(remote_host_list);
}
void recent_add_remote_host(gchar *host, struct remote_host *rh)
static void
free_remote_host(gpointer value)
{
if (remote_host_list == NULL) {
remote_host_list = g_hash_table_new (g_str_hash, g_str_equal);
struct remote_host* rh = (struct remote_host*)value;
g_free(rh->r_host);
g_free(rh->remote_port);
g_free(rh->auth_username);
g_free(rh->auth_password);
}
static int
remote_host_compare(gconstpointer a, gconstpointer b)
{
const struct remote_host* rh_a = (const struct remote_host*)a;
const struct remote_host* rh_b = (const struct remote_host*)b;
/* We assume only one entry per host (the GUI assumes that too.) */
return g_strcmp0(rh_a->r_host, rh_b->r_host);
}
static void
remote_host_reverse(void)
{
if (remote_host_list) {
remote_host_list = g_list_reverse(remote_host_list);
}
g_hash_table_insert (remote_host_list, g_strdup(host), rh);
}
static gboolean
free_remote_host (gpointer key _U_, gpointer value, gpointer user _U_)
void recent_add_remote_host(gchar *host _U_, struct remote_host *rh)
{
struct remote_host *rh = (struct remote_host *) value;
g_free (rh->r_host);
g_free (rh->remote_port);
g_free (rh->auth_username);
g_free (rh->auth_password);
return TRUE;
GList* li = NULL;
if (remote_host_list) {
li = g_list_find_custom(remote_host_list, rh, remote_host_compare);
if (li != NULL) {
free_remote_host(li->data);
remote_host_list = g_list_delete_link(remote_host_list, li);
}
}
remote_host_list = g_list_prepend(remote_host_list, rh);
}
void
recent_remote_host_list_foreach(GHFunc func, gpointer user_data)
recent_remote_host_list_foreach(GFunc func, gpointer user_data)
{
if (remote_host_list != NULL) {
g_hash_table_foreach(remote_host_list, func, user_data);
g_list_foreach(remote_host_list, func, user_data);
}
}
static void
recent_print_remote_host (gpointer key _U_, gpointer value, gpointer user)
recent_print_remote_host(gpointer value, gpointer user)
{
FILE *rf = (FILE *)user;
struct remote_host_info *ri = (struct remote_host_info *)value;
@ -519,16 +547,21 @@ recent_print_remote_host (gpointer key _U_, gpointer value, gpointer user)
static void
capture_remote_combo_recent_write_all(FILE *rf)
{
if (remote_host_list && g_hash_table_size (remote_host_list) > 0) {
/* Write all remote interfaces to the recent file */
g_hash_table_foreach (remote_host_list, recent_print_remote_host, rf);
unsigned max_count = 0;
GList *li = g_list_first(remote_host_list);
/* write all non empty remote capture hosts to the recent file (until max count) */
while (li && (max_count++ <= remote_host_max_recent)) {
recent_print_remote_host(li->data, rf);
li = li->next;
}
}
void recent_free_remote_host_list(void)
{
g_hash_table_foreach_remove(remote_host_list, free_remote_host, NULL);
g_list_free_full(remote_host_list, free_remote_host);
remote_host_list = NULL;
}
struct remote_host *
@ -536,11 +569,13 @@ recent_get_remote_host(const gchar *host)
{
if (host == NULL)
return NULL;
if (remote_host_list == NULL) {
/* No such host exist. */
return NULL;
for (GList* li = g_list_first(remote_host_list); li != NULL; li = li->next) {
struct remote_host *rh = (struct remote_host*)li->data;
if (g_strcmp0(host, rh->r_host) == 0) {
return rh;
}
}
return (struct remote_host *)g_hash_table_lookup(remote_host_list, host);
return NULL;
}
/**
@ -561,11 +596,12 @@ capture_remote_combo_add_recent(const gchar *s)
if (valp == NULL)
return FALSE;
if (remote_host_list == NULL) {
remote_host_list = g_hash_table_new (g_str_hash, g_str_equal);
/* First value is the host */
if (recent_get_remote_host(valp->data)) {
/* Don't add it, it's already in the list (shouldn't happen). */
return FALSE; // Should this be TRUE or FALSE?
}
rh =(struct remote_host *) g_malloc (sizeof (*rh));
rh = (struct remote_host *) g_malloc (sizeof (*rh));
/* First value is the host */
rh->r_host = (gchar *)g_strdup ((const gchar *)valp->data);
@ -606,8 +642,7 @@ capture_remote_combo_add_recent(const gchar *s)
prefs_clear_string_list(vals);
g_hash_table_insert (remote_host_list, g_strdup(rh->r_host), rh);
remote_host_list = g_list_prepend(remote_host_list, rh);
return TRUE;
}
#endif
@ -781,7 +816,7 @@ write_recent(void)
#ifdef HAVE_PCAP_REMOTE
fputs("\n"
"######## Recent remote hosts, cannot be altered through command line ########\n"
"######## Recent remote hosts (latest first), cannot be altered through command line ########\n"
"\n", rf);
capture_remote_combo_recent_write_all(rf);
@ -1620,6 +1655,9 @@ recent_read_dynamic(char **rf_path_return, int *rf_errno_return)
* all to keep the latest first.
*/
cfilter_recent_reverse_all();
#ifdef HAVE_PCAP_REMOTE
remote_host_reverse();
#endif
fclose(rf);
} else {
/* We failed to open it. If we failed for some reason other than

View File

@ -294,7 +294,7 @@ extern int recent_get_remote_host_list_size(void);
* @param func function to be called
* @param user_data argument to pass as user data to the function
*/
extern void recent_remote_host_list_foreach(GHFunc func, gpointer user_data);
extern void recent_remote_host_list_foreach(GFunc func, gpointer user_data);
/**
* Free all entries of the remote host list.