pespin has submitted this change. ( https://gerrit.osmocom.org/c/libosmo-sigtran/+/42212?usp=email )
Change subject: tcap: Support TID with length 1..4 ......................................................................
tcap: Support TID with length 1..4
As described in ITU Q.773 4.2.1.3: "The length of a Transaction ID is 1 to 4 octets."
asn.1 files also describe TIDs the following way: OrigTransactionID ::= [APPLICATION 8] IMPLICIT OCTET STRING (SIZE (1..4) ) DestTransactionID ::=[APPLICATION 9] IMPLICIT OCTET STRING (SIZE (1..4) )
Take the chance to avoid asserting based on received external input msg.
Related: SYS#5423 Change-Id: I2748d85624e4be708f7554ee3e60a5bda9162845 --- M src/sccp2sua.c M src/ss7_internal.h M src/tcap_as_loadshare.c 3 files changed, 42 insertions(+), 19 deletions(-)
Approvals: osmith: Looks good to me, approved Jenkins Builder: Verified laforge: Looks good to me, but someone else must approve
diff --git a/src/sccp2sua.c b/src/sccp2sua.c index 87d9d05..9ca1d7a 100644 --- a/src/sccp2sua.c +++ b/src/sccp2sua.c @@ -35,8 +35,8 @@ #include <osmocom/sigtran/sccp_helpers.h> #include <osmocom/sigtran/protocol/sua.h> #include "xua_msg.h" - #include "xua_internal.h" +#include "ss7_internal.h" #include "sccp_internal.h"
/* libosmocore candidates */ @@ -54,14 +54,6 @@ msgb_put_u8(msg, (val >> 8) & 0xff); }
-/*! \brief load a 24bit value as big-endian */ -static uint32_t load_24be(const void *ptr) -{ - const uint8_t *data = ptr; - return (data[0] << 16) | (data[1] << 8) | data[2]; -} - -
/*! \brief Parse ISUP style address of BCD digets * \param[out] out_digits user-allocated buffer for ASCII digits diff --git a/src/ss7_internal.h b/src/ss7_internal.h index b70954e..f93eb52 100644 --- a/src/ss7_internal.h +++ b/src/ss7_internal.h @@ -44,5 +44,12 @@ #define ss7_llist_round_robin(list, state, struct_type, entry_name) \ llist_entry(_ss7_llist_round_robin(list, state), struct_type, entry_name)
+/*! \brief load a 24bit value as big-endian */ +static inline uint32_t load_24be(const void *ptr) +{ + const uint8_t *data = ptr; + return (data[0] << 16) | (data[1] << 8) | data[2]; +} + /* VTY */ #define XUA_VAR_STR "(sua|m3ua|ipa)" diff --git a/src/tcap_as_loadshare.c b/src/tcap_as_loadshare.c index 803dcd8..f00347c 100644 --- a/src/tcap_as_loadshare.c +++ b/src/tcap_as_loadshare.c @@ -1,4 +1,4 @@ -/* TCAP ID based ASP Load-Sharing */ +/* TCAP ID based ASP Load-Sharing, ITU-T Q.771-Q.775 */
/* (C) 2025 by sysmocom s.f.m.c. GmbH info@sysmocom.de * All Rights Reserved @@ -60,11 +60,31 @@ uint32_t dtid; };
-static inline uint32_t tcap_id_from_octet_str(const OCTET_STRING_t *src) +/* Obtain TID in 32BE format from octetstring. +* returns 0 on success, negative on error. */ +static int tcap_id_from_octet_str(uint32_t *tid, const OCTET_STRING_t *src) { - OSMO_ASSERT(src->size == 4); + switch (src->size) { + case 4: + *tid = osmo_load32be(src->buf); + break; + case 3: + *tid = load_24be(src->buf); + break; + case 2: + *tid = osmo_load16be(src->buf); + break; + case 1: + *tid = src->buf[0]; + break; + default: + LOGP(DLTCAP, LOGL_NOTICE, "Rx TCAP message with unexpected TID length %zu\n", + src->size); + *tid = 0; + return -EINVAL; + }
- return osmo_load32be(src->buf); + return 0; }
/* returns negative on error, mask with any/both OTID_SET|DTID_SET on success */ @@ -88,33 +108,37 @@ case TCAP_TCMessage_PR_begin: { TCAP_Begin_t part = tcapmsg->choice.begin; - ids->otid = tcap_id_from_octet_str(&part.otid); + if ((rc = tcap_id_from_octet_str(&ids->otid, &part.otid)) < 0) + goto free_asn; rc = OTID_SET; break; } case TCAP_TCMessage_PR_continue: { TCAP_Continue_t part = tcapmsg->choice.Continue; - ids->otid = tcap_id_from_octet_str(&part.otid); - ids->dtid = tcap_id_from_octet_str(&part.dtid); + if ((rc = tcap_id_from_octet_str(&ids->otid, &part.otid)) < 0) + goto free_asn; + if ((rc = tcap_id_from_octet_str(&ids->dtid, &part.dtid)) < 0) + goto free_asn; rc = OTID_SET | DTID_SET; break; } case TCAP_TCMessage_PR_end: { TCAP_End_t part = tcapmsg->choice.end; - ids->dtid = tcap_id_from_octet_str(&part.dtid); + if ((rc = tcap_id_from_octet_str(&ids->dtid, &part.dtid)) < 0) + goto free_asn; rc = DTID_SET; break; } case TCAP_TCMessage_PR_abort: { TCAP_Abort_t part = tcapmsg->choice.abort; - ids->dtid = tcap_id_from_octet_str(&part.dtid); + if ((rc = tcap_id_from_octet_str(&ids->dtid, &part.dtid)) < 0) + goto free_asn; rc = DTID_SET; break; } - /* No TID present */ case TCAP_TCMessage_PR_unidirectional: rc = 0;