[svn-commits] mattf: branch mattf/1.6.0-chan_ccs r266780 - /team/mattf/1.6.0-chan_ccs/chann...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Tue Jun 1 14:52:27 CDT 2010


Author: mattf
Date: Tue Jun  1 14:52:26 2010
New Revision: 266780

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=266780
Log:
Fix bug in chan_mgcp with non-atomic acquisition and manipulation of the global sequence number identifier. Increase MGCP number of max retransmissions per packet. Increase max packet size receivable.  Delete outstanding connections on all endpoints when bringing trunk type endpoints up.

Modified:
    team/mattf/1.6.0-chan_ccs/channels/chan_mgcp.c

Modified: team/mattf/1.6.0-chan_ccs/channels/chan_mgcp.c
URL: http://svnview.digium.com/svn/asterisk/team/mattf/1.6.0-chan_ccs/channels/chan_mgcp.c?view=diff&rev=266780&r1=266779&r2=266780
==============================================================================
--- team/mattf/1.6.0-chan_ccs/channels/chan_mgcp.c (original)
+++ team/mattf/1.6.0-chan_ccs/channels/chan_mgcp.c Tue Jun  1 14:52:26 2010
@@ -105,9 +105,9 @@
 
 #define DEFAULT_MGCP_GW_PORT	2427 /*!< From RFC 2705 */
 #define DEFAULT_MGCP_CA_PORT	2727 /*!< From RFC 2705 */
-#define MGCP_MAX_PACKET		1500 /*!< Also from RFC 2543, should sub headers tho */
+#define MGCP_MAX_PACKET		32768 /*!< Also from RFC 2543, should sub headers tho */
 #define DEFAULT_RETRANS		1000 /*!< How frequently to retransmit */
-#define MAX_RETRANS		5    /*!< Try only 5 times for retransmissions */
+#define MAX_RETRANS		7    /*!< Try only 5 times for retransmissions */
 
 /*! MGCP rtp stream modes { */
 #define MGCP_CX_SENDONLY	0
@@ -184,7 +184,9 @@
 
 static int adsi = 0;
 
-static unsigned int oseq;
+static unsigned int _oseq;
+
+ast_mutex_t oseq_lock;
 
 /*! Wait up to 16 seconds for first digit (FXO logic) */
 static int firstdigittimeout = 16000;
@@ -221,8 +223,8 @@
 /*! The private structures of the  mgcp channels are linked for
   ! selecting outgoing channels */
    
-#define MGCP_MAX_HEADERS	128
-#define MGCP_MAX_LINES		128
+#define MGCP_MAX_HEADERS	1024
+#define MGCP_MAX_LINES		1024
 
 struct mgcp_request {
 	int len;
@@ -409,7 +411,7 @@
 static int transmit_notify_request_with_callerid(struct mgcp_subchannel *sub, char *tone, char *callernum, char *callername);
 static int transmit_modify_with_sdp(struct mgcp_subchannel *sub, struct ast_rtp *rtp, int codecs);
 static int transmit_connection_del(struct mgcp_subchannel *sub);
-static int transmit_audit_endpoint(struct mgcp_endpoint *p);
+static int transmit_audit_endpoint(struct mgcp_endpoint *p, char *parms);
 static void start_rtp(struct mgcp_subchannel *sub);
 static void handle_response(struct mgcp_endpoint *p, struct mgcp_subchannel *sub,  
                             int result, unsigned int ident, struct mgcp_request *resp);
@@ -661,8 +663,8 @@
 			else
 				gw->msgs = cur->next;
 
-			ast_log(LOG_WARNING, "Maximum retries exceeded for transaction %u on [%s]\n",
-				cur->seqno, gw->name);
+			ast_log(LOG_WARNING, "Maximum retries exceeded for transaction %u on [%s]\n[\n%s\n]\n",
+				cur->seqno, gw->name, cur->buf);
 
 			w = cur;
 			cur = cur->next;
@@ -1118,7 +1120,7 @@
 	if (!mgcpdebug) {
 		return CLI_SHOWUSAGE;
 	}
-	if (a->argc != 4)
+	if (a->argc < 4)
 		return CLI_SHOWUSAGE;
 	/* split the name into parts by null */
 	ename = a->argv[3];
@@ -1143,7 +1145,10 @@
 			while(me) {
 				if (!strcasecmp(me->name, ename)) {
 					found = 1;
-					transmit_audit_endpoint(me);
+					if (a->argc == 5)
+						transmit_audit_endpoint(me, a->argv[4]);
+					else
+						transmit_audit_endpoint(me, NULL);
 					break;
 				}
 				me = me->next;
@@ -2083,7 +2088,7 @@
 	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, int oseq)
 {
 	/* Initialize a response */
 	if (req->headers || req->len) {
@@ -2114,12 +2119,16 @@
 
 static int reqprep(struct mgcp_request *req, struct mgcp_endpoint *p, char *verb)
 {
+	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++;
+	if (_oseq > 999999999)
+		_oseq = 1;
+	oseq = _oseq;
+	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)
@@ -2243,6 +2252,7 @@
 	char local[256];
 	char tmp[80];
 	int x;
+	int oseq;
 	struct mgcp_endpoint *p = sub->parent;
 
 	if (ast_strlen_zero(sub->cxident) && rtp) {
@@ -2258,7 +2268,7 @@
 			strncat(local, tmp, sizeof(local) - strlen(local) - 1);
 		}
 	}
-	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]);
@@ -2280,6 +2290,7 @@
 	char tmp[80];
 	int x;
 	struct mgcp_endpoint *p = sub->parent;
