| /////////////////////////////////////////////////////////////////////////////// |
| // Copyright (c) 2000-2018 Ericsson Telecom AB |
| // All rights reserved. This program and the accompanying materials |
| // are made available under the terms of the Eclipse Public License v2.0 |
| // which accompanies this distribution, and is available at |
| // https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html |
| /////////////////////////////////////////////////////////////////////////////// |
| // |
| // File: SCTP_Engine_Definition.ttcn |
| // Description: Component definition of the SCTP Engine |
| // Rev: <RnXnn> |
| // Prodnr: CNL 113 840 |
| // |
| module SCTP_Engine_Definition { |
| |
| import from SCTP_Engine_PortTypes all; |
| import from SCTP_Types all; |
| |
| modulepar SCTP_Proto_params tsp_proto_params:={ rto_initial := 3.0, |
| rto_min := 1.0, |
| rto_max := 60.0, |
| max_burst := 4, |
| rto_alpha := 0.125, |
| rto_beta := 0.25, |
| valid_cookie_life :=60, |
| assoc_max_retrans := 10, |
| path_max_retrans := 5, |
| max_init_retrans := 8, |
| hb_interval := 30.0, |
| hb_max_burst :=1, |
| |
| // MTU discovery parameters |
| pmntu_min := 900, // This value is used to calculate the data chunk size |
| // The maximum data chunk size is |
| // pmntu_min - SCTP_common_header_size |
| // This ensures that the data chunk can be delivered every cases |
| // Normal ethernet frame size - (vpn,DTLS,UDP,IPv4 or IPv6) - something more |
| pmtu_max := 8960, // For Jumbo frames |
| |
| pmtu_initial := 1200 // WebRTC draft |
| |
| } |
| |
| modulepar SCTP_Reconfig_config tsp_reconf_params:={ |
| is_supported := true, |
| stream_reset_allowed:= true, |
| assoc_reset_allowed:= true, |
| stream_add_allowed:= true |
| } |
| |
| modulepar boolean tsp_forward_tsn_supported := true |
| |
| type component SCTP_Engine_CT { |
| // Test ports |
| port SCTP_Engine_API_request_PT p_sctp_req_api // the upper side, SCTP test port |
| port SCTP_Engine_API_indication_PT p_sctp_ind_api // the upper side, SCTP test port |
| port SCTP_Engine_packet_PT p_packet_port // The lower side test port |
| |
| // main database |
| var SCTP_Assoc_DB_t v_assoc_db := c_empty_SCTP_Assoc_DB // The association data base |
| |
| var octetstring v_secret_key := '11223344556677889900'O // the key used to generate MAC of the state cookie |
| |
| |
| // time & event queue handling |
| timer t_run_time // timer used to mesure the time, started once |
| // with a very-very long timeout |
| timer t_next_event // expires on the next scheduled event |
| |
| var SCTP_event_db_t v_event_db:= c_empty_event_db // Event queue database |
| var SCTP_Assoc_data c_empty_SCTP_Assoc_data:={ |
| state := SCTP_ASSOC_CLOSED, |
| transport_id:=-1, |
| local_port:=-1, |
| remote_port:=-1, |
| own_tag:=-1, |
| remote_tag:=-1, |
| cookie_validity:=-1, |
| remote_tsn:=-1, |
| own_tsn:=-1, |
| remote_os:=-1, |
| remote_mis:=-1, |
| remote_a_rwnd:=-1, |
| cookie_lifespan:=-1, |
| state_cookie := ''O, |
| rem_comp := null, |
| i_data_supported := false, |
| proto_params := tsp_proto_params, |
| retransmit_counter:=0, |
| retransmit_timer_event := -1, |
| rto:=tsp_proto_params.rto_initial, |
| srtt:=0.0, |
| rttvar:=0.0, |
| pmtu:=tsp_proto_params.pmtu_initial, |
| tx_msg_queues := {}, |
| tx_stream_idx_map_id := -1, |
| tx_chunk_queue := c_empty_chunk_queue_db, |
| cwnd:=0, |
| flight_size:=0, |
| partially_acked_bytes:=0, |
| ssthresh := 0, |
| scheduled_queue := 0, |
| remote_last_sack_tsn := -1, |
| rx_chunk_queue := c_empty_chunk_queue_db, |
| idx_of_last_acked := -1, |
| rx_msg_queues := {}, |
| rx_stream_idx_map_id := -1, |
| hb_event_id := -1, |
| hb_retrial_counter := 0, |
| data_chunk_max_size := tsp_proto_params.pmntu_min-12, // 12: SCTP common header size. See up |
| reconf_params:=tsp_reconf_params, |
| reconf_own_seq_num:=-1, |
| reconf_remote_seq_num:=-1, |
| reconfig_ongoing := false, |
| forward_tsn_supported:=tsp_forward_tsn_supported, |
| reconfig_event_id := -1, |
| ongoing_incoming_reconf_req_seq := -1, |
| ongoing_outgoing_reconf_req_seq := -1, |
| last_reconf_resp := omit, |
| last_reconf_req := omit, |
| deffered_reset := omit, |
| reconfig_retransmit_counter:=0, |
| close_timer := -1 |
| } |
| } |
| |
| // Type for association data base |
| type record SCTP_Assoc_DB_t{ |
| // the data base realized by the list of the association entries. |
| // Each entries are not removed from the list, but reused if needed. |
| // In order to track the free elements, the free entries forms a linked list |
| // holding the index of the next free entry. |
| // The index of first & last free entries are stored also. |
| |
| |
| integer used_entries, // How many entries are used. |
| integer first_free, // points to the first free |
| integer last_free, // points to the last free |
| |
| SCTP_Assoc_entry_list associations // The list of the entries |
| } |
| // constant used to initialize the v_assoc_db |
| const SCTP_Assoc_DB_t c_empty_SCTP_Assoc_DB:={ |
| used_entries := 0, |
| first_free :=-1, |
| last_free :=-1, |
| associations :={} |
| } |
| |
| type record of SCTP_Assoc_entry SCTP_Assoc_entry_list |
| |
| type record SCTP_Assoc_entry { |
| integer next_free, // points to the next free entry if not used |
| SCTP_Assoc_data assoc_data optional // holds the data of the association |
| // if the entry is not used, the data |
| // is ommited in order to free the |
| // memory |
| } |
| |
| const SCTP_Assoc_entry c_empty_SCTP_Assoc_entry:={ |
| next_free := -1, |
| assoc_data := omit |
| } |
| |
| |
| // The value of the enumeration is ordered, so a range can be specified |
| type enumerated SCTP_Assoc_state { SCTP_ASSOC_LISTEN(0), |
| SCTP_ASSOC_COOKIE_WAIT(1),SCTP_ASSOC_COOKIE_ECHOED(2), |
| SCTP_ASSOC_ESTABLISHED(3), |
| SCTP_ASSOC_SHUTDOWN_PENDING(4), SCTP_ASSOC_SHUTDOWN_RECEIVED(5), |
| SCTP_ASSOC_SHUTDOWN_SENT(6), |
| SCTP_ASSOC_SHUTDOWN_ACK_SENT(7), SCTP_ASSOC_CLOSED(8), |
| SCTP_ASSOC_CLOSE_TIME_WAIT(9) } |
| |
| // holds the data belongs to the association |
| type record SCTP_Assoc_data { |
| SCTP_Assoc_state state, |
| |
| integer transport_id, // The transport id |
| integer local_port, // Local sctp port number |
| integer remote_port, // Remote sctp port number |
| integer own_tag, // Own verification tag, The incoming message should come with this |
| integer remote_tag, // Remotes verification tag, set in the outgoing message |
| integer cookie_validity, // 0 - Cookie ok, 1- Cokkie expired. See the return value of SCTP_check_state_cookie |
| integer remote_tsn, // remote initial tsn, last sent SACK tsn + 1 |
| integer own_tsn, // own next tsn/ initial tsn |
| integer remote_os, // remote outgoing sream number |
| integer remote_mis, // remote's max incoming stream number |
| integer remote_a_rwnd, // remote advertised receive window |
| integer cookie_lifespan, // The lifespan of our state cookie |
| |
| octetstring state_cookie, // the stored received state cookie, used for retransmission |
| |
| SCTP_Engine_CT rem_comp, // The component id of sctp user component |
| |
| boolean i_data_supported, // Support I-DATA chunk |
| |
| SCTP_Proto_params proto_params, // SCTP protocol parameters of the association |
| integer retransmit_counter, // the messages was retransmitted that many time without answer |
| integer retransmit_timer_event, // The event id of the retransmitt timer |
| float rto, // RTO |
| float srtt, // SRTT |
| float rttvar, // RTTVAR see: RFC 4960 6.3. Management of Retransmission Timer |
| |
| integer pmtu, // The Path MTU |
| |
| // Message queues |
| SCTP_msg_queue_list_t tx_msg_queues, // The queues of the TX messages, every stream has an own queue |
| // the Nth queue is the ordered msg queue, that idx is stored in the map below |
| // the N+1 th is for the unordered |
| integer tx_stream_idx_map_id, // The ID of the stream -> queue idx map, tells which stream belongs to which queue |
| |
| SCTP_Chunk_queue_db_t tx_chunk_queue, // the TX DATA chunk queue |
| |
| // Congestion control data see the rfc 4690 |
| integer cwnd, // congestion window |
| integer flight_size, // sent but not acked bytes |
| integer partially_acked_bytes, // partially acknowledged bytes |
| |
| integer ssthresh, // Slow start treshold |
| |
| integer scheduled_queue, // the message from that queue will be sent |
| |
| integer remote_last_sack_tsn, // The latest TSN acked by the remote |
| |
| SCTP_Chunk_queue_db_t rx_chunk_queue, // the RX DATA chunk queue, used for reassembly |
| // How the queue is used: When a data chunk is received, it will be inserted into the queue |
| // If there are missing data chunk, a dummy placeholder is inserted into the queue |
| // The chunk field of the queue element is omited in that case |
| |
| integer idx_of_last_acked, // the index of the last acked chunk in the queue |
| |
| SCTP_msg_queue_list_t rx_msg_queues, // The queues of the RX messages, every stream has an own queue |
| // the Nth queue is the ordered msg queue, that idx is stored in the map below |
| // the N+1 th is for the unordered |
| |
| integer rx_stream_idx_map_id, // The ID of the stream -> rx queue idx map, tells which stream belongs to which queue |
| |
| |
| integer hb_event_id, // The event id of the scheduled heartbeat event |
| integer hb_retrial_counter, // The heatbeat retrial counter |
| integer data_chunk_max_size, // the maximum size of the data chunk |
| |
| SCTP_Reconfig_config reconf_params, // reconfiguration extension RFC6525 |
| integer reconf_own_seq_num, // our next seq number/ initial one |
| integer reconf_remote_seq_num , // our next expected |
| boolean reconfig_ongoing, |
| |
| boolean forward_tsn_supported, // indicates the support of RFC3758 |
| |
| integer reconfig_event_id, |
| integer ongoing_incoming_reconf_req_seq, // store the initiated "incomig type request": Incoming SSN Reset, Add Incoming Streams |
| integer ongoing_outgoing_reconf_req_seq, // store the initiated "outgoing type request": Outgoing SSN Reset, Add Outgoing Streams, SSN/TSN Reset Request |
| SCTP_Re_Config_chunk last_reconf_resp optional, // stores the last reconf response chunk for retransmission |
| SCTP_Re_Config_chunk last_reconf_req optional, // stores the last reconf request chunk for retransmission |
| SCTP_Out_SSN_Reset_req_parameter deffered_reset optional, // stores the reconf request for "deferred reset processing" |
| integer reconfig_retransmit_counter, |
| integer close_timer |
| } |
| |
| |
| // Parameters for reconfiguration extension RFC6525 |
| /*type record SCTP_Reconf_data { |
| boolean is_supported, |
| boolean stream_reset_allowed, |
| boolean assoc_reset_allowed, |
| boolean stream_add_allowed |
| }*/ |
| |
| // The type holds the SCTP Protocol Parameters |
| // See RFC4960 chapter 15 |
| type record SCTP_Proto_params{ |
| float rto_initial, |
| float rto_min, |
| float rto_max, |
| integer max_burst, |
| float rto_alpha, |
| float rto_beta, |
| integer valid_cookie_life, |
| integer assoc_max_retrans, |
| integer path_max_retrans, |
| integer max_init_retrans, |
| float hb_interval, |
| integer hb_max_burst, |
| integer pmntu_min, |
| integer pmtu_max, |
| |
| integer pmtu_initial |
| } |
| |
| |
| // Event handling database |
| // All of the scheduled events are stored in the event DB |
| // One event DB entry stores the <assoc_id, timer_id> |
| // the t_next_event timer is sceduled for the earliest event |
| // in the case of timeout, adding or deleting event, the timer is recalculated |
| // The events are stored in the same way as the assoc DB |
| // The order of the events are stored & maintained in an external ordered std::map |
| type record SCTP_event_db_t{ |
| integer used_entries, // How many entries are used. |
| integer first_free, // points to the first free |
| integer last_free, // points to the last free |
| |
| integer the_sceduled_event, // That event is used to start the t_next_event timer |
| |
| SCTP_event_entry_list events // The list of the events |
| } |
| |
| const SCTP_event_db_t c_empty_event_db:={ |
| used_entries := 0, |
| first_free :=-1, |
| last_free :=-1, |
| the_sceduled_event := -1, |
| events :={} |
| } |
| |
| type record of SCTP_event_entry SCTP_event_entry_list |
| |
| type record SCTP_event_entry { |
| integer next_free, // points to the next free entry if not used |
| integer assoc_id, // the event is scheduled by this assoc |
| integer timer_id, // the id of the assoc timer |
| float timeout_time // The absulute time of the timeout |
| // calculated as 'time_since_start' + 'timeout_val' |
| } |
| |
| const SCTP_event_entry c_empty_event_entry:={ |
| next_free:=-1, |
| assoc_id:=-1, |
| timer_id:=-1, |
| timeout_time:=-1.0 |
| } |
| |
| // Data types for queues |
| |
| // Chunk queue |
| // Simple linked list, with free queue |
| type record SCTP_Chunk_queue_db_t{ |
| integer used_entries, // How many entries are used. |
| integer first_free, // points to the first free |
| integer last_free, // points to the last free |
| integer first_element, // points to the head of the chunk queue |
| integer last_element, // points to the tail of the chunk queue |
| |
| SCTP_Chunk_queue_element_list_t chunk_queue |
| } |
| |
| const SCTP_Chunk_queue_db_t c_empty_chunk_queue_db:={ |
| used_entries := 0, |
| first_free :=-1, |
| last_free :=-1, |
| first_element :=-1, |
| last_element := -1, |
| chunk_queue :={} |
| } |
| |
| type record of SCTP_Chunk_queue_element_t SCTP_Chunk_queue_element_list_t |
| |
| type record SCTP_Chunk_queue_element_t { |
| integer next_element, |
| boolean mark_flag, // used to mark the chunk in the queue: |
| // tx chunk queue: mark for retransmit |
| // rx chunk queue: added to the rx stream queue |
| float lifetime, // Used on sender side, partial reliability feature |
| integer counter, // Used on sender side, partial reliability feature |
| boolean unmark_flag, // tx queues: mark for abandon |
| integer tsn, |
| SCTP_Chunk chunk optional |
| } |
| |
| const SCTP_Chunk_queue_element_t c_empty_Chunk_queue_element:={ |
| next_element := -1, |
| mark_flag := false, |
| lifetime := -1.0, |
| counter := -1, |
| unmark_flag := false, |
| tsn := -1, |
| chunk := omit |
| } |
| |
| // TX message queue types |
| // Every outgoing stream has its own queue |
| |
| // represents one msg queue |
| type record SCTP_msg_queue_t { |
| integer next_ssn, // the next SSN for the stream |
| integer num_of_queued_octets, // The number of the octets of the first message already put into the TX queue |
| boolean flag, |
| SCTP_Chunk_queue_db_t messages // Each message is represented by a DATA chunk |
| } |
| |
| const SCTP_msg_queue_t c_empty_msg_queue:={ |
| next_ssn := 0, |
| num_of_queued_octets := 0, |
| flag:=false, |
| messages := c_empty_chunk_queue_db |
| } |
| |
| type record of SCTP_msg_queue_t SCTP_msg_queue_list_t |
| |
| type record of integer integer_list |
| |
| // Timer constants |
| const integer c_timer_T1 := 0; |
| const integer c_timer_T1_cookie := 1; |
| const integer c_timer_T3_rtx := 2; |
| const integer c_timer_T2_shutdown := 3; |
| const integer c_timer_heartbeat := 4; |
| const integer c_timer_reconfig := 5; |
| const integer c_timer_close := 6; |
| |
| const integer c_min_chunk_size := 24 // The minimum data chunk size we use |
| |
| } |