Add a share() method that enables reference counting for the packet and
returns a clone. The packet's deleter will only be invoked after all clones
are destroyed.
This is useful for tcp, which keeps a packet in the unacknowledged transmit
queue while sending it lower down the stack.
Instead of returning a future<packet>, return a future<> (signifying data
is available) and provide a read() method.
This is useful in case the user wants to consume more or less than exactly
one packet.
Rudimentary TCP support (establishes a connection then falls over, lots of
things missing).
In a departure from tradition, we don't have a state enum with all the
traditional LISTENING states etc. Instead we have boolean values
indicating whether an event (like a remote SYN received, or our SYN
acknowledged) has happened. This simplifies things, because in TCP
the sending side and the receiving side are mostly orthogonal, while the
TCP state mixes the two.
TCP is implemented as a template, in order to tune it for the differences
in TCP/IPv4 vs. TCP/IPv6 (mostly address size and pseudo header).
When trimming the tcp header from a tcp packet without any data (such
as a SYN), nothing remains. trim_front() did not account for this,
and crashed.
Fix by checking for the condition.
Linux looks at the gso hdr_len field even if gso is not used, and refuses
to send the packet if it isn't reasonable. mode=debug poisons memory,
causing the value to be unreasonable.
Fix by clearing the entire header.