osmux: Remember the allocated CID and make sure it is released
There appears to be a leak of CIDs: <000b> mgcp_osmux.c:544 All Osmux circuits are in use! There are paths that a CID had been requested and never released of the NAT. Remember the allocated CID inside the endpoint so it can always be released. It is using a new variable as the behavior for the NAT and MGCP MGW is different. The allocated_cid must be signed so that we can assign outside of the 0-255 range of it. Fixes: OW#1493
This commit is contained in:
parent
20626dde8f
commit
1afe7c7fe5
|
@ -192,6 +192,8 @@ struct mgcp_endpoint {
|
|||
/* Osmux state: disabled, activating, active */
|
||||
enum osmux_state state;
|
||||
/* Allocated Osmux circuit ID for this endpoint */
|
||||
int allocated_cid;
|
||||
/* Used Osmux circuit ID for this endpoint */
|
||||
uint8_t cid;
|
||||
/* handle to batch messages */
|
||||
struct osmux_in_handle *in;
|
||||
|
|
|
@ -14,6 +14,8 @@ int osmux_init(int role, struct mgcp_config *cfg);
|
|||
int osmux_enable_endpoint(struct mgcp_endpoint *endp, int role,
|
||||
struct in_addr *addr, uint16_t port);
|
||||
void osmux_disable_endpoint(struct mgcp_endpoint *endp);
|
||||
void osmux_allocate_cid(struct mgcp_endpoint *endp);
|
||||
void osmux_release_cid(struct mgcp_endpoint *endp);
|
||||
|
||||
int osmux_xfrm_to_rtp(struct mgcp_endpoint *endp, int type, char *buf, int rc);
|
||||
int osmux_xfrm_to_osmux(int type, char *buf, int rc, struct mgcp_endpoint *endp);
|
||||
|
|
|
@ -492,6 +492,19 @@ void osmux_disable_endpoint(struct mgcp_endpoint *endp)
|
|||
osmux_handle_put(endp->osmux.in);
|
||||
}
|
||||
|
||||
void osmux_release_cid(struct mgcp_endpoint *endp)
|
||||
{
|
||||
if (endp->osmux.allocated_cid >= 0)
|
||||
osmux_put_cid(endp->osmux.allocated_cid);
|
||||
endp->osmux.allocated_cid = -1;
|
||||
}
|
||||
|
||||
void osmux_allocate_cid(struct mgcp_endpoint *endp)
|
||||
{
|
||||
osmux_release_cid(endp);
|
||||
endp->osmux.allocated_cid = osmux_get_cid();
|
||||
}
|
||||
|
||||
/* We don't need to send the dummy load for osmux so often as another endpoint
|
||||
* may have already punched the hole in the firewall. This approach is simple
|
||||
* though.
|
||||
|
|
|
@ -1314,6 +1314,7 @@ int mgcp_endpoints_allocate(struct mgcp_trunk_config *tcfg)
|
|||
return -1;
|
||||
|
||||
for (i = 0; i < tcfg->number_endpoints; ++i) {
|
||||
tcfg->endpoints[i].osmux.allocated_cid = -1;
|
||||
tcfg->endpoints[i].ci = CI_UNUSED;
|
||||
tcfg->endpoints[i].cfg = tcfg->cfg;
|
||||
tcfg->endpoints[i].tcfg = tcfg;
|
||||
|
@ -1354,6 +1355,9 @@ void mgcp_release_endp(struct mgcp_endpoint *endp)
|
|||
if (endp->osmux.state == OSMUX_STATE_ENABLED)
|
||||
osmux_disable_endpoint(endp);
|
||||
|
||||
/* release the circuit ID if it had been allocated */
|
||||
osmux_release_cid(endp);
|
||||
|
||||
memset(&endp->taps, 0, sizeof(endp->taps));
|
||||
}
|
||||
|
||||
|
|
|
@ -515,7 +515,6 @@ static int bsc_mgcp_policy_cb(struct mgcp_trunk_config *tcfg, int endpoint, int
|
|||
struct nat_sccp_connection *sccp;
|
||||
struct mgcp_endpoint *mgcp_endp;
|
||||
struct msgb *bsc_msg;
|
||||
int osmux_cid = -1;
|
||||
|
||||
nat = tcfg->cfg->data;
|
||||
bsc_endp = &nat->bsc_endpoints[endpoint];
|
||||
|
@ -555,8 +554,9 @@ static int bsc_mgcp_policy_cb(struct mgcp_trunk_config *tcfg, int endpoint, int
|
|||
/* Allocate a Osmux circuit ID */
|
||||
if (state == MGCP_ENDP_CRCX) {
|
||||
if (nat->mgcp_cfg->osmux && sccp->bsc->cfg->osmux) {
|
||||
osmux_cid = osmux_get_cid();
|
||||
if (osmux_cid < 0 && nat_osmux_only(nat->mgcp_cfg, sccp->bsc->cfg)) {
|
||||
osmux_allocate_cid(mgcp_endp);
|
||||
if (mgcp_endp->osmux.allocated_cid < 0 &&
|
||||
nat_osmux_only(nat->mgcp_cfg, sccp->bsc->cfg)) {
|
||||
LOGP(DMGCP, LOGL_ERROR,
|
||||
"Rejecting usage of endpoint\n");
|
||||
return MGCP_POLICY_REJECT;
|
||||
|
@ -567,7 +567,8 @@ static int bsc_mgcp_policy_cb(struct mgcp_trunk_config *tcfg, int endpoint, int
|
|||
/* we need to generate a new and patched message */
|
||||
bsc_msg = bsc_mgcp_rewrite((char *) nat->mgcp_msg, nat->mgcp_length,
|
||||
sccp->bsc_endp, mgcp_bts_src_addr(mgcp_endp),
|
||||
mgcp_endp->bts_end.local_port, osmux_cid,
|
||||
mgcp_endp->bts_end.local_port,
|
||||
mgcp_endp->osmux.allocated_cid,
|
||||
&mgcp_endp->net_end.codec.payload_type,
|
||||
nat->sdp_ensure_amr_mode_set);
|
||||
if (!bsc_msg) {
|
||||
|
@ -587,10 +588,10 @@ static int bsc_mgcp_policy_cb(struct mgcp_trunk_config *tcfg, int endpoint, int
|
|||
/* Annotate the allocated Osmux CID until the bsc confirms that
|
||||
* it agrees to use Osmux for this voice flow.
|
||||
*/
|
||||
if (osmux_cid >= 0 &&
|
||||
if (mgcp_endp->osmux.allocated_cid >= 0 &&
|
||||
mgcp_endp->osmux.state != OSMUX_STATE_ENABLED) {
|
||||
mgcp_endp->osmux.state = OSMUX_STATE_ACTIVATING;
|
||||
mgcp_endp->osmux.cid = osmux_cid;
|
||||
mgcp_endp->osmux.cid = mgcp_endp->osmux.allocated_cid;
|
||||
}
|
||||
|
||||
socklen_t len = sizeof(sock);
|
||||
|
@ -612,7 +613,7 @@ static int bsc_mgcp_policy_cb(struct mgcp_trunk_config *tcfg, int endpoint, int
|
|||
|
||||
/* libmgcp clears the MGCP endpoint for us */
|
||||
if (mgcp_endp->osmux.state == OSMUX_STATE_ENABLED)
|
||||
osmux_put_cid(mgcp_endp->osmux.cid);
|
||||
osmux_release_cid(mgcp_endp);
|
||||
|
||||
return MGCP_POLICY_CONT;
|
||||
} else {
|
||||
|
@ -681,8 +682,7 @@ static void bsc_mgcp_osmux_confirm(struct mgcp_endpoint *endp, const char *str)
|
|||
osmux_cid);
|
||||
return;
|
||||
err:
|
||||
osmux_put_cid(endp->osmux.cid);
|
||||
endp->osmux.cid = -1;
|
||||
osmux_release_cid(endp);
|
||||
endp->osmux.state = OSMUX_STATE_DISABLED;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue