One of the more complex parts in the App Layer API is the handling of transactions. The app layer parser is responsible for creating transactions based on the traffic that comes in. However, the destruction of transactions is handled mostly by the engine itself.
For this to work, one of the things the engine needs to know is when a transaction can be considered complete.
Since the DNS parsing happens only on complete requests and replies at a time (even for TCP), the state handling can be much simpler.
If we have a request, we can immediately consider it complete.
If we have a reply, we can also immediately consider it complete. Furthermore, we can consider the entire TX complete. Even if the request was missed.
Request: if tx is present, it's done.
Response: if tx is tagged as 'replied' or we know the reply was lost, it's done.
Has per direction state tracking. State can be for example HTP_REQUEST_LINE, meaning the request line has been parsed. If state is HTP_REQUEST_HEADERS, it implies HTP_REQUEST_LINE is done. Likewise, HTP_REQUEST_BODY implies request headers are done. Fine grained state updates and tracking allow early inspection. For example, the HTTP request line can already be inspected before the request body is received.
HTPStateGetAlstateProgress returns different states per direction:
Request state: "return ((htp_tx_t *)tx)->request_progress;"
Response state: "return ((htp_tx_t *)tx)->response_progress;"
And we consider a side of the tx complete if its state reaches a value we define in "HTPStateGetAlstateProgressCompletionStatus":
"return (direction & STREAM_TOSERVER) ? HTP_REQUEST_COMPLETE : HTP_RESPONSE_COMPLETE;"