Flow 1.0.0
Flow project: Full implementation reference.
Classes | Public Types | Public Member Functions | Public Attributes | Static Public Attributes | Private Member Functions | Friends | List of all members
flow::net_flow::Ack_packet Struct Reference

Internal net_flow struct that encapsulates the Flow-protocol low-level ACK packet. More...

#include <low_lvl_packet.hpp>

Inheritance diagram for flow::net_flow::Ack_packet:
[legend]
Collaboration diagram for flow::net_flow::Ack_packet:
[legend]

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_contextoperator= (const Log_context &src)
 Assignment operator that behaves similarly to the copy constructor. More...
 
Log_contextoperator= (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...
 
Loggerget_logger () const
 Returns the stored Logger pointer, particularly as many FLOW_LOG_*() macros expect. More...
 
const Componentget_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_offm_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_onm_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_packetLow_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...
 

Detailed Description

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.

Todo:
Conceivably, since Ack_packet actually stores 1+ acknowledgments, it should become Acks_packet, of type ACKS (not ACK). Many comments and log messages would become clearer, as no one would assume an individual packet's acknowledgment when reading "an ACK" or similar phrase.

Definition at line 1019 of file low_lvl_packet.hpp.

Member Typedef Documentation

◆ ack_delay_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.

Todo:
Reconsider the encoding width. If 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

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.

Constructor & Destructor Documentation

◆ Ack_packet()

flow::net_flow::Ack_packet::Ack_packet ( log::Logger logger_ptr)
explicitprivate

The implementation of Low_lvl_packet::create_uninit_packet() for this sub-type of Low_lvl_packet.

Parameters
logger_ptrLogger to use subsequently.

Definition at line 96 of file low_lvl_packet.cpp.

Member Function Documentation

◆ deserialize_type_specific_data_from_raw_data_packet()

bool flow::net_flow::Ack_packet::deserialize_type_specific_data_from_raw_data_packet ( Const_buffer raw_buf,
bool  prefer_no_move,
util::Blob raw_packet 
)
overrideprivatevirtual

◆ serialize_to_raw_data()

size_t flow::net_flow::Ack_packet::serialize_to_raw_data ( Const_buffer_sequence raw_bufs) const
overridevirtual

Implements Low_lvl_packet API.

See that super-method's doc header.

Parameters
raw_bufsSee Low_lvl_packet::serialize_to_raw_data().
Returns
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.

◆ to_ostream()

std::ostream & flow::net_flow::Ack_packet::to_ostream ( std::ostream &  os,
bool  verbose 
) const
overrideprivatevirtual

Implements Low_lvl_packet API.

See that super-method's doc header.

Parameters
osSee Low_lvl_packet::to_ostream().
verboseSee Low_lvl_packet::to_ostream().
Returns
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().

Here is the call graph for this function:

Member Data Documentation

◆ m_rcv_acked_packets

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_acks 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 structs (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().

◆ m_rcv_acked_packets_rexmit_off_out

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.

◆ m_rcv_acked_packets_rexmit_on_out

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.

◆ m_rcv_acked_packets_rexmit_out_size

uint16_t flow::net_flow::Ack_packet::m_rcv_acked_packets_rexmit_out_size
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().

◆ m_rcv_wnd

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().

◆ S_RAW_TYPE_ID

const uint8_t flow::net_flow::Ack_packet::S_RAW_TYPE_ID
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.


The documentation for this struct was generated from the following files: