Graph file: not_initial_subflow_data_handover_cdf.py
Main fields:
conn.flows[*].attr[direction][co.DATA_BYTES] # Number of total bytes seen by tstat
conn.flows[*].attr[co.S2C][co.TIME_LAST_ACK_TCP] # Time of last ACK from smartphone
conn.flows[*].attr[co.S2C][co.TIME_FIN_ACK_TCP] # Time of FIN from smartphone (or 0 if no FIN)
conn.flows[*].attr[direction][co.TIME_LAST_PAYLD_TCP] # Time of the last payload
Formally, a data handover is defined as following.
Let LA_i be the time of the last (non-RST) ACK sent by the smartphone seen on the subflow i (that was used to send data) and LP_j the time of the last (non-retransmitted) segment containing data on subflow j.
If it exist k, l such that k != l, no FIN seen from the smartphone on subflow k, LA_l > LA_k and LP_l > LA_k, then the connection experience handover.
Programmatically, this definition can be translated like this.
# Suppose conns contains connections using at least 2 SFs
for conn_id, conn in conns.iteritems():
handover_detected = False
# Preprocessing
initial_sf_ts = float('inf')
min_last_ack = float('inf')
for flow_id, flow in conn.flows.iteritems():
flow_bytes = 0
for direction in co.DIRECTIONS:
flow_bytes += flow.attr[direction].get[co.BYTES_DATA]
if (flow_bytes > 0 # Flow used
and flow.attr[co.S2C][co.TIME_LAST_ACK_TCP].total_seconds() > 0.0 # ACK from the smartphone
and flow.attr[co.S2C][co.TIME_FIN_ACK_TCP].total_seconds() == 0.0): # No FIN from the smartphone
min_last_ack = min(min_last_ack, flow.attr[co.S2C][co.TIME_LAST_ACK_TCP].total_seconds())
# Handover detection
for flow_id, flow in conn.flows.iteritems():
max_last_payload = 0 - float('inf')
if flow.attr[co.C2S][co.BYTES] > 0 or flow.attr[co.S2C][co.BYTES] > 0: # Flow used
if flow.attr[co.S2C][co.TIME_LAST_ACK_TCP].total_seconds() > min_last_ack: # LA_l > LA_k
max_last_payload = max([flow.attr[direction][co.TIME_LAST_PAYLD_TCP].total_seconds() for direction in co.DIRECTIONS])
handover_delta = max_last_payload - min_last_ack # LP_l - LA_k
if handover_delta > 0.0: # LP_l > LA_k
# A subflow is used after the last ack of the client seen --> Handover
handover_detected = True
Since handover could only happen when at least two subflows are used, the percentage of connections experiencing handover is based on the number of connections using at least two subflows.
The times were computed either by tstat or by our analysis scripts here.
In the graph file, the number of missing ADD_ADDR
s and REMOVE_ADDR
s are also computed.
The collection of ÀDD_ADDR
and REMOVE_ADDR
is made by the analysis script by post-processing the output of mptcptrace in methods process_add_addr_csv
and process_rm_addr_csv
in file mptcp.py
.