[svn-commits] oej: branch oej/iaxtrunkfix-1.2 r44779 - in /team/oej/iaxtrunkfix-1.2: ./ cha...

svn-commits at lists.digium.com svn-commits at lists.digium.com
Tue Oct 10 02:43:13 MST 2006


Author: oej
Date: Tue Oct 10 04:43:12 2006
New Revision: 44779

URL: http://svn.digium.com/view/asterisk?rev=44779&view=rev
Log:
Add patch for setting MTU on trunks.

With a large amount of traffic on IAX2 trunks, there is bad voice quality due to the fact that the
IAX2 trunking scheme depends on the Linux system to handle fragmentation of UDP packets. This is
not very efficient. This patch adds the ability to set an MTU size for *ALL* iAX2 trunks in
Asterisk 1.2. In the patch for svn trunk, we will add new features, like setting MTU per trunk.
In the case of Asterisk 1.2, we wanted a small clean patch to be able to get voice quality back
without changing a lot of source code.

The default behaviour is changed so that we send multiple UDP packets on IAX2 trunks where
the trunk packet size exceeds a standard Ethernet MTU minus overhead for PPTP and IPsec.
If you want to disable this behaviour, set trunkmtu=0 in the [general] section of iax.conf.

This patch is created by Voop AS in Norway.

Modified:
    team/oej/iaxtrunkfix-1.2/   (props changed)
    team/oej/iaxtrunkfix-1.2/channels/chan_iax2.c

Propchange: team/oej/iaxtrunkfix-1.2/
------------------------------------------------------------------------------
    automerge = http://edvina.net/training/

Propchange: team/oej/iaxtrunkfix-1.2/
------------------------------------------------------------------------------
    automerge-email = oej at edvina.net

Modified: team/oej/iaxtrunkfix-1.2/channels/chan_iax2.c
URL: http://svn.digium.com/view/asterisk/team/oej/iaxtrunkfix-1.2/channels/chan_iax2.c?rev=44779&r1=44778&r2=44779&view=diff
==============================================================================
--- team/oej/iaxtrunkfix-1.2/channels/chan_iax2.c (original)
+++ team/oej/iaxtrunkfix-1.2/channels/chan_iax2.c Tue Oct 10 04:43:12 2006
@@ -141,6 +141,15 @@
 static const char desc[] = "Inter Asterisk eXchange (Ver 2)";
 static const char tdesc[] = "Inter Asterisk eXchange Driver (Ver 2)";
 static const char channeltype[] = "IAX2";
+
+
+/*! \brief Maximum transimission unit for the UDP packet in the trunk not to be
+    fragmented. This is based on 1516 - ethernet - ip - udp - iax minus one g711 frame = 1240 */
+#define MAX_TRUNK_MTU 1240 
+
+static int global_max_trunk_mtu; 	/*!< Maximum MTU, 0 if not used */
+static int trunk_timed, trunk_untimed, trunk_maxmtu, trunk_nmaxmtu ; 	/*!< Trunk MTU statistics */
+
 
 static char context[80] = "default";
 
@@ -748,6 +757,8 @@
 static int iax2_sendtext(struct ast_channel *c, const char *text);
 static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img);
 static int iax2_sendhtml(struct ast_channel *c, int subclass, const char *data, int datalen);
+static int send_trunk(struct iax2_trunk_peer *tpeer, struct timeval *now); 
+
 static int iax2_call(struct ast_channel *c, char *dest, int timeout);
 static int iax2_hangup(struct ast_channel *c);
 static int iax2_answer(struct ast_channel *c);
@@ -2052,9 +2063,47 @@
 	ast_cli(fd, "    IAX Statistics\n");
 	ast_cli(fd, "---------------------\n");
 	ast_cli(fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes());
+	ast_cli(fd, "%d timed and %d untimed transmits; MTU %d/%d/%d\n", trunk_timed, trunk_untimed, 
+        	trunk_maxmtu, trunk_nmaxmtu, global_max_trunk_mtu);
 	ast_cli(fd, "Packets in transmit queue: %d dead, %d final, %d total\n", dead, final, cnt);
+
+        trunk_timed = trunk_untimed = 0; 
+        if (trunk_maxmtu > trunk_nmaxmtu)
+		trunk_nmaxmtu = trunk_maxmtu; 
+	trunk_maxmtu = 0; 
+
 	return RESULT_SUCCESS;
 }
