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 220
                between the short name and long name in cache as CNAME record
219 221
 
220 222
 new config variables:
223
+  disable_sctp = yes/no - diable sctp support
224
+  sctp_children = number - sctp children no (similar to udp children)
225
+  sctp_socket_rcvbuf = number - size for the sctp socket receive buffer
226
+  sctp_socket_sndbuf = number - size for the sctp socket send buffer
227
+  sctp_autoclose = seconds - number of seconds before autoclosing an idle
228
+     assocation (default: 180 s).
229
+  sctp_send_ttl = milliseconds - number of milliseconds before an unsent
230
+     message/chunk is dropped (default: 32000 ms or 32 s).
221 231
   server_id = number - A configurable unique server id that can be used to
222 232
                        discriminate server instances within a cluster of
223 233
                        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>
... ...
@@ -129,6 +132,9 @@ int do_action(struct run_act_ctx* h, struct action* a, struct sip_msg* msg)
129 132
 #endif
130 133
 #ifdef USE_TLS
131 134
 		case FORWARD_TLS_T:
135
+#endif
136
+#ifdef USE_SCTP
137
+		case FORWARD_SCTP_T:
132 138
 #endif
133 139
 		case FORWARD_UDP_T:
134 140
 			/* init dst */
... ...
@@ -140,7 +146,10 @@ int do_action(struct run_act_ctx* h, struct action* a, struct sip_msg* msg)
140 146
 #ifdef USE_TLS
141 147
 			else if (a->type==FORWARD_TLS_T) dst.proto= PROTO_TLS;
142 148
 #endif
143
-			else dst.proto= PROTO_NONE;
149
+#ifdef USE_SCTP
150
+			else if (a->type==FORWARD_SCTP_T) dst.proto=PROTO_SCTP;
151
+#endif
152
+			else dst.proto=PROTO_NONE;
144 153
 			if (a->val[0].type==URIHOST_ST){
145 154
 				/*parse uri*/
146 155
 
... ...
@@ -185,6 +194,9 @@ int do_action(struct run_act_ctx* h, struct action* a, struct sip_msg* msg)
185 194
 #endif
186 195
 #ifdef USE_TLS
187 196
 						case PROTO_TLS:
197
+#endif
198
+#ifdef USE_SCTP
199
+						case PROTO_SCTP:
188 200
 #endif
189 201
 							dst.proto=u->proto;
190 202
 							break;
... ...
@@ -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 322
 TLS_CA_LIST		"tls_ca_list"
322 323
 TLS_HANDSHAKE_TIMEOUT	"tls_handshake_timeout"
323 324
 TLS_SEND_TIMEOUT	"tls_send_timeout"
325
+DISABLE_SCTP	"disable_sctp"
326
+SCTP_CHILDREN	"sctp_children"
327
+SCTP_SOCKET_RCVBUF	"sctp_socket_rcvbuf|sctp_socket_receive_buffer"
328
+SCTP_SOCKET_SNDBUF	"sctp_socket_sndbuf|sctp_socket_send_buffer"
329
+SCTP_AUTOCLOSE	"sctp_autoclose"
330
+SCTP_SEND_TTL	"sctp_send_ttl"
324 331
 ADVERTISED_ADDRESS	"advertised_address"
325 332
 ADVERTISED_PORT		"advertised_port"
326 333
 DISABLE_CORE		"disable_core_dump"
... ...
@@ -409,6 +416,7 @@ EAT_ABLE	[\ \t\b\r]
409 416
 <INITIAL>{FORWARD}	{count(); yylval.strval=yytext; return FORWARD; }
410 417
 <INITIAL>{FORWARD_TCP}	{count(); yylval.strval=yytext; return FORWARD_TCP; }
411 418
 <INITIAL>{FORWARD_TLS}	{count(); yylval.strval=yytext; return FORWARD_TLS; }
419
+<INITIAL>{FORWARD_SCTP}	{count(); yylval.strval=yytext; return FORWARD_SCTP;}
412 420
 <INITIAL>{FORWARD_UDP}	{count(); yylval.strval=yytext; return FORWARD_UDP; }
413 421
 <INITIAL>{DROP}	{ count(); yylval.strval=yytext; return DROP; }
414 422
 <INITIAL>{RETURN}	{ count(); yylval.strval=yytext; return RETURN; }
... ...
@@ -621,6 +629,17 @@ EAT_ABLE	[\ \t\b\r]
621 629
 										return TLS_HANDSHAKE_TIMEOUT; }
