proto detect: update behavior on partial detection

When the current direction doesn't get a protocol detection, but the
opposing direction did, previously we would send the current data to
the parser. Then when we'd be invoked again (until the protocol
detection finally failed) we'd get the same data + the new data. To
make sure we'd not send the same data to the parser again, the flow
kept track of how much was already sent to the app-layer using
data_al_so_far.

This patch changes the behaviour. Instead of sending the data for
the current direction right away, we only do this when protocol
detection is complete. This way we won't have to track anything.
pull/2359/head
Victor Julien 9 years ago
parent 6022fa44a5
commit d7c828bcb0

@ -457,28 +457,31 @@ static int TCPProtoDetect(ThreadVars *tv,
goto failure; goto failure;
} }
if (data_len > 0) /* if protocol detection is marked done for our direction we
ssn->data_first_seen_dir = APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER; * pass our data on. We're only succeeded in finding one
* direction: the opposing stream
PACKET_PROFILING_APP_START(app_tctx, *alproto_otherdir); *
int r = AppLayerParserParse(tv, app_tctx->alp_tctx, f, * If PD was not yet complete, we don't do anything.
*alproto_otherdir, flags, */
data + data_al_so_far,
data_len - data_al_so_far);
PACKET_PROFILING_APP_END(app_tctx, *alproto_otherdir);
if (FLOW_IS_PM_DONE(f, flags) && FLOW_IS_PP_DONE(f, flags)) { if (FLOW_IS_PM_DONE(f, flags) && FLOW_IS_PP_DONE(f, flags)) {
if (data_len > 0)
ssn->data_first_seen_dir = APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER;
PACKET_PROFILING_APP_START(app_tctx, *alproto_otherdir);
int r = AppLayerParserParse(tv, app_tctx->alp_tctx, f,
*alproto_otherdir, flags,
data + data_al_so_far,
data_len - data_al_so_far);
PACKET_PROFILING_APP_END(app_tctx, *alproto_otherdir);
AppLayerDecoderEventsSetEventRaw(&p->app_layer_events, AppLayerDecoderEventsSetEventRaw(&p->app_layer_events,
APPLAYER_DETECT_PROTOCOL_ONLY_ONE_DIRECTION); APPLAYER_DETECT_PROTOCOL_ONLY_ONE_DIRECTION);
StreamTcpSetStreamFlagAppProtoDetectionCompleted(stream); StreamTcpSetStreamFlagAppProtoDetectionCompleted(stream);
f->data_al_so_far[dir] = 0; f->data_al_so_far[dir] = 0;
TcpSessionSetReassemblyDepth(ssn, TcpSessionSetReassemblyDepth(ssn,
AppLayerParserGetStreamDepth(f->proto, *alproto)); AppLayerParserGetStreamDepth(f->proto, *alproto));
} else { if (r < 0)
f->data_al_so_far[dir] = data_len; goto failure;
} }
if (r < 0)
goto failure;
} else { } else {
/* both sides unknown, let's see if we need to give up */ /* both sides unknown, let's see if we need to give up */
TCPProtoDetectCheckBailConditions(f, ssn, p); TCPProtoDetectCheckBailConditions(f, ssn, p);
@ -1627,8 +1630,7 @@ static int AppLayerTest03(void)
static int AppLayerTest04(void) static int AppLayerTest04(void)
{ {
Packet *p = SCMalloc(SIZE_OF_PACKET); Packet *p = SCMalloc(SIZE_OF_PACKET);
if (unlikely(p == NULL)) FAIL_IF_NULL(p);
return 0;
Flow f; Flow f;
ThreadVars tv; ThreadVars tv;
StreamTcpThread *stt = NULL; StreamTcpThread *stt = NULL;
@ -1646,8 +1648,6 @@ static int AppLayerTest04(void)
p->flow = &f; p->flow = &f;
p->tcph = &tcph; p->tcph = &tcph;
int ret = 0;
StreamTcpInitConfig(TRUE); StreamTcpInitConfig(TRUE);
StreamTcpThreadInit(&tv, NULL, (void **)&stt); StreamTcpThreadInit(&tv, NULL, (void **)&stt);
@ -1657,25 +1657,22 @@ static int AppLayerTest04(void)
p->flowflags = FLOW_PKT_TOSERVER; p->flowflags = FLOW_PKT_TOSERVER;
p->payload_len = 0; p->payload_len = 0;
p->payload = NULL; p->payload = NULL;
if (StreamTcpPacket(&tv, p, stt, &pq) == -1) FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
goto end;
TcpSession *ssn = (TcpSession *)f.protoctx; TcpSession *ssn = (TcpSession *)f.protoctx;
if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server));
StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client));
f.alproto != ALPROTO_UNKNOWN || FAIL_IF(f.alproto != ALPROTO_UNKNOWN);
f.alproto_ts != ALPROTO_UNKNOWN || FAIL_IF(f.alproto_ts != ALPROTO_UNKNOWN);
f.alproto_tc != ALPROTO_UNKNOWN || FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN);
f.data_al_so_far[0] != 0 || FAIL_IF(f.data_al_so_far[0] != 0);
f.data_al_so_far[1] != 0 || FAIL_IF(f.data_al_so_far[1] != 0);
ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || FAIL_IF(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED);
FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
ssn->data_first_seen_dir != 0) { FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
printf("failure 1\n"); FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
goto end; FAIL_IF(ssn->data_first_seen_dir != 0);
}
/* handshake */ /* handshake */
p->tcph->th_ack = htonl(1); p->tcph->th_ack = htonl(1);
@ -1683,22 +1680,20 @@ static int AppLayerTest04(void)
p->flowflags = FLOW_PKT_TOCLIENT; p->flowflags = FLOW_PKT_TOCLIENT;
p->payload_len = 0; p->payload_len = 0;
p->payload = NULL; p->payload = NULL;
if (StreamTcpPacket(&tv, p, stt, &pq) == -1) FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
goto end; FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server));
if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client));
StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || FAIL_IF(f.alproto != ALPROTO_UNKNOWN);
f.alproto != ALPROTO_UNKNOWN || FAIL_IF(f.alproto_ts != ALPROTO_UNKNOWN);
f.alproto_ts != ALPROTO_UNKNOWN || FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN);
f.alproto_tc != ALPROTO_UNKNOWN || FAIL_IF(f.data_al_so_far[0] != 0);
f.data_al_so_far[0] != 0 || FAIL_IF(f.data_al_so_far[1] != 0);
f.data_al_so_far[1] != 0 || FAIL_IF(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED);
ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
ssn->data_first_seen_dir != 0) { FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
printf("failure 2\n"); FAIL_IF(ssn->data_first_seen_dir != 0);
goto end;
}
/* handshake */ /* handshake */
p->tcph->th_ack = htonl(1); p->tcph->th_ack = htonl(1);
@ -1707,22 +1702,20 @@ static int AppLayerTest04(void)
p->flowflags = FLOW_PKT_TOSERVER; p->flowflags = FLOW_PKT_TOSERVER;
p->payload_len = 0; p->payload_len = 0;
p->payload = NULL; p->payload = NULL;
if (StreamTcpPacket(&tv, p, stt, &pq) == -1) FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
goto end; FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server));
if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client));
StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || FAIL_IF(f.alproto != ALPROTO_UNKNOWN);
f.alproto != ALPROTO_UNKNOWN || FAIL_IF(f.alproto_ts != ALPROTO_UNKNOWN);
f.alproto_ts != ALPROTO_UNKNOWN || FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN);
f.alproto_tc != ALPROTO_UNKNOWN || FAIL_IF(f.data_al_so_far[0] != 0);
f.data_al_so_far[0] != 0 || FAIL_IF(f.data_al_so_far[1] != 0);
f.data_al_so_far[1] != 0 || FAIL_IF(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED);
ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
ssn->data_first_seen_dir != 0) { FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
printf("failure 3\n"); FAIL_IF(ssn->data_first_seen_dir != 0);
goto end;
}
/* request */ /* request */
uint8_t request[] = { uint8_t request[] = {
@ -1737,53 +1730,51 @@ static int AppLayerTest04(void)
0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a, 0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a,
0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20,
0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a }; 0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a };
PrintRawDataFp(stdout, request, sizeof(request));
p->tcph->th_ack = htonl(1); p->tcph->th_ack = htonl(1);
p->tcph->th_seq = htonl(1); p->tcph->th_seq = htonl(1);
p->tcph->th_flags = TH_PUSH | TH_ACK; p->tcph->th_flags = TH_PUSH | TH_ACK;
p->flowflags = FLOW_PKT_TOSERVER; p->flowflags = FLOW_PKT_TOSERVER;
p->payload_len = sizeof(request); p->payload_len = sizeof(request);
p->payload = request; p->payload = request;
if (StreamTcpPacket(&tv, p, stt, &pq) == -1) FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
goto end; FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server));
if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client));
StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || FAIL_IF(f.alproto != ALPROTO_UNKNOWN);
f.alproto != ALPROTO_UNKNOWN || FAIL_IF(f.alproto_ts != ALPROTO_UNKNOWN);
f.alproto_ts != ALPROTO_UNKNOWN || FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN);
f.alproto_tc != ALPROTO_UNKNOWN || FAIL_IF(f.data_al_so_far[0] != 0);
f.data_al_so_far[0] != 0 || FAIL_IF(f.data_al_so_far[1] != 0);
f.data_al_so_far[1] != 0 || FAIL_IF(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED);
ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
ssn->data_first_seen_dir != STREAM_TOSERVER) { FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
printf("failure 4\n"); FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER); // TOSERVER data now seen
goto end;
}
/* partial response */ /* partial response */
uint8_t response1[] = { 0x58, 0x54, 0x54, 0x50, }; uint8_t response1[] = { 0x58, 0x54, 0x54, 0x50, };
PrintRawDataFp(stdout, response1, sizeof(response1));
p->tcph->th_ack = htonl(88); p->tcph->th_ack = htonl(88);
p->tcph->th_seq = htonl(1); p->tcph->th_seq = htonl(1);
p->tcph->th_flags = TH_PUSH | TH_ACK; p->tcph->th_flags = TH_PUSH | TH_ACK;
p->flowflags = FLOW_PKT_TOCLIENT; p->flowflags = FLOW_PKT_TOCLIENT;
p->payload_len = sizeof(response1); p->payload_len = sizeof(response1);
p->payload = response1; p->payload = response1;
if (StreamTcpPacket(&tv, p, stt, &pq) == -1) FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
goto end; FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server));
if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || FAIL_IF(!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client)); // toserver complete
!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || FAIL_IF(f.alproto != ALPROTO_HTTP); // http based on ts
f.alproto != ALPROTO_HTTP || FAIL_IF(f.alproto_ts != ALPROTO_HTTP); // ts complete
f.alproto_ts != ALPROTO_HTTP || FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN);
f.alproto_tc != ALPROTO_UNKNOWN || FAIL_IF(f.data_al_so_far[0] != 0);
f.data_al_so_far[0] != 0 || FAIL_IF(f.data_al_so_far[1] != 0);
f.data_al_so_far[1] != 0 || FAIL_IF(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED);
ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER) { FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
printf("failure 5\n"); FAIL_IF(ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER); // first data sent to applayer
goto end;
}
/* partial response ack */ /* partial response ack */
p->tcph->th_ack = htonl(5); p->tcph->th_ack = htonl(5);
@ -1792,22 +1783,20 @@ static int AppLayerTest04(void)
p->flowflags = FLOW_PKT_TOSERVER; p->flowflags = FLOW_PKT_TOSERVER;
p->payload_len = 0; p->payload_len = 0;
p->payload = NULL; p->payload = NULL;
if (StreamTcpPacket(&tv, p, stt, &pq) == -1) FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
goto end; FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server));
if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || FAIL_IF(!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client)); // toserver complete
!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || FAIL_IF(f.alproto != ALPROTO_HTTP); // http based on ts
f.alproto != ALPROTO_HTTP || FAIL_IF(f.alproto_ts != ALPROTO_HTTP); // ts complete
f.alproto_ts != ALPROTO_HTTP || FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN);
f.alproto_tc != ALPROTO_UNKNOWN || FAIL_IF(f.data_al_so_far[0] != 0);
f.data_al_so_far[0] != 0 || FAIL_IF(f.data_al_so_far[1] != 0);
f.data_al_so_far[1] != 4 || FAIL_IF(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED);
ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || !FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER) { FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT)); // to client pp got nothing
printf("failure 6\n"); FAIL_IF(ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER); // first data sent to applayer
goto end;
}
/* remaining response */ /* remaining response */
uint8_t response2[] = { uint8_t response2[] = {
@ -1852,28 +1841,27 @@ static int AppLayerTest04(void)
0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31, 0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e }; 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
PrintRawDataFp(stdout, response2, sizeof(response2));
p->tcph->th_ack = htonl(88); p->tcph->th_ack = htonl(88);
p->tcph->th_seq = htonl(5); p->tcph->th_seq = htonl(5);
p->tcph->th_flags = TH_PUSH | TH_ACK; p->tcph->th_flags = TH_PUSH | TH_ACK;
p->flowflags = FLOW_PKT_TOCLIENT; p->flowflags = FLOW_PKT_TOCLIENT;
p->payload_len = sizeof(response2); p->payload_len = sizeof(response2);
p->payload = response2; p->payload = response2;
if (StreamTcpPacket(&tv, p, stt, &pq) == -1) FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
goto end; FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server));
if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || FAIL_IF(!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client)); // toserver complete
!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || FAIL_IF(f.alproto != ALPROTO_HTTP); // http based on ts
f.alproto != ALPROTO_HTTP || FAIL_IF(f.alproto_ts != ALPROTO_HTTP); // ts complete
f.alproto_ts != ALPROTO_HTTP || FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN);
f.alproto_tc != ALPROTO_UNKNOWN || FAIL_IF(f.data_al_so_far[0] != 0);
f.data_al_so_far[0] != 0 || FAIL_IF(f.data_al_so_far[1] != 0);
f.data_al_so_far[1] != 4 || FAIL_IF(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED);
ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || !FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER) { FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT)); // to client pp got nothing
printf("failure 7\n"); FAIL_IF(ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER); // first data sent to applayer
goto end;
}
/* response ack */ /* response ack */
p->tcph->th_ack = htonl(328); p->tcph->th_ack = htonl(328);
@ -1882,31 +1870,25 @@ static int AppLayerTest04(void)
p->flowflags = FLOW_PKT_TOSERVER; p->flowflags = FLOW_PKT_TOSERVER;
p->payload_len = 0; p->payload_len = 0;
p->payload = NULL; p->payload = NULL;
if (StreamTcpPacket(&tv, p, stt, &pq) == -1) FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
goto end; FAIL_IF(!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server)); // toclient complete (failed)
if (!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || FAIL_IF(!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client)); // toserver complete
!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || FAIL_IF(f.alproto != ALPROTO_HTTP); // http based on ts
f.alproto != ALPROTO_HTTP || FAIL_IF(f.alproto_ts != ALPROTO_HTTP); // ts complete
f.alproto_ts != ALPROTO_HTTP || FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN);
f.alproto_tc != ALPROTO_UNKNOWN || FAIL_IF(f.data_al_so_far[0] != 0);
f.data_al_so_far[0] != 0 || FAIL_IF(f.data_al_so_far[1] != 0);
f.data_al_so_far[1] != 0 || FAIL_IF(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED);
ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || !FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER) { FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT)); // to client pp got nothing
printf("failure 8\n"); FAIL_IF(ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER); // first data sent to applayer
goto end;
}
StreamTcpSessionClear(p->flow->protoctx); StreamTcpSessionClear(p->flow->protoctx);
ret = 1;
end:
StreamTcpFreeConfig(TRUE); StreamTcpFreeConfig(TRUE);
SCFree(p); SCFree(p);
FLOW_DESTROY(&f); FLOW_DESTROY(&f);
return ret; PASS;
} }
/** /**
@ -1915,8 +1897,7 @@ static int AppLayerTest04(void)
static int AppLayerTest05(void) static int AppLayerTest05(void)
{ {
Packet *p = SCMalloc(SIZE_OF_PACKET); Packet *p = SCMalloc(SIZE_OF_PACKET);
if (unlikely(p == NULL)) FAIL_IF_NULL(p);
return 0;
Flow f; Flow f;
ThreadVars tv; ThreadVars tv;
StreamTcpThread *stt = NULL; StreamTcpThread *stt = NULL;
@ -1934,8 +1915,6 @@ static int AppLayerTest05(void)
p->flow = &f; p->flow = &f;
p->tcph = &tcph; p->tcph = &tcph;
int ret = 0;
StreamTcpInitConfig(TRUE); StreamTcpInitConfig(TRUE);
StreamTcpThreadInit(&tv, NULL, (void **)&stt); StreamTcpThreadInit(&tv, NULL, (void **)&stt);
@ -1944,27 +1923,25 @@ static int AppLayerTest05(void)
p->flowflags = FLOW_PKT_TOSERVER; p->flowflags = FLOW_PKT_TOSERVER;
p->payload_len = 0; p->payload_len = 0;
p->payload = NULL; p->payload = NULL;
if (StreamTcpPacket(&tv, p, stt, &pq) == -1)
goto end;
TcpSession *ssn = (TcpSession *)f.protoctx;
/* handshake */ /* handshake */
if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) ||
f.alproto != ALPROTO_UNKNOWN || TcpSession *ssn = (TcpSession *)f.protoctx;
f.alproto_ts != ALPROTO_UNKNOWN ||
f.alproto_tc != ALPROTO_UNKNOWN ||
f.data_al_so_far[0] != 0 ||
f.data_al_so_far[1] != 0 ||
ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED ||
FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) ||
FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) ||
ssn->data_first_seen_dir != 0) {
printf("failure 1\n");
goto end;
}
FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server));
FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client));
FAIL_IF(f.alproto != ALPROTO_UNKNOWN);
FAIL_IF(f.alproto_ts != ALPROTO_UNKNOWN);
FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN);
FAIL_IF(f.data_al_so_far[0] != 0);
FAIL_IF(f.data_al_so_far[1] != 0);
FAIL_IF(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED);
FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
FAIL_IF(ssn->data_first_seen_dir != 0);
/* handshake */ /* handshake */
p->tcph->th_ack = htonl(1); p->tcph->th_ack = htonl(1);
@ -1972,22 +1949,20 @@ static int AppLayerTest05(void)
p->flowflags = FLOW_PKT_TOCLIENT; p->flowflags = FLOW_PKT_TOCLIENT;
p->payload_len = 0; p->payload_len = 0;
p->payload = NULL; p->payload = NULL;
if (StreamTcpPacket(&tv, p, stt, &pq) == -1) FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
goto end; FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server));
if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client));
StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || FAIL_IF(f.alproto != ALPROTO_UNKNOWN);
f.alproto != ALPROTO_UNKNOWN || FAIL_IF(f.alproto_ts != ALPROTO_UNKNOWN);
f.alproto_ts != ALPROTO_UNKNOWN || FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN);
f.alproto_tc != ALPROTO_UNKNOWN || FAIL_IF(f.data_al_so_far[0] != 0);
f.data_al_so_far[0] != 0 || FAIL_IF(f.data_al_so_far[1] != 0);
f.data_al_so_far[1] != 0 || FAIL_IF(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED);
ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
ssn->data_first_seen_dir != 0) { FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
printf("failure 2\n"); FAIL_IF(ssn->data_first_seen_dir != 0);
goto end;
}
/* handshake */ /* handshake */
p->tcph->th_ack = htonl(1); p->tcph->th_ack = htonl(1);
@ -1996,22 +1971,20 @@ static int AppLayerTest05(void)
p->flowflags = FLOW_PKT_TOSERVER; p->flowflags = FLOW_PKT_TOSERVER;
p->payload_len = 0; p->payload_len = 0;
p->payload = NULL; p->payload = NULL;
if (StreamTcpPacket(&tv, p, stt, &pq) == -1) FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
goto end; FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server));
if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client));
StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || FAIL_IF(f.alproto != ALPROTO_UNKNOWN);
f.alproto != ALPROTO_UNKNOWN || FAIL_IF(f.alproto_ts != ALPROTO_UNKNOWN);
f.alproto_ts != ALPROTO_UNKNOWN || FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN);
f.alproto_tc != ALPROTO_UNKNOWN || FAIL_IF(f.data_al_so_far[0] != 0);
f.data_al_so_far[0] != 0 || FAIL_IF(f.data_al_so_far[1] != 0);
f.data_al_so_far[1] != 0 || FAIL_IF(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED);
ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
ssn->data_first_seen_dir != 0) { FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
printf("failure 3\n"); FAIL_IF(ssn->data_first_seen_dir != 0);
goto end;
}
/* full request */ /* full request */
uint8_t request[] = { uint8_t request[] = {
@ -2026,28 +1999,27 @@ static int AppLayerTest05(void)
0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a, 0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a,
0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20,
0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a }; 0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a };
PrintRawDataFp(stdout, request, sizeof(request));
p->tcph->th_ack = htonl(1); p->tcph->th_ack = htonl(1);
p->tcph->th_seq = htonl(1); p->tcph->th_seq = htonl(1);
p->tcph->th_flags = TH_PUSH | TH_ACK; p->tcph->th_flags = TH_PUSH | TH_ACK;
p->flowflags = FLOW_PKT_TOSERVER; p->flowflags = FLOW_PKT_TOSERVER;
p->payload_len = sizeof(request); p->payload_len = sizeof(request);
p->payload = request; p->payload = request;
if (StreamTcpPacket(&tv, p, stt, &pq) == -1) FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
goto end; FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server));
if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client));
StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || FAIL_IF(f.alproto != ALPROTO_UNKNOWN);
f.alproto != ALPROTO_UNKNOWN || FAIL_IF(f.alproto_ts != ALPROTO_UNKNOWN);
f.alproto_ts != ALPROTO_UNKNOWN || FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN);
f.alproto_tc != ALPROTO_UNKNOWN || FAIL_IF(f.data_al_so_far[0] != 0);
f.data_al_so_far[0] != 0 || FAIL_IF(f.data_al_so_far[1] != 0);
f.data_al_so_far[1] != 0 || FAIL_IF(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED);
ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
ssn->data_first_seen_dir != STREAM_TOSERVER) { FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
printf("failure 4\n"); FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
goto end;
}
/* full response - request ack */ /* full response - request ack */
uint8_t response[] = { uint8_t response[] = {
@ -2092,28 +2064,27 @@ static int AppLayerTest05(void)
0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31, 0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e }; 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
PrintRawDataFp(stdout, response, sizeof(response));
p->tcph->th_ack = htonl(88); p->tcph->th_ack = htonl(88);
p->tcph->th_seq = htonl(1); p->tcph->th_seq = htonl(1);
p->tcph->th_flags = TH_PUSH | TH_ACK; p->tcph->th_flags = TH_PUSH | TH_ACK;
p->flowflags = FLOW_PKT_TOCLIENT; p->flowflags = FLOW_PKT_TOCLIENT;
p->payload_len = sizeof(response); p->payload_len = sizeof(response);
p->payload = response; p->payload = response;
if (StreamTcpPacket(&tv, p, stt, &pq) == -1) FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
goto end; FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server));
if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client));
StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || FAIL_IF(f.alproto != ALPROTO_UNKNOWN);
f.alproto != ALPROTO_UNKNOWN || FAIL_IF(f.alproto_ts != ALPROTO_UNKNOWN);
f.alproto_ts != ALPROTO_UNKNOWN || FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN);
f.alproto_tc != ALPROTO_UNKNOWN || FAIL_IF(f.data_al_so_far[0] != 0);
f.data_al_so_far[0] != 0 || FAIL_IF(f.data_al_so_far[1] != 0);
f.data_al_so_far[1] != 0 || FAIL_IF(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED);
ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || !FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
ssn->data_first_seen_dir != STREAM_TOSERVER) { FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
printf("failure 5\n"); FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
goto end;
}
/* response ack */ /* response ack */
p->tcph->th_ack = htonl(328); p->tcph->th_ack = htonl(328);
@ -2122,31 +2093,26 @@ static int AppLayerTest05(void)
p->flowflags = FLOW_PKT_TOSERVER; p->flowflags = FLOW_PKT_TOSERVER;
p->payload_len = 0; p->payload_len = 0;
p->payload = NULL; p->payload = NULL;
if (StreamTcpPacket(&tv, p, stt, &pq) == -1) FAIL_IF(StreamTcpPacket(&tv, p, stt, &pq) == -1);
goto end; FAIL_IF(!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server));
if (!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) || FAIL_IF(!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client));
!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) || FAIL_IF(f.alproto != ALPROTO_HTTP);
f.alproto != ALPROTO_HTTP || FAIL_IF(f.alproto_ts != ALPROTO_UNKNOWN);
f.alproto_ts != ALPROTO_UNKNOWN || FAIL_IF(f.alproto_tc != ALPROTO_HTTP);
f.alproto_tc != ALPROTO_HTTP || FAIL_IF(f.data_al_so_far[0] != 0);
f.data_al_so_far[0] != 0 || FAIL_IF(f.data_al_so_far[1] != 0);
f.data_al_so_far[1] != 0 || FAIL_IF(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED);
ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED || FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || !FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) || FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) || FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER) { FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
printf("failure 6\n"); FAIL_IF(ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER);
goto end;
}
StreamTcpSessionClear(p->flow->protoctx); StreamTcpSessionClear(p->flow->protoctx);
ret = 1;
end:
StreamTcpFreeConfig(TRUE); StreamTcpFreeConfig(TRUE);
SCFree(p); SCFree(p);
FLOW_DESTROY(&f); FLOW_DESTROY(&f);
return ret; PASS;
} }
/** /**

Loading…
Cancel
Save