+
+
+/*! \brief Set trunk MTU from CLI */
+static int iax2_set_mtu(int fd, int argc, char *argv[])
+{
+	int mtuv;
+
+	if (argc != 4)
+		return RESULT_SHOWUSAGE; 
+	if (strncasecmp(argv[3], "default", strlen(argv[3])) == 0) 
+		mtuv = MAX_TRUNK_MTU; 
+	else                                         
+		mtuv = atoi(argv[3]); 
+
+	if (mtuv == 0) {
+		ast_cli(fd, "Trunk MTU control disabled (mtu was %d)\n", global_max_trunk_mtu); 
+		global_max_trunk_mtu = 0; 
+		return RESULT_SUCCESS; 
+	}
+	if (mtuv < 172 || mtuv > 4000) {
+		ast_cli(fd, "Trunk MTU must be between 172 and 4000\n"); 
+		return RESULT_SHOWUSAGE; 
+	}
+	ast_cli(fd, "Trunk MTU changed from %d to %d\n", global_max_trunk_mtu, mtuv); 
+	global_max_trunk_mtu = mtuv; 
+	return RESULT_SUCCESS;
+}
+
+
+
 
 static int iax2_show_cache(int fd, int argc, char *argv[])
 {
@@ -3754,6 +3803,8 @@
 	struct ast_frame *f;
 	struct iax2_trunk_peer *tpeer;
 	void *tmp, *ptr;
+	struct timeval now;
+	int res; 
 	struct ast_iax2_meta_trunk_entry *met;
 	struct ast_iax2_meta_trunk_mini *mtm;
 	char iabuf[INET_ADDRSTRLEN];
@@ -3804,6 +3855,18 @@
 		tpeer->trunkdatalen += f->datalen;
 
 		tpeer->calls++;
+
+		/* track the largest mtu we actually have sent */
+		if (tpeer->trunkdatalen + f->datalen + 4 > trunk_maxmtu) 
+			trunk_maxmtu = tpeer->trunkdatalen + f->datalen + 4 ; 
+
+		/* if we have enough for a full MTU, ship it now without waiting */
+		if (global_max_trunk_mtu > 0 && tpeer->trunkdatalen + f->datalen + 4 >= global_max_trunk_mtu) {
+			gettimeofday(&now, NULL);
+			res = send_trunk(tpeer, &now); 
+			trunk_untimed ++; 
+		}
+
 		ast_mutex_unlock(&tpeer->lock);
 	}
 	return 0;
@@ -6121,6 +6184,7 @@
 			drop = tpeer;
 		} else {
 			res = send_trunk(tpeer, &now);
+			trunk_timed++; 
 			if (iaxtrunkdebug)
 				ast_verbose(" - Trunk peer (%s:%d) has %d call chunk%s in transit, %d bytes backloged and has hit a high water mark of %d bytes\n", ast_inet_ntoa(iabuf, sizeof(iabuf), tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port), res, (res != 1) ? "s" : "", tpeer->trunkdatalen, tpeer->trunkdataalloc);
 		}		
@@ -8708,6 +8772,7 @@
 	int format;
 	int portno = IAX_DEFAULT_PORTNO;
 	int  x;
+	int mtuv; 
 	struct iax2_user *user;
 	struct iax2_peer *peer;
 	struct ast_netsock *ns;
@@ -8847,6 +8912,15 @@
 			trunkfreq = atoi(v->value);
 			if (trunkfreq < 10)
 				trunkfreq = 10;
+		} else if (!strcasecmp(v->name, "trunkmtu")) {
+			mtuv = atoi(v->value);
+			if (mtuv  == 0 )  
+				global_max_trunk_mtu = 0; 
+			else if (mtuv >= 172 && mtuv < 4000) 
+				global_max_trunk_mtu = mtuv; 
+			else 
+				ast_log(LOG_NOTICE, "trunkmtu value out of bounds (%d) at line %d\n",
+					mtuv, v->lineno); 
 		} else if (!strcasecmp(v->name, "autokill")) {
 			if (sscanf(v->value, "%d", &x) == 1) {
 				if (x >= 0)
@@ -8964,6 +9038,7 @@
 	struct iax2_peer *peer;
 	ast_copy_string(accountcode, "", sizeof(accountcode));
 	ast_copy_string(language, "", sizeof(language));
+	global_max_trunk_mtu = MAX_TRUNK_MTU; 
 	amaflags = 0;
 	delayreject = 0;
 	ast_clear_flag((&globalflags), IAX_NOTRANSFER);	
@@ -8973,6 +9048,9 @@
 	set_config(config,1);
 	prune_peers();
 	prune_users();
+        trunk_timed = trunk_untimed = 0; 
+	trunk_nmaxmtu = trunk_maxmtu = 0; 
+
 	for (reg = registrations; reg; reg = reg->next)
 		iax2_do_register(reg);
 	/* Qualify hosts, too */
@@ -9482,6 +9560,13 @@
 "Usage: iax show stats\n"
 "       Display statistics on IAX channel driver.\n";
 
+static char set_mtu_usage[] =
+"Usage: iax2 set mtu <value>\n"
+"       Set the system-wide IAX IP mtu to <value> bytes net or zero to disable.\n"
+"       Disabling means that the operating system must handle fragmentation of UDP packets\n"
+"       when the IAX2 trunk packet exceeds the UDP payload size.\n"
+"       This is substantially below the IP mtu. Try 1240 on ethernets.\n"
+"       Must be 172 or greater for G.711 samples.\n"; 
 static char show_cache_usage[] =
 "Usage: iax show cache\n"
 "       Display currently cached IAX Dialplan results.\n";
@@ -9587,6 +9672,8 @@
 	  "Prune a cached realtime lookup", prune_realtime_usage, complete_iax2_show_peer },
 	{ { "iax2", "reload", NULL }, iax2_reload,
 	  "Reload IAX configuration", iax2_reload_usage },
+	{ { "iax2", "set", "mtu", NULL },iax2_set_mtu, 
+	  "Set the IAX systemwide trunking MTU",set_mtu_usage },
 	{ { "iax2", "show", "users", NULL }, iax2_show_users,
 	  "Show defined IAX users", show_users_usage },
 	{ { "iax2", "show", "firmware", NULL }, iax2_show_firmware,



More information about the svn-commits mailing list