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 ccd2312d10
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
This commit is contained in:
parent
dac5867af5
commit
725f3f1de0
|
@ -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 */
|
/* The context is gone while we made a request */
|
||||||
if (!lookup->mmctx) {
|
if (!lookup->mmctx) {
|
||||||
|
talloc_free(lookup->orig_msg);
|
||||||
talloc_free(lookup);
|
talloc_free(lookup);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2230,6 +2231,7 @@ static void ggsn_lookup_cb(void *arg, int status, int timeouts, struct hostent *
|
||||||
lookup->sapi, &lookup->tp, 1);
|
lookup->sapi, &lookup->tp, 1);
|
||||||
|
|
||||||
/* Now free it */
|
/* Now free it */
|
||||||
|
talloc_free(lookup->orig_msg);
|
||||||
talloc_free(lookup);
|
talloc_free(lookup);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -2237,10 +2239,11 @@ reject_due_failure:
|
||||||
gsm48_tx_gsm_act_pdp_rej(lookup->mmctx, lookup->ti,
|
gsm48_tx_gsm_act_pdp_rej(lookup->mmctx, lookup->ti,
|
||||||
GMM_CAUSE_NET_FAIL, 0, NULL);
|
GMM_CAUSE_NET_FAIL, 0, NULL);
|
||||||
lookup->mmctx->ggsn_lookup = NULL;
|
lookup->mmctx->ggsn_lookup = NULL;
|
||||||
|
talloc_free(lookup->orig_msg);
|
||||||
talloc_free(lookup);
|
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_hdr *gh = (struct gsm48_hdr *) msgb_gmmh(msg);
|
||||||
struct gsm48_act_pdp_ctx_req *act_req = (struct gsm48_act_pdp_ctx_req *) gh->data;
|
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");
|
LOGMMCTXP(LOGL_ERROR, mmctx, "Failed to start ares query.\n");
|
||||||
goto no_context;
|
goto no_context;
|
||||||
}
|
}
|
||||||
|
*delete = 0;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -2402,6 +2406,7 @@ no_context:
|
||||||
static int gsm48_rx_gsm_act_pdp_req(struct sgsn_mm_ctx *mmctx,
|
static int gsm48_rx_gsm_act_pdp_req(struct sgsn_mm_ctx *mmctx,
|
||||||
struct msgb *_msg)
|
struct msgb *_msg)
|
||||||
{
|
{
|
||||||
|
bool delete = 1;
|
||||||
struct msgb *msg;
|
struct msgb *msg;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
@ -2428,8 +2433,9 @@ static int gsm48_rx_gsm_act_pdp_req(struct sgsn_mm_ctx *mmctx,
|
||||||
0, NULL);
|
0, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = do_act_pdp_req(mmctx, _msg);
|
rc = do_act_pdp_req(mmctx, msg, &delete);
|
||||||
msgb_free(msg);
|
if (delete)
|
||||||
|
msgb_free(msg);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue