21#include <boost/array.hpp> 
   31  m_total_data_count(0),
 
   34  m_good_data_accepted_size(0),
 
   35  m_good_data_accepted_count(0),
 
   36  m_good_data_delivered_size(0),
 
   37  m_good_data_delivered_count(0),
 
   38  m_good_data_first_qd_size(0),
 
   39  m_good_data_first_qd_count(0),
 
   40  m_good_data_dropped_buf_overflow_size(0),
 
   41  m_good_data_dropped_buf_overflow_count(0),
 
   42  m_good_data_dropped_reassembly_q_overflow_size(0),
 
   43  m_good_data_dropped_reassembly_q_overflow_count(0),
 
   45  m_error_data_count(0),
 
   46  m_late_or_dupe_data_size(0),
 
   47  m_late_or_dupe_data_count(0),
 
   48  m_presumed_dropped_data_size(0),
 
   49  m_total_to_send_acks_data_size(0),
 
   50  m_total_to_send_acks_count(0),
 
   51  m_good_to_send_acks_data_size(0),
 
   52  m_good_to_send_acks_count(0),
 
   53  m_late_or_dupe_to_send_acks_data_size(0),
 
   54  m_late_or_dupe_to_send_acks_count(0),
 
   55  m_current_pending_acks_count(0),
 
   56  m_delayed_acks_count(0),
 
   57  m_sent_individual_acks_count(0),
 
   58  m_sent_low_lvl_acks_count(0),
 
   59  m_rcv_wnd_recovery_count(0),
 
   60  m_rcv_wnd_recovery_success_count(0),
 
   61  m_rcv_wnd_recovery_timeout_count(0),
 
   62  m_sent_low_lvl_rcv_wnd_only_acks_count(0),
 
   63  m_max_buf_data_size(0)
 
   70  using boost::chrono::duration;
 
   71  using boost::chrono::duration_cast;
 
   72  using boost::chrono::seconds;
 
   73  using Float_seconds = duration<double, seconds::period>;
 
   76  const Float_seconds lifetime = duration_cast<Float_seconds>(Fine_clock::now() - 
m_init_time);
 
   91    << 
"[rcv] format of sizes: [bytes|packets]\n" 
   92       "[rcv] socket_lifetime [" << lifetime << 
"]\n" 
   93       "[rcv] lifetime_goodput_delivered [" 
  123       "[rcv]   observed_net_drop_rate = presumed_dropped / (presumed_dropped + good) = [" << drop_pct << 
"%]\n" 
  152    << 
"[rcv] low_lvl_packets (AFTER simulation): ";
 
  168  m_sent_data_count(0),
 
  169  m_sent_rexmitted_data_size(0),
 
  170  m_sent_rexmitted_data_count(0),
 
  171  m_received_low_lvl_ack_count(0),
 
  172  m_received_low_lvl_rcv_wnd_only_ack_count(0),
 
  173  m_received_ack_count(0),
 
  174  m_rcv_wnd_exhausted(false),
 
  175  m_remote_rcv_wnd_exhaustion_events(0),
 
  176  m_remote_rcv_wnd_recovery_events(0),
 
  177  m_good_ack_data_size(0),
 
  179  m_late_or_dupe_ack_count(0),
 
  180  m_error_acks_data_count(0),
 
  181  m_dropped_data_size(0),
 
  182  m_dropped_data_count(0),
 
  186  m_max_buf_data_size(0)
 
  193  using boost::chrono::duration;
 
  194  using boost::chrono::duration_cast;
 
  195  using boost::chrono::seconds;
 
  197  using std::type_index;
 
  199  using Float_seconds = duration<double, seconds::period>;
 
  202  const Float_seconds lifetime = duration_cast<Float_seconds>(Fine_clock::now() - 
m_init_time);
 
  209  const double drop_pct
 
  215  const double rexmit_pct
 
  221    << 
"[snd] format of sizes: [bytes|packets]\n" 
  223       "[snd] socket_lifetime [" << lifetime << 
