} __attribute__((__packed__));
typedef struct DNSTcpHeader_ DNSTcpHeader;
+static uint16_t DNSTcpProbingParser(uint8_t *input, uint32_t ilen,
+ uint32_t *offset);
+
/** \internal
* \param input_len at least enough for the DNSTcpHeader
*/
DNSState *dns_state = (DNSState *)dstate;
SCLogDebug("starting %u", input_len);
+ if (input == NULL && input_len > 0) {
+ SCLogDebug("Input is NULL, but len is %"PRIu32": must be a gap.",
+ input_len);
+ dns_state->gap_ts = 1;
+ SCReturnInt(1);
+ }
+
if (input == NULL && AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF)) {
SCReturnInt(1);
}
goto insufficient_data;
}
+ /* Clear gap state. */
+ if (dns_state->gap_ts) {
+ if (DNSTcpProbingParser(input, input_len, NULL) == ALPROTO_DNS) {
+ SCLogDebug("New data probed as DNS, clearing gap state.");
+ BufferReset(dns_state);
+ dns_state->gap_ts = 0;
+ } else {
+ SCLogDebug("Unable to sync DNS parser, leaving gap state.");
+ SCReturnInt(1);
+ }
+ }
+
next_record:
/* if this is the beginning of a record, we need at least the header */
if (dns_state->offset == 0 && input_len < sizeof(DNSTcpHeader)) {
{
DNSState *dns_state = (DNSState *)dstate;
+ if (input == NULL && input_len > 0) {
+ SCLogDebug("Input is NULL, but len is %"PRIu32": must be a gap.",
+ input_len);
+ dns_state->gap_tc = 1;
+ SCReturnInt(1);
+ }
+
if (input == NULL && AppLayerParserStateIssetFlag(pstate, APP_LAYER_PARSER_EOF)) {
SCReturnInt(1);
}
goto insufficient_data;
}
+ /* Clear gap state. */
+ if (dns_state->gap_tc) {
+ if (DNSTcpProbingParser(input, input_len, NULL) == ALPROTO_DNS) {
+ SCLogDebug("New data probed as DNS, clearing gap state.");
+ BufferReset(dns_state);
+ dns_state->gap_tc = 0;
+ } else {
+ SCLogDebug("Unable to sync DNS parser, leaving gap state.");
+ SCReturnInt(1);
+ }
+ }
+
next_record:
/* if this is the beginning of a record, we need at least the header */
if (dns_state->offset == 0 && input_len < sizeof(DNSTcpHeader)) {
AppLayerParserRegisterGetStateProgressCompletionStatus(ALPROTO_DNS,
DNSGetAlstateProgressCompletionStatus);
DNSAppLayerRegisterGetEventInfo(IPPROTO_TCP, ALPROTO_DNS);
+
+ /* This parser accepts gaps. */
+ AppLayerParserRegisterOptionFlags(IPPROTO_TCP, ALPROTO_DNS,
+ APP_LAYER_PARSER_OPT_ACCEPT_GAPS);
+
} else {
SCLogInfo("Parsed disabled for %s protocol. Protocol detection"
"still on.", proto_name);