Skip to content

Commit

Permalink
pcap-file: improve setvbuf implementation
Browse files Browse the repository at this point in the history
Make optional through `pcap-file.buffer-size` config option.

Make sure to check through configure.

Ticket: OISF#7155.
  • Loading branch information
victorjulien committed Aug 30, 2024
1 parent 5f2aef7 commit 7b730c2
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 7 deletions.
2 changes: 1 addition & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@
AC_CHECK_FUNCS([gethostname inet_ntoa uname])
AC_CHECK_FUNCS([gettimeofday clock_gettime utime strptime tzset localtime_r])
AC_CHECK_FUNCS([socket setenv select putenv dup2 endgrent endpwent atexit munmap])
AC_CHECK_FUNCS([setrlimit])
AC_CHECK_FUNCS([setrlimit setvbuf])

AC_CHECK_FUNCS([fwrite_unlocked])

Expand Down
5 changes: 4 additions & 1 deletion src/source-pcap-file-directory-helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ static TmEcode PcapDirectoryPopulateBuffer(PcapFileDirectoryVars *ptv,
static TmEcode PcapDirectoryDispatchForTimeRange(PcapFileDirectoryVars *pv,
struct timespec *older_than);

extern PcapFileGlobalVars pcap_g;

void GetTime(struct timespec *tm)
{
struct timeval now;
Expand Down Expand Up @@ -414,7 +416,8 @@ TmEcode PcapDirectoryDispatchForTimeRange(PcapFileDirectoryVars *pv,
} else {
SCLogDebug("Processing file %s", current_file->filename);

PcapFileFileVars *pftv = SCCalloc(1, sizeof(PcapFileFileVars));
const size_t toalloc = sizeof(PcapFileFileVars) + pcap_g.read_buffer_size;
PcapFileFileVars *pftv = SCCalloc(1, toalloc);
if (unlikely(pftv == NULL)) {
SCLogError("Failed to allocate PcapFileFileVars");
SCReturnInt(TM_ECODE_FAILED);
Expand Down
11 changes: 8 additions & 3 deletions src/source-pcap-file-helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -208,10 +208,15 @@ TmEcode InitPcapFile(PcapFileFileVars *pfv)
SCReturnInt(TM_ECODE_FAILED);
}

errno = 0;
if (setvbuf(pcap_file(pfv->pcap_handle), pfv->buffer, _IOFBF, sizeof(pfv->buffer)) < 0) {
SCLogWarning("Failed to setvbuf on PCAP file handle: %s", strerror(errno));
#if defined(HAVE_SETVBUF) && !defined(OS_WIN32)
if (pcap_g.read_buffer_size > 0) {
errno = 0;
if (setvbuf(pcap_file(pfv->pcap_handle), pfv->buffer, _IOFBF, pcap_g.read_buffer_size) <
0) {
SCLogWarning("Failed to setvbuf on PCAP file handle: %s", strerror(errno));
}
}
#endif

if (pfv->shared != NULL && pfv->shared->bpf_string != NULL) {
SCLogInfo("using bpf-filter \"%s\"", pfv->shared->bpf_string);
Expand Down
7 changes: 6 additions & 1 deletion src/source-pcap-file-helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ typedef struct PcapFileGlobalVars_ {
ChecksumValidationMode conf_checksum_mode;
ChecksumValidationMode checksum_mode;
SC_ATOMIC_DECLARE(unsigned int, invalid_checksums);
uint32_t read_buffer_size;
} PcapFileGlobalVars;

/**
Expand Down Expand Up @@ -81,7 +82,11 @@ typedef struct PcapFileFileVars_
struct pcap_pkthdr *first_pkt_hdr;
struct timeval first_pkt_ts;

char buffer[131072];
/** flex array member for the libc io read buffer. Size controlled by
* PcapFileGlobalVars::read_buffer_size. */
#if defined(HAVE_SETVBUF) && !defined(OS_WIN32)
char buffer[];
#endif
} PcapFileFileVars;

/**
Expand Down
27 changes: 26 additions & 1 deletion src/source-pcap-file.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include "runmode-unix-socket.h"
#include "suricata.h"
#include "conf.h"
#include "util-misc.h"

extern uint32_t max_pending_packets;
PcapFileGlobalVars pcap_g;
Expand Down Expand Up @@ -136,10 +137,33 @@ void TmModuleDecodePcapFileRegister (void)
tmm_modules[TMM_DECODEPCAPFILE].flags = TM_FLAG_DECODE_TM;
}

#define PCAP_FILE_BUFFER_SIZE_DEFAULT 131072U // 128 KiB
#define PCAP_FILE_BUFFER_SIZE_MIN 4096U // 4 KiB
#define PCAP_FILE_BUFFER_SIZE_MAX 67108864U // 64MiB

void PcapFileGlobalInit(void)
{
memset(&pcap_g, 0x00, sizeof(pcap_g));
SC_ATOMIC_INIT(pcap_g.invalid_checksums);

#if defined(HAVE_SETVBUF) && !defined(OS_WIN32)
pcap_g.read_buffer_size = PCAP_FILE_BUFFER_SIZE_DEFAULT;

const char *str = NULL;
if (ConfGet("pcap-file.buffer-size", &str) == 1) {
uint32_t value = 0;
if (ParseSizeStringU32(str, &value) < 0) {
SCLogWarning("failed to parse pcap-file.buffer-size %s", str);
}
if (value >= PCAP_FILE_BUFFER_SIZE_MIN && value <= PCAP_FILE_BUFFER_SIZE_MAX) {
SCLogInfo("Pcap-file will use %u buffer size", value);
pcap_g.read_buffer_size = value;
} else {
SCLogWarning("pcap-file.buffer-size value of %u is invalid. Valid range is %u-%u",
value, PCAP_FILE_BUFFER_SIZE_MIN, PCAP_FILE_BUFFER_SIZE_MAX);
}
}
#endif
}

TmEcode PcapFileExit(TmEcode status, struct timespec *last_processed)
Expand Down Expand Up @@ -250,7 +274,8 @@ TmEcode ReceivePcapFileThreadInit(ThreadVars *tv, const void *initdata, void **d

if(directory == NULL) {
SCLogDebug("argument %s was a file", (char *)initdata);
PcapFileFileVars *pv = SCCalloc(1, sizeof(PcapFileFileVars));
const size_t toalloc = sizeof(PcapFileFileVars) + pcap_g.read_buffer_size;
PcapFileFileVars *pv = SCCalloc(1, toalloc);
if (unlikely(pv == NULL)) {
SCLogError("Failed to allocate file vars");
CleanupPcapFileThreadVars(ptv);
Expand Down

0 comments on commit 7b730c2

Please sign in to comment.