"]\n" 
  225       "[snd] lifetime_data_sent " 
  226       "[" << util::to_mbit_per_sec<Float_seconds>(
double(
m_sent_data_size) / lifetime.count()) << 
" Mbit/s]\n" 
  233       "[snd]     observed_net_drop_rate = dropped / (acked + dropped) = [" << drop_pct << 
"%]\n" 
  242       "[snd]     rexmit_rate = rexmitted / sent = [" << rexmit_pct << 
"%]\n" 
  267       "[snd] low_lvl_packet_send_requested ";
 
  270                                             static_cast<const map<type_index, uint64_t>*
>(0));
 
  274       "[snd]   send_called ";
 
  281       "[snd]     send_completed ";
 
  296  m_low_lvl_max_buf_size(0),
 
  297  m_is_active_connect(false),
 
  300  m_rcv_wnd_last_advertised(0),
 
  301  m_rcv_reassembly_q_data_size(0),
 
  302  m_rcv_packets_with_gaps(0),
 
  303  m_rcv_syn_rcvd_data_cumulative_size(0),
 
  304  m_rcv_syn_rcvd_data_q_size(0),
 
  307  m_snd_cong_ctl_wnd_bytes(0),
 
  308  m_snd_cong_ctl_wnd_count_approx(0),
 
  309  m_snd_cong_ctl_in_flight_bytes(0),
 
  310  m_snd_cong_ctl_in_flight_count(0),
 
  311  m_snd_smoothed_round_trip_time(0),
 
  312  m_snd_round_trip_time_variance(0),
 
  313  m_snd_drop_timeout(0),
 
  314  m_snd_pacing_packet_q_size(0),
 
  315  m_snd_pacing_slice_period(0),
 
  316  m_snd_pacing_bytes_allowed_this_slice(0),
 
  317  m_snd_est_bandwidth_mbit_per_sec(0)
 
  324  using boost::chrono::milliseconds;
 
  325  using boost::chrono::round;
 
  333    "--- Basic socket state ---\n" 
  338    "--- Buffers/queues/lists ----\n" 
  339    "Receive window (free space): [" << 
m_rcv_wnd << 
"]\n" 
  350    *os << 
"  ^-- CAUTION!  No space in [advertised] Receive buffer + reassembly queue!  " 
  351           "Peer may think they cannot send to us!\n";
 
  356    "DATA packets in SYN_RCVD queue: " 
  359    "--- Peer's buffers ---\n" 
  360    "Receive window (free Receive buffer + reassembly queue space): [" << 
m_snd_rcv_wnd << 
"].\n";
 
  365    *os << 
"^-- CAUTION!  No space in peer Receive buffer + reassembly queue!  " 
  366           "Is that true, or did we never receive an update from peer?\n";
 
  371    "--- Traffic stats (outgoing) ---\n" << 
m_snd << 
"\n" 
  372    "--- Traffic stats (incoming) ---\n" << 
m_rcv << 
"\n" 
  374    "--- Congestion control status ---\n" 
  381    "--- RTT/DTO data ---\n" 
  382    "Smoothed RTT: [" << round<milliseconds>(srtt) << 
" = " << srtt << 
"].\n" 
  383    "RTT variance: [" << round<milliseconds>(rtt_var) << 
" = " << rtt_var << 
"].\n" 
  384    "Drop Timeout: [" << round<milliseconds>(dto) << 
" = " << dto << 
"].\n" 
  386    "--- Send pacing status ---\n" 
  391    "currently in slice? = " 
  397    "--- Send bandwidth data ---\n" 
  398    "Estimated outgoing available bandwidth for socket: " 
  403    "--- Other info ---\n" 
  407template<
