capture: Set update interval in capture opts, default to 100ms

Reduce the default update interval for dumpcap to notify its parent
of new packets (or to check if we've met file duration, etc.) from
500 ms to 100 ms, and put in the capture options.

This makes the GUI appear to update more in real time rather than
in visible batches of packets.

This also reduces the amount of ring buffer space needed in cases
where we're doing dissection, and dissection is able to keep up,
but the files can be deleted before tshark gets to them because of
the notification lag. (See #1650.)
This commit is contained in:
John Thacker 2023-03-08 22:15:21 -05:00 committed by AndersBroman
parent 15ed53005b
commit f0712606a3
16 changed files with 135 additions and 9 deletions

View File

@ -412,6 +412,13 @@ sync_pipe_start(capture_options *capture_opts, GPtrArray *capture_comments,
argv = sync_pipe_add_arg(argv, &argc, "-g");
}
if (capture_opts->update_interval != DEFAULT_UPDATE_INTERVAL) {
char scount[ARGV_NUMBER_LEN];
argv = sync_pipe_add_arg(argv, &argc, "--update-interval");
snprintf(scount, ARGV_NUMBER_LEN, "%d", capture_opts->update_interval);
argv = sync_pipe_add_arg(argv, &argc, scount);
}
for (j = 0; j < capture_opts->ifaces->len; j++) {
interface_opts = &g_array_index(capture_opts->ifaces, interface_options, j);

View File

@ -99,6 +99,7 @@ capture_opts_init(capture_options *capture_opts)
capture_opts->save_file = NULL;
capture_opts->group_read_access = FALSE;
capture_opts->use_pcapng = TRUE; /* Save as pcapng by default */
capture_opts->update_interval = DEFAULT_UPDATE_INTERVAL; /* 100 ms */
capture_opts->real_time_mode = TRUE;
capture_opts->show_info = TRUE;
capture_opts->restart = FALSE;
@ -270,6 +271,7 @@ capture_opts_log(const char *log_domain, enum ws_log_level log_level, capture_op
ws_log(log_domain, log_level, "SaveFile : %s", (capture_opts->save_file) ? capture_opts->save_file : "");
ws_log(log_domain, log_level, "GroupReadAccess : %u", capture_opts->group_read_access);
ws_log(log_domain, log_level, "Fileformat : %s", (capture_opts->use_pcapng) ? "PCAPNG" : "PCAP");
ws_log(log_domain, log_level, "UpdateInterval : %u (ms)", capture_opts->update_interval);
ws_log(log_domain, log_level, "RealTimeMode : %u", capture_opts->real_time_mode);
ws_log(log_domain, log_level, "ShowInfo : %u", capture_opts->show_info);
@ -1056,6 +1058,9 @@ capture_opts_add_opt(capture_options *capture_opts, int opt, const char *optarg_
#endif /* S_IRWXU */
capture_opts->temp_dir = g_strdup(optarg_str_p);
break;
case LONGOPT_UPDATE_INTERVAL: /* capture update interval */
capture_opts->update_interval = get_positive_int(optarg_str_p, "update interval");
break;
default:
/* the caller is responsible to send us only the right opt's */
ws_assert_not_reached();

View File

@ -48,6 +48,7 @@ extern "C" {
#define LONGOPT_SET_TSTAMP_TYPE LONGOPT_BASE_CAPTURE+2
#define LONGOPT_COMPRESS_TYPE LONGOPT_BASE_CAPTURE+3
#define LONGOPT_CAPTURE_TMPDIR LONGOPT_BASE_CAPTURE+4
#define LONGOPT_UPDATE_INTERVAL LONGOPT_BASE_CAPTURE+5
/*
* Options for capturing common to all capturing programs.
@ -89,7 +90,8 @@ extern "C" {
{"list-time-stamp-types", ws_no_argument, NULL, LONGOPT_LIST_TSTAMP_TYPES}, \
{"time-stamp-type", ws_required_argument, NULL, LONGOPT_SET_TSTAMP_TYPE}, \
{"compress-type", ws_required_argument, NULL, LONGOPT_COMPRESS_TYPE}, \
{"temp-dir", ws_required_argument, NULL, LONGOPT_CAPTURE_TMPDIR},
{"temp-dir", ws_required_argument, NULL, LONGOPT_CAPTURE_TMPDIR},\
{"update-interval", ws_required_argument, NULL, LONGOPT_UPDATE_INTERVAL},
#define OPTSTRING_CAPTURE_COMMON \
@ -280,6 +282,7 @@ typedef struct capture_options_tag {
gchar *save_file; /**< the capture file name */
gboolean group_read_access; /**< TRUE is group read permission needs to be set */
gboolean use_pcapng; /**< TRUE if file format is pcapng */
guint update_interval; /**< Time in milliseconds. How often to notify parent of new packet counts, check file duration, etc. */
/* GUI related */
gboolean real_time_mode; /**< Update list of packets in real time */
@ -390,6 +393,9 @@ capture_opts_free_interface_t(interface_t *device);
/* Default capture buffer size in Mbytes. */
#define DEFAULT_CAPTURE_BUFFER_SIZE 2
/* Default update interval in milliseconds */
#define DEFAULT_UPDATE_INTERVAL 100
#ifdef __cplusplus
}
#endif /* __cplusplus */

View File

@ -45,6 +45,7 @@ dumpcap - Dump network traffic
[ *--capture-comment* <comment> ]
[ *--list-time-stamp-types* ]
[ *--time-stamp-type* <type> ]
[ *--update-interval* <interval> ]
== DESCRIPTION
@ -509,6 +510,14 @@ set, no time stamp types are listed.
Change the interface's timestamp method.
--
--update-interval <interval>::
+
--
Set the length of time in milliseconds between new packet reports during
a capture. Also sets the granularity of file duration conditions.
The default value is 100ms.
--
include::diagnostic-options.adoc[]
== CAPTURE FILTER SYNTAX

View File

@ -2531,6 +2531,14 @@ set, no time stamp types are listed.
Change the interface's timestamp method.
--
--update-interval <interval>::
+
--
Set the length of time in milliseconds between new packet reports during
a capture. Also sets the granularity of file duration conditions.
The default value is 100ms.
--
--color::
+
--

View File

@ -683,6 +683,14 @@ Change the interface's timestamp method. See --list-time-stamp-types.
Output format of seconds (def: s: seconds)
--
--update-interval <interval>::
+
--
Set the length of time in milliseconds between new packet reports during
a capture. Also sets the granularity of file duration conditions.
The default value is 100ms.
--
-v|--version::
+
--

View File

@ -75,6 +75,9 @@ The following features are new (or have been significantly updated) since versio
* ciscodump support Cisco IOS XE 17.x
* The default interval between GUI updates when capturing has been decreased
from 500ms to 100ms, and is now configurable.
// === Removed Features and Support
// === Removed Dissectors

View File

@ -401,6 +401,7 @@ print_usage(FILE *output)
fprintf(output, " -L, --list-data-link-types\n");
fprintf(output, " print list of link-layer types of iface and exit\n");
fprintf(output, " --list-time-stamp-types print list of timestamp types for iface and exit\n");
fprintf(output, " --update-interval interval between updates with new packets (def: %dms)\n", DEFAULT_UPDATE_INTERVAL);
fprintf(output, " -d print generated BPF code for capture filter\n");
fprintf(output, " -k <freq>,[<type>],[<center_freq1>],[<center_freq2>]\n");
fprintf(output, " set channel on wifi interface\n");
@ -4099,19 +4100,19 @@ capture_loop_start(capture_options *capture_opts, gboolean *stats_known, struct
}
} /* inpkts */
/* Only update once every 500ms so as not to overload slow displays.
/* Only update after an interval so as not to overload slow displays.
* This also prevents too much context-switching between the dumpcap
* and wireshark processes.
* XXX: Should we send updates sooner if there have been lots of
* packets we haven't notified the parent about, such as on fast links?
*/
#define DUMPCAP_UPD_TIME 500
#ifdef _WIN32
cur_time = GetTickCount(); /* Note: wraps to 0 if sys runs for 49.7 days */
if ((cur_time - upd_time) > DUMPCAP_UPD_TIME) /* wrap just causes an extra update */
if ((cur_time - upd_time) > capture_opts->update_interval) /* wrap just causes an extra update */
#else
gettimeofday(&cur_time, NULL);
if (((guint64)cur_time.tv_sec * 1000000 + cur_time.tv_usec) >
((guint64)upd_time.tv_sec * 1000000 + upd_time.tv_usec + DUMPCAP_UPD_TIME*1000))
((guint64)upd_time.tv_sec * 1000000 + upd_time.tv_usec + capture_opts->update_interval*1000))
#endif
{
@ -5186,6 +5187,7 @@ main(int argc, char *argv[])
#endif
case LONGOPT_COMPRESS_TYPE: /* compress type */
case LONGOPT_CAPTURE_TMPDIR: /* capture temp directory */
case LONGOPT_UPDATE_INTERVAL: /* sync pipe update interval */
status = capture_opts_add_opt(&global_capture_opts, opt, ws_optarg);
if (status != 0) {
exit_main(status);

View File

@ -34,6 +34,7 @@
#include <epan/strutil.h>
#include <epan/column.h>
#include <epan/decode_as.h>
#include <capture_opts.h>
#include "print.h"
#include <wsutil/file_util.h>
#include <wsutil/report_message.h>
@ -3618,6 +3619,12 @@ prefs_register_modules(void)
prefs_register_bool_preference(capture_module, "real_time_update", "Update packet list in real time during capture",
"Update packet list in real time during capture?", &prefs.capture_real_time);
prefs_register_uint_preference(capture_module, "update_interval",
"Capture update interval",
"Capture update interval in ms",
10,
&prefs.capture_update_interval);
prefs_register_bool_preference(capture_module, "no_interface_load", "Don't load interfaces on startup",
"Don't automatically load capture interfaces on startup", &prefs.capture_no_interface_load);
@ -4245,6 +4252,7 @@ pre_init_prefs(void)
prefs.capture_prom_mode = TRUE;
prefs.capture_pcap_ng = TRUE;
prefs.capture_real_time = TRUE;
prefs.capture_update_interval = DEFAULT_UPDATE_INTERVAL;
prefs.capture_no_extcap = FALSE;
prefs.capture_auto_scroll = TRUE;
prefs.capture_show_info = FALSE;

View File

@ -193,6 +193,7 @@ typedef struct _e_prefs {
gboolean capture_prom_mode;
gboolean capture_pcap_ng;
gboolean capture_real_time;
guint capture_update_interval;
gboolean capture_auto_scroll; /* XXX - Move to recent */
gboolean capture_no_interface_load;
gboolean capture_no_extcap;

View File

@ -369,6 +369,7 @@ print_usage(FILE *output)
fprintf(output, " -L, --list-data-link-types\n");
fprintf(output, " print list of link-layer types of iface and exit\n");
fprintf(output, " --list-time-stamp-types print list of timestamp types for iface and exit\n");
fprintf(output, " --update-interval interval between updates with new packets (def: %dms)\n", DEFAULT_UPDATE_INTERVAL);
fprintf(output, "\n");
fprintf(output, "Capture stop conditions:\n");
fprintf(output, " -c <packet count> stop after n packets (def: infinite)\n");
@ -1260,6 +1261,7 @@ main(int argc, char *argv[])
#endif
case LONGOPT_COMPRESS_TYPE: /* compress type */
case LONGOPT_CAPTURE_TMPDIR: /* capture temp directory */
case LONGOPT_UPDATE_INTERVAL: /* sync pipe update interval */
/* These are options only for packet capture. */
#ifdef HAVE_LIBPCAP
exit_status = capture_opts_add_opt(&global_capture_opts, opt, ws_optarg);

View File

@ -83,9 +83,6 @@ commandline_print_usage(gboolean for_help_option) {
#endif
fprintf(output, " -p, --no-promiscuous-mode\n");
fprintf(output, " don't capture in promiscuous mode\n");
fprintf(output, " -k start capturing immediately (def: do nothing)\n");
fprintf(output, " -S update packet display when new packets are captured\n");
fprintf(output, " -l turn on automatic scrolling while -S is in use\n");
#ifdef HAVE_PCAP_CREATE
fprintf(output, " -I, --monitor-mode capture in monitor mode, if available\n");
#endif
@ -101,6 +98,11 @@ commandline_print_usage(gboolean for_help_option) {
fprintf(output, " print list of link-layer types of iface and exit\n");
fprintf(output, " --list-time-stamp-types print list of timestamp types for iface and exit\n");
fprintf(output, "\n");
fprintf(output, "Capture display:\n");
fprintf(output, " -k start capturing immediately (def: do nothing)\n");
fprintf(output, " -S update packet display when new packets are captured\n");
fprintf(output, " --update-interval interval between updates with new packets (def: %dms)\n", DEFAULT_UPDATE_INTERVAL);
fprintf(output, " -l turn on automatic scrolling while -S is in use\n");
fprintf(output, "Capture stop conditions:\n");
fprintf(output, " -c <packet count> stop after n packets (def: infinite)\n");
fprintf(output, " -a <autostop cond.> ..., --autostop <autostop cond.> ...\n");
@ -438,6 +440,7 @@ void commandline_other_options(int argc, char *argv[], gboolean opt_reset)
case 'i': /* Use interface x */
case LONGOPT_SET_TSTAMP_TYPE: /* Set capture timestamp type */
case LONGOPT_CAPTURE_TMPDIR: /* capture temp directory */
case LONGOPT_UPDATE_INTERVAL: /* sync pipe update interval */
#ifdef HAVE_PCAP_CREATE
case 'I': /* Capture in monitor mode, if available */
#endif

View File

@ -45,6 +45,7 @@ prefs_to_capture_opts(void)
global_capture_opts.use_pcapng = prefs.capture_pcap_ng;
global_capture_opts.show_info = prefs.capture_show_info;
global_capture_opts.real_time_mode = prefs.capture_real_time;
global_capture_opts.update_interval = prefs.capture_update_interval;
auto_scroll_live = prefs.capture_auto_scroll;
#endif /* HAVE_LIBPCAP */
}

View File

@ -17,6 +17,7 @@
#include "capture_preferences_frame.h"
#include <ui/qt/models/pref_models.h>
#include <ui/qt/widgets/syntax_line_edit.h>
#include <ui_capture_preferences_frame.h>
#include "main_application.h"
@ -37,6 +38,7 @@ CapturePreferencesFrame::CapturePreferencesFrame(QWidget *parent) :
pref_prom_mode_ = prefFromPrefPtr(&prefs.capture_prom_mode);
pref_pcap_ng_ = prefFromPrefPtr(&prefs.capture_pcap_ng);
pref_real_time_ = prefFromPrefPtr(&prefs.capture_real_time);
pref_update_interval_ = prefFromPrefPtr(&prefs.capture_update_interval);
pref_auto_scroll_ = prefFromPrefPtr(&prefs.capture_auto_scroll);
pref_no_interface_load_ = prefFromPrefPtr(&prefs.capture_no_interface_load);
pref_no_extcap_ = prefFromPrefPtr(&prefs.capture_no_extcap);
@ -106,6 +108,9 @@ void CapturePreferencesFrame::updateWidgets()
ui->capturePromModeCheckBox->setChecked(prefs_get_bool_value(pref_prom_mode_, pref_stashed));
ui->capturePcapNgCheckBox->setChecked(prefs_get_bool_value(pref_pcap_ng_, pref_stashed));
ui->captureRealTimeCheckBox->setChecked(prefs_get_bool_value(pref_real_time_, pref_stashed));
ui->captureUpdateIntervalLineEdit->setText(QString::number(prefs_get_uint_value_real(pref_update_interval_, pref_stashed)));
ui->captureUpdateIntervalLineEdit->setPlaceholderText(QString::number(prefs_get_uint_value_real(pref_update_interval_, pref_default)));
ui->captureUpdateIntervalLineEdit->setSyntaxState(SyntaxLineEdit::Empty);
ui->captureAutoScrollCheckBox->setChecked(prefs_get_bool_value(pref_auto_scroll_, pref_stashed));
#endif // HAVE_LIBPCAP
ui->captureNoInterfaceLoad->setChecked(prefs_get_bool_value(pref_no_interface_load_, pref_stashed));
@ -132,6 +137,27 @@ void CapturePreferencesFrame::on_captureRealTimeCheckBox_toggled(bool checked)
prefs_set_bool_value(pref_real_time_, checked, pref_stashed);
}
void CapturePreferencesFrame::on_captureUpdateIntervalLineEdit_textChanged(const QString &new_str)
{
uint new_uint;
if (new_str.isEmpty()) {
new_uint = prefs_get_uint_value_real(pref_update_interval_, pref_default);
prefs_set_uint_value(pref_update_interval_, new_uint, pref_stashed);
ui->captureUpdateIntervalLineEdit->setSyntaxState(SyntaxLineEdit::Empty);
return;
}
bool ok;
new_uint = new_str.toUInt(&ok, 0);
if (ok) {
ui->captureUpdateIntervalLineEdit->setSyntaxState(SyntaxLineEdit::Valid);
} else {
new_uint = prefs_get_uint_value_real(pref_update_interval_, pref_current);
ui->captureUpdateIntervalLineEdit->setSyntaxState(SyntaxLineEdit::Invalid);
}
prefs_set_uint_value(pref_update_interval_, new_uint, pref_stashed);
}
void CapturePreferencesFrame::on_captureAutoScrollCheckBox_toggled(bool checked)
{
prefs_set_bool_value(pref_auto_scroll_, checked, pref_stashed);

View File

@ -34,6 +34,7 @@ private slots:
void on_capturePromModeCheckBox_toggled(bool checked);
void on_capturePcapNgCheckBox_toggled(bool checked);
void on_captureRealTimeCheckBox_toggled(bool checked);
void on_captureUpdateIntervalLineEdit_textChanged(const QString &new_str);
void on_captureAutoScrollCheckBox_toggled(bool checked);
void on_captureNoInterfaceLoad_toggled(bool checked);
void on_captureNoExtcapCheckBox_toggled(bool checked);
@ -45,6 +46,7 @@ private:
pref_t *pref_prom_mode_;
pref_t *pref_pcap_ng_;
pref_t *pref_real_time_;
pref_t *pref_update_interval_;
pref_t *pref_auto_scroll_;
pref_t *pref_no_interface_load_;
pref_t *pref_no_extcap_;

View File

@ -87,6 +87,34 @@
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="captureUpdateInterval">
<item>
<widget class="QLabel" name="captureUpdateIntervalLabel">
<property name="text">
<string>Interval between updates (ms)</string>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;How often the capture notifies the GUI of new packets. Affects how often the GUI updates and the granularity of timers.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
<item>
<widget class="SyntaxLineEdit" name="captureUpdateIntervalLineEdit">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;The interval between new packet updates. Affects how often the GUI updates and the granularity of timers.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
<item>
<spacer name="captureUpdateIntervalHorizontalSpacer">
<property name="orientation">
<enum>Qt:Horizontal</enum>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<widget class="QCheckBox" name="captureAutoScrollCheckBox">
<property name="toolTip">
@ -126,6 +154,13 @@
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>SyntaxLineEdit</class>
<extends>QLineEdit</extends>
<header>widgets/syntax_line_edit.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>