rlc_am_lte: add further sanity check when creating status PDU

the test verifies that the ACK_SN of a status PDU falls inside the
rx_window of the receiver. If not, than the RLC state has been
corrupted and the status PDU is likely invalid.
master
Andre Puschmann 4 years ago
parent 46265c5829
commit 878142843e

@ -574,7 +574,7 @@ int rlc_am_write_status_pdu(rlc_status_pdu_t* status, uint8_t* payload);
uint32_t rlc_am_packed_length(rlc_amd_pdu_header_t* header); uint32_t rlc_am_packed_length(rlc_amd_pdu_header_t* header);
uint32_t rlc_am_packed_length(rlc_status_pdu_t* status); uint32_t rlc_am_packed_length(rlc_status_pdu_t* status);
uint32_t rlc_am_packed_length(rlc_amd_retx_t retx); uint32_t rlc_am_packed_length(rlc_amd_retx_t retx);
bool rlc_am_is_valid_status_pdu(const rlc_status_pdu_t& status); bool rlc_am_is_valid_status_pdu(const rlc_status_pdu_t& status, uint32_t rx_win_min = 0);
bool rlc_am_is_pdu_segment(uint8_t* payload); bool rlc_am_is_pdu_segment(uint8_t* payload);
std::string rlc_am_undelivered_sdu_info_to_string(const std::map<uint32_t, pdcp_pdu_info>& info_queue); std::string rlc_am_undelivered_sdu_info_to_string(const std::map<uint32_t, pdcp_pdu_info>& info_queue);
void log_rlc_amd_pdu_header_to_string(srslog::log_channel& log_ch, const rlc_amd_pdu_header_t& header); void log_rlc_amd_pdu_header_to_string(srslog::log_channel& log_ch, const rlc_amd_pdu_header_t& header);

@ -1924,9 +1924,9 @@ int rlc_am_lte::rlc_am_lte_rx::get_status_pdu(rlc_status_pdu_t* status, const ui
logger.debug("Removing last NACK SN=%d", status->nacks[status->N_nack].nack_sn); logger.debug("Removing last NACK SN=%d", status->nacks[status->N_nack].nack_sn);
status->N_nack--; status->N_nack--;
// make sure we don't have the current ACK_SN in the NACK list // make sure we don't have the current ACK_SN in the NACK list
if (rlc_am_is_valid_status_pdu(*status) == false) { if (rlc_am_is_valid_status_pdu(*status, vr_r) == false) {
// No space to send any NACKs, play safe and just ack lower edge // No space to send any NACKs, play safe and just ack lower edge
logger.debug("Resetting ACK_SN and N_nack to initial state"); logger.warning("Resetting ACK_SN and N_nack to initial state");
status->ack_sn = vr_r; status->ack_sn = vr_r;
status->N_nack = 0; status->N_nack = 0;
} }
@ -2396,8 +2396,13 @@ int rlc_am_write_status_pdu(rlc_status_pdu_t* status, uint8_t* payload)
return tmp.N_bits / 8; return tmp.N_bits / 8;
} }
bool rlc_am_is_valid_status_pdu(const rlc_status_pdu_t& status) bool rlc_am_is_valid_status_pdu(const rlc_status_pdu_t& status, uint32_t rx_win_min)
{ {
// check if ACK_SN is inside Rx window
if ((MOD + status.ack_sn - rx_win_min) % MOD > RLC_AM_WINDOW_SIZE) {
return false;
}
for (uint32_t i = 0; i < status.N_nack; ++i) { for (uint32_t i = 0; i < status.N_nack; ++i) {
// NACK can't be larger than ACK // NACK can't be larger than ACK
if ((MOD + status.ack_sn - status.nacks[i].nack_sn) % MOD > RLC_AM_WINDOW_SIZE) { if ((MOD + status.ack_sn - status.nacks[i].nack_sn) % MOD > RLC_AM_WINDOW_SIZE) {

Loading…
Cancel
Save