}
}
}
-#if 0
-static inline uint64_t FramesLeftEdge(const TcpStream *stream, const Frames *frames)
-{
- uint64_t le = STREAM_APP_PROGRESS(stream);
- for (uint16_t i = 0; i < frames->cnt; i++) {
- if (i < FRAMES_STATIC_CNT) {
- const Frame *frame = &frames->sframes[i];
- le = MIN(le, FrameLeftEdge(stream, frame));
- } else {
- const uint16_t o = i - FRAMES_STATIC_CNT;
- const Frame *frame = &frames->dframes[o];
- le = MIN(le, FrameLeftEdge(stream, frame));
- }
- }
- return le;
-}
-#endif
/** Stream buffer slides forward, we need to update and age out
* frame offsets/frames. Aging out means we move existing frames
BUG_ON(frames == NULL);
SCLogDebug("%s frames %p: sliding %u bytes", ds, frames, slide);
uint64_t le = STREAM_APP_PROGRESS(stream);
-
- if (slide >= frames->progress_rel)
- frames->progress_rel = 0;
- else
- frames->progress_rel -= slide;
-
const uint64_t next_base = STREAM_BASE_OFFSET(stream) + slide;
const uint16_t start = frames->cnt;
uint16_t removed = 0;
return 0;
}
-void AppLayerFramesUpdateProgress(
- Flow *f, TcpStream *stream, const uint64_t progress, const uint8_t direction)
-{
- FramesContainer *frames_container = AppLayerFramesGetContainer(f);
- if (frames_container == NULL)
- return;
-
- Frames *frames;
- if (direction == STREAM_TOSERVER) {
- frames = &frames_container->toserver;
- } else {
- frames = &frames_container->toclient;
- }
-
- const uint32_t slide = progress - STREAM_APP_PROGRESS(stream);
- frames->progress_rel += slide;
-}
-
void AppLayerFramesSlide(Flow *f, const uint32_t slide, const uint8_t direction)
{
FramesContainer *frames_container = AppLayerFramesGetContainer(f);
SCLogDebug("start: left edge %" PRIu64 ", left_edge_rel %u, stream base %" PRIu64,
(uint64_t)frames->left_edge_rel + STREAM_BASE_OFFSET(stream), frames->left_edge_rel,
STREAM_BASE_OFFSET(stream));
- const uint64_t abs_offset = STREAM_BASE_OFFSET(stream) + (uint64_t)frames->progress_rel;
+ const uint64_t abs_offset = STREAM_BASE_OFFSET(stream);
const uint64_t acked = StreamTcpGetUsable(stream, eof);
uint64_t le = STREAM_APP_PROGRESS(stream);
det_ctx, ctx->transforms, p, frames, frame, ctx->list_id, idx, true);
if (buffer == NULL)
return;
+ BUG_ON(buffer->orig_len > frame->len);
const uint32_t data_len = buffer->inspect_len;
const uint8_t *data = buffer->inspect;
return buffer;
}
+struct FrameStreamData {
+ DetectEngineThreadCtx *det_ctx;
+ const DetectEngineTransforms *transforms;
+ const Frame *frame;
+ int list_id;
+ uint32_t idx;
+ uint64_t frame_data_offset_abs;
+ uint64_t frame_start_offset_abs;
+};
+
+static int FrameStreamDataFunc(
+ void *cb_data, const uint8_t *input, const uint32_t input_len, const uint64_t offset)
+{
+ struct FrameStreamData *fsd = cb_data;
+ SCLogDebug("fsd %p { det_ct:%p, transforms:%p, frame:%p, list_id:%d, idx:%u, "
+ "frame_data_offset_abs:%" PRIu64 ", frame_start_offset_abs:%" PRIu64
+ " }, input: %p, input_len:%u, offset:%" PRIu64,
+ fsd, fsd->det_ctx, fsd->transforms, fsd->frame, fsd->list_id, fsd->idx,
+ fsd->frame_data_offset_abs, fsd->frame_start_offset_abs, input, input_len, offset);
+
+ InspectionBuffer *buffer =
+ InspectionBufferMultipleForListGet(fsd->det_ctx, fsd->list_id, fsd->idx);
+ BUG_ON(buffer == NULL);
+ SCLogDebug("buffer %p", buffer);
+
+ const Frame *frame = fsd->frame;
+ SCLogDebug("frame rel_offset:%" PRIi64, frame->rel_offset);
+ const uint8_t *data = input;
+ uint8_t ci_flags = 0;
+ uint32_t data_len;
+ if (fsd->frame_start_offset_abs == offset) {
+ ci_flags |= DETECT_CI_FLAGS_START;
+ SCLogDebug("have frame data start");
+
+ if (frame->len >= 0) {
+ data_len = MIN(input_len, frame->len);
+ } else {
+ data_len = input_len;
+ }
+
+ if (data_len == frame->len) {
+ ci_flags |= DETECT_CI_FLAGS_END;
+ SCLogDebug("have frame data end");
+ }
+ } else {
+ BUG_ON(offset < fsd->frame_data_offset_abs);
+
+ uint64_t frame_delta = offset - fsd->frame_start_offset_abs;
+ uint64_t request_delta =
+ offset -
+ fsd->frame_data_offset_abs; // diff between what we requested and what we got
+ BUG_ON(request_delta > frame_delta);
+
+ if (frame->len >= 0) {
+ if (frame_delta >= (uint64_t)frame->len) {
+ SCLogDebug("data entirely past frame");
+ return 1;
+ }
+ uint32_t adjusted_frame_len = (uint32_t)((uint64_t)frame->len - frame_delta);
+ SCLogDebug("frame len after applying offset %" PRIu64 ": %u", frame_delta,
+ adjusted_frame_len);
+
+ data_len = MIN(adjusted_frame_len, input_len);
+ SCLogDebug("usable data len for frame: %u", data_len);
+
+ if ((uint64_t)data_len + frame_delta == (uint64_t)frame->len) {
+ ci_flags |= DETECT_CI_FLAGS_END;
+ SCLogDebug("have frame data end");
+ }
+ } else {
+ data_len = input_len;
+ }
+ }
+ // PrintRawDataFp(stdout, data, data_len);
+ InspectionBufferSetupMulti(buffer, fsd->transforms, data, data_len);
+ buffer->inspect_offset = frame->rel_offset < 0 ? -1 * frame->rel_offset : 0; // TODO review/test
+ buffer->flags = ci_flags;
+ return 1; // for now only the first chunk
+}
+
InspectionBuffer *DetectFrame2InspectBuffer(DetectEngineThreadCtx *det_ctx,
const DetectEngineTransforms *transforms, Packet *p, const Frames *frames,
const Frame *frame, const int list_id, const uint32_t idx, const bool first)
avail: 50 (complete)
*/
- SCLogDebug("frame %" PRIi64 ", len %" PRIi64, frame->id, frame->len);
-
- uint32_t data_len = 0;
- const uint8_t *data = NULL;
+ SCLogDebug("frame %" PRIi64 ", len %" PRIi64 ", rel_offset %" PRIi64, frame->id, frame->len,
+ frame->rel_offset);
uint64_t offset = STREAM_BASE_OFFSET(stream);
- if (frame->rel_offset > 0 || frames->progress_rel) {
- uint64_t frame_offset = 0;
- if (frame->rel_offset >= 0) {
- frame_offset = MAX((uint64_t)frame->rel_offset, (uint64_t)frames->progress_rel);
- } else {
- frame_offset = (uint64_t)frames->progress_rel;
- }
- offset += frame_offset;
+ if (frame->rel_offset > 0) {
+ offset += (uint64_t)frame->rel_offset;
}
+ const int64_t frame_start_abs_offset = frame->rel_offset + (int64_t)STREAM_BASE_OFFSET(stream);
+ BUG_ON(frame_start_abs_offset < 0);
const bool eof = ssn->state == TCP_CLOSED || PKT_IS_PSEUDOPKT(p);
if (usable <= offset)
return NULL;
- // TODO GAP handling
- if (StreamingBufferGetDataAtOffset(&stream->sb, &data, &data_len, offset) == 0) {
- return NULL;
- }
+ struct FrameStreamData fsd = { det_ctx, transforms, frame, list_id, idx, offset,
+ (uint64_t)frame_start_abs_offset };
+ StreamReassembleForFrame(ssn, stream, FrameStreamDataFunc, &fsd, offset, eof);
+ SCLogDebug("offset %" PRIu64, offset);
- const uint64_t data_right_edge = offset + data_len;
- if (data_right_edge > usable)
- data_len = usable - offset;
-
- const int64_t frame_start_abs_offset = frame->rel_offset + (int64_t)STREAM_BASE_OFFSET(stream);
- const uint64_t usable_right_edge = MIN(data_right_edge, usable);
-
- bool have_end = false;
-
- if (frame->len > 0) {
- const int64_t frame_avail_data_abs = (int64_t)usable_right_edge;
- const int64_t frame_end_abs_offset = frame_start_abs_offset + frame->len;
- have_end = (int64_t)usable_right_edge >= frame_end_abs_offset;
-
- SCLogDebug("frame_end_abs_offset %" PRIi64 ", usable_right_edge %" PRIu64,
- frame_end_abs_offset, usable_right_edge);
-
- const int64_t avail_from_frame = MIN(frame_end_abs_offset, frame_avail_data_abs) - offset;
- if (avail_from_frame < (int64_t)data_len) {
- SCLogDebug("adjusted data len from %u to %" PRIi64, data_len, avail_from_frame);
- data_len = (uint32_t)avail_from_frame;
- }
- }
- const bool have_start = frame_start_abs_offset == (int64_t)offset;
-
- if (data == NULL || data_len == 0) {
- return NULL;
- }
-
- // TODO use eof too?
- SCLogDebug("stream->min_inspect_depth %u", stream->min_inspect_depth);
- if (data_len < frame->len && data_len < stream->min_inspect_depth) {
- if (ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || ssn->state == TCP_CLOSED ||
- stream->flags & STREAMTCP_STREAM_FLAG_DEPTH_REACHED) {
- SCLogDebug("EOF use available data: %u bytes", data_len);
- } else {
- SCLogDebug("not enough data to inspect now: have %u, want %u", data_len,
- stream->min_inspect_depth);
- return NULL;
- }
- }
-
- const uint8_t ci_flags =
- (have_start ? DETECT_CI_FLAGS_START : 0) | (have_end ? DETECT_CI_FLAGS_END : 0);
- SCLogDebug("packet %" PRIu64 " -> frame %p/%" PRIi64 "/%s rel_offset %" PRIi64
- " type %u len %" PRIi64 " ci_flags %02x (start:%s, end:%s)",
- p->pcap_cnt, frame, frame->id,
- AppLayerParserGetFrameNameById(p->flow->proto, p->flow->alproto, frame->type),
- frame->rel_offset, frame->type, frame->len, ci_flags,
- (ci_flags & DETECT_CI_FLAGS_START) ? "true" : "false",
- (ci_flags & DETECT_CI_FLAGS_END) ? "true" : "false");
- // PrintRawDataFp(stdout, data, MIN(32,data_len));
-
- InspectionBufferSetupMulti(buffer, transforms, data, data_len);
- buffer->inspect_offset = frame->rel_offset < 0 ? -1 * frame->rel_offset : 0; // TODO review/test
- buffer->flags = ci_flags;
- return buffer;
+ InspectionBuffer *ret = InspectionBufferMultipleForListGet(det_ctx, list_id, idx);
+ SCLogDebug("ret %p", ret);
+ return ret;
}
/**