622 630
 <INITIAL>{TLS_SEND_TIMEOUT}	{ count(); yylval.strval=yytext;
623 631
 										return TLS_SEND_TIMEOUT; }
632
+<INITIAL>{DISABLE_SCTP}	{ count(); yylval.strval=yytext; return DISABLE_SCTP;}
633
+<INITIAL>{SCTP_CHILDREN}	{ count(); yylval.strval=yytext;
634
+										return SCTP_CHILDREN; }
635
+<INITIAL>{SCTP_SOCKET_RCVBUF}	{ count(); yylval.strval=yytext;
636
+										return SCTP_SOCKET_RCVBUF; }
637
+<INITIAL>{SCTP_SOCKET_SNDBUF}	{ count(); yylval.strval=yytext;
638
+										return SCTP_SOCKET_SNDBUF; }
639
+<INITIAL>{SCTP_AUTOCLOSE}	{ count(); yylval.strval=yytext;
640
+										return SCTP_AUTOCLOSE; }
641
+<INITIAL>{SCTP_SEND_TTL}	{ count(); yylval.strval=yytext;
642
+										return SCTP_SEND_TTL; }
624 643
 <INITIAL>{SERVER_SIGNATURE}	{ count(); yylval.strval=yytext; return SERVER_SIGNATURE; }
625 644
 <INITIAL>{REPLY_TO_VIA}	{ count(); yylval.strval=yytext; return REPLY_TO_VIA; }
626 645
 <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 209
 %token FORWARD
209 210
 %token FORWARD_TCP
210 211
 %token FORWARD_TLS
212
+%token FORWARD_SCTP
211 213
 %token FORWARD_UDP
212 214
 %token SEND
213 215
 %token SEND_TCP
... ...
@@ -369,6 +371,12 @@ static struct socket_id* mk_listen_id(char*, int, int);
369 371
 %token TLS_CERTIFICATE
370 372
 %token TLS_PRIVATE_KEY
371 373
 %token TLS_CA_LIST
374
+%token DISABLE_SCTP
375
+%token SCTP_CHILDREN
376
+%token SCTP_SOCKET_RCVBUF
377
+%token SCTP_SOCKET_SNDBUF
378
+%token SCTP_AUTOCLOSE
379
+%token SCTP_SEND_TTL
372 380
 %token ADVERTISED_ADDRESS
373 381
 %token ADVERTISED_PORT
374 382
 %token DISABLE_CORE
... ...
@@ -1039,6 +1047,54 @@ assign_stm:
1039 1047
 		#endif
1040 1048
 	}
1041 1049
 	| TLS_SEND_TIMEOUT EQUAL error { yyerror("number expected"); }
1050
+	| DISABLE_SCTP EQUAL NUMBER {
1051
+		#ifdef USE_SCTP
1052
+			sctp_disable=$3;
1053
+		#else
1054
+			warn("sctp support not compiled in");
1055
+		#endif
1056
+	}
1057
+	| DISABLE_SCTP EQUAL error { yyerror("boolean value expected"); }
1058
+	| SCTP_CHILDREN EQUAL NUMBER {
1059
+		#ifdef USE_SCTP
1060
+			sctp_children_no=$3;
1061
+		#else
1062
+			warn("sctp support not compiled in");
1063
+		#endif
1064
+	}
1065
+	| SCTP_CHILDREN EQUAL error { yyerror("number expected"); }
1066
+	| SCTP_SOCKET_RCVBUF EQUAL NUMBER {
1067
+		#ifdef USE_SCTP
1068
+			sctp_options.sctp_so_rcvbuf=$3;
1069
+		#else
1070
+			warn("sctp support not compiled in");
1071
+		#endif
1072
+	}
1073
+	| SCTP_SOCKET_RCVBUF EQUAL error { yyerror("number expected"); }
1074
+	| SCTP_SOCKET_SNDBUF EQUAL NUMBER {
1075
+		#ifdef USE_SCTP
1076
+			sctp_options.sctp_so_sndbuf=$3;
1077
+		#else
1078
+			warn("sctp support not compiled in");
1079
+		#endif
1080
+	}
1081
+	| SCTP_SOCKET_SNDBUF EQUAL error { yyerror("number expected"); }
1082
+	| SCTP_AUTOCLOSE EQUAL NUMBER {
1083
+		#ifdef USE_SCTP
1084
+			sctp_options.sctp_autoclose=$3;
1085
+		#else
1086
+			warn("sctp support not compiled in");
1087
+		#endif
1088
+	}
1089
+	| SCTP_AUTOCLOSE EQUAL error { yyerror("number expected"); }
1090
+	| SCTP_SEND_TTL EQUAL NUMBER {
1091
+		#ifdef USE_SCTP
1092
+			sctp_options.sctp_send_ttl=$3;
1093
+		#else
1094
+			warn("sctp support not compiled in");
1095
+		#endif
1096
+	}
1097
+	| SCTP_SEND_TTL EQUAL error { yyerror("number expected"); }
1042 1098
 	| SERVER_SIGNATURE EQUAL NUMBER { server_signature=$3; }
1043 1099
 	| SERVER_SIGNATURE EQUAL error { yyerror("boolean value expected"); }
1044 1100
 	| REPLY_TO_VIA EQUAL NUMBER { reply_to_via=$3; }
... ...
@@ -1965,7 +2021,87 @@ cmd:
1965 2021
 		#endif
1966 2022
 	}
1967 2023
 	| FORWARD_TLS error { $$=0; yyerror("missing '(' or ')' ?"); }
1968
-	| FORWARD_TLS LPAREN error RPAREN { $$=0; yyerror("bad forward_tls argument"); }
2024
+	| FORWARD_TLS LPAREN error RPAREN { $$=0; 
2025
+									yyerror("bad forward_tls argument"); }
2026
+	| FORWARD_SCTP LPAREN host RPAREN {
2027
+		#ifdef USE_SCTP
2028
+			$$=mk_action(FORWARD_SCTP_T, 2, STRING_ST, $3, NUMBER_ST, 0);
2029
+		#else
2030
+			$$=0;
2031
+			yyerror("sctp support not compiled in");
2032
+		#endif
2033
+	}
2034
+	| FORWARD_SCTP LPAREN STRING RPAREN {
2035
+		#ifdef USE_SCTP
2036
+			$$=mk_action(FORWARD_SCTP_T, 2, STRING_ST, $3, NUMBER_ST, 0);
2037
+		#else
2038
+			$$=0;
2039
+			yyerror("sctp support not compiled in");
2040
+		#endif
2041
+	}
2042
+	| FORWARD_SCTP LPAREN ip RPAREN	{
2043
+		#ifdef USE_SCTP
2044
+			$$=mk_action(FORWARD_SCTP_T, 2, IP_ST, (void*)$3, NUMBER_ST, 0);
2045
+		#else
2046
+			$$=0;
2047
+			yyerror("sctp support not compiled in");
2048
+		#endif
2049
+	}
2050
+	| FORWARD_SCTP LPAREN host COMMA NUMBER RPAREN {
2051
+		#ifdef USE_SCTP
2052
+			$$=mk_action(FORWARD_SCTP_T, 2, STRING_ST, $3, NUMBER_ST,
2053
+							(void*)$5);
2054
+		#else
2055
+			$$=0;
2056
+			yyerror("sctp support not compiled in");
2057
+		#endif
2058
+	}
2059
+	| FORWARD_SCTP LPAREN STRING COMMA NUMBER RPAREN {
2060
+		#ifdef USE_SCTP
2061
+			$$=mk_action(FORWARD_SCTP_T, 2, STRING_ST, $3, NUMBER_ST,
2062
+							(void*)$5);
2063
+		#else
2064
+			$$=0;
2065
+			yyerror("sctp support not compiled in");
2066
+		#endif
2067
+	}
2068
+	| FORWARD_SCTP LPAREN ip COMMA NUMBER RPAREN {
2069
+		#ifdef USE_SCTP
2070
+			$$=mk_action(FORWARD_SCTP_T, 2, IP_ST, (void*)$3, NUMBER_ST, 
2071
+							(void*)$5);
2072
+		#else
2073
+			$$=0;
2074
+			yyerror("sctp support not compiled in");
2075
+		#endif
2076
+					}
2077
+	| FORWARD_SCTP LPAREN URIHOST COMMA URIPORT RPAREN {
2078
+		#ifdef USE_SCTP
2079
+			$$=mk_action(FORWARD_SCTP_T, 2, URIHOST_ST, 0, URIPORT_ST, 0);
2080
+		#else
2081
+			$$=0;
2082
+			yyerror("sctp support not compiled in");
2083
+		#endif
2084
+	}
2085
+	| FORWARD_SCTP LPAREN URIHOST COMMA NUMBER RPAREN {
2086
+		#ifdef USE_SCTP
2087
+			$$=mk_action(FORWARD_SCTP_T, 2, URIHOST_ST, 0, NUMBER_ST,
2088
+							(void*)$5);
2089
+		#else
2090
+			$$=0;
2091
+			yyerror("sctp support not compiled in");
2092
+		#endif
2093
+	}
2094
+	| FORWARD_SCTP LPAREN URIHOST RPAREN {
2095
+		#ifdef USE_SCTP
2096
+			$$=mk_action(FORWARD_SCTP_T, 2, URIHOST_ST, 0, NUMBER_ST, 0);
2097
+		#else
2098
+			$$=0;
2099
+			yyerror("tls support not compiled in");
2100
+		#endif
2101
+	}
2102
+	| FORWARD_SCTP error { $$=0; yyerror("missing '(' or ')' ?"); }
2103
+	| FORWARD_SCTP LPAREN error RPAREN { $$=0; 
2104
+									yyerror("bad forward_tls argument"); }
1969 2105
 	| SEND LPAREN host RPAREN	{ $$=mk_action(SEND_T, 2, STRING_ST, $3, NUMBER_ST, 0); }
1970 2106
 	| SEND LPAREN STRING RPAREN { $$=mk_action(SEND_T, 2, STRING_ST, $3, NUMBER_ST, 0); }
1971 2107
 	| 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 592
 
590 593
 
591 594
 
595
+static const char* core_sctp_options_doc[] = {
596
+	"Returns active sctp options.",    /* Documentation string */
597
+	0                                 /* Method signature(s) */
598
+};
599
+
600
+static void core_sctp_options(rpc_t* rpc, void* c)
601
+{
602
+#ifdef USE_SCTP
603
+	void *handle;
604
+	struct sctp_cfg_options t;
605
+
606
+	if (!sctp_disable){
607
+		sctp_options_get(&t);
608
+		rpc->add(c, "{", &handle);
609
+		rpc->struct_add(handle, "dddd",
610
+			"sctp_autoclose",		t.sctp_autoclose,
611
+			"sctp_send_ttl",	t.sctp_autoclose,
612
+			"sctp_socket_rcvbuf",	t.sctp_so_rcvbuf,
613
+			"sctp_socket_sndbuf",	t.sctp_so_sndbuf
614
+		);
615
+	}else{
616
+		rpc->fault(c, 500, "sctp support disabled");
617
+	}
618
+#else
619
+	rpc->fault(c, 500, "sctp support not compiled");
620
+#endif
621
+}
622
+
623
+
624
+
592 625
 /*
593 626
  * RPC Methods exported by this module
594 627
  */
