Quic fsm
include quic_types
include quic_frame
Since we want to represent the receiving FSM of the tested implementation, we will use these relations when WE sent frame infering the state of the opponant. We assume perfect reliability of the medium. However a more correct way would be to represent state when, we receive ACK for the corresponding frame but this would introduce some delay between the real current state of receiver and the represented one.
- For each stream id S,
receiving_recv(S)indicates that a STREAM frame, either a STREAM_DATA_BLOCKED or that a bidirectional stream is send by the sender to the receiver. => We can check when we send these frame
relation receiving_recv(S:stream_id)
receiving_sizeKnown(S) indicates that
the stream transmitted to receiver on stream id S is finished (that is, a
FIN frame has been sent). (+-stream_finished)
=> We can check that when we send STREAM+FIN
relation receiving_sizeKnown(S:stream_id)
receiving_dataRecvd(S) indicates that
the stream id S is finished and that all the data has been received
=> We can test by checking all ACK received meaning that receiver receive data
relation receiving_dataRecvd(S:stream_id)
receiving_dataRead(S) indicates that
the stream transmitted to receiver on stream id S is read (that is, a
RESET_STREAM frame has been sent).
=> We cannot test if the application has read all the data
relation receiving_dataRead(S:stream_id)
receiving_resetRecvd(S) indicates that
the stream transmitted to receiver on stream id S is reset (that is, a
RESET_STREAM frame has been sent). (+-stream_reset)
=> We assume that when we sent the RESET_STREAM
relation receiving_resetRecvd(S:stream_id)
receiving_resetRead(S) indicates that
the reset stream transmitted to receiver on stream id S is read (that is, a
RESET_STREAM frame has been sent). (+-stream_reset)
=> We cannot check (maybe check if stream is reset)
relation receiving_resetRead(S:stream_id)
instance idx_r : unbounded_sequence
instance arr_streamid_r : array(idx_r,stream_id)
function lastest_stream_id_receiving(P:pkt_num) : this.arr_streamid_r
instance jdx_r : unbounded_sequence
instance arr_pkt_num_r : array(jdx_r,pkt_num)
function lastest_pkt_num_receiving : this.arr_pkt_num_r
Initial stateยค
after init {
receiving_recv(S) := false;
receiving_sizeKnown(S) := false;
receiving_dataRecvd(S) := false;
receiving_dataRead(S) := false;
receiving_resetRecvd(S):= false;
receiving_resetRead(S) := false;
}
action handle_receiving_recv(id:stream_id,seq:pkt_num) = {
if ~stream_frame_restransmitted(id) & ~sdb_frame_restransmitted(id) {
receiving_recv(id) := true;
};
lastest_stream_id_receiving(seq) := lastest_stream_id_receiving(seq).append(id);
lastest_pkt_num_receiving := lastest_pkt_num_receiving.append(seq);
}
action handle_receiving_sizeKnown(id:stream_id,seq:pkt_num) = {
if ~stream_frame_restransmitted(id) {
receiving_recv(id) := false;
receiving_sizeKnown(id) := true;
};
lastest_stream_id_receiving(seq) := lastest_stream_id_receiving(seq).append(id);
lastest_pkt_num_receiving := lastest_pkt_num_receiving.append(seq);
}
action handle_receiving_dataRecvd(id:stream_id) = {
receiving_sizeKnown(id) := false;
receiving_resetRecvd(id):= false;
receiving_dataRecvd(id) := true;
}
action handle_receiving_dataRead(id:stream_id) = {
receiving_dataRecvd(id) := false;
receiving_dataRead(id) := true;
}
action handle_receiving_resetRecvd(id:stream_id,seq:pkt_num) = {
if ~reset_frame_restransmitted(id) {
receiving_recv(id) := false;
receiving_sizeKnown(id) := false;
receiving_dataRecvd(id) := false;
receiving_resetRecvd(id):= true;
};
lastest_stream_id_receiving(seq) := lastest_stream_id_receiving(seq).append(id);
lastest_pkt_num_receiving := lastest_pkt_num_receiving.append(seq);
}
action handle_receiving_resetRead(id:stream_id) = {
receiving_resetRecvd(id) := false;
receiving_resetRead(id) := true;
}
largest ack
action handle_receiving_ack(largest_acked:pkt_num) = {
var jdx_r : jdx_r := 0;
while jdx_r < lastest_pkt_num_receiving.end {
var seq := lastest_pkt_num_receiving.value(jdx_r);
var idx_r : idx_r := 0;
while seq <= largest_acked & idx_r < lastest_stream_id_receiving(seq).end {
var sid := lastest_stream_id_receiving(seq).value(idx_r);
if receiving_resetRecvd(sid) {
call handle_receiving_resetRead(sid);
} else if receiving_sizeKnown(sid) {
call handle_receiving_dataRecvd(sid);
};
idx_r := idx_r.next;
};
jdx_r := jdx_r.next;
};
}
import action show_receiving_fsm_event(receiving_recv:bool,receiving_sizeKnown:bool,
receiving_dataRecvd:bool,receiving_dataRead:bool,
receiving_resetRecvd:bool,receiving_resetRead:bool)
import action show_fsm_receiving_recv_event
import action show_fsm_receiving_sizeKnown_event
import action show_fsm_receiving_dataRecvd_event
import action show_fsm_receiving_dataRead_event
import action show_fsm_receiving_resetRecvd_event
import action show_fsm_receiving_resetRead_event
import action show_fsm_receiving_ack_event