What
Found while fixing #443 (TCP stream reassembly's analogous last-write-wins
overwrite). Investigating whether that code path was shared with IP fragment
reassembly, I found pcapkit/foundation/reassembly/ip.py has a structurally
similar defect, but it is a separate implementation governed by a
different RFC, so it is filed separately rather than folded into #443's
fix (which only touches pcapkit/foundation/reassembly/tcp.py and its data
model).
pcapkit/foundation/reassembly/ip.py:133:
# put data into data buffer
start = FO
stop = TL - IHL + FO
self._buffer[BUFID].datagram[start:stop] = info.payload
This slice-assigns the arriving fragment's payload into the preallocated
65535-byte datagram buffer with no check of RCVBT (the fragment-received
bit table, set immediately after at line 138) beforehand. So when two IP
fragments claim an overlapping byte range within the same datagram (same
source, destination, protocol, and IP identification field) but carry
different bytes, the later-arriving one silently wins -- the same
last-write-wins-with-no-record shape as #443, just one layer down.
Why this is a separate issue, not scope creep on #443
Reproduction shape (not yet executed)
Two fragments with the same (src, dst, id, proto) buffer identifier and
overlapping fo/tl ranges, differing in the overlapping bytes, followed by
enough fragments to complete the datagram. Expect (unverified) the same
shape as #443's original report: the datagram reports complete with the
later fragment's bytes silently kept in the overlap, and nothing on the
returned Datagram records the disagreement.
Scope
Not fixing here. Whoever picks this up should first determine whether RFC
791/815/1122 specify a resolution (unlike RFC 9293 for TCP, which is explicit
about first-write-wins), then decide whether the same "record a conflict
range, additive field on Datagram" shape from #443 fits, or something else
is more appropriate for fragment reassembly.
What
Found while fixing #443 (TCP stream reassembly's analogous last-write-wins
overwrite). Investigating whether that code path was shared with IP fragment
reassembly, I found
pcapkit/foundation/reassembly/ip.pyhas a structurallysimilar defect, but it is a separate implementation governed by a
different RFC, so it is filed separately rather than folded into #443's
fix (which only touches
pcapkit/foundation/reassembly/tcp.pyand its datamodel).
pcapkit/foundation/reassembly/ip.py:133:This slice-assigns the arriving fragment's payload into the preallocated
65535-byte
datagrambuffer with no check ofRCVBT(the fragment-receivedbit table, set immediately after at line 138) beforehand. So when two IP
fragments claim an overlapping byte range within the same datagram (same
source, destination, protocol, and IP identification field) but carry
different bytes, the later-arriving one silently wins -- the same
last-write-wins-with-no-record shape as #443, just one layer down.
Why this is a separate issue, not scope creep on #443
ip.pyhas its ownreassembly()/submit()and itsown
Buffer/Datagramdata model inpcapkit/foundation/reassembly/data/ip.py; nothing here is shared withtcp.py.RFC 791 algorithm (
RCVBT), withRCVBT's own reassembly timeout comingfrom RFC 1122 §3.3.2 (IPv4) / RFC 8200 §4.5 (IPv6). Whether that
algorithm has anything to say about a conflicting overlap -- and if so,
what the resolution should be -- is an open question that needs its own
reading of those RFCs; nothing in TCP reassembly silently resolves conflicting retransmissions last-write-wins and still reports COMPLETE #443's research (RFC 9293 §3.10, which is
TCP-specific) answers it. RFC 1122's overlap language is about IP fragment
reassembly, so unlike in TCP reassembly silently resolves conflicting retransmissions last-write-wins and still reports COMPLETE #443 it may actually be the right RFC to start
from here -- but that has not been checked yet, so this issue is not
proposing a fix.
Reproduction shape (not yet executed)
Two fragments with the same
(src, dst, id, proto)buffer identifier andoverlapping
fo/tlranges, differing in the overlapping bytes, followed byenough fragments to complete the datagram. Expect (unverified) the same
shape as #443's original report: the datagram reports complete with the
later fragment's bytes silently kept in the overlap, and nothing on the
returned
Datagramrecords the disagreement.Scope
Not fixing here. Whoever picks this up should first determine whether RFC
791/815/1122 specify a resolution (unlike RFC 9293 for TCP, which is explicit
about first-write-wins), then decide whether the same "record a conflict
range, additive field on
Datagram" shape from #443 fits, or something elseis more appropriate for fragment reassembly.