Skip to content

Commit a405782

Browse files
gnosekpoiana
authored andcommitted
fix(plugin): fix and clarify extract offsets docs/tests
The docs (and a unit test) specified `value_offsets` to be an array of `ss_plugin_extract_value_offsets` structs, while the code in plugin_filtercheck.cpp expected it to be a struct of arrays. Things worked out only because we never extract multiple fields in one go (at least in libsinsp itself). Keep the plugin_filtercheck.cpp behavior and adapt the documentation and tests to match. Additionally, clarify that the offsets are counted from the start of the event buffer (including the header). Signed-off-by: Grzegorz Nosek <[email protected]>
1 parent 3540a0a commit a405782

File tree

4 files changed

+58
-11
lines changed

4 files changed

+58
-11
lines changed

userspace/libsinsp/test/plugins.ut.cpp

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -376,8 +376,30 @@ TEST_F(sinsp_with_test_input, plugin_custom_source) {
376376
ASSERT_FALSE(field_has_value(evt, "fd.name", filterlist));
377377
ASSERT_EQ(get_field_as_string(evt, "evt.pluginname", filterlist), src_pl->name());
378378
ASSERT_EQ(get_field_as_string(evt, "sample.hello", filterlist), "hello world");
379-
ASSERT_EQ(get_value_offset_start(evt, "sample.hello", filterlist, 0), 0);
380-
ASSERT_EQ(get_value_offset_length(evt, "sample.hello", filterlist, 0), 11);
379+
380+
auto offset = get_value_offset_start(evt, "sample.hello", filterlist, 0);
381+
ASSERT_EQ(offset, PLUGIN_EVENT_PAYLOAD_OFFSET);
382+
auto length = get_value_offset_length(evt, "sample.hello", filterlist, 0);
383+
ASSERT_EQ(length, 11);
384+
385+
const auto raw_evt = reinterpret_cast<const char*>(evt->get_scap_evt());
386+
for(int i = 0; i < evt->get_scap_evt()->len; i++) {
387+
printf("%02x ", (unsigned char)raw_evt[i]);
388+
}
389+
printf("\n");
390+
for(int i = 0; i < evt->get_scap_evt()->len; i++) {
391+
char c = ' ';
392+
if(i >= offset && i < offset + length) {
393+
c = '^';
394+
}
395+
printf("%c%c%c", c, c, c);
396+
}
397+
printf("\n");
398+
399+
// Note: here we are asserting that the exact bytes are present in the event payload
400+
// This does not need to hold for all plugins (e.g. due to serialization format)
401+
// but is a useful check here to validate we got the offsets correct.
402+
ASSERT_EQ(memcmp(raw_evt + offset, "hello world", 11), 0);
381403
ASSERT_EQ(next_event(), nullptr); // EOF is expected
382404
}
383405

userspace/libsinsp/test/plugins/plugin_extract.cpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ namespace {
3535
struct plugin_state {
3636
std::string lasterr;
3737
std::string strstorage;
38+
std::vector<uint32_t> offsets;
39+
std::vector<uint32_t> lengths;
3840
const char* strptr;
3941
std::vector<uint16_t> event_types;
4042
ss_plugin_owner_t* owner;
@@ -130,6 +132,12 @@ ss_plugin_rc plugin_extract_fields(ss_plugin_t* s,
130132
const ss_plugin_event_input* ev,
131133
const ss_plugin_field_extract_input* in) {
132134
auto ps = reinterpret_cast<plugin_state*>(s);
135+
136+
if(in->value_offsets) {
137+
ps->offsets.resize(in->num_fields);
138+
ps->lengths.resize(in->num_fields);
139+
}
140+
133141
for(uint32_t i = 0; i < in->num_fields; i++) {
134142
switch(in->fields[i].field_id) {
135143
case 0: // test.hello
@@ -141,15 +149,19 @@ ss_plugin_rc plugin_extract_fields(ss_plugin_t* s,
141149
in->fields[i].res.str = &ps->strptr;
142150
in->fields[i].res_len = 1;
143151
if(in->value_offsets) {
144-
in->value_offsets[i].start = &res_start;
145-
in->value_offsets[i].length = &res_length;
152+
ps->offsets[i] = PLUGIN_EVENT_PAYLOAD_OFFSET + res_start;
153+
ps->lengths[i] = res_length;
146154
}
147155
} break;
148156
default:
149157
in->fields[i].res_len = 0;
150158
return SS_PLUGIN_FAILURE;
151159
}
152160
}
161+
if(in->value_offsets) {
162+
in->value_offsets->start = ps->offsets.data();
163+
in->value_offsets->length = ps->lengths.data();
164+
}
153165
return SS_PLUGIN_SUCCESS;
154166
}
155167

userspace/plugin/plugin_api.h

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,15 @@ extern "C" {
4646
//
4747
#define PLUGIN_MAX_ERRLEN 1024
4848

49+
// The offset in the event where a plugin event payload starts
50+
// Since the event payload is at a fixed offset, you can add this value
51+
// to the start of an extracted field within the payload to get the offset
52+
// from the start of the event.
53+
//
54+
// 26 bytes for the event header, plus 2*4 bytes for the parameter lengths,
55+
// plus 4 bytes for the plugin ID.
56+
#define PLUGIN_EVENT_PAYLOAD_OFFSET 38
57+
4958
// Supported by the API but deprecated. Use the extended version ss_plugin_table_reader_vtable_ext
5059
// instead. todo(jasondellaluce): when/if major changes to v4, remove this and give this name to the
5160
// associated *_ext struct.
@@ -371,9 +380,13 @@ typedef struct ss_plugin_field_extract_input {
371380
// Vtable for controlling a state table for read operations.
372381
ss_plugin_table_reader_vtable_ext* table_reader_ext;
373382

374-
// An array of ss_plugin_extract_value_offsets structs. The start
375-
// and length in each entry should be set to nullptr, and as with
376-
// the "fields" member, memory pointers set as output must be
383+
// An optional ss_plugin_extract_value_offsets struct. If set, the plugin
384+
// is expected to allocate two arrays of size num_fields, one for
385+
// the offsets and one for the lengths of the extracted values.
386+
// The offsets are counted starting from the beginning of the event
387+
// (including the header), and the lengths are the number of bytes
388+
// that the extracted value occupies in the event data.
389+
// As with the "fields" member, memory pointers set as output must be
377390
// allocated by the plugin and must not be deallocated or modified
378391
// until the next extract_fields() call.
379392
// This member is optional, and might be ignored by extractors.

userspace/plugin/plugin_types.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -130,11 +130,11 @@ typedef struct ss_plugin_byte_buffer {
130130

131131
// Used in extract_fields_and_offsets to receive field value offsets
132132
// along with field data.
133-
// Extraction functions that support offsets should be set these to an
133+
// Extraction functions that support offsets should set these to an
134134
// array of zero-indexed start offsets and lengths of each returned
135-
// value in the event or log data. {0, 0} can be used to indicate that
136-
// there are no valid offsets, e.g. if the value was generated or
137-
// computed from other data.
135+
// value in the event or log data, counting from the start of the event
136+
// header. {0, 0} can be used to indicate that there are no valid offsets,
137+
// e.g. if the value was generated or computed from other data.
138138
// Extraction functions might not support offsets. In order to detect
139139
// this, callers should initialize the start and length to nullptr.
140140
typedef struct ss_plugin_extract_value_offsets {

0 commit comments

Comments
 (0)