瀏覽代碼

script: udp_mtu fallback script config & commands

new config variables:
 - udp_mtu = number  - size in bytes after which fallback to
   another protocol will be attempted. Default 0 (off),
   recommended 1300.
 - udp_mtu_try_proto = TCP|TLS|SCTP|UDP - protocol to fallback to.
   Default: UDP (off).
 - force_rport = yes|no - global force_rport().

new script commands:
 - udp_mtu_try_proto(TCP|TLS|SCTP|UDP) - like udp_mtu_try_proto
   above but works on a per packet basis and not globally.


Author: Andrei Pelinescu-Onciul <[email protected]>
Andrei Pelinescu-Onciul 16 年之前
父節點
當前提交
f62c96d869
共有 7 個文件被更改,包括 85 次插入9 次删除
  1. 22 2
      NEWS
  2. 5 0
      action.c
  3. 5 0
      cfg.lex
  4. 16 0
      cfg.y
  5. 8 6
      forward.c
  6. 26 0
      route.c
  7. 3 1
      route_struct.h

+ 22 - 2
NEWS

@@ -200,6 +200,10 @@ modules:
                         - t_set_retr(t1, t2) - changes the retransmissions
                            intervals on the fly, on a per transaction basis.
 core:
+             - fallback to tcp or other congestion controlled transport 
+               protocol if a forwarded udp sip request is greater then 
+               udp_mtu (config). Default off. See udp_mtu and 
+               udp_mtu_try_proto.
              - sctp support (one-to-many, work in progress, for now linux
                only with no fallback to one-to-one on full send buffers)
              - partial cygwin (windows) support revived: core+static modules, 
@@ -220,6 +224,17 @@ core:
                between the short name and long name in cache as CNAME record
 
 new config variables:
+  udp_mtu = number - fallback to another protocol (udp_mtu_try_proto must be
+                     set also either globally or per packet) if the constructed
+                     request size is greater then udp_mtu.
+                     Recommended size: 1300. Default: 0 (off).
+  udp_mtu_try_proto = TCP|TLS|SCTP|UDP - if udp_mtu !=0 and udp forwarded
+                     request size (after adding all the "local" headers) >
+                     udp_mtu, use this protocol instead of udp. Only the
+                     Via header will be updated (e.g. The Record-Route
+                     will be the one built for udp).
+                     Default: UDP (off). Recommended: TCP.
+  force_rport =yes/no - like force_rport(), but works globally.
   disable_sctp = yes/no - disable sctp support (default auto, see enable_sctp)
   enable_sctp = 0/1/2  - disable (0)/enable (1)/auto (2) sctp support, 
                          default auto (2)
@@ -240,8 +255,8 @@ new config variables:
                       hosts (default: 0).
   server_id = number - A configurable unique server id that can be used to
                        discriminate server instances within a cluster of
-                       servers when all other information, such as IP adddresses
-                       are same.
+                       servers when all other information, such as IP addresses
+                       are the same.
   loadpath = <modules path> - directory where to load the modules from (-L
      equivalent); modules can be loaded simply by specifying their name
      (loadmodule "maxfwd")
@@ -336,6 +351,11 @@ new config variables:
     is not initialized at startup and cannot be enabled runtime,
     that saves some memory.
 
