-
Notifications
You must be signed in to change notification settings - Fork 1.7k
pcap-file: move packet counter to PCAP packet structure v5.1 #14656
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Use of t_pcapcnt is only relevant when compiled in debug mode only. This patch adds additional debug guard to also shield the declaration and assignment.
For an easier review process, this is a two-step change process, in which pcap_cnt is first accessed by functions-to-be, implemented as simple macros. In the follow-up commit, the actual refactor is implemented with the new function. The old macros are deleted. Ticket: 7835
Code refactor to gather all PCAP-related structure members under one structure. New pcap_v structure guards protect the union variables from other capture modes trying to access the packet number incorrectly. Ticket: 7835
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR refactors packet counter (pcap_cnt) handling by moving it from the main Packet structure into the PCAP-specific PcapPacketVars structure. The change introduces getter/setter functions (PcapPacketCntGet() and PcapPacketCntSet()) that validate runmode before accessing the counter, ensuring it's only used in appropriate contexts (PCAP file, unittest, or unix socket runmodes).
Changes:
- Moved
pcap_cntfrom Packet struct toPcapPacketVarsstruct within the packet - Introduced runmode-aware getter/setter accessor functions in decode.c/h
- Updated all references throughout the codebase to use the new accessor functions
Reviewed changes
Copilot reviewed 45 out of 45 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| src/decode.h | Removed pcap_cnt member from Packet struct; added getter/setter declarations |
| src/decode.c | Implemented getter/setter functions with runmode validation |
| src/source-pcap.h | Added pcap_cnt to PcapPacketVars structure |
| src/source-pcap-file-helper.c | Direct access to pcap_cnt in PCAP-native code path |
| src/packet.c | Removed pcap_cnt initialization from PacketReinit |
| src/stream-tcp.c | Replaced direct access with getter; fixed "steam" to "stream" typos; moved t_pcapcnt declaration under DEBUG |
| src/stream-tcp-reassemble.c | Replaced direct access with getter; moved t_pcapcnt definition under DEBUG |
| src/stream-tcp-sack.c | Replaced direct access with getter in debug logs |
| src/stream-tcp-private.h | Updated StreamTcpSetEvent macro to use getter |
| src/output-json.c | Replaced direct access with getter, properly cached result |
| src/output-json-alert.c | Replaced direct access with getter, properly cached result |
| src/output-tx.c | Replaced direct access with getter in debug logs |
| src/alert-syslog.c | Replaced direct access with getter |
| src/alert-fastlog.c | Replaced direct access with getter |
| src/alert-debuglog.c | Replaced direct access with getter |
| src/log-tlsstore.c | Replaced direct access with getter |
| src/util-profiling.c | Replaced direct access with getter |
| src/util-lua-packetlib.c | Replaced direct access with getter |
| src/util-exception-policy.c | Replaced direct access with getter in debug log |
| src/flow.c, src/flow-worker.c, src/flow-hash.c | Replaced direct access with getter in debug logs |
| src/detect*.c files | Replaced direct access with getter in debug logs |
| src/defrag.c, src/defrag-hash.c | Replaced direct access with getter |
| src/app-layer.c | Replaced direct access with getter in debug log |
| tests/fuzz/*.c | Replaced direct assignment with setter |
| tests/detect-tls-*.c | Replaced direct assignment with setter in test setup |
| tests/detect-http-header.c | Replaced direct assignment with setter in test setup |
| plugins/ndpi/ndpi.c | Replaced direct access with getter in debug logs |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| static inline bool PcapPacketNumRunmodeCanAccess(void) | ||
| { | ||
| SCRunMode m = SCRunmodeGet(); | ||
| return m == RUNMODE_PCAP_FILE || m == RUNMODE_UNITTEST || m == RUNMODE_UNIX_SOCKET; | ||
| } | ||
|
|
||
| inline uint64_t PcapPacketCntGet(const Packet *p) | ||
| { | ||
| if (PcapPacketNumRunmodeCanAccess() && p != NULL) { | ||
| return p->pcap_v.pcap_cnt; | ||
| } | ||
| return 0; | ||
| } | ||
|
|
||
| inline void PcapPacketCntSet(Packet *p, uint64_t pcap_cnt) | ||
| { | ||
| if (PcapPacketNumRunmodeCanAccess() && p != NULL) { | ||
| p->pcap_v.pcap_cnt = pcap_cnt; | ||
| } | ||
| } |
Copilot
AI
Jan 20, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The getter and setter functions call SCRunmodeGet() on every invocation, which can be expensive in hot paths. Since the runmode does not change during execution, consider caching the result of PcapPacketNumRunmodeCanAccess() in a static variable initialized at startup. This would avoid the function call overhead on every packet.
For example, you could use a static boolean variable set during initialization that remains constant for the lifetime of the process. This would improve performance in hot paths where these functions are called frequently.
| if (PcapPacketCntGet(p) != 0) { | ||
| snprintf(temp_buf_tail, sizeof(temp_buf_tail), "] [pcap file packet: %" PRIu64 "]", | ||
| PcapPacketCntGet(p)); |
Copilot
AI
Jan 20, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PcapPacketCntGet(p) is called twice (on lines 346 and 348) in the same code block. Since this function has overhead (calls SCRunmodeGet()), the result should be cached in a local variable to avoid redundant calls. For example:
uint64_t pcap_cnt = PcapPacketCntGet(p);
if (pcap_cnt != 0) {
snprintf(temp_buf_tail, sizeof(temp_buf_tail), "] [pcap file packet: %" PRIu64 "]", pcap_cnt);| if (PcapPacketCntGet(p) != 0) { | |
| snprintf(temp_buf_tail, sizeof(temp_buf_tail), "] [pcap file packet: %" PRIu64 "]", | |
| PcapPacketCntGet(p)); | |
| uint64_t pcap_cnt = PcapPacketCntGet(p); | |
| if (pcap_cnt != 0) { | |
| snprintf(temp_buf_tail, sizeof(temp_buf_tail), "] [pcap file packet: %" PRIu64 "]", | |
| pcap_cnt); |
| if (PcapPacketCntGet(p) != 0) { | ||
| PrintBufferData(alert_buffer, &size, MAX_FASTLOG_ALERT_SIZE, | ||
| "] [pcap file packet: %" PRIu64 "]\n", PcapPacketCntGet(p)); |
Copilot
AI
Jan 20, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PcapPacketCntGet(p) is called twice (on lines 182 and 184) in the same code block. Since this function has overhead (calls SCRunmodeGet()), the result should be cached in a local variable to avoid redundant calls. For example:
uint64_t pcap_cnt = PcapPacketCntGet(p);
if (pcap_cnt != 0) {
PrintBufferData(alert_buffer, &size, MAX_FASTLOG_ALERT_SIZE,
"] [pcap file packet: %" PRIu64 "]\n", pcap_cnt);| if (PcapPacketCntGet(p) != 0) { | |
| PrintBufferData(alert_buffer, &size, MAX_FASTLOG_ALERT_SIZE, | |
| "] [pcap file packet: %" PRIu64 "]\n", PcapPacketCntGet(p)); | |
| uint64_t pcap_cnt = PcapPacketCntGet(p); | |
| if (pcap_cnt != 0) { | |
| PrintBufferData(alert_buffer, &size, MAX_FASTLOG_ALERT_SIZE, | |
| "] [pcap file packet: %" PRIu64 "]\n", pcap_cnt); |
| if (PcapPacketCntGet(p) > 0) { | ||
| if (fprintf(fpmeta, "PCAP PKT NUM: %" PRIu64 "\n", PcapPacketCntGet(p)) < 0) |
Copilot
AI
Jan 20, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PcapPacketCntGet(p) is called twice (on lines 220 and 221) in the same code block. Since this function has overhead (calls SCRunmodeGet()), the result should be cached in a local variable to avoid redundant calls. For example:
uint64_t pcap_cnt = PcapPacketCntGet(p);
if (pcap_cnt > 0) {
if (fprintf(fpmeta, "PCAP PKT NUM: %" PRIu64 "\n", pcap_cnt) < 0)| if (PcapPacketCntGet(p) > 0) { | |
| if (fprintf(fpmeta, "PCAP PKT NUM: %" PRIu64 "\n", PcapPacketCntGet(p)) < 0) | |
| uint64_t pcap_cnt = PcapPacketCntGet(p); | |
| if (pcap_cnt > 0) { | |
| if (fprintf(fpmeta, "PCAP PKT NUM: %" PRIu64 "\n", pcap_cnt) < 0) |
| if (PcapPacketCntGet(p) > 0) { | ||
| MemBufferWriteString(aft->buffer, "PCAP PKT NUM: %" PRIu64 "\n", PcapPacketCntGet(p)); |
Copilot
AI
Jan 20, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PcapPacketCntGet(p) is called twice (on lines 170 and 171) in the same code block. Since this function has overhead (calls SCRunmodeGet()), the result should be cached in a local variable to avoid redundant calls. For example:
uint64_t pcap_cnt = PcapPacketCntGet(p);
if (pcap_cnt > 0) {
MemBufferWriteString(aft->buffer, "PCAP PKT NUM: %" PRIu64 "\n", pcap_cnt);| if (PcapPacketCntGet(p) > 0) { | |
| MemBufferWriteString(aft->buffer, "PCAP PKT NUM: %" PRIu64 "\n", PcapPacketCntGet(p)); | |
| uint64_t pcap_cnt = PcapPacketCntGet(p); | |
| if (pcap_cnt > 0) { | |
| MemBufferWriteString(aft->buffer, "PCAP PKT NUM: %" PRIu64 "\n", pcap_cnt); |
| if (PcapPacketCntGet(p) > 0) { | ||
| MemBufferWriteString(aft->buffer, "PCAP PKT NUM: %" PRIu64 "\n", PcapPacketCntGet(p)); |
Copilot
AI
Jan 20, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PcapPacketCntGet(p) is called twice (on lines 330 and 331) in the same code block. Since this function has overhead (calls SCRunmodeGet()), the result should be cached in a local variable to avoid redundant calls. For example:
uint64_t pcap_cnt = PcapPacketCntGet(p);
if (pcap_cnt > 0) {
MemBufferWriteString(aft->buffer, "PCAP PKT NUM: %" PRIu64 "\n", pcap_cnt);| if (PcapPacketCntGet(p) > 0) { | |
| MemBufferWriteString(aft->buffer, "PCAP PKT NUM: %" PRIu64 "\n", PcapPacketCntGet(p)); | |
| uint64_t pcap_cnt = PcapPacketCntGet(p); | |
| if (pcap_cnt > 0) { | |
| MemBufferWriteString(aft->buffer, "PCAP PKT NUM: %" PRIu64 "\n", pcap_cnt); |
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #14656 +/- ##
==========================================
- Coverage 82.11% 82.10% -0.01%
==========================================
Files 1011 1011
Lines 262812 262858 +46
==========================================
+ Hits 215812 215830 +18
- Misses 47000 47028 +28
Flags with carried forward coverage won't be shown. Click here to find out more. 🚀 New features to boost your workflow:
|
|
Information: QA ran without warnings. Pipeline = 29189 |
| SCLogDebug("detect->packet_alert_max set to %d", packet_alert_max); | ||
| } | ||
|
|
||
| static inline bool PcapPacketNumRunmodeCanAccess(void) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: PcapPacketCntRunmodeCanAccess, so s/Num/Cnt/g
|
Continues in #14657 |
Follow-up of #14653
Code refactoring to gather all PCAP-related structure members under one structure.
Link to ticket: https://redmine.openinfosecfoundation.org/issues/7835
Some considerations:
The PR has been previously OKAY-ed by Philippe (#13972 ).
Describe changes:
v5.1 (address copilot review comments):
v5:
v4.2
v4.1
v4
v2+3
v1