tcp: fix OoO reassembly when the first data packet is OoO

OoO reassembly assumed that the stream starts with the first data
segment, but this can already be OoO. Use the hint from SYN instead.
The test capture is based on a local capture, post-processed with scapy
to introduce an OoO condition and fixup the frame time.

Bug: 15078
Change-Id: Id0e312bb3d0e7c7f8f1b243a2be9f15c9851c501
Fixes: v2.9.0rc0-1097-gca42331437 ("tcp: add support for reassembling out-of-order segments")
Reviewed-on: https://code.wireshark.org/review/29305
Petri-Dish: Peter Wu <peter@lekensteyn.nl>
Tested-by: Petri Dish Buildbot
Reviewed-by: Anders Broman <a.broman58@gmail.com>
This commit is contained in:
Peter Wu 2018-08-27 15:31:03 +02:00 committed by Anders Broman
parent 28524f1abf
commit 3fea3c3709
3 changed files with 19 additions and 2 deletions

View File

@ -3179,8 +3179,8 @@ again:
* the MSP is not complete yet. */
}
if (tcpd->fwd->maxnextseq == 0 || LT_SEQ(tcpd->fwd->maxnextseq, nxtseq)) {
/* Update the maximum expected seqno if unknown or if the new
* segment succeeds previous segments. */
/* Update the maximum expected seqno if no SYN packet was seen
* before, or if the new segment succeeds previous segments. */
tcpd->fwd->maxnextseq = nxtseq;
}
}
@ -6308,6 +6308,12 @@ dissect_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
tcpd->server_port = tcph->th_dport;
tcpd->ts_mru_syn = pinfo->abs_ts;
}
/* Remember where the next segment will start. */
if (tcp_desegment && tcp_reassemble_out_of_order && tcpd && !PINFO_FD_VISITED(pinfo)) {
if (tcpd->fwd->maxnextseq == 0) {
tcpd->fwd->maxnextseq = tcph->th_seq + 1;
}
}
}
if(tcph->th_flags & TH_FIN) {
/* XXX - find a way to know the server port and output only that one */

BIN
test/captures/dns-ooo.pcap Normal file

Binary file not shown.

View File

@ -79,3 +79,14 @@ class case_dissect_tcp(subprocesstest.SubprocessTestCase):
self.assertTrue(self.grepOutput(r'^\s*11\s.*PUT /3 HTTP/1.1'))
self.assertTrue(self.grepOutput(r'^\s*11\s.*PUT /4 HTTP/1.1'))
self.assertTrue(self.grepOutput(r'^\s*15\s.*PUT /5 HTTP/1.1'))
def test_tcp_out_of_order_data_after_syn(self):
'''Test when the first non-empty segment is OoO.'''
capture_file = os.path.join(config.capture_dir, 'dns-ooo.pcap')
proc = self.runProcess((config.cmd_tshark,
'-r', capture_file,
'-otcp.reassemble_out_of_order:TRUE',
'-Y', 'dns', '-Tfields', '-edns.qry.name',
),
env=config.test_env)
self.assertEqual(proc.stdout_str.strip(), 'example.com')