From ccd2312d10e14747e8a4d26d8f72b052ffcfc282 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Sun, 24 May 2015 16:48:22 +0800 Subject: sgsn: Create a copy of the msgb for later usage When needing to do an asynchronous DNS query we need to keep the TLV data around. So create a wrapper that takes a copy of it and frees it after the call. I can change the code to add an out parameter to decide if the msgb should be freed or not. Pick network failure in case the msgb could not be cloned in the hope the MS will retry then. --- openbsc/src/gprs/gprs_gmm.c | 38 +++++++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) (limited to 'openbsc/src/gprs/gprs_gmm.c') diff --git a/openbsc/src/gprs/gprs_gmm.c b/openbsc/src/gprs/gprs_gmm.c index 728377637..d7ba5b4f5 100644 --- a/openbsc/src/gprs/gprs_gmm.c +++ b/openbsc/src/gprs/gprs_gmm.c @@ -1650,9 +1650,8 @@ static int activate_ggsn(struct sgsn_mm_ctx *mmctx, return 0; } -/* Section 9.5.1: Activate PDP Context Request */ -static int gsm48_rx_gsm_act_pdp_req(struct sgsn_mm_ctx *mmctx, - struct msgb *msg) + +static int do_act_pdp_req(struct sgsn_mm_ctx *mmctx, struct msgb *msg) { struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_gmmh(msg); struct gsm48_act_pdp_ctx_req *act_req = (struct gsm48_act_pdp_ctx_req *) gh->data; @@ -1765,6 +1764,39 @@ static int gsm48_rx_gsm_act_pdp_req(struct sgsn_mm_ctx *mmctx, &tp); } +/* Section 9.5.1: Activate PDP Context Request */ +static int gsm48_rx_gsm_act_pdp_req(struct sgsn_mm_ctx *mmctx, + struct msgb *_msg) +{ + struct msgb *msg; + int rc; + + /* + * This is painful. We might not have a static GGSN + * configuration and then would need to copy the msg + * and re-do most of this routine (or call it again + * and make sure it only goes through the dynamic + * resolving. The question is what to optimize for + * and the dynamic resolution will be the right thing + * in the long run. + */ + msg = gprs_msgb_copy(_msg, __func__); + if (!msg) { + struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_gmmh(_msg); + uint8_t transaction_id = (gh->proto_discr >> 4); + + LOGMMCTXP(LOGL_ERROR, mmctx, "-> ACTIVATE PDP CONTEXT REQ failed copy.\n"); + /* Send reject with GSM_CAUSE_INV_MAND_INFO */ + return gsm48_tx_gsm_act_pdp_rej(mmctx, transaction_id, + GSM_CAUSE_NET_FAIL, + 0, NULL); + } + + rc = do_act_pdp_req(mmctx, _msg); + msgb_free(msg); + return rc; +} + /* Section 9.5.8: Deactivate PDP Context Request */ static int gsm48_rx_gsm_deact_pdp_req(struct sgsn_mm_ctx *mm, struct msgb *msg) { -- cgit v1.2.3