summaryrefslogtreecommitdiff
path: root/channels/chan_mgcp.c
diff options
context:
space:
mode:
authorKinsey Moore <kmoore@digium.com>2014-01-21 20:28:57 +0000
committerKinsey Moore <kmoore@digium.com>2014-01-21 20:28:57 +0000
commitb2a682bae29f85d1978f9e28768da791c392330f (patch)
tree1abeec3413b245897b02fc0eab392f9645ec01d2 /channels/chan_mgcp.c
parente0da867dbee6a1f90fd8f791b77371cc6e2c1824 (diff)
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
Diffstat (limited to 'channels/chan_mgcp.c')
-rw-r--r--channels/chan_mgcp.c48
1 files changed, 31 insertions, 17 deletions
diff --git a/channels/chan_mgcp.c b/channels/chan_mgcp.c
index e250a9220..304488213 100644
--- a/channels/chan_mgcp.c
+++ b/channels/chan_mgcp.c
@@ -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);