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,...