mgcp: Allow to dynamically allocate ports from a range..
Allow to switch to a dynamic port allocator and not reuse the ports for a long time... This should help with a crazy network sending two streams at the same time.
This commit is contained in:
parent
f330729dc9
commit
05d8f5f46a
|
@ -66,6 +66,7 @@ struct mgcp_rtp_end {
|
||||||
struct bsc_fd rtcp;
|
struct bsc_fd rtcp;
|
||||||
|
|
||||||
int local_port;
|
int local_port;
|
||||||
|
int local_alloc;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mgcp_endpoint {
|
struct mgcp_endpoint {
|
||||||
|
@ -100,5 +101,6 @@ int mgcp_analyze_header(struct mgcp_config *cfg, struct msgb *msg,
|
||||||
int mgcp_send_dummy(struct mgcp_endpoint *endp);
|
int mgcp_send_dummy(struct mgcp_endpoint *endp);
|
||||||
int mgcp_bind_bts_rtp_port(struct mgcp_endpoint *endp, int rtp_port);
|
int mgcp_bind_bts_rtp_port(struct mgcp_endpoint *endp, int rtp_port);
|
||||||
int mgcp_bind_net_rtp_port(struct mgcp_endpoint *endp, int rtp_port);
|
int mgcp_bind_net_rtp_port(struct mgcp_endpoint *endp, int rtp_port);
|
||||||
|
int mgcp_free_rtp_port(struct mgcp_rtp_end *end);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -394,3 +394,25 @@ int mgcp_bind_net_rtp_port(struct mgcp_endpoint *endp, int rtp_port)
|
||||||
endp->net_end.rtcp.cb = rtp_data_net;
|
endp->net_end.rtcp.cb = rtp_data_net;
|
||||||
return bind_rtp(endp->cfg, &endp->net_end, ENDPOINT_NUMBER(endp));
|
return bind_rtp(endp->cfg, &endp->net_end, ENDPOINT_NUMBER(endp));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int mgcp_free_rtp_port(struct mgcp_rtp_end *end)
|
||||||
|
{
|
||||||
|
if (end->local_alloc != PORT_ALLOC_DYNAMIC) {
|
||||||
|
LOGP(DMGCP, LOGL_ERROR, "Should only be called for dynamic ports.\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (end->rtp.fd != -1) {
|
||||||
|
close(end->rtp.fd);
|
||||||
|
end->rtp.fd = -1;
|
||||||
|
bsc_unregister_fd(&end->rtp);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (end->rtcp.fd != -1) {
|
||||||
|
close(end->rtcp.fd);
|
||||||
|
end->rtcp.fd = -1;
|
||||||
|
bsc_unregister_fd(&end->rtcp);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -72,6 +72,7 @@
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void mgcp_rtp_end_reset(struct mgcp_rtp_end *end);
|
||||||
|
|
||||||
struct mgcp_request {
|
struct mgcp_request {
|
||||||
char *name;
|
char *name;
|
||||||
|
@ -367,6 +368,54 @@ static int parse_conn_mode(const char* msg, int *conn_mode)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int allocate_port(struct mgcp_endpoint *endp, struct mgcp_rtp_end *end,
|
||||||
|
struct mgcp_port_range *range, int for_net)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (range->mode == PORT_ALLOC_STATIC) {
|
||||||
|
end->local_port = rtp_calculate_port(ENDPOINT_NUMBER(endp), range->base_port);
|
||||||
|
end->local_alloc = PORT_ALLOC_STATIC;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* attempt to find a port */
|
||||||
|
for (i = 0; i < 200; ++i) {
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if (range->last_port >= range->range_end)
|
||||||
|
range->last_port = range->range_start;
|
||||||
|
|
||||||
|
rc = for_net ?
|
||||||
|
mgcp_bind_net_rtp_port(endp, range->last_port) :
|
||||||
|
mgcp_bind_bts_rtp_port(endp, range->last_port);
|
||||||
|
|
||||||
|
range->last_port += 2;
|
||||||
|
if (rc == 0) {
|
||||||
|
end->local_alloc = PORT_ALLOC_DYNAMIC;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
LOGP(DMGCP, LOGL_ERROR, "Allocating a RTP/RTCP port failed 200 times 0x%x net: %d\n",
|
||||||
|
ENDPOINT_NUMBER(endp), for_net);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int allocate_ports(struct mgcp_endpoint *endp)
|
||||||
|
{
|
||||||
|
if (allocate_port(endp, &endp->net_end, &endp->cfg->net_ports, 0) != 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (allocate_port(endp, &endp->bts_end, &endp->cfg->bts_ports, 1) != 0) {
|
||||||
|
mgcp_rtp_end_reset(&endp->net_end);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static struct msgb *handle_create_con(struct mgcp_config *cfg, struct msgb *msg)
|
static struct msgb *handle_create_con(struct mgcp_config *cfg, struct msgb *msg)
|
||||||
{
|
{
|
||||||
struct mgcp_msg_ptr data_ptrs[6];
|
struct mgcp_msg_ptr data_ptrs[6];
|
||||||
|
@ -374,7 +423,6 @@ static struct msgb *handle_create_con(struct mgcp_config *cfg, struct msgb *msg)
|
||||||
const char *trans_id;
|
const char *trans_id;
|
||||||
struct mgcp_endpoint *endp;
|
struct mgcp_endpoint *endp;
|
||||||
int error_code = 500;
|
int error_code = 500;
|
||||||
int port;
|
|
||||||
|
|
||||||
found = mgcp_analyze_header(cfg, msg, data_ptrs, ARRAY_SIZE(data_ptrs), &trans_id, &endp);
|
found = mgcp_analyze_header(cfg, msg, data_ptrs, ARRAY_SIZE(data_ptrs), &trans_id, &endp);
|
||||||
if (found != 0)
|
if (found != 0)
|
||||||
|
@ -427,11 +475,8 @@ static struct msgb *handle_create_con(struct mgcp_config *cfg, struct msgb *msg)
|
||||||
memset(&endp->net_end.addr, 0, sizeof(endp->net_end.addr));
|
memset(&endp->net_end.addr, 0, sizeof(endp->net_end.addr));
|
||||||
|
|
||||||
/* bind to the port now */
|
/* bind to the port now */
|
||||||
port = rtp_calculate_port(ENDPOINT_NUMBER(endp), cfg->bts_ports.base_port);
|
if (allocate_ports(endp) != 0)
|
||||||
endp->bts_end.local_port = port;
|
goto error2;
|
||||||
|
|
||||||
port = rtp_calculate_port(ENDPOINT_NUMBER(endp), cfg->net_ports.base_port);
|
|
||||||
endp->net_end.local_port = port;
|
|
||||||
|
|
||||||
/* assign a local call identifier or fail */
|
/* assign a local call identifier or fail */
|
||||||
endp->ci = generate_call_id(cfg);
|
endp->ci = generate_call_id(cfg);
|
||||||
|
@ -470,6 +515,7 @@ error:
|
||||||
LOGP(DMGCP, LOGL_ERROR, "Malformed line: %s on 0x%x with: line_start: %d %d\n",
|
LOGP(DMGCP, LOGL_ERROR, "Malformed line: %s on 0x%x with: line_start: %d %d\n",
|
||||||
hexdump(msg->l3h, msgb_l3len(msg)),
|
hexdump(msg->l3h, msgb_l3len(msg)),
|
||||||
ENDPOINT_NUMBER(endp), line_start, i);
|
ENDPOINT_NUMBER(endp), line_start, i);
|
||||||
|
mgcp_free_endp(endp);
|
||||||
return create_response(error_code, "CRCX", trans_id);
|
return create_response(error_code, "CRCX", trans_id);
|
||||||
|
|
||||||
error2:
|
error2:
|
||||||
|
@ -719,10 +765,14 @@ struct mgcp_config *mgcp_config_alloc(void)
|
||||||
|
|
||||||
static void mgcp_rtp_end_reset(struct mgcp_rtp_end *end)
|
static void mgcp_rtp_end_reset(struct mgcp_rtp_end *end)
|
||||||
{
|
{
|
||||||
|
if (end->local_alloc == PORT_ALLOC_DYNAMIC)
|
||||||
|
mgcp_free_rtp_port(end);
|
||||||
|
|
||||||
end->packets = 0;
|
end->packets = 0;
|
||||||
memset(&end->addr, 0, sizeof(end->addr));
|
memset(&end->addr, 0, sizeof(end->addr));
|
||||||
end->rtp_port = end->rtcp_port = end->local_port;
|
end->rtp_port = end->rtcp_port = end->local_port = 0;
|
||||||
end->payload_type = -1;
|
end->payload_type = -1;
|
||||||
|
end->local_alloc = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mgcp_rtp_end_init(struct mgcp_rtp_end *end)
|
static void mgcp_rtp_end_init(struct mgcp_rtp_end *end)
|
||||||
|
|
|
@ -377,6 +377,7 @@ int mgcp_parse_config(const char *config_file, struct mgcp_config *cfg)
|
||||||
LOGP(DMGCP, LOGL_FATAL, "Failed to bind: %d\n", rtp_port);
|
LOGP(DMGCP, LOGL_FATAL, "Failed to bind: %d\n", rtp_port);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
endp->bts_end.local_alloc = PORT_ALLOC_STATIC;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_cfg->net_ports.mode == PORT_ALLOC_STATIC) {
|
if (g_cfg->net_ports.mode == PORT_ALLOC_STATIC) {
|
||||||
|
@ -386,6 +387,7 @@ int mgcp_parse_config(const char *config_file, struct mgcp_config *cfg)
|
||||||
LOGP(DMGCP, LOGL_FATAL, "Failed to bind: %d\n", rtp_port);
|
LOGP(DMGCP, LOGL_FATAL, "Failed to bind: %d\n", rtp_port);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
endp->net_end.local_alloc = PORT_ALLOC_STATIC;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue