Breaking changes:
- `parse_frame_header` returns a named `FrameHeader` instead of a six-element tuple.
- Root re-exports are an explicit list rather than a glob over `types`, so a type added there is no longer public API by default. `types::` paths are unaffected.
- `FrameIterator::stats_mut` and `parse_stats_mut` on the message and parsed-message iterators are gone; nothing constructed a use for a mutable handle to the byte accounting.
- `PcapError::InvalidTimestamp` is gone; nothing ever produced it.
- `--pcap-layer` without `--pcap-export` is now an error instead of being silently ignored.
- The `torture-test` and `pidf-test` features and the optional `sip-uri` dependency are gone with the torture suite, which now lives in a separate crate outside this package.
New features:
- `FrameMeta` carries the direction, transport, address and timestamp that every level records, with one `socket_addr` and one `Display` behind the three types that expose them.
- `MimePart` gained `body_text` and `json_field`, so a per-part loop can unescape a JSON part the way a whole message already could.
- `Headers::values` iterates every value recorded under a name, for headers that legitimately repeat.
- `Direction` and `Transport` parse from their frame-header keywords.
- `StaleClock` exposes the elapsed-time rule the reassembly buffers evict by.
Bug fixes:
- A transport keep-alive frame no longer keeps its connection buffer alive, and no longer counts toward the frame count of the next message on that connection.
- Level 3 splits the body at the same blank line that ends the header block, so bytes between a bare-LF blank line and the next CRLF pair are no longer dropped from both halves.
- The multipart boundary is read as a Content-Type parameter matched by name, so a parameter merely ending in the word can no longer supply one.
- Level 2 accepts whitespace between a header name and its colon, matching Level 3 and the header crate.
- Level 2 resynchronises on any method Level 3 would parse, instead of a fixed table, and waits for a start line cut short by a frame boundary.
- Buffer eviction reads elapsed time from a timestamp's own date where it carries one, so a multi-day gap is no longer counted as a single day.
- A sweep emits one warning carrying how many buffers it evicted, not one per buffer.
- A corrupt declared byte count can no longer grow the read buffer to the size of the input.
- The pcap writer refuses a payload no IP length field can carry instead of writing a truncated one.
- The backtick is accepted in SIP tokens, per RFC 3261.
- `MimePart::content_type` reads the compact `c` form, as the sibling accessors already did.
- `--dialog` bounds its memory: dialogs end on CANCEL and on a failure response, and a dialog silent past the reassembly timeout is flushed rather than held to end of input.
Build:
- Clippy denies `unwrap`, `expect`, `panic` and `unreachable` in library code outside tests.
- `scripts/pre-release.sh` runs the whole release gate, including the integration and torture suites when the sample corpus is present.