diff options
author | Vinicius Silva Nogueira <vinicius_snogueira@hotmail.com> | 2022-03-24 06:51:31 -0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-03-24 10:51:31 +0100 |
commit | 26df1403e6e8c0f17a5e419d3e614ed4a86e1885 (patch) | |
tree | 1b26e6e3ad29b13f551a5e5b1a70a3b99a4ea347 /src/lib/protocols | |
parent | bb12837ca75efc2691ecb18fd5f56e2d097ef26b (diff) |
Trying to improve QUIC reassembler (#1195) (#1489)
* handling QUIC out-of-order fragments
* minor fix
* updated quic_frags_ch_out_of_order_same_packet_craziness.pcapng.out
* quic test: buf_len + last_pos
* QUIC: comment update in __reassemble function and minor change is_ch_complete function
Diffstat (limited to 'src/lib/protocols')
-rw-r--r-- | src/lib/protocols/quic.c | 29 |
1 files changed, 13 insertions, 16 deletions
diff --git a/src/lib/protocols/quic.c b/src/lib/protocols/quic.c index bdd6cc133..cd9f00f9c 100644 --- a/src/lib/protocols/quic.c +++ b/src/lib/protocols/quic.c @@ -1008,12 +1008,10 @@ static int __reassemble(struct ndpi_flow_struct *flow, const u_int8_t *frag, const u_int8_t **buf, u_int64_t *buf_len) { const uint64_t max_quic_reasm_buffer_len = 4096; /* Let's say a couple of full-MTU packets... */ - - /* TODO: at the moment, this function is only a little more than a stub. - We should reassemble the fragments, but nDPI lacks any proper generic - reassembler code. So, to keep the code simple here, try reassembling - the simplest case: only in-order fragments using a fixed-size buffer (i.e. no - retransmissions, no out-of-order, no overlapping...) + const uint64_t last_pos = frag_offset + frag_len; + /* + Working: in-order and out-of order, non overlapping, fragments + Not supported: retransmissions and (partial) overlapping */ if(!flow->l4.udp.quic_reasm_buf) { @@ -1021,25 +1019,24 @@ static int __reassemble(struct ndpi_flow_struct *flow, const u_int8_t *frag, if(!flow->l4.udp.quic_reasm_buf) return -1; /* Memory error */ flow->l4.udp.quic_reasm_buf_len = 0; + flow->l4.udp.quic_reasm_buf_last_pos = 0; } - if(flow->l4.udp.quic_reasm_buf_len != frag_offset) - return -2; /* Out-of-order, retransmission, overlapping */ - if(frag_offset + frag_len > max_quic_reasm_buffer_len) + if(last_pos > max_quic_reasm_buffer_len) return -3; /* Buffer too small */ - memcpy(&flow->l4.udp.quic_reasm_buf[flow->l4.udp.quic_reasm_buf_len], - frag, frag_len); + memcpy(&flow->l4.udp.quic_reasm_buf[frag_offset], frag, frag_len); flow->l4.udp.quic_reasm_buf_len += frag_len; + flow->l4.udp.quic_reasm_buf_last_pos = last_pos > flow->l4.udp.quic_reasm_buf_last_pos ? last_pos : flow->l4.udp.quic_reasm_buf_last_pos; *buf = flow->l4.udp.quic_reasm_buf; *buf_len = flow->l4.udp.quic_reasm_buf_len; return 0; } -static int is_ch_complete(const u_int8_t *buf, uint64_t buf_len) +static int is_ch_complete(const u_int8_t *buf, uint64_t buf_len, uint64_t last_pos) { uint32_t msg_len; - if(buf_len >= 4) { + if(buf_len >= 4 && last_pos == buf_len) { msg_len = (buf[1] << 16) + (buf[2] << 8) + buf[3]; if (4 + msg_len == buf_len) { return 1; @@ -1051,7 +1048,7 @@ static int is_ch_reassembler_pending(struct ndpi_flow_struct *flow) { return flow->l4.udp.quic_reasm_buf != NULL && !is_ch_complete(flow->l4.udp.quic_reasm_buf, - flow->l4.udp.quic_reasm_buf_len); + flow->l4.udp.quic_reasm_buf_len, flow->l4.udp.quic_reasm_buf_last_pos); } static const uint8_t *get_reassembled_crypto_data(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow, @@ -1066,7 +1063,7 @@ static const uint8_t *get_reassembled_crypto_data(struct ndpi_detection_module_s /* Fast path: no need of reassembler stuff */ if(frag_offset == 0 && - is_ch_complete(frag, frag_len)) { + is_ch_complete(frag, frag_len, frag_len)) { NDPI_LOG_DBG2(ndpi_struct, "Complete CH (fast path)\n"); *crypto_data_len = frag_len; return frag; @@ -1075,7 +1072,7 @@ static const uint8_t *get_reassembled_crypto_data(struct ndpi_detection_module_s rc = __reassemble(flow, frag, frag_len, frag_offset, &crypto_data, crypto_data_len); if(rc == 0) { - if(is_ch_complete(crypto_data, *crypto_data_len)) { + if(is_ch_complete(crypto_data, *crypto_data_len, flow->l4.udp.quic_reasm_buf_last_pos)) { NDPI_LOG_DBG2(ndpi_struct, "Reassembler completed!\n"); return crypto_data; } |