[asterisk-commits] russell: branch 1.4 r86371 - in /branches/1.4: channels/ configs/

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Thu Oct 18 16:14:16 CDT 2007


Author: russell
Date: Thu Oct 18 16:14:15 2007
New Revision: 86371

URL: http://svn.digium.com/view/asterisk?view=rev&rev=86371
Log:
Add support for setting the maximum trunk size for IAX2 trunking

Modified:
    branches/1.4/channels/chan_iax2.c
    branches/1.4/configs/iax.conf.sample

Modified: branches/1.4/channels/chan_iax2.c
URL: http://svn.digium.com/view/asterisk/branches/1.4/channels/chan_iax2.c?view=diff&rev=86371&r1=86370&r2=86371
==============================================================================
--- branches/1.4/channels/chan_iax2.c (original)
+++ branches/1.4/channels/chan_iax2.c Thu Oct 18 16:14:15 2007
@@ -141,6 +141,15 @@
 
 static const char tdesc[] = "Inter Asterisk eXchange Driver (Ver 2)";
 
+
+/*! \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";
 
 static char language[MAX_LANGUAGE] = "";
@@ -375,6 +384,7 @@
 	unsigned char *trunkdata;
 	unsigned int trunkdatalen;
 	unsigned int trunkdataalloc;
+	int trunkmaxmtu;
 	struct iax2_trunk_peer *next;
 	int trunkerror;
 	int calls;
@@ -831,6 +841,7 @@
 static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen);
 static int iax2_transfer(struct ast_channel *c, const char *dest);
 static int iax2_write(struct ast_channel *c, struct ast_frame *f);
+static int send_trunk(struct iax2_trunk_peer *tpeer, struct timeval *now);
 static int send_command(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
 static int send_command_final(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
 static int send_command_immediate(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
@@ -2323,8 +2334,41 @@
 	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\n", dead, final, cnt);
+
+	trunk_timed = trunk_untimed = 0;
+	if (trunk_maxmtu > trunk_nmaxmtu)
+		trunk_nmaxmtu = trunk_maxmtu;
 	
+	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;
 }
 
@@ -3813,6 +3857,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;
 
@@ -3860,6 +3906,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;
@@ -6295,6 +6353,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(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port), res, (res != 1) ? "s" : "", tpeer->trunkdatalen, tpeer->trunkdataalloc);
 		}		
@@ -9470,6 +9529,7 @@
 	int format;
 	int portno = IAX_DEFAULT_PORTNO;
 	int  x;
+	int mtuv; 
 	struct iax2_user *user;
 	struct iax2_peer *peer;
 	struct ast_netsock *ns;
@@ -9635,6 +9695,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)
@@ -9832,6 +9901,7 @@
 	strcpy(language, "");
 	strcpy(mohinterpret, "default");
 	strcpy(mohsuggest, "");
+	global_max_trunk_mtu = MAX_TRUNK_MTU;
 	amaflags = 0;
 	delayreject = 0;
 	ast_clear_flag((&globalflags), IAX_NOTRANSFER);	
@@ -9842,6 +9912,10 @@
 	set_config(config, 1);
 	prune_peers();
 	prune_users();
+
+	trunk_timed = trunk_untimed = 0;
+	trunk_nmaxmtu = trunk_maxmtu = 0;
+
 	AST_LIST_LOCK(&registrations);
 	AST_LIST_TRAVERSE(&registrations, reg, entry)
 		iax2_do_register(reg);
@@ -10342,6 +10416,13 @@
 "Usage: iax2 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: iax2 show cache\n"
 "       Display currently cached IAX Dialplan results.\n";
@@ -10495,6 +10576,10 @@
 	{ { "iax2", "show", "threads", NULL },
 	iax2_show_threads, "Display IAX helper thread info",
 	show_threads_usage, NULL, },
+
+ 	{ { "iax2", "set", "mtu", NULL },
+ 	iax2_set_mtu, "Set the IAX systemwide trunking MTU",
+ 	set_mtu_usage, NULL, NULL },
 
 	{ { "iax2", "show", "users", NULL },
 	iax2_show_users, "List defined IAX users",

Modified: branches/1.4/configs/iax.conf.sample
URL: http://svn.digium.com/view/asterisk/branches/1.4/configs/iax.conf.sample?view=diff&rev=86371&r1=86370&r2=86371
==============================================================================
--- branches/1.4/configs/iax.conf.sample (original)
+++ branches/1.4/configs/iax.conf.sample Thu Oct 18 16:14:15 2007
@@ -152,7 +152,16 @@
 ; minregexpire = 60
 ; maxregexpire = 60
 ;
+; With a large amount of traffic on IAX2 trunks, there is a risk of bad voice quality due to
+; the fact that the IAX2 trunking scheme depends on the Linux system to handle fragmentation of
+; UDP packets. This may not be very efficient. 
+; This setting sets the maximum transmission unit for IAX2 UDP trunking.
+; default is 1240 bytes. Zero disables this functionality and let's the O/S handle fragmentation.
+;
+; trunkmtu = 0
+;
 ; IAX helper threads
+
 ; Establishes the number of iax helper threads to handle I/O.
 ; iaxthreadcount = 10
 ; Establishes the number of extra dynamic threads that may be spawned to handle I/O




More information about the asterisk-commits mailing list