// nhttp_flow_data.cc author Tom Peters <thopeter@cisco.com>
#include "nhttp_enum.h"
+#include "nhttp_test_manager.h"
#include "nhttp_flow_data.h"
#include "nhttp_transaction.h"
unsigned NHttpFlowData::nhttp_flow_id = 0;
-NHttpFlowData::NHttpFlowData() : FlowData(nhttp_flow_id) { }
+NHttpFlowData::NHttpFlowData() : FlowData(nhttp_flow_id) {
+ /* FIXIT-L Temporary printf while we shake out stream interface */
+ if (!NHttpTestManager::use_test_input() && NHttpTestManager::use_test_output()) {
+ printf("Flow Data destruct %p\n", (void*)this);
+ fflush(nullptr);
+ }
+}
NHttpFlowData::~NHttpFlowData() {
+ /* FIXIT-L Temporary printf while we shake out stream interface */
+ if (!NHttpTestManager::use_test_input() && NHttpTestManager::use_test_output()) {
+ printf("Flow Data destruct %p\n", (void*)this);
+ fflush(nullptr);
+ }
for (int k=0; k <= 1; k++) {
if (section_buffer_owned[k]) {
delete[] section_buffer[k];
assert(length <= MAXOCTETS);
+ /* FIXIT-L Temporary printf while we shake out stream interface */
+ if (!NHttpTestManager::use_test_input() && NHttpTestManager::use_test_output()) {
+ printf("scan() from flow %p direction %d\n", (void*)flow, 1 - (int)to_server());
+ fflush(nullptr);
+ }
+
// When the system begins providing TCP connection close information this won't always be false. FIXIT-H
bool tcp_close = false;
// by a TCP connection. Since scan() is the first to see a new TCP connection the new flow data object is created
// here.
NHttpFlowData* session_data = (NHttpFlowData*)flow->get_application_data(NHttpFlowData::nhttp_flow_id);
- if (session_data == nullptr) flow->set_application_data(session_data = new NHttpFlowData);
+ if (session_data == nullptr) {
+ assert(!flow_data_exists);
+ flow->set_application_data(session_data = new NHttpFlowData);
+ }
assert(session_data != nullptr);
+ flow_data_exists = true;
SourceId source_id = to_server() ? SRC_CLIENT : SRC_SERVER;
if (NHttpTestManager::use_test_input()) {
assert(session_data->type_expected[source_id] != SEC_CLOSED);
}
else if (NHttpTestManager::use_test_output()) {
- printf("Scan from flow %p direction %d\n", (void*)session_data, source_id);
+ printf("Scan from flow data %p direction %d\n", (void*)session_data, source_id);
fflush(stdout);
}
// FIXIT-P total is not used because it is not reliably correct. Could be used to compute required buffer size
// instead of always allocating the maximum
-const StreamBuffer* NHttpStreamSplitter::reassemble(Flow* flow, unsigned /* total */, unsigned offset,
+const StreamBuffer* NHttpStreamSplitter::reassemble(Flow* flow, unsigned total, unsigned offset,
const uint8_t* data, unsigned len, uint32_t flags, unsigned& copied)
{
+ static THREAD_LOCAL StreamBuffer nhttp_buf;
+
// When the system begins providing TCP connection close information this won't always be false. FIXIT-H
bool tcp_close = false;
- static THREAD_LOCAL StreamBuffer nhttp_buf;
+ /* FIXIT-L Temporary printf while we shake out stream interface */
+ if (!NHttpTestManager::use_test_input() && NHttpTestManager::use_test_output()) {
+ printf("reassemble() from flow %p direction %d\n", (void*)flow, 1 - (int)to_server()); fflush(nullptr);
+ }
NHttpFlowData* session_data = (NHttpFlowData*)flow->get_application_data(NHttpFlowData::nhttp_flow_id);
assert(session_data != nullptr);
SourceId source_id = to_server() ? SRC_CLIENT : SRC_SERVER;
+ if (session_data->section_type[source_id] == SEC__NOTCOMPUTE) {
+ // FIXIT-M Apparently scan() did not flush this data. Probably Stream is flushing excess data while it prunes
+ // a session. In any event it doesn't belong here because we cannot process it. Forward it to our parent class
+ // for processing. There should be no more calls to scan() for this session but tell it to abort just in case.
+
+ // session_data->type_expected[source_id] = SEC_ABORT; /* FIXIT-M this statetment breaks the test tool */
+ return StreamSplitter::reassemble(flow, total, offset, data, len, flags, copied);
+ }
copied = len;
if (NHttpTestManager::use_test_input()) {
offset = 0;
}
else if (NHttpTestManager::use_test_output()) {
- printf("Reassemble from flow %p direction %d\n", (void*)session_data, source_id);
+ printf("Reassemble from flow data %p direction %d\n", (void*)session_data, source_id);
fflush(stdout);
}
case RES_INSPECT:
nhttp_buf.data = buffer;
nhttp_buf.length = buffer_length + offset + len - num_excess;
+ assert((nhttp_buf.length <= MAXOCTETS) && (nhttp_buf.length != 0));
buffer = nullptr;
buffer_length = 0;
if (NHttpTestManager::use_test_output()) {
NHttpStreamSplitter(bool is_client_to_server, NHttpInspect* my_inspector_) : StreamSplitter(is_client_to_server),
my_inspector(my_inspector_) { };
Status scan(Flow* flow, const uint8_t* data, uint32_t length, uint32_t not_used, uint32_t* flush_offset) override;
- const StreamBuffer* reassemble(Flow* flow, unsigned /*total*/, unsigned offset, const uint8_t* data, unsigned len,
+ const StreamBuffer* reassemble(Flow* flow, unsigned total, unsigned offset, const uint8_t* data, unsigned len,
uint32_t flags, unsigned& copied) override;
bool is_paf() override { return true; };
unsigned max() override { return NHttpTestManager::use_test_input() ? NHttpEnums::DATABLOCKSIZE : paf_max; };
const NHttpFlowData* session_data) const;
NHttpInspect* const my_inspector;
unsigned paf_max = NHttpEnums::MAXOCTETS;
+
+ // FIXIT-P a precaution we may wish to remove later
+ bool flow_data_exists = false;
};
#endif