Browse code

- core sctp support

Andrei Pelinescu-Onciul authored on 08/08/2008 20:47:53
Showing 16 changed files
... ...
@@ -1395,6 +1395,30 @@ ifeq ($(OS), linux)
1395 1395
 	ifeq ($(NO_SELECT),)
1396 1396
 		DEFS+=-DHAVE_SELECT
1397 1397
 	endif
1398
+	# sctp support
1399
+	ifeq ($(SCTP),1)
1400
+		# test to see if the devfiles and lib are installed
1401
+		sctp_dev_locations := /usr/include/netinet/sctp.h \
1402
+								$(LOCALBASE)/include/netinet/sctp.h
1403
+		sctp_lib_locations := /usr/lib/libsctp.so \
1404
+								$(LOCALBASE)/usr/local/lib/libsctp.so
1405
+		sctp_dev_path := $(wildcard $(sctp_dev_locations))
1406
+		sctp_lib_path := $(wildcard $(sctp_lib_locations))
1407
+		ifeq ($(sctp_dev_path),)
1408
+			$(info "sctp development files not installed -- sctp disabled")
1409
+			override SCTP := 
1410
+		endif
1411
+		ifeq ($(sctp_lib_path),)
1412
+			$(info "sctp libraries not installed -- sctp disabled")
1413
+			override SCTP := 
1414
+		endif
1415
+		
1416
+		ifeq ($(SCTP),1)
1417
+			# use lksctp
1418
+			DEFS+=-DUSE_SCTP
1419
+			LIBS+=-lsctp
1420
+		endif
1421
+	endif # SCTP
1398 1422
 endif
1399 1423
 
1400 1424
 ifeq  ($(OS), solaris)
... ...
@@ -200,6 +200,8 @@ 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
+             - sctp support (one-to-many, work in progress, for now linux
204
+               only with no fallback to one-to-one on full send buffers)
203 205
              - partial cygwin (windows) support revived: core+static modules, 
204 206
                no ipv6, no tcp, no dynamic modules
205 207
              - most of the config variables can now be changed on the fly,
... ...
@@ -218,6 +220,14 @@ core:
218 218
                between the short name and long name in cache as CNAME record
219 219
 
220 220
 new config variables:
221
+  disable_sctp = yes/no - diable sctp support
222
+  sctp_children = number - sctp children no (similar to udp children)
223
+  sctp_socket_rcvbuf = number - size for the sctp socket receive buffer
224
+  sctp_socket_sndbuf = number - size for the sctp socket send buffer
225
+  sctp_autoclose = seconds - number of seconds before autoclosing an idle
226
+     assocation (default: 180 s).
227
+  sctp_send_ttl = milliseconds - number of milliseconds before an unsent
228
+     message/chunk is dropped (default: 32000 ms or 32 s).
221 229
   server_id = number - A configurable unique server id that can be used to
222 230
                        discriminate server instances within a cluster of
223 231
                        servers when all other information, such as IP adddresses
... ...
@@ -71,6 +71,9 @@
71 71
 #ifdef USE_TCP
72 72
 #include "tcp_server.h"
73 73
 #endif
74
+#ifdef USE_SCTP
75
+#include "sctp_server.h"
76
+#endif
74 77
 
75 78
 #include <sys/types.h>
76 79
 #include <sys/socket.h>
... ...
@@ -130,6 +133,9 @@ int do_action(struct run_act_ctx* h, struct action* a, struct sip_msg* msg)
130 130
 #ifdef USE_TLS
131 131
 		case FORWARD_TLS_T:
132 132
 #endif
133
+#ifdef USE_SCTP
134
+		case FORWARD_SCTP_T:
135
+#endif
133 136
 		case FORWARD_UDP_T:
134 137
 			/* init dst */
135 138
 			init_dest_info(&dst);
... ...
@@ -140,7 +146,10 @@ int do_action(struct run_act_ctx* h, struct action* a, struct sip_msg* msg)
140 140
 #ifdef USE_TLS
141 141
 			else if (a->type==FORWARD_TLS_T) dst.proto= PROTO_TLS;
142 142
 #endif
143
-			else dst.proto= PROTO_NONE;
143
+#ifdef USE_SCTP
144
+			else if (a->type==FORWARD_SCTP_T) dst.proto=PROTO_SCTP;
145
+#endif
146
+			else dst.proto=PROTO_NONE;
144 147
 			if (a->val[0].type==URIHOST_ST){
145 148
 				/*parse uri*/
146 149
 
... ...
@@ -186,6 +195,9 @@ int do_action(struct run_act_ctx* h, struct action* a, struct sip_msg* msg)
186 186
 #ifdef USE_TLS
187 187
 						case PROTO_TLS:
188 188
 #endif
189
+#ifdef USE_SCTP
190
+						case PROTO_SCTP:
191
+#endif
189 192
 							dst.proto=u->proto;
190 193
 							break;
191 194
 						default:
... ...
@@ -127,6 +127,7 @@ FORWARD	forward
127 127
 FORWARD_TCP	forward_tcp
128 128
 FORWARD_UDP	forward_udp
129 129
 FORWARD_TLS	forward_tls
130
+FORWARD_SCTP	forward_sctp
130 131
 DROP	"drop"|"exit"
131 132
 RETURN	"return"
132 133
 BREAK	"break"
... ...
@@ -321,6 +322,12 @@ TLS_PRIVATE_KEY "tls_private_key"
321 321
 TLS_CA_LIST		"tls_ca_list"
322 322
 TLS_HANDSHAKE_TIMEOUT	"tls_handshake_timeout"
323 323
 TLS_SEND_TIMEOUT	"tls_send_timeout"
324
+DISABLE_SCTP	"disable_sctp"
325
+SCTP_CHILDREN	"sctp_children"
326
+SCTP_SOCKET_RCVBUF	"sctp_socket_rcvbuf|sctp_socket_receive_buffer"
327
+SCTP_SOCKET_SNDBUF	"sctp_socket_sndbuf|sctp_socket_send_buffer"
328
+SCTP_AUTOCLOSE	"sctp_autoclose"
329
+SCTP_SEND_TTL	"sctp_send_ttl"
324 330
 ADVERTISED_ADDRESS	"advertised_address"
325 331
 ADVERTISED_PORT		"advertised_port"
326 332
 DISABLE_CORE		"disable_core_dump"
... ...
@@ -409,6 +416,7 @@ EAT_ABLE	[\ \t\b\r]
409 409
 <INITIAL>{FORWARD}	{count(); yylval.strval=yytext; return FORWARD; }
410 410
 <INITIAL>{FORWARD_TCP}	{count(); yylval.strval=yytext; return FORWARD_TCP; }
411 411
 <INITIAL>{FORWARD_TLS}	{count(); yylval.strval=yytext; return FORWARD_TLS; }
412
+<INITIAL>{FORWARD_SCTP}	{count(); yylval.strval=yytext; return FORWARD_SCTP;}
412 413
 <INITIAL>{FORWARD_UDP}	{count(); yylval.strval=yytext; return FORWARD_UDP; }
413 414
 <INITIAL>{DROP}	{ count(); yylval.strval=yytext; return DROP; }
414 415
 <INITIAL>{RETURN}	{ count(); yylval.strval=yytext; return RETURN; }
... ...
@@ -621,6 +629,17 @@ EAT_ABLE	[\ \t\b\r]
621 621
 										return TLS_HANDSHAKE_TIMEOUT; }
622 622
 <INITIAL>{TLS_SEND_TIMEOUT}	{ count(); yylval.strval=yytext;
623 623
 										return TLS_SEND_TIMEOUT; }
624
+<INITIAL>{DISABLE_SCTP}	{ count(); yylval.strval=yytext; return DISABLE_SCTP;}
625
+<INITIAL>{SCTP_CHILDREN}	{ count(); yylval.strval=yytext;
626
+										return SCTP_CHILDREN; }
627
+<INITIAL>{SCTP_SOCKET_RCVBUF}	{ count(); yylval.strval=yytext;
628
+										return SCTP_SOCKET_RCVBUF; }
629
+<INITIAL>{SCTP_SOCKET_SNDBUF}	{ count(); yylval.strval=yytext;
630
+										return SCTP_SOCKET_SNDBUF; }
631
+<INITIAL>{SCTP_AUTOCLOSE}	{ count(); yylval.strval=yytext;
632
+										return SCTP_AUTOCLOSE; }
633
+<INITIAL>{SCTP_SEND_TTL}	{ count(); yylval.strval=yytext;
634
+										return SCTP_SEND_TTL; }
624 635
 <INITIAL>{SERVER_SIGNATURE}	{ count(); yylval.strval=yytext; return SERVER_SIGNATURE; }
625 636
 <INITIAL>{REPLY_TO_VIA}	{ count(); yylval.strval=yytext; return REPLY_TO_VIA; }
626 637
 <INITIAL>{ADVERTISED_ADDRESS}	{	count(); yylval.strval=yytext;
... ...
@@ -116,6 +116,7 @@
116 116
 #include "flags.h"
117 117
 #include "tcp_init.h"
118 118
 #include "tcp_options.h"
119
+#include "sctp_options.h"
119 120
 
120 121
 #include "config.h"
121 122
 #include "cfg_core.h"
... ...
@@ -208,6 +209,7 @@ static struct socket_id* mk_listen_id(char*, int, int);
208 208
 %token FORWARD
209 209
 %token FORWARD_TCP
210 210
 %token FORWARD_TLS
211
+%token FORWARD_SCTP
211 212
 %token FORWARD_UDP
212 213
 %token SEND
213 214
 %token SEND_TCP
... ...
@@ -369,6 +371,12 @@ static struct socket_id* mk_listen_id(char*, int, int);
369 369
 %token TLS_CERTIFICATE
370 370
 %token TLS_PRIVATE_KEY
371 371
 %token TLS_CA_LIST
372
+%token DISABLE_SCTP
373
+%token SCTP_CHILDREN
374
+%token SCTP_SOCKET_RCVBUF
375
+%token SCTP_SOCKET_SNDBUF
376
+%token SCTP_AUTOCLOSE
377
+%token SCTP_SEND_TTL
372 378
 %token ADVERTISED_ADDRESS
373 379
 %token ADVERTISED_PORT
374 380
 %token DISABLE_CORE
... ...
@@ -1039,6 +1047,54 @@ assign_stm:
1039 1039
 		#endif
1040 1040
 	}
1041 1041
 	| TLS_SEND_TIMEOUT EQUAL error { yyerror("number expected"); }
1042
+	| DISABLE_SCTP EQUAL NUMBER {
1043
+		#ifdef USE_SCTP
1044
+			sctp_disable=$3;
1045
+		#else
1046
+			warn("sctp support not compiled in");
1047
+		#endif
1048
+	}
1049
+	| DISABLE_SCTP EQUAL error { yyerror("boolean value expected"); }
1050
+	| SCTP_CHILDREN EQUAL NUMBER {
1051
+		#ifdef USE_SCTP
1052
+			sctp_children_no=$3;
1053
+		#else
1054
+			warn("sctp support not compiled in");
1055
+		#endif
1056
+	}
1057
+	| SCTP_CHILDREN EQUAL error { yyerror("number expected"); }
1058
+	| SCTP_SOCKET_RCVBUF EQUAL NUMBER {
1059
+		#ifdef USE_SCTP
1060
+			sctp_options.sctp_so_rcvbuf=$3;
1061
+		#else
1062
+			warn("sctp support not compiled in");
1063
+		#endif
1064
+	}
1065
+	| SCTP_SOCKET_RCVBUF EQUAL error { yyerror("number expected"); }
1066
+	| SCTP_SOCKET_SNDBUF EQUAL NUMBER {
1067
+		#ifdef USE_SCTP
1068
+			sctp_options.sctp_so_sndbuf=$3;
1069
+		#else
1070
+			warn("sctp support not compiled in");
1071
+		#endif
1072
+	}
1073
+	| SCTP_SOCKET_SNDBUF EQUAL error { yyerror("number expected"); }
1074
+	| SCTP_AUTOCLOSE EQUAL NUMBER {
1075
+		#ifdef USE_SCTP
1076
+			sctp_options.sctp_autoclose=$3;
1077
+		#else
1078
+			warn("sctp support not compiled in");
1079
+		#endif
1080
+	}
1081
+	| SCTP_AUTOCLOSE EQUAL error { yyerror("number expected"); }
1082
+	| SCTP_SEND_TTL EQUAL NUMBER {
1083
+		#ifdef USE_SCTP
1084
+			sctp_options.sctp_send_ttl=$3;
1085
+		#else
1086
+			warn("sctp support not compiled in");
1087
+		#endif
1088
+	}
1089
+	| SCTP_SEND_TTL EQUAL error { yyerror("number expected"); }
1042 1090
 	| SERVER_SIGNATURE EQUAL NUMBER { server_signature=$3; }
1043 1091
 	| SERVER_SIGNATURE EQUAL error { yyerror("boolean value expected"); }
1044 1092
 	| REPLY_TO_VIA EQUAL NUMBER { reply_to_via=$3; }
... ...
@@ -1965,7 +2021,87 @@ cmd:
1965 1965
 		#endif
1966 1966
 	}
1967 1967
 	| FORWARD_TLS error { $$=0; yyerror("missing '(' or ')' ?"); }
1968
-	| FORWARD_TLS LPAREN error RPAREN { $$=0; yyerror("bad forward_tls argument"); }
1968
+	| FORWARD_TLS LPAREN error RPAREN { $$=0; 
1969
+									yyerror("bad forward_tls argument"); }
1970
+	| FORWARD_SCTP LPAREN host RPAREN {
1971
+		#ifdef USE_SCTP
1972
+			$$=mk_action(FORWARD_SCTP_T, 2, STRING_ST, $3, NUMBER_ST, 0);
1973
+		#else
1974
+			$$=0;
1975
+			yyerror("sctp support not compiled in");
1976
+		#endif
1977
+	}
1978
+	| FORWARD_SCTP LPAREN STRING RPAREN {
1979
+		#ifdef USE_SCTP
1980
+			$$=mk_action(FORWARD_SCTP_T, 2, STRING_ST, $3, NUMBER_ST, 0);
1981
+		#else
1982
+			$$=0;
1983
+			yyerror("sctp support not compiled in");
1984
+		#endif
1985
+	}
1986
+	| FORWARD_SCTP LPAREN ip RPAREN	{
1987
+		#ifdef USE_SCTP
1988
+			$$=mk_action(FORWARD_SCTP_T, 2, IP_ST, (void*)$3, NUMBER_ST, 0);
1989
+		#else
1990
+			$$=0;
1991
+			yyerror("sctp support not compiled in");
1992
+		#endif
1993
+	}
1994
+	| FORWARD_SCTP LPAREN host COMMA NUMBER RPAREN {
1995
+		#ifdef USE_SCTP
1996
+			$$=mk_action(FORWARD_SCTP_T, 2, STRING_ST, $3, NUMBER_ST,
1997
+							(void*)$5);
1998
+		#else
1999
+			$$=0;
2000
+			yyerror("sctp support not compiled in");
2001
+		#endif
2002
+	}
2003
+	| FORWARD_SCTP LPAREN STRING COMMA NUMBER RPAREN {
2004
+		#ifdef USE_SCTP
2005
+			$$=mk_action(FORWARD_SCTP_T, 2, STRING_ST, $3, NUMBER_ST,
2006
+							(void*)$5);
2007
+		#else
2008
+			$$=0;
2009
+			yyerror("sctp support not compiled in");
2010
+		#endif
2011
+	}
2012
+	| FORWARD_SCTP LPAREN ip COMMA NUMBER RPAREN {
2013
+		#ifdef USE_SCTP
2014
+			$$=mk_action(FORWARD_SCTP_T, 2, IP_ST, (void*)$3, NUMBER_ST, 
2015
+							(void*)$5);
2016
+		#else
2017
+			$$=0;
2018
+			yyerror("sctp support not compiled in");
2019
+		#endif
2020
+					}
2021
+	| FORWARD_SCTP LPAREN URIHOST COMMA URIPORT RPAREN {
2022
+		#ifdef USE_SCTP
2023
+			$$=mk_action(FORWARD_SCTP_T, 2, URIHOST_ST, 0, URIPORT_ST, 0);
2024
+		#else
2025
+			$$=0;
2026
+			yyerror("sctp support not compiled in");
2027
+		#endif
2028
+	}
2029
+	| FORWARD_SCTP LPAREN URIHOST COMMA NUMBER RPAREN {
2030
+		#ifdef USE_SCTP
2031
+			$$=mk_action(FORWARD_SCTP_T, 2, URIHOST_ST, 0, NUMBER_ST,
2032
+							(void*)$5);
2033
+		#else
2034
+			$$=0;
2035
+			yyerror("sctp support not compiled in");
2036
+		#endif
2037
+	}
2038
+	| FORWARD_SCTP LPAREN URIHOST RPAREN {
2039
+		#ifdef USE_SCTP
2040
+			$$=mk_action(FORWARD_SCTP_T, 2, URIHOST_ST, 0, NUMBER_ST, 0);
2041
+		#else
2042
+			$$=0;
2043
+			yyerror("tls support not compiled in");
2044
+		#endif
2045
+	}
2046
+	| FORWARD_SCTP error { $$=0; yyerror("missing '(' or ')' ?"); }
2047
+	| FORWARD_SCTP LPAREN error RPAREN { $$=0; 
2048
+									yyerror("bad forward_tls argument"); }
1969 2049
 	| SEND LPAREN host RPAREN	{ $$=mk_action(SEND_T, 2, STRING_ST, $3, NUMBER_ST, 0); }
1970 2050
 	| SEND LPAREN STRING RPAREN { $$=mk_action(SEND_T, 2, STRING_ST, $3, NUMBER_ST, 0); }
1971 2051
 	| SEND LPAREN ip RPAREN		{ $$=mk_action(SEND_T, 2, IP_ST, (void*)$3, NUMBER_ST, 0); }
... ...
@@ -199,6 +199,8 @@
199 199
 /* minimum packet size; smaller packets will be dropped silently */
200 200
 #define MIN_UDP_PACKET        32
201 201
 
202
+#define MIN_SCTP_PACKET  MIN_UDP_PACKET 
203
+
202 204
 #define DEFAULT_RADIUS_CONFIG "/usr/local/etc/radiusclient/radiusclient.conf"
203 205
 
204 206
 #define DEFAULT_DID "_default"
... ...
@@ -39,6 +39,9 @@
39 39
 #include "tcp_info.h"
40 40
 #include "tcp_options.h"
41 41
 #include "core_cmd.h"
42
+#ifdef USE_SCTP
43
+#include "sctp_options.h"
44
+#endif
42 45
 
43 46
 #ifdef USE_DNS_CACHE
44 47
 void dns_cache_debug(rpc_t* rpc, void* ctx);
... ...
@@ -589,6 +592,36 @@ static void core_tcp_options(rpc_t* rpc, void* c)
589 589
 
590 590
 
591 591
 
592
+static const char* core_sctp_options_doc[] = {
593
+	"Returns active sctp options.",    /* Documentation string */
594
+	0                                 /* Method signature(s) */
595
+};
596
+
597
+static void core_sctp_options(rpc_t* rpc, void* c)
598
+{
599
+#ifdef USE_SCTP
600
+	void *handle;
601
+	struct sctp_cfg_options t;
602
+
603
+	if (!sctp_disable){
604
+		sctp_options_get(&t);
605
+		rpc->add(c, "{", &handle);
606
+		rpc->struct_add(handle, "dddd",
607
+			"sctp_autoclose",		t.sctp_autoclose,
608
+			"sctp_send_ttl",	t.sctp_autoclose,
609
+			"sctp_socket_rcvbuf",	t.sctp_so_rcvbuf,
610
+			"sctp_socket_sndbuf",	t.sctp_so_sndbuf
611
+		);
612
+	}else{
613
+		rpc->fault(c, 500, "sctp support disabled");
614
+	}
615
+#else
616
+	rpc->fault(c, 500, "sctp support not compiled");
617
+#endif
618
+}
619
+
620
+
621
+
592 622
 /*
593 623
  * RPC Methods exported by this module
594 624
  */
... ...
@@ -609,6 +642,8 @@ rpc_export_t core_rpc_methods[] = {
609 609
 #endif
610 610
 	{"core.tcp_info",          core_tcpinfo,           core_tcpinfo_doc,    0},
611 611
 	{"core.tcp_options",       core_tcp_options,       core_tcp_options_doc,0},
612
+	{"core.sctp_options",      core_sctp_options,      core_sctp_options_doc,
613
+		0},
612 614
 #ifdef USE_DNS_CACHE
613 615
 	{"dns.mem_info",          dns_cache_mem_info,     dns_cache_mem_info_doc,     0	},
614 616
 	{"dns.debug",          dns_cache_debug,           dns_cache_debug_doc,        0	},
... ...
@@ -233,9 +233,29 @@ not_forced:
233 233
 			}
