Skip to content

Commit fdd6f1b

Browse files
committed
support: handle invalid transaction ids instead of asserting
1 parent 08dc31a commit fdd6f1b

File tree

7 files changed

+44
-18
lines changed

7 files changed

+44
-18
lines changed

include/srsran/support/async/protocol_transaction_manager.h

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,8 @@ class protocol_transaction_manager
7474
unsigned transaction_id = next_transaction_id.fetch_add(1, std::memory_order_relaxed) % N;
7575
if (not transactions[transaction_id].is_set()) {
7676
// cancel any existing awaiter.
77-
set(transaction_id, cancel_value);
77+
bool ignore = set(transaction_id, cancel_value);
78+
(void)ignore;
7879
}
7980
transactions[transaction_id].reset();
8081
return {transaction_id, transactions[transaction_id]};
@@ -90,19 +91,26 @@ class protocol_transaction_manager
9091
// Create a new timer if it doesn't exist yet.
9192
running_timers[t.id()] = timer_db.create_unique_timer();
9293
}
93-
running_timers[t.id()].set(time_to_cancel,
94-
[this, transaction_id = t.id()](timer_id_t tid) { set(transaction_id, cancel_value); });
94+
running_timers[t.id()].set(time_to_cancel, [this, transaction_id = t.id()](timer_id_t tid) {
95+
if (not set(transaction_id, cancel_value)) {
96+
srslog::fetch_basic_logger("ALL").warning("Transaction id={} timeout but transaction is already completed",
97+
transaction_id);
98+
}
99+
});
95100
running_timers[t.id()].run();
96101
return t;
97102
}
98103

99104
/// \brief Sets the result of a managed transaction with the provided transaction_id.
100105
template <typename U>
101-
void set(unsigned transaction_id, U&& u)
106+
bool __attribute__((warn_unused_result)) set(unsigned transaction_id, U&& u)
102107
{
108+
if (transactions[transaction_id].is_set()) {
109+
return false;
110+
}
103111
running_timers[transaction_id].stop();
104-
srsran_assert(not transactions[transaction_id].is_set(), "Transaction result cannot be overwritten.");
105112
transactions[transaction_id].set(std::forward<U>(u));
113+
return true;
106114
}
107115

108116
private:

lib/e1ap/cu_cp/e1ap_cu_cp_impl.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,10 @@ void e1ap_cu_cp_impl::handle_successful_outcome(const asn1::e1ap::successful_out
235235
}
236236

237237
// Set transaction result and resume suspended procedure.
238-
ev_mng.transactions.set(transaction_id.value(), outcome);
238+
if (not ev_mng.transactions.set(transaction_id.value(), outcome)) {
239+
logger.warning("Ignoring message. Cause: Transaction with id={} has already completed.",
240+
transaction_id.value());
241+
}
239242
}
240243
}
241244

@@ -259,6 +262,9 @@ void e1ap_cu_cp_impl::handle_unsuccessful_outcome(const asn1::e1ap::unsuccessful
259262
}
260263

261264
// Set transaction result and resume suspended procedure.
262-
ev_mng.transactions.set(transaction_id.value(), outcome);
265+
if (not ev_mng.transactions.set(transaction_id.value(), outcome)) {
266+
logger.warning("Ignoring message. Cause: Transaction with id={} has already completed.",
267+
transaction_id.value());
268+
}
263269
}
264270
}

lib/e2/common/e2_impl.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,9 @@ void e2_impl::handle_successful_outcome(const asn1::e2ap::successful_outcome_s&
9696
return;
9797
}
9898
// Set transaction result and resume suspended procedure.
99-
events->transactions.set(transaction_id.value(), outcome);
99+
if (not events->transactions.set(transaction_id.value(), outcome)) {
100+
logger.warning("Unrecognized transaction id={}", transaction_id.value());
101+
}
100102
} break;
101103
default:
102104
logger.error("Invalid E2AP successful outcome message type");
@@ -115,7 +117,9 @@ void e2_impl::handle_unsuccessful_outcome(const asn1::e2ap::unsuccessful_outcome
115117
return;
116118
}
117119
// Set transaction result and resume suspended procedure.
118-
events->transactions.set(transaction_id.value(), outcome);
120+
if (not events->transactions.set(transaction_id.value(), outcome)) {
121+
logger.warning("Unrecognized transaction id={}", transaction_id.value());
122+
}
119123
} break;
120124
default:
121125
logger.error("Invalid E2AP unsuccessful outcome message type");

lib/f1ap/du/f1ap_du_impl.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -269,19 +269,23 @@ void f1ap_du_impl::handle_successful_outcome(const asn1::f1ap::successful_outcom
269269
}
270270

271271
// Set transaction result and resume suspended procedure.
272-
events->transactions.set(transaction_id.value(), outcome);
272+
if (not events->transactions.set(transaction_id.value(), outcome)) {
273+
logger.warning("Unexpected transaction id={}", transaction_id.value());
274+
}
273275
}
274276

275277
void f1ap_du_impl::handle_unsuccessful_outcome(const asn1::f1ap::unsuccessful_outcome_s& outcome)
276278
{
277279
expected<uint8_t> transaction_id = get_transaction_id(outcome);
278280
if (transaction_id.is_error()) {
279-
logger.error("Successful outcome of type {} is not supported", outcome.value.type().to_string());
281+
logger.error("Unsuccessful outcome of type {} is not supported", outcome.value.type().to_string());
280282
return;
281283
}
282284

283285
// Set transaction result and resume suspended procedure.
284-
events->transactions.set(transaction_id.value(), outcome);
286+
if (not events->transactions.set(transaction_id.value(), outcome)) {
287+
logger.warning("Unexpected transaction id={}", transaction_id.value());
288+
}
285289
}
286290

287291
bool f1ap_du_impl::handle_rx_message_gnb_cu_ue_f1ap_id(f1ap_du_ue& ue, gnb_cu_ue_f1ap_id_t gnb_cu_ue_f1ap_id)

lib/f1ap/du/ue_context/f1c_du_bearer_impl.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,9 @@ void f1c_srb0_du_bearer::handle_sdu(byte_buffer_slice_chain sdu)
5555
f1ap_notifier.on_new_message(msg);
5656

5757
// Signal that the transaction has completed and the DU does not expect a response.
58-
ev_manager.transactions.set(transaction.id(), f1ap_outcome{});
58+
if (not ev_manager.transactions.set(transaction.id(), f1ap_outcome{})) {
59+
logger.warning("Unexpected transaction id={}", transaction.id());
60+
}
5961

6062
log_ue_event(logger,
6163
ue_event_prefix{"UL", ue_ctxt.ue_index}.set_channel("SRB0") | ue_ctxt.rnti,

lib/rrc/ue/rrc_ue_message_handlers.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,9 @@ void rrc_ue_impl::handle_rrc_transaction_complete(const ul_dcch_msg_s& msg, uint
157157
expected<uint8_t> transaction_id = transaction_id_;
158158

159159
// Set transaction result and resume suspended procedure.
160-
event_mng->transactions.set(transaction_id.value(), msg);
160+
if (not event_mng->transactions.set(transaction_id.value(), msg)) {
161+
logger.warning("Unexpected transaction id={}", transaction_id.value());
162+
}
161163
}
162164

163165
void rrc_ue_impl::handle_new_guami(const guami& msg)

tests/unittests/support/protocol_transaction_manager_test.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ TEST_F(protocol_transaction_test, when_transaction_is_set_after_suspend_then_awa
5454

5555
// Test Section.
5656
ASSERT_FALSE(t.ready());
57-
transaction_manager.set(tr.id(), 1);
57+
ASSERT_TRUE(transaction_manager.set(tr.id(), 1));
5858
ASSERT_TRUE(t.ready());
5959
ASSERT_EQ(1, tr.result());
6060
}
@@ -66,7 +66,7 @@ TEST_F(protocol_transaction_test, when_transaction_is_set_before_suspend_then_aw
6666
CORO_BEGIN(ctx);
6767
EXPECT_FALSE(tr.complete());
6868
// transaction set before await.
69-
this->transaction_manager.set(tr.id(), 2);
69+
ASSERT_TRUE(this->transaction_manager.set(tr.id(), 2));
7070
CORO_AWAIT(tr);
7171
EXPECT_TRUE(tr.complete());
7272
CORO_RETURN(tr.result());
@@ -90,9 +90,9 @@ TEST_F(protocol_transaction_test,
9090

9191
// Test Section.
9292
ASSERT_FALSE(t.ready());
93-
transaction_manager.set(tr2.id(), 1);
93+
ASSERT_TRUE(transaction_manager.set(tr2.id(), 1));
9494
ASSERT_FALSE(t.ready());
95-
transaction_manager.set(tr.id(), 2);
95+
ASSERT_TRUE(transaction_manager.set(tr.id(), 2));
9696
ASSERT_TRUE(t.ready());
9797
}
9898

0 commit comments

Comments
 (0)