aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/src/abis_rsl.c
diff options
context:
space:
mode:
authorHarald Welte (local) <laflocal@hanuman.gnumonks.org>2009-12-27 18:12:29 +0100
committerHarald Welte (local) <laflocal@hanuman.gnumonks.org>2009-12-27 18:12:29 +0100
commit1fa3b78f4ae81bba8a750317aa684ddcbddc22cb (patch)
tree62dda9c4cba5496f3290148ed3de12bae293db6f /openbsc/src/abis_rsl.c
parent945b8da98c669fb52dd9d105181fce434e064401 (diff)
Introduce new ACT_REQ state to prevent race condition during channel allocation
When we allocate a channel, we send the RSL CHAN ACT REQ and wait until we get a CHAN ACT ACK. Only the ACK will change the state, so there is a race where we allocate that same channel to a different channel request before we get the ACT ACK. Introducing a new ACT_REQ state resolves this issue.
Diffstat (limited to 'openbsc/src/abis_rsl.c')
-rw-r--r--openbsc/src/abis_rsl.c15
1 files changed, 10 insertions, 5 deletions
diff --git a/openbsc/src/abis_rsl.c b/openbsc/src/abis_rsl.c
index a4c54190f..bd41283b7 100644
--- a/openbsc/src/abis_rsl.c
+++ b/openbsc/src/abis_rsl.c
@@ -957,12 +957,15 @@ static int rsl_rx_chan_act_nack(struct msgb *msg)
return -EINVAL;
rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
- if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
- print_rsl_cause(LOGL_ERROR, TLVP_VAL(&tp, RSL_IE_CAUSE),
+ if (TLVP_PRESENT(&tp, RSL_IE_CAUSE)) {
+ const u_int8_t *cause = TLVP_VAL(&tp, RSL_IE_CAUSE);
+ print_rsl_cause(LOGL_ERROR, cause,
TLVP_LEN(&tp, RSL_IE_CAUSE));
-
- msg->lchan->state = LCHAN_S_NONE;
-
+ if (*cause != RSL_ERR_RCH_ALR_ACTV_ALLOC)
+ msg->lchan->state = LCHAN_S_NONE;
+ } else
+ msg->lchan->state = LCHAN_S_NONE;
+
LOGPC(DRSL, LOGL_ERROR, "\n");
dispatch_signal(SS_LCHAN, S_LCHAN_ACTIVATE_NACK, msg->lchan);
@@ -1298,6 +1301,8 @@ static int rsl_rx_chan_rqd(struct msgb *msg)
return -ENOMEM;
}
+ lchan->state = LCHAN_S_ACT_REQ;
+
ts_number = lchan->ts->nr;
arfcn = lchan->ts->trx->arfcn;
subch = lchan->nr;