aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/src/gprs/gprs_gmm.c
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <holger@moiji-mobile.com>2017-01-26 11:05:33 +0100
committerHolger Freyther <holger@freyther.de>2017-02-01 15:02:54 +0000
commit725f3f1de0bb71cb743e5af00d6d56549fc5f692 (patch)
tree3c0d97fda5cfcf87e29bb04ce678b8f0b18d0127 /openbsc/src/gprs/gprs_gmm.c
parentdac5867af5ff90d4beb70fc30a5743f60f159e3a (diff)
sgsn: Fix deeply flawed copying logic for PDP context activation
It is one of these changes that should have never worked but did for a long time. Only recently a corrupted GTP message was seen. The code in ccd2312d10e14747e8a4d26d8f72b052ffcfc282 tried to solve the right problem but was deeply flawed. * Make the code operate on the copied message and not the original one that is deleted by the underlaying layers on return * Add an out variable to determine if the msgb should be deleted and assume that by default it will be deleted. Change-Id: I564526e7cde2b8a2f0ce900492cd38fc23c176a7
Diffstat (limited to 'openbsc/src/gprs/gprs_gmm.c')
-rw-r--r--openbsc/src/gprs/gprs_gmm.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/openbsc/src/gprs/gprs_gmm.c b/openbsc/src/gprs/gprs_gmm.c
index dc73693ce..6fde75704 100644
--- a/openbsc/src/gprs/gprs_gmm.c
+++ b/openbsc/src/gprs/gprs_gmm.c
@@ -2169,6 +2169,7 @@ static void ggsn_lookup_cb(void *arg, int status, int timeouts, struct hostent *
/* The context is gone while we made a request */
if (!lookup->mmctx) {
+ talloc_free(lookup->orig_msg);
talloc_free(lookup);
return;
}
@@ -2230,6 +2231,7 @@ static void ggsn_lookup_cb(void *arg, int status, int timeouts, struct hostent *
lookup->sapi, &lookup->tp, 1);
/* Now free it */
+ talloc_free(lookup->orig_msg);
talloc_free(lookup);
return;
@@ -2237,10 +2239,11 @@ reject_due_failure:
gsm48_tx_gsm_act_pdp_rej(lookup->mmctx, lookup->ti,
GMM_CAUSE_NET_FAIL, 0, NULL);
lookup->mmctx->ggsn_lookup = NULL;
+ talloc_free(lookup->orig_msg);
talloc_free(lookup);
}
-static int do_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, bool *delete)
{
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;
@@ -2389,6 +2392,7 @@ static int do_act_pdp_req(struct sgsn_mm_ctx *mmctx, struct msgb *msg)
LOGMMCTXP(LOGL_ERROR, mmctx, "Failed to start ares query.\n");
goto no_context;
}
+ *delete = 0;
return 0;
@@ -2402,6 +2406,7 @@ no_context:
static int gsm48_rx_gsm_act_pdp_req(struct sgsn_mm_ctx *mmctx,
struct msgb *_msg)
{
+ bool delete = 1;
struct msgb *msg;
int rc;
@@ -2428,8 +2433,9 @@ static int gsm48_rx_gsm_act_pdp_req(struct sgsn_mm_ctx *mmctx,
0, NULL);
}
- rc = do_act_pdp_req(mmctx, _msg);
- msgb_free(msg);
+ rc = do_act_pdp_req(mmctx, msg, &delete);
+ if (delete)
+ msgb_free(msg);
return rc;
}