chan_mgcp: Enforce locking for oseq

This restricts direct usage of global oseq so that all accesses are
locked and threads are not racing to get oseq values that they did not
claim.

This also fixes a build error in res_pktccops under dev mode.

(closes issue ASTERISK-23100)
Reported by: adomjan
Patch by: adomjan
........

Merged revisions 406037 from http://svn.asterisk.org/svn/asterisk/branches/1.8
........

Merged revisions 406038 from http://svn.asterisk.org/svn/asterisk/branches/11
........

Merged revisions 406049 from http://svn.asterisk.org/svn/asterisk/branches/12


git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@406078 65c4cc65-6c06-0410-ace0-fbb531ad65f3
changes/97/197/1
Kinsey Moore 11 years ago
parent e0da867dbe
commit b2a682bae2

@ -208,7 +208,8 @@ static int amaflags = 0;
static int adsi = 0;
static unsigned int oseq;
static unsigned int oseq_global = 0;
AST_MUTEX_DEFINE_STATIC(oseq_lock);
/*! Wait up to 16 seconds for first digit (FXO logic) */
static int firstdigittimeout = 16000;
@ -2112,7 +2113,7 @@ static int init_resp(struct mgcp_request *req, char *resp, struct mgcp_request *
return 0;
}
static int init_req(struct mgcp_endpoint *p, struct mgcp_request *req, char *verb)
static int init_req(struct mgcp_endpoint *p, struct mgcp_request *req, char *verb, unsigned int oseq)
{
/* Initialize a response */
if (req->headers || req->len) {
@ -2145,13 +2146,17 @@ static int respprep(struct mgcp_request *resp, struct mgcp_endpoint *p, char *ms
static int reqprep(struct mgcp_request *req, struct mgcp_endpoint *p, char *verb)
{
unsigned int oseq;
memset(req, 0, sizeof(struct mgcp_request));
oseq++;
if (oseq > 999999999) {
oseq = 1;
}
init_req(p, req, verb);
return 0;
ast_mutex_lock(&oseq_lock);
oseq_global++;
if (oseq_global > 999999999) {
oseq_global = 1;
}
oseq = oseq_global;
ast_mutex_unlock(&oseq_lock);
init_req(p, req, verb, oseq);
return oseq;
}
static int transmit_response(struct mgcp_subchannel *sub, char *msg, struct mgcp_request *req, char *msgrest)
@ -2289,6 +2294,7 @@ static int transmit_modify_with_sdp(struct mgcp_subchannel *sub, struct ast_rtp_
struct mgcp_endpoint *p = sub->parent;
struct ast_format tmpfmt;
struct ast_sockaddr sub_tmpdest_tmp;
unsigned int oseq;
if (ast_strlen_zero(sub->cxident) && rtp) {
/* We don't have a CXident yet, store the destination and
@ -2325,7 +2331,7 @@ static int transmit_modify_with_sdp(struct mgcp_subchannel *sub, struct ast_rtp_
}
reqprep(&resp, p, "MDCX");
oseq = reqprep(&resp, p, "MDCX");
add_header(&resp, "C", sub->callid);
add_header(&resp, "L", local);
add_header(&resp, "M", mgcp_cxmodes[sub->cxmode]);
@ -2347,6 +2353,7 @@ static int transmit_connect_with_sdp(struct mgcp_subchannel *sub, struct ast_rtp
char tmp[80];
struct ast_format tmpfmt;
struct mgcp_endpoint *p = sub->parent;
unsigned int oseq;
ast_debug(3, "Creating connection for %s@%s-%d in cxmode: %s callid: %s\n",
p->name, p->parent->name, sub->id, mgcp_cxmodes[sub->cxmode], sub->callid);
@ -2373,7 +2380,7 @@ static int transmit_connect_with_sdp(struct mgcp_subchannel *sub, struct ast_rtp
}
}
sub->sdpsent = 1;
reqprep(&resp, p, "CRCX");
oseq = reqprep(&resp, p, "CRCX");
add_header(&resp, "C", sub->callid);
add_header(&resp, "L", local);
add_header(&resp, "M", mgcp_cxmodes[sub->cxmode]);
@ -2444,6 +2451,7 @@ static int transmit_connect(struct mgcp_subchannel *sub)
char tmp[80];
struct ast_format tmpfmt;
struct mgcp_endpoint *p = sub->parent;
unsigned int oseq;
ast_copy_string(local, "p:20, s:off, e:on", sizeof(local));
@ -2459,7 +2467,7 @@ static int transmit_connect(struct mgcp_subchannel *sub)
ast_debug(3, "Creating connection for %s@%s-%d in cxmode: %s callid: %s\n",
p->name, p->parent->name, sub->id, mgcp_cxmodes[sub->cxmode], sub->callid);
sub->sdpsent = 0;
reqprep(&resp, p, "CRCX");
oseq = reqprep(&resp, p, "CRCX");
add_header(&resp, "C", sub->callid);
add_header(&resp, "L", local);
add_header(&resp, "M", "inactive");
@ -2476,11 +2484,12 @@ static int transmit_notify_request(struct mgcp_subchannel *sub, char *tone)
{
struct mgcp_request resp;
struct mgcp_endpoint *p = sub->parent;
unsigned int oseq;
ast_debug(3, "MGCP Asked to indicate tone: %s on %s@%s-%d in cxmode: %s\n",
tone, p->name, p->parent->name, sub->id, mgcp_cxmodes[sub->cxmode]);
ast_copy_string(p->curtone, tone, sizeof(p->curtone));
reqprep(&resp, p, "RQNT");
oseq = reqprep(&resp, p, "RQNT");
add_header(&resp, "X", p->rqnt_ident);
switch (p->hookstate) {
case MGCP_ONHOOK:
@ -2507,6 +2516,7 @@ static int transmit_notify_request_with_callerid(struct mgcp_subchannel *sub, ch
struct timeval t = ast_tvnow();
struct ast_tm tm;
struct mgcp_endpoint *p = sub->parent;
unsigned int oseq;
ast_localtime(&t, &tm, NULL);
n = callername;
@ -2522,7 +2532,7 @@ static int transmit_notify_request_with_callerid(struct mgcp_subchannel *sub, ch
snprintf(tone2, sizeof(tone2), "%s,L/ci(%02d/%02d/%02d/%02d,%s,%s)", tone,
tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, l, n);
ast_copy_string(p->curtone, tone, sizeof(p->curtone));
reqprep(&resp, p, "RQNT");
oseq = reqprep(&resp, p, "RQNT");
add_header(&resp, "X", p->rqnt_ident);
switch (p->hookstate) {
case MGCP_ONHOOK:
@ -2551,6 +2561,7 @@ static int transmit_modify_request(struct mgcp_subchannel *sub)
int fc = 1;
char local[256];
char tmp[80];
unsigned int oseq;
if (ast_strlen_zero(sub->cxident)) {
/* We don't have a CXident yet, store the destination and
@ -2586,7 +2597,7 @@ static int transmit_modify_request(struct mgcp_subchannel *sub)
}
}
reqprep(&resp, p, "MDCX");
oseq = reqprep(&resp, p, "MDCX");
add_header(&resp, "C", sub->callid);
if (!sub->sdpsent) {
add_header(&resp, "L", local);
@ -2645,7 +2656,8 @@ static void add_header_offhook(struct mgcp_subchannel *sub, struct mgcp_request
static int transmit_audit_endpoint(struct mgcp_endpoint *p)
{
struct mgcp_request resp;
reqprep(&resp, p, "AUEP");
unsigned int oseq;
oseq = reqprep(&resp, p, "AUEP");
/* removed unknown param VS */
/*add_header(&resp, "F", "A,R,D,S,X,N,I,T,O,ES,E,MD,M");*/
add_header(&resp, "F", "A");
@ -2659,10 +2671,11 @@ static int transmit_connection_del(struct mgcp_subchannel *sub)
{
struct mgcp_endpoint *p = sub->parent;
struct mgcp_request resp;
unsigned int oseq;
ast_debug(3, "Delete connection %s %s@%s-%d with new mode: %s on callid: %s\n",
sub->cxident, p->name, p->parent->name, sub->id, mgcp_cxmodes[sub->cxmode], sub->callid);
reqprep(&resp, p, "DLCX");
oseq = reqprep(&resp, p, "DLCX");
/* check if call id is avail */
if (sub->callid[0])
add_header(&resp, "C", sub->callid);
@ -2680,10 +2693,11 @@ static int transmit_connection_del(struct mgcp_subchannel *sub)
static int transmit_connection_del_w_params(struct mgcp_endpoint *p, char *callid, char *cxident)
{
struct mgcp_request resp;
unsigned int oseq;
ast_debug(3, "Delete connection %s %s@%s on callid: %s\n",
cxident ? cxident : "", p->name, p->parent->name, callid ? callid : "");
reqprep(&resp, p, "DLCX");
oseq = reqprep(&resp, p, "DLCX");
/* check if call id is avail */
if (callid && *callid)
add_header(&resp, "C", callid);

Loading…
Cancel
Save