+new script commands:
+  udp_mtu_try_proto(TCP|TLS|SCTP|UDP) - same as udp_mtu_try_proto=... (see
+    above), but works per packet and not globally.
+
+
 build system:
  - check defines and includes used at compile time and if different 
    force rebuilding everything in the current dir (creates a new file: 

+ 5 - 0
action.c

@@ -46,6 +46,7 @@
  *              (andrei)
  *  2007-06-14  run_actions & do_action need a ctx or handle now, no more 
  *               static vars (andrei)
+ *  2008-12-17  added UDP_MTU_TRY_PROTO_T (andrei)
  */
 
 
@@ -731,6 +732,10 @@ int do_action(struct run_act_ctx* h, struct action* a, struct sip_msg* msg)
 			msg->msg_flags|=FL_FORCE_RPORT;
 			ret=1; /* continue processing */
 			break;
+		case UDP_MTU_TRY_PROTO_T:
+			msg->msg_flags|= (unsigned int)a->val[0].u.number & FL_MTU_FB_MASK;
+			ret=1; /* continue processing */
+			break;
 		case SET_ADV_ADDR_T:
 			if (a->val[0].type!=STR_ST){
 				LOG(L_CRIT, "BUG: do_action: bad set_advertised_address() "

+ 5 - 0
cfg.lex

@@ -143,6 +143,8 @@ ROUTE_SEND onsend_route
 EXEC	exec
 FORCE_RPORT		"force_rport"|"add_rport"
 FORCE_TCP_ALIAS		"force_tcp_alias"|"add_tcp_alias"
+UDP_MTU		"udp_mtu"
+UDP_MTU_TRY_PROTO	"udp_mtu_try_proto"
 SETFLAG		setflag
 RESETFLAG	resetflag
 ISFLAGSET	isflagset
@@ -463,6 +465,9 @@ EAT_ABLE	[\ \t\b\r]
 <INITIAL>{FORCE_RPORT}	{ count(); yylval.strval=yytext; return FORCE_RPORT; }
 <INITIAL>{FORCE_TCP_ALIAS}	{ count(); yylval.strval=yytext;
 								return FORCE_TCP_ALIAS; }
+<INITIAL>{UDP_MTU}	{ count(); yylval.strval=yytext; return UDP_MTU; }
+<INITIAL>{UDP_MTU_TRY_PROTO}	{ count(); yylval.strval=yytext;
+									return UDP_MTU_TRY_PROTO; }
 <INITIAL>{IF}	{ count(); yylval.strval=yytext; return IF; }
 <INITIAL>{ELSE}	{ count(); yylval.strval=yytext; return ELSE; }
 

+ 16 - 0
cfg.y

@@ -117,6 +117,7 @@
 #include "tcp_init.h"
 #include "tcp_options.h"
 #include "sctp_options.h"
+#include "msg_translator.h"
 
 #include "config.h"
 #include "cfg_core.h"
@@ -244,6 +245,8 @@ static void free_socket_id_lst(struct socket_id* i);
 %token REVERT_URI
 %token FORCE_RPORT
 %token FORCE_TCP_ALIAS
+%token UDP_MTU
+%token UDP_MTU_TRY_PROTO
 %token IF
 %token ELSE
 %token SET_ADV_ADDRESS
@@ -1248,6 +1251,15 @@ assign_stm:
 	| STUN_ALLOW_FP EQUAL NUMBER { IF_STUN(stun_allow_fp=$3) ; }
 	| STUN_ALLOW_FP EQUAL error{ yyerror("number expected"); }
     | SERVER_ID EQUAL NUMBER { server_id=$3; }
+	| UDP_MTU EQUAL NUMBER { default_core_cfg.udp_mtu=$3; }
+	| UDP_MTU EQUAL error { yyerror("number expected"); }
+	| FORCE_RPORT EQUAL NUMBER 
+		{ default_core_cfg.force_rport=$3; fix_global_req_flags(0); }
+	| FORCE_RPORT EQUAL error { yyerror("boolean value expected"); }
+	| UDP_MTU_TRY_PROTO EQUAL proto
+		{ default_core_cfg.udp_mtu_try_proto=$3; fix_global_req_flags(0); }
+	| UDP_MTU_TRY_PROTO EQUAL error
+		{ yyerror("TCP, TLS, SCTP or UDP expected"); }
 	| cfg_var
 	| error EQUAL { yyerror("unknown config variable"); }
 	;
@@ -2322,6 +2334,10 @@ cmd:
 		#endif
 	}
 	| FORCE_TCP_ALIAS LPAREN error RPAREN	{$$=0; yyerror("bad argument, number expected"); }
+	| UDP_MTU_TRY_PROTO LPAREN proto RPAREN
+		{ $$=mk_action(UDP_MTU_TRY_PROTO_T, 1, NUMBER_ST, $3); }
+	| UDP_MTU_TRY_PROTO LPAREN error RPAREN
+		{ $$=0; yyerror("bad argument, UDP, TCP, TLS or SCTP expected"); }
 	| SET_ADV_ADDRESS LPAREN listen_id RPAREN {
 		$$=0;
 		if ((str_tmp=pkg_malloc(sizeof(str)))==0) {

+ 8 - 6
forward.c

@@ -342,6 +342,7 @@ int forward_request(struct sip_msg* msg, str* dst, unsigned short port,
 	struct socket_info* orig_send_sock; /* initial send_sock */
 	int ret;
 	struct ip_addr ip; /* debugging only */
+	char proto;
 #ifdef USE_DNS_FAILOVER
 	struct socket_info* prev_send_sock;
 	int err;
@@ -354,6 +355,7 @@ int forward_request(struct sip_msg* msg, str* dst, unsigned short port,
 	
 	buf=0;
 	orig_send_sock=send_info->send_sock;
+	proto=send_info->proto;
 	ret=0;
 
 	if(dst){
@@ -361,7 +363,7 @@ int forward_request(struct sip_msg* msg, str* dst, unsigned short port,
 		if (cfg_get(core, core_cfg, use_dns_failover)){
 			dns_srv_handle_init(&dns_srv_h);
 			err=dns_sip_resolve2su(&dns_srv_h, &send_info->to, dst, port,
-									&send_info->proto, dns_flags);
+									&proto, dns_flags);
 			if (err!=0){
 				LOG(L_ERR, "ERROR: forward_request: resolving \"%.*s\""
 						" failed: %s [%d]\n", dst->len, ZSW(dst->s),
@@ -371,7 +373,7 @@ int forward_request(struct sip_msg* msg, str* dst, unsigned short port,
 			}
 		}else
 #endif
-		if (sip_hostport2su(&send_info->to, dst, port, &send_info->proto)<0){
+		if (sip_hostport2su(&send_info->to, dst, port, &proto)<0){
 			LOG(L_ERR, "ERROR: forward_request: bad host name %.*s,"
 						" dropping packet\n", dst->len, ZSW(dst->s));
 			ret=E_BAD_ADDRESS;
@@ -410,12 +412,11 @@ int forward_request(struct sip_msg* msg, str* dst, unsigned short port,
 	do{
 #endif
 		if (orig_send_sock==0) /* no forced send_sock => find it **/
-			send_info->send_sock=get_send_socket(msg, &send_info->to,
-												send_info->proto);
+			send_info->send_sock=get_send_socket(msg, &send_info->to, proto);
 		if (send_info->send_sock==0){
 			LOG(L_ERR, "forward_req: ERROR: cannot forward to af %d, proto %d "
 						"no corresponding listening socket\n",
-						send_info->to.s.sa_family, send_info->proto);
+						send_info->to.s.sa_family, proto);
 			ret=ser_error=E_NO_SOCKET;
 #ifdef USE_DNS_FAILOVER
 			/* continue, maybe we find a socket for some other ip */
@@ -431,6 +432,7 @@ int forward_request(struct sip_msg* msg, str* dst, unsigned short port,
 			prev_send_sock=send_info->send_sock;
 #endif
 			if (buf) pkg_free(buf);
+			send_info->proto=proto;
 			buf = build_req_buf_from_sip_req(msg, &len, send_info);
 			if (!buf){
 				LOG(L_ERR, "ERROR: forward_request: building failed\n");
@@ -496,7 +498,7 @@ int forward_request(struct sip_msg* msg, str* dst, unsigned short port,
 	}while(dst && cfg_get(core, core_cfg, use_dns_failover) &&
 			dns_srv_handle_next(&dns_srv_h, err) && 
 			((err=dns_sip_resolve2su(&dns_srv_h, &send_info->to, dst, port,
-								  &send_info->proto, dns_flags))==0));
+										&proto, dns_flags))==0));
 	if ((err!=0) && (err!=-E_DNS_EOR)){
 		LOG(L_ERR, "ERROR:  resolving %.*s host name in uri"
 							" failed: %s [%d] (dropping packet)\n",

+ 26 - 0
route.c

@@ -564,6 +564,32 @@ static int fix_actions(struct action* a)
 				t->val[0].u.data=si;
 				t->val[0].type=SOCKETINFO_ST;
 				break;
+			case UDP_MTU_TRY_PROTO_T:
+				if (t->val[0].type!=NUMBER_ST){
+					LOG(L_CRIT, "BUG: fix_actions: invalid subtype"
+								"%d for udp_mtu_try_proto\n",
+								t->val[0].type);
+					return E_BUG;
+				}
+				switch(t->val[0].u.number){
+					case PROTO_UDP:
+						t->val[0].u.number=0;
+						break;
+					case PROTO_TCP:
+						t->val[0].u.number=FL_MTU_TCP_FB;
+						break;
+					case PROTO_TLS:
+						t->val[0].u.number=FL_MTU_TLS_FB;
+						break;
+					case PROTO_SCTP:
+						t->val[0].u.number=FL_MTU_SCTP_FB;
+						break;
+					default:
+						LOG(L_CRIT, "BUG: fix actions: invalid argument for"
+									" udp_mtu_try_proto (%d)\n", 
+									(unsigned int)t->val[0].u.number);
+				}
+				break;
 		}
 	}
 	return 0;

+ 3 - 1
route_struct.h

@@ -35,6 +35,7 @@
  *  2004-02-24  added LOAD_AVP_T and AVP_TO_URI_T (bogdan)
  *  2005-12-11  added SND{IP,PORT,PROTO,AF}_O & TO{IP,PORT}_O (andrei)
  *  2005-12-19  select framework added SELECT_O and SELECT_ST (mma)
+ *  2008-12-17  added UDP_MTU_TRY_PROTO_T (andrei)
  */
 
 
@@ -89,7 +90,8 @@ enum { FORWARD_T=1, SEND_T, DROP_T, LOG_T, ERROR_T, ROUTE_T, EXEC_T,
 		AVP_TO_URI_T,
 		FORCE_SEND_SOCKET_T,
 		ASSIGN_T,
-		ADD_T
+		ADD_T,
+		UDP_MTU_TRY_PROTO_T
 };
 enum { NOSUBTYPE=0, STRING_ST, NET_ST, NUMBER_ST, IP_ST, RE_ST, PROXY_ST,
 		EXPR_ST, ACTIONS_ST, MODEXP_ST, MODFIXUP_ST, URIHOST_ST, URIPORT_ST,