234 234
 			break;
235 235
 #endif /* USE_TLS */
236
+#ifdef USE_SCTP
237
+		case PROTO_SCTP:
238
+			if ((bind_address==0) ||
239
+					(to->s.sa_family!=bind_address->address.af) ||
240
+					(bind_address->proto!=PROTO_SCTP)){
241
+				switch(to->s.sa_family){
242
+					case AF_INET:	send_sock=sendipv4_sctp;
243
+									break;
244
+#ifdef USE_IPV6
245
+					case AF_INET6:	send_sock=sendipv6_sctp;
246
+									break;
247
+#endif
248
+					default:	LOG(L_ERR, "get_send_socket: BUG: don't know"
249
+										" how to forward to af %d\n",
250
+										to->s.sa_family);
251
+				}
252
+			}else send_sock=bind_address;
253
+			break;
254
+#endif /* USE_SCTP */
236 255
 		case PROTO_UDP:
237
-			if ((bind_address==0)||(to->s.sa_family!=bind_address->address.af)||
238
-				  (bind_address->proto!=PROTO_UDP)){
256
+			if ((bind_address==0) ||
257
+					(to->s.sa_family!=bind_address->address.af) ||
258
+					(bind_address->proto!=PROTO_UDP)){
239 259
 				switch(to->s.sa_family){
240 260
 					case AF_INET:	send_sock=sendipv4;
241 261
 									break;
... ...
@@ -55,6 +55,9 @@
55 55
 #ifdef USE_TCP
56 56
 #include "tcp_server.h"
57 57
 #endif
58
+#ifdef USE_SCTP
59
+#include "sctp_server.h"
60
+#endif
58 61
 
59 62
 #include "compiler_opt.h"
60 63
 
... ...
@@ -147,6 +150,22 @@ static inline int msg_send(struct dest_info* dst, char* buf, int len)
147 147
 	}
148 148
 #endif /* USE_TLS */
149 149
 #endif /* USE_TCP */
150
+#ifdef USE_SCTP
151
+	else if (dst->proto==PROTO_SCTP){
152
+		if (unlikely(sctp_disable)){
153
+			STATS_TX_DROPS;
154
+			LOG(L_WARN, "msg_send: WARNING: attempt to send on sctp and sctp"
155
+					" support is disabled\n");
156
+			goto error;
157
+		}else{
158
+			if (unlikely(sctp_msg_send(dst, buf, len)<0)){
159
+				STATS_TX_DROPS;
160
+				LOG(L_ERR, "msg_send: ERROR: sctp_msg_send failed\n");
161
+				goto error;
162
+			}
163
+		}
164
+	}
165
+#endif /* USE_SCTP */
150 166
 	else{
151 167
 			LOG(L_CRIT, "BUG: msg_send: unknown proto %d\n", dst->proto);
152 168
 			goto error;
... ...
@@ -75,6 +75,11 @@ extern struct socket_info* sendipv4_tls; /* ipv4 socket to use when msg.
75 75
 										comes from ipv6*/
76 76
 extern struct socket_info* sendipv6_tls; /* same as above for ipv6 */
77 77
 #endif
78
+#ifdef USE_SCTP
79
+extern struct socket_info* sendipv4_sctp; /* ipv4 socket to use when msg.
80
+										comes from ipv6*/
81
+extern struct socket_info* sendipv6_sctp; /* same as above for ipv6 */
82
+#endif
78 83
 
79 84
 extern unsigned int maxbuffer;
80 85
 extern int children_no;
... ...
@@ -93,6 +98,10 @@ extern int tcp_max_connections;
93 93
 extern int tls_disable;
94 94
 extern unsigned short tls_port_no;
95 95
 #endif
96
+#ifdef USE_SCTP
97
+extern int sctp_disable;
98
+extern int sctp_children_no;
99
+#endif
96 100
 extern int dont_fork;
97 101
 extern int dont_daemonize;
98 102
 extern int check_via;
... ...
@@ -52,6 +52,8 @@
52 52
 #include "dprint.h"
53 53
 
54 54
 enum sip_protos { PROTO_NONE, PROTO_UDP, PROTO_TCP, PROTO_TLS, PROTO_SCTP };
55
+#define PROTO_LAST PROTO_SCTP
56
+
55 57
 #ifdef USE_COMP
56 58
 enum comp_methods { COMP_NONE, COMP_SIGCOMP, COMP_SERGZ };
57 59
 #endif
... ...
@@ -2035,6 +2035,7 @@ char* via_builder( unsigned int *len,
2035 2035
 	unsigned int  via_len, extra_len;
2036 2036
 	char               *line_buf;
2037 2037
 	int max_len;
2038
+	int via_prefix_len;
2038 2039
 	str* address_str; /* address displayed in via */
2039 2040
 	str* port_str; /* port no displayed in via */
2040 2041
 	struct socket_info* send_sock;
... ...
@@ -2075,7 +2076,8 @@ char* via_builder( unsigned int *len,
2075 2075
 	}
2076 2076
 #endif /* USE_COMP */
2077 2077
 			
2078
-	max_len=MY_VIA_LEN+address_str->len /* space in MY_VIA */
2078
+	via_prefix_len=MY_VIA_LEN+(send_info->proto==PROTO_SCTP);
2079
+	max_len=via_prefix_len +address_str->len /* space in MY_VIA */
2079 2080
 		+2 /* just in case it is a v6 address ... [ ] */
2080 2081
 		+1 /*':'*/+port_str->len
2081 2082
 		+(branch?(MY_BRANCH_LEN+branch->len):0)
... ...
@@ -2091,7 +2093,7 @@ char* via_builder( unsigned int *len,
2091 2091
 
2092 2092
 	extra_len=0;
2093 2093
 
2094
-	via_len=MY_VIA_LEN+address_str->len; /*space included in MY_VIA*/
2094
+	via_len=via_prefix_len+address_str->len; /*space included in MY_VIA*/
2095 2095
 
2096 2096
 	memcpy(line_buf, MY_VIA, MY_VIA_LEN);
2097 2097
 	if (send_info->proto==PROTO_UDP){
... ...
@@ -2100,6 +2102,8 @@ char* via_builder( unsigned int *len,
2100 2100
 		memcpy(line_buf+MY_VIA_LEN-4, "TCP ", 4);
2101 2101
 	}else if (send_info->proto==PROTO_TLS){
2102 2102
 		memcpy(line_buf+MY_VIA_LEN-4, "TLS ", 4);
2103
+	}else if (send_info->proto==PROTO_SCTP){
2104
+		memcpy(line_buf+MY_VIA_LEN-4, "SCTP ", 5);
2103 2105
 	}else{
2104 2106
 		LOG(L_CRIT, "BUG: via_builder: unknown proto %d\n", send_info->proto);
2105 2107
 		return 0;
... ...
@@ -2109,14 +2113,16 @@ char* via_builder( unsigned int *len,
2109 2109
 	 * if using pre-set no check is made */
2110 2110
 	if ((send_sock->address.af==AF_INET6) &&
2111 2111
 		(address_str==&(send_sock->address_str))) {
2112
-		line_buf[MY_VIA_LEN]='[';
2113
-		line_buf[MY_VIA_LEN+1+address_str->len]=']';
2112
+		line_buf[via_prefix_len]='[';
2113
+		line_buf[via_prefix_len+1+address_str->len]=']';
2114 2114
 		extra_len=1;
2115 2115
 		via_len+=2; /* [ ]*/
2116 2116
 	}
2117 2117
 #	endif
2118
-	memcpy(line_buf+MY_VIA_LEN+extra_len, address_str->s, address_str->len);
2119
-	if ((send_sock->port_no!=SIP_PORT) || (port_str!=&send_sock->port_no_str)){
2118
+	memcpy(line_buf+via_prefix_len+extra_len, address_str->s,
2119
+				address_str->len);
2120
+	if ((send_sock->port_no!=SIP_PORT) ||
2121
+				(port_str!=&send_sock->port_no_str)){
2120 2122
 		line_buf[via_len]=':'; via_len++;
2121 2123
 		memcpy(line_buf+via_len, port_str->s, port_str->len);
2122 2124
 		via_len+=port_str->len;
... ...
@@ -83,9 +83,10 @@ static int calc_common_open_fds_no()
83 83
 	 *  + 1 udp sock/udp proc + 1 possible dns comm. socket + 
84 84
 	 *  + 1 temporary tcp send sock.
85 85
 	 */
86
-	max_fds_no=estimated_proc_no*4 /* udp + tcp unix sock + tmp. tcp send +
87
-									  tmp dns.*/ -1 /* timer (no udp)*/ + 
88
-				3 /* stdin/out/err */;
86
+	max_fds_no=estimated_proc_no*4 /* udp|sctp + tcp unix sock +
87
+									  tmp. tcp send +
88
+									  tmp dns.*/
89
+				-1 /* timer (no udp)*/ + 3 /* stdin/out/err */;
89 90
 	return max_fds_no;
90 91
 }
91 92
 
... ...
@@ -401,6 +401,7 @@ static int fix_actions(struct action* a)
401 401
 			case FORWARD_T:
402 402
 			case FORWARD_TLS_T:
403 403
 			case FORWARD_TCP_T:
404
+			case FORWARD_SCTP_T:
404 405
 			case FORWARD_UDP_T:
405 406
 			case SEND_T:
406 407
 			case SEND_TCP_T:
... ...
@@ -79,6 +79,7 @@ enum { FORWARD_T=1, SEND_T, DROP_T, LOG_T, ERROR_T, ROUTE_T, EXEC_T,
79 79
 		FORWARD_TCP_T,
80 80
 		FORWARD_UDP_T,
81 81
 		FORWARD_TLS_T,
82
+		FORWARD_SCTP_T,
82 83
 		SEND_TCP_T,
83 84
 		FORCE_RPORT_T,
84 85
 		SET_ADV_ADDR_T,
... ...
@@ -86,10 +87,9 @@ enum { FORWARD_T=1, SEND_T, DROP_T, LOG_T, ERROR_T, ROUTE_T, EXEC_T,
86 86
 		FORCE_TCP_ALIAS_T,
87 87
 		LOAD_AVP_T,
88 88
 		AVP_TO_URI_T,
89
-                FORCE_SEND_SOCKET_T,
90
-                ASSIGN_T,
91
-                ADD_T
92
-
89
+		FORCE_SEND_SOCKET_T,
90
+		ASSIGN_T,
91
+		ADD_T
93 92
 };
94 93
 enum { NOSUBTYPE=0, STRING_ST, NET_ST, NUMBER_ST, IP_ST, RE_ST, PROXY_ST,
95 94
 		EXPR_ST, ACTIONS_ST, MODEXP_ST, MODFIXUP_ST, URIHOST_ST, URIPORT_ST,
... ...
@@ -57,6 +57,12 @@
57 57
 #define USE_TLS_STR ""
58 58
 #endif
59 59
 
60
+#ifdef USE_SCTP
61
+#define USE_SCTP_STR ", USE_SCTP"
62
+#else
63
+#define USE_SCTP_STR ""
64
+#endif
65
+
60 66
 #ifdef CORE_TLS
61 67
 #define CORE_TLS_STR ", CORE_TLS"
62 68
 #else 
... ...
@@ -334,7 +340,7 @@
334 334
 
335 335
 #define SER_COMPILE_FLAGS \
336 336
 	STATS_STR EXTRA_DEBUG_STR USE_IPV6_STR USE_TCP_STR USE_TLS_STR \
337
-	CORE_TLS_STR TLS_HOOKS_STR \
337
+	USE_SCTP_STR CORE_TLS_STR TLS_HOOKS_STR \
338 338
 	USE_STUN_STR DISABLE_NAGLE_STR USE_MCAST_STR NO_DEBUG_STR NO_LOG_STR \
339 339
 	NO_SIG_DEBUG_STR DNS_IP_HACK_STR  SHM_MEM_STR SHM_MMAP_STR PKG_MALLOC_STR \
340 340
 	VQ_MALLOC_STR F_MALLOC_STR DL_MALLOC_STR SF_MALLOC_STR  LL_MALLOC_STR \