M3UA: Accept DATA without routing context IE if only a single AS in ASP
There are some M3UA implementations out there who use a routing context during the ASPAC procedure, but who then don't use it in subsequent DATA transmission. This behavior seems to be at the edge of what's possible within the spec; if you don't configure a routing context, The RCTX IE it is not required to be sent. And if you have multiple routing contexts/AS within one ASP, it *must* be sent. But the situation where a routing context has been configured (but not multiple) is not explicitly covered. Change-Id: I59f47a999f40411aadc88b8f362d8d2b89a66332 Closes: OS#4594
This commit is contained in:
parent
3d8605d868
commit
deca2bd75e
69
src/m3ua.c
69
src/m3ua.c
|
@ -532,9 +532,26 @@ struct m3ua_data_hdr *data_hdr_from_m3ua(struct xua_msg *xua)
|
|||
return data_hdr;
|
||||
}
|
||||
|
||||
/* if given ASP only has one AS, return that AS */
|
||||
static struct osmo_ss7_as *find_single_as_for_asp(struct osmo_ss7_asp *asp)
|
||||
{
|
||||
struct osmo_ss7_as *as, *as_found = NULL;
|
||||
|
||||
llist_for_each_entry(as, &asp->inst->as_list, list) {
|
||||
if (!osmo_ss7_as_has_asp(as, asp))
|
||||
continue;
|
||||
/* check if we already had found another AS within this ASP -> not unique */
|
||||
if (as_found)
|
||||
return NULL;
|
||||
as_found = as;
|
||||
}
|
||||
|
||||
return as_found;
|
||||
}
|
||||
|
||||
static int m3ua_rx_xfer(struct osmo_ss7_asp *asp, struct xua_msg *xua)
|
||||
{
|
||||
uint32_t rctx = xua_msg_get_u32(xua, M3UA_IEI_ROUTE_CTX);
|
||||
struct xua_msg_part *rctx_ie = xua_msg_find_tag(xua, M3UA_IEI_ROUTE_CTX);
|
||||
struct m3ua_data_hdr *dh;
|
||||
struct osmo_ss7_as *as;
|
||||
|
||||
|
@ -548,23 +565,33 @@ static int m3ua_rx_xfer(struct osmo_ss7_asp *asp, struct xua_msg *xua)
|
|||
return M3UA_ERR_UNSUPP_MSG_TYPE;
|
||||
}
|
||||
|
||||
/* Use routing context IE to look up the AS for which the
|
||||
* message was received. */
|
||||
as = osmo_ss7_as_find_by_rctx(asp->inst, rctx);
|
||||
if (!as) {
|
||||
LOGPASP(asp, DLM3UA, LOGL_ERROR,
|
||||
"%s(): invalid routing context: %u\n",
|
||||
__func__, rctx);
|
||||
return M3UA_ERR_INVAL_ROUT_CTX;
|
||||
}
|
||||
if (rctx_ie) {
|
||||
uint32_t rctx = xua_msg_part_get_u32(rctx_ie);
|
||||
/* Use routing context IE to look up the AS for which the
|
||||
* message was received. */
|
||||
as = osmo_ss7_as_find_by_rctx(asp->inst, rctx);
|
||||
if (!as) {
|
||||
LOGPASP(asp, DLM3UA, LOGL_ERROR, "%s(): invalid routing context: %u\n",
|
||||
__func__, rctx);
|
||||
return M3UA_ERR_INVAL_ROUT_CTX;
|
||||
}
|
||||
|
||||
/* Verify that this ASP is part of the AS. */
|
||||
if (!osmo_ss7_as_has_asp(as, asp)) {
|
||||
LOGPASP(asp, DLM3UA, LOGL_ERROR,
|
||||
"%s(): This Application Server Process is not part of the AS %s resolved by"
|
||||
" routing context %u\n",
|
||||
__func__, (as)->cfg.name, rctx);
|
||||
return M3UA_ERR_NO_CONFGD_AS_FOR_ASP;
|
||||
/* Verify that this ASP is part of the AS. */
|
||||
if (!osmo_ss7_as_has_asp(as, asp)) {
|
||||
LOGPASP(asp, DLM3UA, LOGL_ERROR,
|
||||
"%s(): This Application Server Process is not part of the AS %s "
|
||||
"resolved by routing context %u\n", __func__, (as)->cfg.name, rctx);
|
||||
return M3UA_ERR_NO_CONFGD_AS_FOR_ASP;
|
||||
}
|
||||
} else {
|
||||
/* no explicit routing context; this only works if there is only one AS in the ASP */
|
||||
as = find_single_as_for_asp(asp);
|
||||
if (!as) {
|
||||
LOGPASP(asp, DLM3UA, LOGL_ERROR,
|
||||
"%s(): ASP sent M3UA without Routing Context IE but unable to uniquely "
|
||||
"identify the AS for this message\n", __func__);
|
||||
return M3UA_ERR_INVAL_ROUT_CTX;
|
||||
}
|
||||
}
|
||||
|
||||
/* FIXME: check for AS state == ACTIVE */
|
||||
|
@ -579,9 +606,11 @@ static int m3ua_rx_xfer(struct osmo_ss7_asp *asp, struct xua_msg *xua)
|
|||
__func__, xua->mtp.opc, osmo_ss7_pointcode_print(asp->inst, xua->mtp.opc),
|
||||
xua->mtp.dpc, osmo_ss7_pointcode_print2(asp->inst, xua->mtp.dpc));
|
||||
|
||||
/* remove ROUTE_CTX as in the routing case we want to add a new
|
||||
* routing context on the outbound side */
|
||||
xua_msg_free_tag(xua, M3UA_IEI_ROUTE_CTX);
|
||||
if (rctx_ie) {
|
||||
/* remove ROUTE_CTX as in the routing case we want to add a new
|
||||
* routing context on the outbound side */
|
||||
xua_msg_free_tag(xua, M3UA_IEI_ROUTE_CTX);
|
||||
}
|
||||
|
||||
return m3ua_hmdc_rx_from_l2(asp->inst, xua);
|
||||
/* xua will be freed by caller m3ua_rx_msg() */
|
||||
|
|
Loading…
Reference in New Issue