+	int seqnum;
 
 	ast_copy_string(local, "p:20", sizeof(local));
 	for (x = 1; x <= AST_FORMAT_AUDIO_MASK; x <<= 1) {
@@ -2292,7 +2303,7 @@
 		ast_verb(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);
 	}
-	reqprep(&resp, p, "CRCX");
+	seqnum = reqprep(&resp, p, "CRCX");
 	add_header(&resp, "C", sub->callid);
 	add_header(&resp, "L", local);
 	add_header(&resp, "M", mgcp_cxmodes[sub->cxmode]);
@@ -2302,21 +2313,22 @@
 	add_sdp(&resp, sub, rtp);
 	/* fill in new fields */
 	resp.cmd = MGCP_CMD_CRCX;
-	resp.trid = oseq;
-	return send_request(p, sub, &resp, oseq);  /* SC */
+	resp.trid = seqnum;
+	return send_request(p, sub, &resp, seqnum);  /* SC */
 }
 
 static int transmit_notify_request(struct mgcp_subchannel *sub, char *tone)
 {
 	struct mgcp_request resp;
 	struct mgcp_endpoint *p = sub->parent;
+	int oseq;
 
 	if (mgcpdebug) {
 		ast_verb(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); /* SC */
 	switch (p->hookstate) {
 	case MGCP_ONHOOK:
@@ -2343,6 +2355,7 @@
 	struct timeval t = ast_tvnow();
 	struct ast_tm tm;
 	struct mgcp_endpoint *p = sub->parent;
+	int oseq;
 	
 	ast_localtime(&t, &tm, NULL);
 	n = callername;
@@ -2358,7 +2371,7 @@
 	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); /* SC */
 	switch (p->hookstate) {
 	case MGCP_ONHOOK:
@@ -2385,6 +2398,7 @@
 {
 	struct mgcp_request resp;
 	struct mgcp_endpoint *p = sub->parent;
+	int oseq;
 
 	if (ast_strlen_zero(sub->cxident)) {
 		/* We don't have a CXident yet, store the destination and
@@ -2395,7 +2409,7 @@
 		ast_verb(3, "Modified %s@%s-%d with new mode: %s on callid: %s\n",
 			p->name, p->parent->name, sub->id, mgcp_cxmodes[sub->cxmode], sub->callid);
 	}
-	reqprep(&resp, p, "MDCX");
+	oseq = reqprep(&resp, p, "MDCX");
 	add_header(&resp, "C", sub->callid);
 	add_header(&resp, "M", mgcp_cxmodes[sub->cxmode]);
 	/* X header should not be sent. kept for compatibility */
@@ -2426,13 +2440,17 @@
 		add_header(resp, "R", "L/hu(N),L/hf(N),D/[0-9#*](N)");
 }
 
-static int transmit_audit_endpoint(struct mgcp_endpoint *p)
+static int transmit_audit_endpoint(struct mgcp_endpoint *p, char *parms)
 {
 	struct mgcp_request resp;
-	reqprep(&resp, p, "AUEP");
+	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");
+	if (!parms)
+		add_header(&resp, "F", "I");
+	else
+		add_header(&resp, "F", parms);
 	/* fill in new fields */
 	resp.cmd = MGCP_CMD_AUEP;
 	resp.trid = oseq;
@@ -2443,12 +2461,13 @@
 {
 	struct mgcp_endpoint *p = sub->parent;
 	struct mgcp_request resp;
+	int oseq;
 
 	if (mgcpdebug) {
 		ast_verb(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);
@@ -2466,12 +2485,13 @@
 static int transmit_connection_del_w_params(struct mgcp_endpoint *p, char *callid, char *cxident)
 {
 	struct mgcp_request resp;
+	int oseq;
 
 	if (mgcpdebug) {
 		ast_verb(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);
@@ -2641,25 +2661,34 @@
 					}
 				}
 			}
+			if (result == 502) {
+				//transmit_audit_endpoint(p, NULL);
+				transmit_connection_del_w_params(p, NULL, NULL);
+			}
 		}
 
 		if (req->cmd == MGCP_CMD_AUEP) {
 			/* check stale connection ids */
 			if ((c = get_header(resp, "I"))) {
 				char *v, *n;
-				int len;
+				int len, newlen = 0;
+				ast_verb(3, "get_header:%s\n", c);
 				while ((v = get_csv(c, &len, &n))) {
+					ast_verb(3, "len %d, get_csv:%s\n", len, v);
 					if (len) {
 						if (strncasecmp(v, p->sub->cxident, len) &&
 						    strncasecmp(v, p->sub->next->cxident, len)) {
 							/* connection id not found. delete it */
 							char cxident[80] = "";
 
+#if 0
 							if (len > (sizeof(cxident) - 1))
-								len = sizeof(cxident) - 1;
-							ast_copy_string(cxident, v, len);
-							ast_verb(3, "Non existing connection id %s on %s@%s \n",
-									    cxident, p->name, gw->name);
+								newlen = sizeof(cxident) - 1;
+							else newlen = len;
+#endif
+							ast_copy_string(cxident, v, sizeof(cxident) - 1);
+							ast_verb(3, "len %d newlen %d %s Non existing connection id %s on %s@%s \n",
+									    len, newlen, v, cxident, p->name, gw->name);
 							transmit_connection_del_w_params(p, NULL, cxident);
 						}
 					}
@@ -3246,7 +3275,7 @@
 				/* Audit endpoint. 
 				 Idea is to prevent lost lines due to race conditions 
 				*/
-				transmit_audit_endpoint(p);
+				transmit_audit_endpoint(p, NULL);
 			}
 		}
 	} else if (!strcasecmp(req->verb, "CRCX")) {
@@ -4257,9 +4286,10 @@
 					e->capability = capability;
 					e->dtmfmode = dtmfmode;
 					e->adsi = adsi;
-					if (!strcasecmp(v->name, "trunk"))
+					if (!strcasecmp(v->name, "trunk")) {
 						e->type = TYPE_TRUNK;
-					else
+						//e->needaudit = 0;
+					} else
 						e->type = TYPE_LINE;
 
 					e->immediate = immediate;
@@ -4713,7 +4743,8 @@
 		e = g->endpoints;
 		while (e && e->needaudit) {
 			e->needaudit = 0;
-			transmit_audit_endpoint(e);
+			//transmit_audit_endpoint(e, NULL);
+			transmit_connection_del_w_params(e, NULL, NULL);
 			ast_verb(3, "MGCP Auditing endpoint %s@%s for hookstate\n", e->name, g->name);
 			e = e->next;
 		}
@@ -4726,6 +4757,7 @@
 /*! \brief  load_module: PBX load module - initialization ---*/
 static int load_module(void)
 {
+	ast_mutex_init(&oseq_lock);
 	if (!(sched = sched_context_create())) {
 		ast_log(LOG_WARNING, "Unable to create schedule context\n");
 		return AST_MODULE_LOAD_FAILURE;




More information about the svn-commits mailing list