Graph file: plot_acksize.py
From all our results, this one does not rely on the statistic files discussed in other results.
Rather, it relies on two pickled dictionaries in acksize
and acksize_tcp
folders, obtained during the preprocessing of the trace.
The plot shows a weighted CDF over the ACKed bytes, and the code below shows how it is generated.
sums_acks = {MPTCP: {}, TCP: {}}
multiflow_conn = set()
# First manage the TCP ACKS
for fname, acks_fname in acks[TCP].iteritems():
for conn_id, acks_conn in acks_fname[co.S2C].iteritems():
# Only take connections with ACKs on at least 2 subflows
if len(acks_conn) >= 2:
multiflow_conn.add((fname, conn_id))
for flow_id, acks_flow in acks_conn.iteritems():
for value_ack, nb_ack in acks_flow.iteritems():
# Manage the case where this is the first ack of this size seen
if value_ack not in sums_acks[TCP]:
sums_acks[TCP][value_ack] = nb_ack
else:
sums_acks[TCP][value_ack] += nb_ack
# Then the MPTCP ones
for fname, acks_fname in acks[MPTCP].iteritems():
for conn_id, acks_conn in acks_fname[co.S2C].iteritems():
# Filter single_flow MPTCP connections
if (fname, conn_id) in multiflow_conn:
for value_ack, nb_ack in acks_conn.iteritems():
if value_ack not in sums_acks[MPTCP]:
sums_acks[MPTCP][value_ack] = nb_ack
else:
sums_acks[MPTCP][value_ack] += nb_ack
# Now generate the plot
to_plot = {MPTCP: [], TCP: []}
for protocol, acks_protocol in sums_acks.iteritems():
total_bytes = 0
for value_ack, nb_ack in sorted(acks_protocol.iteritems()):
total_bytes += value_ack * nb_ack
to_plot[protocol].append([value_ack, total_bytes])
# Then set values between 0 and 1 to have the weighted CDF
for i in range(0, len(to_plot[protoco])):
to_plot[protocol][i][1] = (to_plot[protocol][i][1] + 0.0) / total_bytes
# Then plot to_plot
The MPTCP ACK sizes are extracted with mptcptrace, and the TCP ACK sizes are extracted by a traversal of the trace with dpkt. For more information about the TCP ACK size extraction, see the tcp.py file, and in particular the compute_tcp_acks_retrans()
method.