Flow 1.0.2
Flow project: Full implementation reference.
|
Internal net_flow
struct
that encapsulates the Flow-protocol low-level ACK packet.
More...
#include <low_lvl_packet.hpp>
Classes | |
struct | Individual_ack |
Specifies the incoming (post-deserialization) acknowledgment of a single received Data_packet. More... | |
struct | Individual_ack_rexmit_off |
Specifies the outgoing (pre-serialization) acknowledgment of a single received Data_packet, when retranmission is disabled on the socket. More... | |
struct | Individual_ack_rexmit_on |
Equivalent of Individual_ack_rexmit_off but for sockets with retransmission enabled. More... | |
Public Types | |
using | ack_delay_t = uint64_t |
Type used to store the ACK delay for a given individual acknowledged packet. More... | |
using | Ack_delay_time_unit = Fine_duration |
Ack_delay_time_unit(1) is the duration corresponding to the ack_delay_t value 1; and proportionally further. More... | |
Public Types inherited from flow::net_flow::Low_lvl_packet | |
using | Const_buffer = boost::asio::const_buffer |
Short-hand for boost.asio immutable buffer, which essentially is a pointer to and length of a memory area. More... | |
using | Const_buffer_sequence = std::vector< Const_buffer > |
Short-hand for sequence of immutable buffers; i.e., a sequence of 1 or more scattered areas in memory. More... | |
using | security_token_t = uint64_t |
Type used for m_security_token member of a couple different packet types. More... | |
using | rexmit_id_t = uint8_t |
Type used to store the retransmission count in DATA and ACK packets. More... | |
using | rcv_wnd_t = uint32_t |
Type used to store the size of m_rcv_wnd member in a couple of different packet types. More... | |
Public Types inherited from flow::util::Shared_ptr_alias_holder< boost::shared_ptr< Low_lvl_packet > > | |
using | Ptr = boost::shared_ptr< Low_lvl_packet > |
Short-hand for ref-counted pointer to mutable values of type Target_type::element_type (a-la T* ). More... | |
using | Const_ptr = Const_target_ptr |
Short-hand for ref-counted pointer to immutable values of type Target_type::element_type (a-la T const * ). More... | |
Public Member Functions | |
size_t | serialize_to_raw_data (Const_buffer_sequence *raw_bufs) const override |
Implements Low_lvl_packet API. More... | |
Public Member Functions inherited from flow::net_flow::Low_lvl_packet | |
virtual size_t | serialize_to_raw_data (Const_buffer_sequence *raw_bufs) const =0 |
Serializes the current logical packet data from *this into the given Const_buffer_sequence , which is a sequence of pointers and lengths of existing scattered areas in memory, presumably for transmission over the wire to a compatible serializing Node. More... | |
size_t | serialize_to_raw_data_and_log (Const_buffer_sequence *raw_bufs) const |
Identical to serialize_to_raw_data() but adds log-level-appropriate logging after the operation. More... | |
Public Member Functions inherited from flow::util::Null_interface | |
virtual | ~Null_interface ()=0 |
Boring virtual destructor. More... | |
Public Member Functions inherited from flow::log::Log_context | |
Log_context (Logger *logger=0) | |
Constructs Log_context by storing the given pointer to a Logger and a null Component. More... | |
template<typename Component_payload > | |
Log_context (Logger *logger, Component_payload component_payload) | |
Constructs Log_context by storing the given pointer to a Logger and a new Component storing the specified generically typed payload (an enum value). More... | |
Log_context (const Log_context &src) | |
Copy constructor that stores equal Logger* and Component values as the source. More... | |
Log_context (Log_context &&src) | |
Move constructor that makes this equal to src , while the latter becomes as-if default-constructed. More... | |
Log_context & | operator= (const Log_context &src) |
Assignment operator that behaves similarly to the copy constructor. More... | |
Log_context & | operator= (Log_context &&src) |
Move assignment operator that behaves similarly to the move constructor. More... | |
void | swap (Log_context &other) |
Swaps Logger pointers and Component objects held by *this and other . More... | |
Logger * | get_logger () const |
Returns the stored Logger pointer, particularly as many FLOW_LOG_*() macros expect. More... | |
const Component & | get_log_component () const |
Returns reference to the stored Component object, particularly as many FLOW_LOG_*() macros expect. More... | |
Public Attributes | |
rcv_wnd_t | m_rcv_wnd |
Current receive window (remaining Receive buffer size) of the ACK sender. More... | |
uint16_t | m_rcv_acked_packets_rexmit_out_size |
This is the serialized version of m_rcv_acked_packets_rexmit_{on|off}_out.size() and m_rcv_acked_packets.size() (whichever is applicable in context). More... | |
std::vector< boost::shared_ptr< Individual_ack > > | m_rcv_acked_packets |
List of incoming (post-deserialization of ACK) acknowledgments of DATA packets, each identified by its first datum's sequence number as provided by the other side and ordered in the chronological order they were received. More... | |
std::vector< Individual_ack_rexmit_off > | m_rcv_acked_packets_rexmit_off_out |
Equivalent of m_rcv_acked_packets but used for outgoing (pre-serialization of ACK) acknowledgments and only if retransmission is disabled. More... | |
std::vector< Individual_ack_rexmit_on > | m_rcv_acked_packets_rexmit_on_out |
Equivalent of m_rcv_acked_packets_rexmit_off_out but for retransmission enabled. More... | |
Public Attributes inherited from flow::net_flow::Low_lvl_packet | |
bool | m_opt_rexmit_on |
Option indicating whether this connection is using retransmission or not. More... | |
struct { | |
flow_port_t m_src_port | |
Flow-protocol port # of socket in sending Node. More... | |
flow_port_t m_dst_port | |
Flow-protocol port # of socket in receiving Node. More... | |
} | m_packed |
Packed group affected by #pragma pack . | |
const Function< std::ostream &(std::ostream &)> | m_type_ostream_manip |
ostream manipulator (argument to ostream << ) that will output packet's type ("ACK", "RST", etc.). More... | |
const Function< std::ostream &(std::ostream &)> | m_verbose_ostream_manip |
ostream manipulator (argument to ostream << ) that will output packet info suitable for DATA log level. More... | |
const Function< std::ostream &(std::ostream &)> | m_concise_ostream_manip |
ostream manipulator (argument to ostream << ) that will output packet info suitable for TRACE log level. More... | |
Static Public Attributes | |
static const uint8_t | S_RAW_TYPE_ID |
In serialized packet, the type ID byte identifying this as an ACK packet. Must not equal any other packet type's. More... | |
Private Member Functions | |
Ack_packet (log::Logger *logger_ptr) | |
The implementation of Low_lvl_packet::create_uninit_packet() for this sub-type of Low_lvl_packet. More... | |
std::ostream & | to_ostream (std::ostream &os, bool verbose) const override |
Implements Low_lvl_packet API. More... | |
bool | deserialize_type_specific_data_from_raw_data_packet (Const_buffer *raw_buf, bool prefer_no_move, util::Blob *raw_packet) override |
Implements Low_lvl_packet API. More... | |
Friends | |
boost::shared_ptr< Ack_packet > | Low_lvl_packet::create_uninit_packet (log::Logger *) |
Friend of Ack_packet: For access to private constructor Ack_packet(Logger*) . | |
Additional Inherited Members | |
Static Public Member Functions inherited from flow::net_flow::Low_lvl_packet | |
template<typename Low_lvl_packet_sub > | |
static boost::shared_ptr< Low_lvl_packet_sub > | create_uninit_packet (log::Logger *logger_ptr) |
Constructs packet with uninitialized (essentially random) values, of the Low_lvl_packet sub-type specified as the template parameter (Ack_packet, Rst_packet, etc.). More... | |
template<typename Low_lvl_packet_sub > | |
static Ptr | create_uninit_packet_base (log::Logger *logger_ptr) |
A simple convenience method that casts the result of create_uninit_packet() from shared_ptr<T> , where T is a sub-type of Low_lvl_packet, to shared_ptr<Low_lvl_packet> a/k/a Ptr. More... | |
static Ptr | create_from_raw_data_packet (log::Logger *logger_ptr, util::Blob *raw_packet, bool prefer_no_move) |
Constructs packet on the heap with values determined by the given raw binary data as presumably received from the wire and originally serialized by a compatible serializing Node. More... | |
static const std::string & | type_id_to_str (const std::type_index &type_id) |
Returns a brief (a few characters) string description of the given packet type given as type_index(typeid(p)) , where p is a reference to an instance of a concrete Low_lvl_packet sub-type. More... | |
Static Public Member Functions inherited from flow::util::Shared_ptr_alias_holder< boost::shared_ptr< Low_lvl_packet > > | |
static Ptr | ptr_cast (const From_ptr &ptr_to_cast) |
Provides syntactic-sugary way to perform a static_pointer_cast<> from a compatible smart pointer type From_ptr , typically From_ptr::element_type being in the same class hierarchy as Target_ptr::element_type . More... | |
static Const_ptr | const_ptr_cast (const From_ptr &ptr_to_cast) |
Identical to ptr_cast() but adds const -ness (immutability) to the pointed-to type. More... | |
static Ptr | dynamic_ptr_cast (const From_ptr &ptr_to_cast) |
Equivalent to ptr_cast() but a dynamic_pointer_cast instead of static. More... | |
static Const_ptr | dynamic_const_ptr_cast (const From_ptr &ptr_to_cast) |
Identical to const_ptr_cast() but a dynamic_pointer_cast instead of static. More... | |
Protected Member Functions inherited from flow::net_flow::Low_lvl_packet | |
Low_lvl_packet (log::Logger *logger_ptr) | |
Constructs packet with uninitialized (essentially random) values. More... | |
size_t | serialize_common_header_to_raw_data (Const_buffer_sequence *raw_bufs) const |
Helper for serialize_to_raw_data() implementations in sub-types that encodes the header common to all packet types, starting with the packet type ID leading that header. More... | |
virtual std::ostream & | to_ostream (std::ostream &os, bool verbose=false) const |
Writes a multi-line representation of *this to an output stream. More... | |
Static Protected Member Functions inherited from flow::net_flow::Low_lvl_packet | |
static constexpr bool | native_is_big_endian () |
Returns true , at compile time, if and only if the native memory representation is big-endian, meaning, for example, the value uint32_t(1) is stored as the bytes, in order, 0x00 0x00 0x00 0x01, and not the reverse. More... | |
Internal net_flow
struct
that encapsulates the Flow-protocol low-level ACK packet.
See Low_lvl_packet doc header for information common to all low-level packets including this one.
Each ACK packet encapsulates 0 or more individual acknowledgments, each acknowledging receipt of a specific, distinct Data_packaet; and the current rcv_wnd (receive window state) on the ACK sender's side. The latter datum is always present. If individual acks are present, then the rcv_wnd advertising is merely opportunistic. If NO individual acks are present, then the rcv_wnd advertising is intentional for its own sake. The algorithm for the latter is discussed elsewhere.
The mechanics of individual acks are further explored in the doc header for Ack_packet::Individual_ack nested struct
.
Definition at line 1019 of file low_lvl_packet.hpp.
using flow::net_flow::Ack_packet::ack_delay_t = uint64_t |
Type used to store the ACK delay for a given individual acknowledged packet.
The value specifies the number of multiples of Ack_delay_time_unit(1)
comprising a packet's ACK delay.
An earlier version of net_flow
used the unit milliseconds and the encoding type uint16_t. The reasoning was that this allowed a maximum ACK delay of ~65 sec which should be plenty; and that the 1-millisecond finegrainedness was acceptable. However when implementing queue delay-based congestion control (like FAST or Vegas) we realized it is important for RTTs (which use the ACK delay value) to be quite precise (microsecond level or so). Therefore, to be totally safe, we choose to use the same units as Fine_duration, which is how we compute all time periods. As for the the encoding width, we use 64 bits just in case.
Ack_delay_time_unit(1)
is a nanosecond, then 32 bits would support a maximum delay of ~4.1 seconds which is likely fine for most real-world scenarios. This would reduce the size of ACK packets quite a bit. Definition at line 1039 of file low_lvl_packet.hpp.
Ack_delay_time_unit(1)
is the duration corresponding to the ack_delay_t value 1; and proportionally further.
Definition at line 1042 of file low_lvl_packet.hpp.
|
explicitprivate |
The implementation of Low_lvl_packet::create_uninit_packet() for this sub-type of Low_lvl_packet.
logger_ptr | Logger to use subsequently. |
Definition at line 96 of file low_lvl_packet.cpp.
|
overrideprivatevirtual |
Implements Low_lvl_packet API.
See that super-method's doc header.
Implements flow::net_flow::Low_lvl_packet.
Definition at line 785 of file low_lvl_packet.cpp.
References FLOW_LOG_TRACE, FLOW_LOG_WARNING, flow::net_flow::Low_lvl_packet::m_opt_rexmit_on, m_rcv_acked_packets, m_rcv_acked_packets_rexmit_out_size, m_rcv_wnd, flow::net_flow::Low_lvl_packet::m_type_ostream_manip, flow::net_flow::Sequence_number::set_metadata(), and flow::net_flow::Sequence_number::set_raw_num().
|
overridevirtual |
Implements Low_lvl_packet API.
See that super-method's doc header.
raw_bufs | See Low_lvl_packet::serialize_to_raw_data(). |
Implements flow::net_flow::Low_lvl_packet.
Definition at line 321 of file low_lvl_packet.cpp.
|
overrideprivatevirtual |
Implements Low_lvl_packet API.
See that super-method's doc header.
os | See Low_lvl_packet::to_ostream(). |
verbose | See Low_lvl_packet::to_ostream(). |
os
. Reimplemented from flow::net_flow::Low_lvl_packet.
Definition at line 996 of file low_lvl_packet.cpp.
References flow::net_flow::Low_lvl_packet::to_ostream().
std::vector<boost::shared_ptr<Individual_ack> > flow::net_flow::Ack_packet::m_rcv_acked_packets |
List of incoming (post-deserialization of ACK) acknowledgments of DATA packets, each identified by its first datum's sequence number as provided by the other side and ordered in the chronological order they were received.
This may also be empty, in which case the containing ACK acknowledges no DATA packets but only advertises the current receive window size (m_rcv_wnd). (Note that it advertises it if m_rcv_acked_packets is NOT empty as well.)
This is used if and only if this Ack_packet is incoming. See m_rcv_acked_packets_rexmit_on_out and m_rcv_acked_packets_rexmit_off_out for the outgoing scenario.
Unlike vanilla TCP from RFC 793, which features cumulative acknowledgment (wherein only the latest received segment BEFORE any unreceived gap is acknowledged, thus just one total number in the ACK), and unlike later enhanced TCPs, which feature both cumulative acknowledgement and individual ACKs (Selective ACKs), we use something similar to Selective ACKs only. That is, we only acknowledge each packet individually (though we combine many such little acknowledgments into one packet via delayed ACKs). Moreover, we do not piggy-back ACK info onto DATA packets; ACK is its own type.
Rationale for using SACKs only: Selective ACKs help greatly in giving accurate congestion control data (e.g., ACK delay per packet, dropped packets) and remove complex ambiguities of trying to interpret cumulative ACKs for that purpose. For retransmits, when enabled, Selective ACKs also greatly simplify the design choices (since we know exactly what they don't have [assuming no lost ACKs], we can send exactly what they want and no more).
Rationale for keeping ACK and DATA separate: This is less clear-cut. It is easier to think about, certainly, as the two types of traffic aren't really logically related in a full-duplex connection. On the other hand it increases overhead. On the third hand that disadvantage is not a big deal assuming mostly unidirectional traffic flow (which is typical), since most of the time the ACKs would be data-less anyway in that situation. Delayed ACKs also help combat overhead – somewhat.
Rationale for delayed ACKs a/k/a accumulating more than 1 acknowledgment into an ACK: Combat overhead which can be a big deal for high bitrate streaming traffic for example (research shows ACK flow can be 10% of data flow in the other direction). The cost is that the other side gets somewhat delayed congestion control information, but the delay can be tuned. In TCP implementations delayed ACKs appear to be universal since a long time ago.
Any two packets represented by these Individual_ack
s may be duplicates of each other (same Sequence_number, possibly different delay values). It's up to the sender (receiver of ACK) to sort it out. However, again, they MUST be ordered chronologicaly based on the time when they were received; from earliest to latest.
Storing shared pointers to avoid copying of struct
s (however small) during internal reshuffling; shared instead of raw pointers to not worry about delete
.
Definition at line 1115 of file low_lvl_packet.hpp.
Referenced by deserialize_type_specific_data_from_raw_data_packet().
std::vector<Individual_ack_rexmit_off> flow::net_flow::Ack_packet::m_rcv_acked_packets_rexmit_off_out |
Equivalent of m_rcv_acked_packets but used for outgoing (pre-serialization of ACK) acknowledgments and only if retransmission is disabled.
See notes in Individual_ack_rexmit_off doc header about how this is used for efficient serialization of Ack_packet.
This is used if and only if Ack_packet is outgoing, and retransmission is disabled. See m_rcv_acked_packets for the incoming scenario.
Definition at line 1125 of file low_lvl_packet.hpp.
std::vector<Individual_ack_rexmit_on> flow::net_flow::Ack_packet::m_rcv_acked_packets_rexmit_on_out |
Equivalent of m_rcv_acked_packets_rexmit_off_out but for retransmission enabled.
Definition at line 1128 of file low_lvl_packet.hpp.
|
mutable |
This is the serialized version of m_rcv_acked_packets_rexmit_{on|off}_out.size()
and m_rcv_acked_packets.size()
(whichever is applicable in context).
We send this value, even though it could be figured out from the overall serialized size, to ensure integrity (see the deserialization logic for details). This here is set to size()
, when Low_lvl_packet::serialize_to_raw_data() needs to serialize that value. Outside serialization size()
is used directly, and this value is meaningless.
Definition at line 1062 of file low_lvl_packet.hpp.
Referenced by deserialize_type_specific_data_from_raw_data_packet().
rcv_wnd_t flow::net_flow::Ack_packet::m_rcv_wnd |
Current receive window (remaining Receive buffer size) of the ACK sender.
Definition at line 1051 of file low_lvl_packet.hpp.
Referenced by deserialize_type_specific_data_from_raw_data_packet().
|
static |
In serialized packet, the type ID byte identifying this as an ACK packet. Must not equal any other packet type's.
Definition at line 1131 of file low_lvl_packet.hpp.