... ...
@@ -609,6 +642,8 @@ rpc_export_t core_rpc_methods[] = {
609 642
 #endif
610 643
 	{"core.tcp_info",          core_tcpinfo,           core_tcpinfo_doc,    0},
611 644
 	{"core.tcp_options",       core_tcp_options,       core_tcp_options_doc,0},
645
+	{"core.sctp_options",      core_sctp_options,      core_sctp_options_doc,
646
+		0},
612 647
 #ifdef USE_DNS_CACHE
613 648
 	{"dns.mem_info",          dns_cache_mem_info,     dns_cache_mem_info_doc,     0	},
614 649
 	{"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 150
 	}
148 151
 #endif /* USE_TLS */
149 152
 #endif /* USE_TCP */
153
+#ifdef USE_SCTP
154
+	else if (dst->proto==PROTO_SCTP){
155
+		if (unlikely(sctp_disable)){
156
+			STATS_TX_DROPS;
157
+			LOG(L_WARN, "msg_send: WARNING: attempt to send on sctp and sctp"
158
+					" support is disabled\n");
159
+			goto error;
160
+		}else{
161
+			if (unlikely(sctp_msg_send(dst, buf, len)<0)){
162
+				STATS_TX_DROPS;
163
+				LOG(L_ERR, "msg_send: ERROR: sctp_msg_send failed\n");
164
+				goto error;
165
+			}
166
+		}
167
+	}
168
+#endif /* USE_SCTP */
150 169
 	else{
151 170
 			LOG(L_CRIT, "BUG: msg_send: unknown proto %d\n", dst->proto);
152 171
 			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 98
 extern int tls_disable;
94 99
 extern unsigned short tls_port_no;
95 100
 #endif
101
+#ifdef USE_SCTP
102
+extern int sctp_disable;
103
+extern int sctp_children_no;
104
+#endif
96 105
 extern int dont_fork;
97 106
 extern int dont_daemonize;
98 107
 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 2076
 	}
2076 2077
 #endif /* USE_COMP */
2077 2078
 			
2078
-	max_len=MY_VIA_LEN+address_str->len /* space in MY_VIA */
2079
+	via_prefix_len=MY_VIA_LEN+(send_info->proto==PROTO_SCTP);
2080
+	max_len=via_prefix_len +address_str->len /* space in MY_VIA */
2079 2081
 		+2 /* just in case it is a v6 address ... [ ] */
2080 2082
 		+1 /*':'*/+port_str->len
2081 2083
 		+(branch?(MY_BRANCH_LEN+branch->len):0)
... ...
@@ -2091,7 +2093,7 @@ char* via_builder( unsigned int *len,
2091 2093
 
2092 2094
 	extra_len=0;
2093 2095
 
2094
-	via_len=MY_VIA_LEN+address_str->len; /*space included in MY_VIA*/
2096
+	via_len=via_prefix_len+address_str->len; /*space included in MY_VIA*/
2095 2097
 
2096 2098
 	memcpy(line_buf, MY_VIA, MY_VIA_LEN);
2097 2099
 	if (send_info->proto==PROTO_UDP){
... ...
@@ -2100,6 +2102,8 @@ char* via_builder( unsigned int *len,
2100 2102
 		memcpy(line_buf+MY_VIA_LEN-4, "TCP ", 4);
2101 2103
 	}else if (send_info->proto==PROTO_TLS){
2102 2104
 		memcpy(line_buf+MY_VIA_LEN-4, "TLS ", 4);
2105
+	}else if (send_info->proto==PROTO_SCTP){
2106
+		memcpy(line_buf+MY_VIA_LEN-4, "SCTP ", 5);
2103 2107
 	}else{
2104 2108
 		LOG(L_CRIT, "BUG: via_builder: unknown proto %d\n", send_info->proto);
2105 2109
 		return 0;
... ...
@@ -2109,14 +2113,16 @@ char* via_builder( unsigned int *len,
2109 2113
 	 * if using pre-set no check is made */
2110 2114
 	if ((send_sock->address.af==AF_INET6) &&
2111 2115
 		(address_str==&(send_sock->address_str))) {
2112
-		line_buf[MY_VIA_LEN]='[';
2113
-		line_buf[MY_VIA_LEN+1+address_str->len]=']';
2116
+		line_buf[via_prefix_len]='[';
2117
+		line_buf[via_prefix_len+1+address_str->len]=']';
2114 2118
 		extra_len=1;
2115 2119
 		via_len+=2; /* [ ]*/
2116 2120
 	}
2117 2121
 #	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)){
2122
+	memcpy(line_buf+via_prefix_len+extra_len, address_str->s,
2123
+				address_str->len);
2124
+	if ((send_sock->port_no!=SIP_PORT) ||
2125
+				(port_str!=&send_sock->port_no_str)){
2120 2126
 		line_buf[via_len]=':'; via_len++;
2121 2127
 		memcpy(line_buf+via_len, port_str->s, port_str->len);
2122 2128
 		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 87
 		FORCE_TCP_ALIAS_T,
87 88
 		LOAD_AVP_T,
88 89
 		AVP_TO_URI_T,
89
-                FORCE_SEND_SOCKET_T,
90
-                ASSIGN_T,
91
-                ADD_T
92
-
90
+		FORCE_SEND_SOCKET_T,
91
+		ASSIGN_T,
92
+		ADD_T
93 93
 };
94 94
 enum { NOSUBTYPE=0, STRING_ST, NET_ST, NUMBER_ST, IP_ST, RE_ST, PROXY_ST,
95 95
 		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 340
 
335 341
 #define SER_COMPILE_FLAGS \
336 342
 	STATS_STR EXTRA_DEBUG_STR USE_IPV6_STR USE_TCP_STR USE_TLS_STR \
337
-	CORE_TLS_STR TLS_HOOKS_STR \
343
+	USE_SCTP_STR CORE_TLS_STR TLS_HOOKS_STR \
338 344
 	USE_STUN_STR DISABLE_NAGLE_STR USE_MCAST_STR NO_DEBUG_STR NO_LOG_STR \
339 345
 	NO_SIG_DEBUG_STR DNS_IP_HACK_STR  SHM_MEM_STR SHM_MMAP_STR PKG_MALLOC_STR \
340 346
 	VQ_MALLOC_STR F_MALLOC_STR DL_MALLOC_STR SF_MALLOC_STR  LL_MALLOC_STR \