typename Key, 
typename Value>
 
  409                                                const std::map<Key, Value>& count_by_type,
 
  410                                                const std::map<Key, Value>* size_by_type) 
 
  416  for (
const auto& type_id_and_count : count_by_type)
 
  419    const Key& type_id = type_id_and_count.first;
 
  420    const Value& value = type_id_and_count.second;
 
  442    if (idx != count_by_type.size() - 1)
 
  458                                              const boost::array<uint64_t, 2>& value_by_delay_type) 
 
  460  const auto& value_no_delay = value_by_delay_type[0];
 
  461  const auto& value_paced = value_by_delay_type[1];
 
  462  const char* 
const NO_DELAY = 
"NO_DELAY";
 
  463  const char* 
const PACED = 
"PACED";
 
  465  if ((value_no_delay == 0) && (value_paced == 0))
 
  469  else if (value_no_delay == 0)
 
  471    *os << 
'[' << PACED << 
':' << value_paced << 
']';
 
  473  else if (value_paced == 0)
 
  475    *os << 
'[' << NO_DELAY << 
':' << value_no_delay << 
']';
 
  479    *os << 
'[' << NO_DELAY << 
':' << value_no_delay << 
' ' << PACED << 
':' << value_paced << 
']';
 
  484                                              const std::map<Xfer_op_result, uint64_t>& value_by_op_result) 
 
  487  output_map_of_pkt_counts<Xfer_op_result, uint64_t>(os, value_by_op_result, 0);
 
  497  const auto result_to_str = [&]() -> 
const char*
 
  505    assert(
false && 
"Should be unreachable; compiler should warn if incomplete switch.");
 
  509  *os << result_to_str();
 
