Browse code

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 <andrei@iptel.org>

Andrei Pelinescu-Onciul authored on 18/12/2008 16:09:16
Showing 7 changed files
... ...
@@ -200,6 +200,10 @@ modules:
200 200
                         - t_set_retr(t1, t2) - changes the retransmissions
201 201
                            intervals on the fly, on a per transaction basis.
202 202
 core:
203
+             - fallback to tcp or other congestion controlled transport 
204
+               protocol if a forwarded udp sip request is greater then 
205
+               udp_mtu (config). Default off. See udp_mtu and 
206
+               udp_mtu_try_proto.
203 207
              - sctp support (one-to-many, work in progress, for now linux
204 208
                only with no fallback to one-to-one on full send buffers)
205 209
              - partial cygwin (windows) support revived: core+static modules, 
... ...
@@ -220,6 +224,17 @@ core:
220 220
                between the short name and long name in cache as CNAME record
221 221
 
222 222
 new config variables:
223
+  udp_mtu = number - fallback to another protocol (udp_mtu_try_proto must be
224
+                     set also either globally or per packet) if the constructed
225
+                     request size is greater then udp_mtu.
226
+                     Recommended size: 1300. Default: 0 (off).
227
+  udp_mtu_try_proto = TCP|TLS|SCTP|UDP - if udp_mtu !=0 and udp forwarded
228
+                     request size (after adding all the "local" headers) >
229
+                     udp_mtu, use this protocol instead of udp. Only the
230
+                     Via header will be updated (e.g. The Record-Route
231
+                     will be the one built for udp).
232
+                     Default: UDP (off). Recommended: TCP.
233
+  force_rport =yes/no - like force_rport(), but works globally.
223 234
   disable_sctp = yes/no - disable sctp support (default auto, see enable_sctp)
224 235
   enable_sctp = 0/1/2  - disable (0)/enable (1)/auto (2) sctp support, 
225 236
                          default auto (2)
... ...
@@ -240,8 +255,8 @@ new config variables:
240 240
                       hosts (default: 0).
241 241
   server_id = number - A configurable unique server id that can be used to
242 242
                        discriminate server instances within a cluster of
243
-                       servers when all other information, such as IP adddresses
244
-                       are same.
243
+                       servers when all other information, such as IP addresses
244
+                       are the same.
245 245
   loadpath = <modules path> - directory where to load the modules from (-L
246 246
      equivalent); modules can be loaded simply by specifying their name
247 247
      (loadmodule "maxfwd")
... ...
@@ -336,6 +351,11 @@ new config variables:
336 336
     is not initialized at startup and cannot be enabled runtime,
337 337
     that saves some memory.
338 338
 
339
+new script commands:
340
+  udp_mtu_try_proto(TCP|TLS|SCTP|UDP) - same as udp_mtu_try_proto=... (see
341
+    above), but works per packet and not globally.
342
+
343
+
339 344
 build system:
340 345
  - check defines and includes used at compile time and if different 
