Linux required IP_TOS to be set as an int prior to 2016 kernel commit
e895cdce683161081e3626c4f5a5c55cb72089f8, even though it's a u8 when
read via IP_RECVTOS.
This fixes dual-stack operation on less recent Linux kernels, and
reduces the rate of address conversion to once per connection by
assuming that dual-stack sockets will always yield IPv4-mapped IPv6
addresses.
Servers may only send at most 3x received data until address
verification is complete, so large handshakes or packet loss may
require the client to send dummy packets.
The sample offset is now always exactly 4 bytes after the PN offset,
so much extra computation is now unnecessary, and some interfaces can
be simplified. As a bonus, a bug in the redundant computation was
eliminated in the process.
1-RTT packets may be sent before the handshake has genuinely
completed, making the prior logic wrong.
This approach relies on the inference that if the server has sent any
Handshake ACK in the Established state, there is no need to retransmit
any outstanding CRYPTO data. This holds because the server cannot
enter Established until the client has fully completed the handshake,
so any outstanding CRYPTO data must be a spurious retransmit, and need
not be reliably delivered.
No ultimate behavioral change here so long as handshake keys are
unavailable to clients until after all Initial CRYPTO data has been
transmitted, but less fragile: discarding the previous space in
write_tls is only correct if the write attempt generated no data.
Previously, we might have sent an ACK-only packet in response to a
probe timeout, and were not correctly accounting for ack-eliciting
probes in loss detection.
When two ACKs acknowledging new packets were received simultaneously
in different number spaces, the first ECN verification would update
the ECN feedback state, leading the second verification to erroneously
conclude that no ECN counter increase corresponding to the newly acked
packet occurred and hence ECN bleaching must be taking place.