A data store that keeps stats about the outgoing direction of a Peer_socket connection to another Flo...
uint64_t m_sent_rexmitted_data_count
Of m_sent_data_count, the data that were retransmitted (as opposed to original) data.
Fine_time_pt m_init_time
The time this object was created; should be about equal to when the socket was created.
uint64_t m_remote_rcv_wnd_recovery_events
Number of times m_rcv_wnd_exhausted changed from true (not counting it being initially set to false).
uint64_t m_sent_rexmitted_data_size
Of m_sent_data_size, the data that were retransmitted (as opposed to original) data.
Peer_socket_send_stats()
Constructs object by initializing stats to their initial values.
uint64_t m_received_ack_count
Individual acknowledgments inside low-level ACK packets that have been received (not necessarily all ...
size_t m_max_buf_data_size
Maximum number of bytes in the Send buffer so far.
uint64_t m_late_or_dupe_ack_count
Of m_received_ack_count, those packets that had either already been convered from In-flight to Acknow...
uint64_t m_drop_timeouts
Number of times Drop Timer has fired so far.
std::map< std::type_index, boost::array< uint64_t, 2 > > m_low_lvl_packet_xfer_called_size_by_type
Total size in serialized form of low-level packets that were given to OS in a send call,...
uint64_t m_idle_timeouts
Number of idle timeouts (in the send direction) so far that have been detected and indicated to conge...
uint64_t m_loss_events
Number of loss events so far (not counting Drop Timeouts) that have been reported to congestion contr...
uint64_t m_sent_data_size
Total bytes sent in DATA packets.
uint64_t m_sent_data_count
Number of packets sent in DATA packets.
std::map< std::type_index, std::map< Xfer_op_result, uint64_t > > m_low_lvl_packet_xfer_completed_count_by_type_and_result
Of m_low_lvl_packet_xfer_called_count_by_type, the data for which the send completion handler execute...
uint64_t m_good_ack_count
Of m_received_ack_count, those packets that were properly acknowledged and converted from In-flight t...
void output(std::ostream *os) const
Outputs the current stats, across multiple lines but not ending with a newline, into the given output...
uint64_t m_dropped_data_size
Total bytes in sent DATA packets that are considered permanently dropped (i.e., whose status has chan...
uint64_t m_error_acks_data_count
Of m_received_ack_count, those acknowledgments that contained some error about the sequence numbers s...
std::map< std::type_index, uint64_t > m_low_lvl_packet_xfer_requested_count_by_type
Total count of low-level packets that were given to the sending module to be sent,...
uint64_t m_dropped_data_count
Number of sent DATA packets that are considered permanently dropped (i.e., whose status has changed f...
uint64_t m_received_low_lvl_rcv_wnd_only_ack_count
Of m_received_low_lvl_ack_count, the packets that contained no individual acknowledgments but sent on...
uint64_t m_good_ack_data_size
Of the individual acknowledgments covered by m_received_ack_count, the total bytes in the DATA packet...
uint64_t m_received_low_lvl_ack_count
Number of low-level ACK packets received.
std::map< std::type_index, boost::array< uint64_t, 2 > > m_low_lvl_packet_xfer_called_count_by_type
Count of low-level packets that were given to OS in a send call, from this socket,...
std::map< std::type_index, std::map< Xfer_op_result, uint64_t > > m_low_lvl_packet_xfer_completed_size_by_type_and_result
Of m_low_lvl_packet_xfer_called_size_by_type, the data for which the send completion handler executed...
uint64_t m_remote_rcv_wnd_exhaustion_events
Number of times m_rcv_wnd_exhausted changed from false.
Flow module containing the API and implementation of the Flow network protocol, a TCP-inspired stream...
Xfer_op_result
Result of a send or receive operation, used at least in stat reporting.
@ S_FULLY_XFERRED
Bytes transferred equals bytes expected.
@ S_PARTIALLY_XFERRED
Bytes transferred less than bytes expected.
@ S_ERROR
Error occurred – probably no bytes transferred.
std::ostream & operator<<(std::ostream &os, const Congestion_control_selector::Strategy_choice &strategy_choice)
Serializes a Peer_socket_options::Congestion_control_strategy_choice enum to a standard ostream – the...
bool in_closed_range(T const &min_val, T const &val, T const &max_val)
Returns true if and only if the given value is within the given range, inclusive.
boost::chrono::high_resolution_clock Fine_clock
Clock used for delicate time measurements, such that the now() method gets the current time relative ...
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(ty...
A data store that keeps stats about the a Peer_socket connection.
Peer_socket_send_stats m_snd
Stats for outgoing direction of traffic. As opposed to the other m_snd_* members, this typically accu...
Node_options m_node_opts
Per-node options currently set on the socket's Node.
size_t m_low_lvl_max_buf_size
The UDP receive buffer maximum size, as reported by an appropriate call to the appropriate getsockopt...
static void output_map_of_pkt_counts(std::ostream *os, const std::map< Key, Value > &count_by_type, const std::map< Key, Value > *size_by_type)
Helper for various output() methods that outputs a one-line representation of a sorted map,...
size_t m_rcv_buf_size
The number of bytes in the internal Receive buffer.
size_t m_rcv_wnd_last_advertised
The last rcv_wnd (receive window) size sent to sender (not necessarily received; packets can be lost)...
Peer_socket_info()
Constructs object by initializing stats to their initial values.
Fine_duration m_snd_pacing_slice_period
In pacing, the duration of the current pacing time slice.
size_t m_rcv_reassembly_q_data_size
If rexmit_on is false then 0; otherwise the total DATA payload in the reassembly queue of the socket.
size_t m_snd_pacing_bytes_allowed_this_slice
This many bytes worth of DATA packets may still be sent, at this time, within the time slice defined ...
Peer_socket_options m_sock_opts
Per-socket options currently set on the socket.
size_t m_snd_buf_size
The number of bytes in the internal Send buffer.
size_t m_rcv_syn_rcvd_data_cumulative_size
Total size of DATA payload queued while waiting for SYN_ACK_ACK in SYN_RCVD state.
size_t m_rcv_syn_rcvd_data_q_size
Number of DATA packets queued while waiting for SYN_ACK_ACK in SYN_RCVD state.
std::string m_int_state_str
The internal state of the socket, rendered into string (e.g., "SYN_RECEIVED" or "ESTABLISHED").
Fine_time_pt m_snd_pacing_slice_start
In pacing, the time point marking the beginning of the current pacing time slice.
size_t m_snd_cong_ctl_in_flight_count
In congestion control, the current sent data packets that have been neither acknowledged nor consider...
size_t m_snd_cong_ctl_in_flight_bytes
In congestion control, the current sent data bytes that have been neither acknowledged nor considered...
double m_snd_est_bandwidth_mbit_per_sec
Estimate of the currently available (to this connection) outgoing bandwidth, in megabits per second.
size_t m_rcv_wnd
Receive window size = max Receive buffer space minus space taken. Infinity if flow control disabled.
size_t m_rcv_packets_with_gaps
Number of DATA packets tracked in structure tracking all valid received packets such at least one pac...
size_t m_snd_cong_ctl_wnd_bytes
In congestion control, the current congestion window (number of outgoing data bytes allowed In-flight...
Fine_duration m_snd_smoothed_round_trip_time
Estimated current round trip time of packets, computed as a smooth value over the past individual RTT...
size_t m_snd_cong_ctl_wnd_count_approx
In congestion control, the approximate equivalent of m_snd_cong_ctl_in_flight_bytes as a full packet ...
size_t m_snd_rcv_wnd
The receive window (rcv_wnd a/k/a free Receive buffer space) value of the peer socket on the other si...
static void output_pkt_count_value(std::ostream *os, uint64_t value)
Helper for output_map_of_pkt_counts() that outputs a count or size.
bool m_is_active_connect
true if this is the "client" socket (connect()ed); false otherwise (accept()ed).
size_t m_snd_pacing_packet_q_size
In pacing, number of packets currently queued to be sent out by the pacing module.
static void output_pkt_count_key(std::ostream *os, const std::type_index &type_id)
Helper for output_map_of_pkt_counts() that outputs a raw packet type ID index, namely type_index(type...
void output(std::ostream *os) const
Outputs the current stats, across multiple lines but not ending with a newline, into the given output...
Fine_duration m_snd_round_trip_time_variance
RTTVAR used for m_snd_smoothed_round_trip_time calculation; it is the current RTT variance.
flow::Fine_duration Fine_duration
Short-hand for a fine boost.chrono time duration type.
Peer_socket_receive_stats m_rcv
Stats for incoming direction of traffic. As opposed to the other m_rcv_* members, this typically accu...
Fine_duration m_snd_drop_timeout
Drop Timeout: how long a given packet must remain unacknowledged to be considered dropped due to Drop...
bool m_st_rexmit_on
Whether to enable reliability via retransmission.
A data store that keeps stats about the incoming direction of a Peer_socket connection to another Flo...
uint64_t m_good_data_delivered_size
Of m_good_data_accepted_size, the data that were delivered into Receive buffer (either immediately up...
uint64_t m_rcv_wnd_recovery_success_count
Of m_rcv_wnd_recovery_count, the number of times the recovery was successful: i.e....
uint64_t m_total_data_size
Bytes in DATA packets received on socket.
void output(std::ostream *os) const
Outputs the current stats, across multiple lines but not ending with a newline, into the given output...
uint64_t m_good_to_send_acks_data_size
Of m_total_to_send_acks_data_size, the data that also satisfy the criteria in m_good_data_delivered_s...
uint64_t m_good_data_accepted_size
Of m_good_data_size, the data that were not dropped (so either delivered into Receive buffer or queue...
uint64_t m_late_or_dupe_data_size
Of m_total_data_size, the data that had either already been received before or (more likely) had been...
uint64_t m_rcv_wnd_recovery_timeout_count
Of m_rcv_wnd_recovery_count, the number of times the recovery failed: i.e., resulted in a certain len...
uint64_t m_delayed_acks_count
The total number of individual packet acknowledgments whose sending was delayed (via delayed ACK mech...
uint64_t m_good_to_send_acks_count
Of m_total_to_send_acks_count, the data that also satisfy the criteria in m_good_data_delivered_count...
uint64_t m_total_to_send_acks_count
Number of DATA packets acknowledged thus far or that have been received and are pending to be acknowl...
uint64_t m_total_to_send_acks_data_size
Bytes in received DATA packets acknowledged thus far or that have been received and are pending to be...
uint64_t m_good_data_size
Of m_total_data_size, the data that were new and acceptable into Receive buffer assuming there was sp...
uint64_t m_late_or_dupe_data_count
Of m_total_data_count, the data that had either already been received before or (more likely) had bee...
uint64_t m_sent_individual_acks_count
Number of DATA packets such that for a given packet an individual acknowledgment has been packaged in...
size_t m_max_buf_data_size
Maximum number of bytes in the Receive buffer so far.
uint64_t m_sent_low_lvl_acks_count
Number of low-level ACK packets that have been sent or will be sent as soon as possible.
uint64_t m_good_data_delivered_count
Of m_good_data_accepted_count, the data that were delivered into Receive buffer (either immediately u...
std::map< std::type_index, uint64_t > m_low_lvl_packet_count_by_type
Count of low-level packets received targeted at this socket, split up by packet type similarly to m_l...
uint64_t m_late_or_dupe_to_send_acks_data_size
Of m_total_to_send_acks_data_size, the data that also satisfy the criteria in m_late_or_dupe_data_siz...
uint64_t m_total_data_count
Number of DATA packets received on socket.
uint64_t m_good_data_count
Of m_total_data_count, the data that were new and acceptable into Receive buffer assuming there was s...
size_t m_current_pending_acks_count
Of m_total_to_send_acks_count, the packets that have not yet been sent to the sender (pending acknowl...
uint64_t m_sent_low_lvl_rcv_wnd_only_acks_count
Of m_sent_low_lvl_acks_count, the packets that contained no individual acknowledgments but are to be ...
uint64_t m_good_data_first_qd_size
Of m_good_data_accepted_size, the data that were, upon receipt, queued for reassembly (not immediatel...
uint64_t m_error_data_size
Of m_total_data_size, the data that contained some error about the sequence numbers so that they were...
uint64_t m_good_data_dropped_buf_overflow_size
Of m_good_data_size, the data that were dropped due to insufficient Receive buffer space.
Peer_socket_receive_stats()
Constructs object by initializing stats to their initial values.
uint64_t m_presumed_dropped_data_size
Total number of bytes in hypothetical data packets that have been considered Dropped due to the numbe...
uint64_t m_late_or_dupe_to_send_acks_count
Of m_total_to_send_acks_count, the data that also satisfy the criteria in m_late_or_dupe_data_count.
Fine_time_pt m_init_time
The time this object (or source object from assignment) was made; should be about equal to when socke...
uint64_t m_good_data_accepted_count
Of m_good_data_count, the data that were not dropped (so either delivered into Receive buffer or queu...
uint64_t m_good_data_dropped_reassembly_q_overflow_size
Of m_good_data_size, the data that were dropped due to insufficient Receive reassembly queue space (o...
uint64_t m_error_data_count
Of m_total_data_count, the data that contained some error about the sequence numbers so that they wer...
uint64_t m_rcv_wnd_recovery_count
Number of times we detected (heuristically but fairly reliably) that the following event occurred: ou...
uint64_t m_good_data_dropped_reassembly_q_overflow_count
Of m_good_data_count, the data that were dropped due to insufficient Receive reassembly queue space (...
uint64_t m_good_data_first_qd_count
Of m_good_data_accepted_count, the data that were, upon receipt, queued for reassembly (not immediate...
uint64_t m_good_data_dropped_buf_overflow_count
Of m_good_data_count, the data that were dropped due to insufficient Receive buffer space.
std::map< std::type_index, uint64_t > m_low_lvl_packet_size_by_type
Total size in serialized form of low-level packets received targeted at this socket,...