341 346
    force rebuilding everything in the current dir (creates a new file: 
... ...
@@ -46,6 +46,7 @@
46 46
  *              (andrei)
47 47
  *  2007-06-14  run_actions & do_action need a ctx or handle now, no more 
48 48
  *               static vars (andrei)
49
+ *  2008-12-17  added UDP_MTU_TRY_PROTO_T (andrei)
49 50
  */
50 51
 
51 52
 
... ...
@@ -731,6 +732,10 @@ int do_action(struct run_act_ctx* h, struct action* a, struct sip_msg* msg)
731 731
 			msg->msg_flags|=FL_FORCE_RPORT;
732 732
 			ret=1; /* continue processing */
733 733
 			break;
734
+		case UDP_MTU_TRY_PROTO_T:
735
+			msg->msg_flags|= (unsigned int)a->val[0].u.number & FL_MTU_FB_MASK;
736
+			ret=1; /* continue processing */
737
+			break;
734 738
 		case SET_ADV_ADDR_T:
735 739
 			if (a->val[0].type!=STR_ST){
736 740
 				LOG(L_CRIT, "BUG: do_action: bad set_advertised_address() "
... ...
@@ -143,6 +143,8 @@ ROUTE_SEND onsend_route
143 143
 EXEC	exec
144 144
 FORCE_RPORT		"force_rport"|"add_rport"
145 145
 FORCE_TCP_ALIAS		"force_tcp_alias"|"add_tcp_alias"
146
+UDP_MTU		"udp_mtu"
147
+UDP_MTU_TRY_PROTO	"udp_mtu_try_proto"
146 148
 SETFLAG		setflag
147 149
 RESETFLAG	resetflag
148 150
 ISFLAGSET	isflagset
... ...
@@ -463,6 +465,9 @@ EAT_ABLE	[\ \t\b\r]
463 463
 <INITIAL>{FORCE_RPORT}	{ count(); yylval.strval=yytext; return FORCE_RPORT; }
464 464
 <INITIAL>{FORCE_TCP_ALIAS}	{ count(); yylval.strval=yytext;
465 465
 								return FORCE_TCP_ALIAS; }
466
+<INITIAL>{UDP_MTU}	{ count(); yylval.strval=yytext; return UDP_MTU; }
467
+<INITIAL>{UDP_MTU_TRY_PROTO}	{ count(); yylval.strval=yytext;
468
+									return UDP_MTU_TRY_PROTO; }
466 469
 <INITIAL>{IF}	{ count(); yylval.strval=yytext; return IF; }
467 470
 <INITIAL>{ELSE}	{ count(); yylval.strval=yytext; return ELSE; }
468 471
 
... ...
@@ -117,6 +117,7 @@
117 117
 #include "tcp_init.h"
118 118
 #include "tcp_options.h"
119 119
 #include "sctp_options.h"
120
+#include "msg_translator.h"
120 121
 
121 122
 #include "config.h"
122 123
 #include "cfg_core.h"
... ...
@@ -244,6 +245,8 @@ static void free_socket_id_lst(struct socket_id* i);
244 244
 %token REVERT_URI
245 245
 %token FORCE_RPORT
246 246
 %token FORCE_TCP_ALIAS
247
+%token UDP_MTU
248
+%token UDP_MTU_TRY_PROTO
247 249
 %token IF
248 250
 %token ELSE
249 251
 %token SET_ADV_ADDRESS
... ...
@@ -1248,6 +1251,15 @@ assign_stm:
1248 1248
 	| STUN_ALLOW_FP EQUAL NUMBER { IF_STUN(stun_allow_fp=$3) ; }
1249 1249
 	| STUN_ALLOW_FP EQUAL error{ yyerror("number expected"); }
1250 1250
     | SERVER_ID EQUAL NUMBER { server_id=$3; }
1251
+	| UDP_MTU EQUAL NUMBER { default_core_cfg.udp_mtu=$3; }
1252
+	| UDP_MTU EQUAL error { yyerror("number expected"); }
1253
+	| FORCE_RPORT EQUAL NUMBER 
1254
+		{ default_core_cfg.force_rport=$3; fix_global_req_flags(0); }
1255
+	| FORCE_RPORT EQUAL error { yyerror("boolean value expected"); }
1256
+	| UDP_MTU_TRY_PROTO EQUAL proto
1257
+		{ default_core_cfg.udp_mtu_try_proto=$3; fix_global_req_flags(0); }
1258
+	| UDP_MTU_TRY_PROTO EQUAL error
1259
+		{ yyerror("TCP, TLS, SCTP or UDP expected"); }
1251 1260
 	| cfg_var
1252 1261
 	| error EQUAL { yyerror("unknown config variable"); }
1253 1262
 	;
... ...
@@ -2322,6 +2334,10 @@ cmd:
2322 2322
 		#endif
2323 2323
 	}
2324 2324
 	| FORCE_TCP_ALIAS LPAREN error RPAREN	{$$=0; yyerror("bad argument, number expected"); }
2325
+	| UDP_MTU_TRY_PROTO LPAREN proto RPAREN
2326
+		{ $$=mk_action(UDP_MTU_TRY_PROTO_T, 1, NUMBER_ST, $3); }
2327
+	| UDP_MTU_TRY_PROTO LPAREN error RPAREN
2328
+		{ $$=0; yyerror("bad argument, UDP, TCP, TLS or SCTP expected"); }
2325 2329
 	| SET_ADV_ADDRESS LPAREN listen_id RPAREN {
2326 2330
 		$$=0;
2327 2331
 		if ((str_tmp=pkg_malloc(sizeof(str)))==0) {
... ...
@@ -342,6 +342,7 @@ int forward_request(struct sip_msg* msg, str* dst, unsigned short port,
342 342
 	struct socket_info* orig_send_sock; /* initial send_sock */
343 343
 	int ret;
344 344
 	struct ip_addr ip; /* debugging only */
345
+	char proto;
345 346
 #ifdef USE_DNS_FAILOVER
346 347
 	struct socket_info* prev_send_sock;
347 348
 	int err;
... ...
@@ -354,6 +355,7 @@ int forward_request(struct sip_msg* msg, str* dst, unsigned short port,
354 354
 	
355 355
 	buf=0;
356 356
 	orig_send_sock=send_info->send_sock;
357
+	proto=send_info->proto;
357 358
 	ret=0;
358 359
 
359 360
 	if(dst){
... ...
@@ -361,7 +363,7 @@ int forward_request(struct sip_msg* msg, str* dst, unsigned short port,
361 361
 		if (cfg_get(core, core_cfg, use_dns_failover)){
362 362
 			dns_srv_handle_init(&dns_srv_h);
363 363
 			err=dns_sip_resolve2su(&dns_srv_h, &send_info->to, dst, port,
364
-									&send_info->proto, dns_flags);
364
+									&proto, dns_flags);
365 365
 			if (err!=0){
366 366
 				LOG(L_ERR, "ERROR: forward_request: resolving \"%.*s\""
367 367
 						" 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,
371 371
 			}
372 372
 		}else
373 373
 #endif
374
-		if (sip_hostport2su(&send_info->to, dst, port, &send_info->proto)<0){
374
+		if (sip_hostport2su(&send_info->to, dst, port, &proto)<0){
375 375
 			LOG(L_ERR, "ERROR: forward_request: bad host name %.*s,"
376 376
 						" dropping packet\n", dst->len, ZSW(dst->s));
377 377
 			ret=E_BAD_ADDRESS;
... ...
@@ -410,12 +412,11 @@ int forward_request(struct sip_msg* msg, str* dst, unsigned short port,
410 410
 	do{
411 411
 #endif
412 412
 		if (orig_send_sock==0) /* no forced send_sock => find it **/
413
-			send_info->send_sock=get_send_socket(msg, &send_info->to,
414
-												send_info->proto);
413
+			send_info->send_sock=get_send_socket(msg, &send_info->to, proto);
415 414
 		if (send_info->send_sock==0){
416 415
 			LOG(L_ERR, "forward_req: ERROR: cannot forward to af %d, proto %d "
417 416
 						"no corresponding listening socket\n",
418
-						send_info->to.s.sa_family, send_info->proto);
417
+						send_info->to.s.sa_family, proto);
419 418
 			ret=ser_error=E_NO_SOCKET;
420 419
 #ifdef USE_DNS_FAILOVER
421 420
 			/* 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,
431 431
 			prev_send_sock=send_info->send_sock;
432 432
 #endif
433 433
 			if (buf) pkg_free(buf);
434
+			send_info->proto=proto;
434 435
 			buf = build_req_buf_from_sip_req(msg, &len, send_info);
435 436
 			if (!buf){
436 437
 				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,
496 496
 	}while(dst && cfg_get(core, core_cfg, use_dns_failover) &&
497 497
 			dns_srv_handle_next(&dns_srv_h, err) && 
498 498
 			((err=dns_sip_resolve2su(&dns_srv_h, &send_info->to, dst, port,
499
-								  &send_info->proto, dns_flags))==0));
499
+										&proto, dns_flags))==0));
500 500
 	if ((err!=0) && (err!=-E_DNS_EOR)){
501 501
 		LOG(L_ERR, "ERROR:  resolving %.*s host name in uri"
502 502
 							" failed: %s [%d] (dropping packet)\n",
... ...
@@ -564,6 +564,32 @@ static int fix_actions(struct action* a)
564 564
 				t->val[0].u.data=si;
565 565
 				t->val[0].type=SOCKETINFO_ST;
566 566
 				break;
567
+			case UDP_MTU_TRY_PROTO_T:
568
+				if (t->val[0].type!=NUMBER_ST){
569
+					LOG(L_CRIT, "BUG: fix_actions: invalid subtype"
570
+								"%d for udp_mtu_try_proto\n",
571
+								t->val[0].type);
572
+					return E_BUG;
573
+				}
574
+				switch(t->val[0].u.number){
575
+					case PROTO_UDP:
576
+						t->val[0].u.number=0;
577
+						break;
578
+					case PROTO_TCP:
579
+						t->val[0].u.number=FL_MTU_TCP_FB;
580
+						break;
581
+					case PROTO_TLS:
582
+						t->val[0].u.number=FL_MTU_TLS_FB;
583
+						break;
584
+					case PROTO_SCTP:
585
+						t->val[0].u.number=FL_MTU_SCTP_FB;
586
+						break;
587
+					default:
588
+						LOG(L_CRIT, "BUG: fix actions: invalid argument for"
589
+									" udp_mtu_try_proto (%d)\n", 
590
+									(unsigned int)t->val[0].u.number);
591
+				}
592
+				break;
567 593
 		}
568 594
 	}
569 595
 	return 0;
... ...
@@ -35,6 +35,7 @@
35 35
  *  2004-02-24  added LOAD_AVP_T and AVP_TO_URI_T (bogdan)
36 36
  *  2005-12-11  added SND{IP,PORT,PROTO,AF}_O & TO{IP,PORT}_O (andrei)
37 37
  *  2005-12-19  select framework added SELECT_O and SELECT_ST (mma)
38
+ *  2008-12-17  added UDP_MTU_TRY_PROTO_T (andrei)
38 39
  */
39 40
 
40 41
 
... ...
@@ -89,7 +90,8 @@ enum { FORWARD_T=1, SEND_T, DROP_T, LOG_T, ERROR_T, ROUTE_T, EXEC_T,
89 89
 		AVP_TO_URI_T,
90 90
 		FORCE_SEND_SOCKET_T,
91 91
 		ASSIGN_T,
92
-		ADD_T
92
+		ADD_T,
93
+		UDP_MTU_TRY_PROTO_T
93 94
 };
94 95
 enum { NOSUBTYPE=0, STRING_ST, NET_ST, NUMBER_ST, IP_ST, RE_ST, PROXY_ST,
95 96
 		EXPR_ST, ACTIONS_ST, MODEXP_ST, MODFIXUP_ST, URIHOST_ST, URIPORT_ST,