Browse Source

- core sctp support

Andrei Pelinescu-Onciul 17 years ago
parent
commit
ed990c3149
16 changed files with 320 additions and 18 deletions
  1. 24 0
      Makefile.defs
  2. 10 0
      NEWS
  3. 13 1
      action.c
  4. 19 0
      cfg.lex
  5. 137 1
      cfg.y
  6. 2 0
      config.h
  7. 35 0
      core_cmd.c
  8. 22 2
      forward.c
  9. 19 0
      forward.h
  10. 9 0
      globals.h
  11. 2 0
      ip_addr.h
  12. 12 6
      msg_translator.c
  13. 4 3
      pt.c
  14. 1 0
      route.c
  15. 4 4
      route_struct.h
  16. 7 1
      version.h

+ 24 - 0
Makefile.defs

@@ -1395,6 +1395,30 @@ ifeq ($(OS), linux)
 	ifeq ($(NO_SELECT),)
 		DEFS+=-DHAVE_SELECT
 	endif
+	# sctp support
+	ifeq ($(SCTP),1)
+		# test to see if the devfiles and lib are installed
+		sctp_dev_locations := /usr/include/netinet/sctp.h \
+								$(LOCALBASE)/include/netinet/sctp.h
+		sctp_lib_locations := /usr/lib/libsctp.so \
+								$(LOCALBASE)/usr/local/lib/libsctp.so
+		sctp_dev_path := $(wildcard $(sctp_dev_locations))
+		sctp_lib_path := $(wildcard $(sctp_lib_locations))
+		ifeq ($(sctp_dev_path),)
+			$(info "sctp development files not installed -- sctp disabled")
+			override SCTP := 
+		endif
+		ifeq ($(sctp_lib_path),)
+			$(info "sctp libraries not installed -- sctp disabled")
+			override SCTP := 
+		endif
+		
+		ifeq ($(SCTP),1)
+			# use lksctp
+			DEFS+=-DUSE_SCTP
+			LIBS+=-lsctp
+		endif
+	endif # SCTP
 endif
 
 ifeq  ($(OS), solaris)

+ 10 - 0
NEWS

@@ -200,6 +200,8 @@ modules:
                         - t_set_retr(t1, t2) - changes the retransmissions
                            intervals on the fly, on a per transaction basis.
 core:
+             - 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, 
                no ipv6, no tcp, no dynamic modules
              - most of the config variables can now be changed on the fly,
@@ -218,6 +220,14 @@ core:
                between the short name and long name in cache as CNAME record
 
 new config variables:
+  disable_sctp = yes/no - diable sctp support
+  sctp_children = number - sctp children no (similar to udp children)
+  sctp_socket_rcvbuf = number - size for the sctp socket receive buffer
+  sctp_socket_sndbuf = number - size for the sctp socket send buffer
+  sctp_autoclose = seconds - number of seconds before autoclosing an idle
+     assocation (default: 180 s).
+  sctp_send_ttl = milliseconds - number of milliseconds before an unsent
+     message/chunk is dropped (default: 32000 ms or 32 s).
   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

+ 13 - 1
action.c

@@ -71,6 +71,9 @@
 #ifdef USE_TCP
 #include "tcp_server.h"
 #endif
+#ifdef USE_SCTP
+#include "sctp_server.h"
+#endif
 
 #include <sys/types.h>
 #include <sys/socket.h>
@@ -129,6 +132,9 @@ int do_action(struct run_act_ctx* h, struct action* a, struct sip_msg* msg)
 #endif
 #ifdef USE_TLS
 		case FORWARD_TLS_T:
+#endif
+#ifdef USE_SCTP
+		case FORWARD_SCTP_T:
 #endif
 		case FORWARD_UDP_T:
 			/* init dst */
@@ -140,7 +146,10 @@ int do_action(struct run_act_ctx* h, struct action* a, struct sip_msg* msg)
 #ifdef USE_TLS
 			else if (a->type==FORWARD_TLS_T) dst.proto= PROTO_TLS;
 #endif
-			else dst.proto= PROTO_NONE;
+#ifdef USE_SCTP
+			else if (a->type==FORWARD_SCTP_T) dst.proto=PROTO_SCTP;
+#endif
+			else dst.proto=PROTO_NONE;
 			if (a->val[0].type==URIHOST_ST){
 				/*parse uri*/
 
@@ -185,6 +194,9 @@ int do_action(struct run_act_ctx* h, struct action* a, struct sip_msg* msg)
 #endif
 #ifdef USE_TLS
 						case PROTO_TLS:
+#endif
+#ifdef USE_SCTP
+						case PROTO_SCTP:
 #endif
 							dst.proto=u->proto;
 							break;

+ 19 - 0
cfg.lex

@@ -127,6 +127,7 @@ FORWARD	forward
 FORWARD_TCP	forward_tcp
 FORWARD_UDP	forward_udp
 FORWARD_TLS	forward_tls
+FORWARD_SCTP	forward_sctp
 DROP	"drop"|"exit"
 RETURN	"return"
 BREAK	"break"
@@ -321,6 +322,12 @@ TLS_PRIVATE_KEY "tls_private_key"
 TLS_CA_LIST		"tls_ca_list"
 TLS_HANDSHAKE_TIMEOUT	"tls_handshake_timeout"
 TLS_SEND_TIMEOUT	"tls_send_timeout"
+DISABLE_SCTP	"disable_sctp"
+SCTP_CHILDREN	"sctp_children"
+SCTP_SOCKET_RCVBUF	"sctp_socket_rcvbuf|sctp_socket_receive_buffer"
+SCTP_SOCKET_SNDBUF	"sctp_socket_sndbuf|sctp_socket_send_buffer"
+SCTP_AUTOCLOSE	"sctp_autoclose"
+SCTP_SEND_TTL	"sctp_send_ttl"
 ADVERTISED_ADDRESS	"advertised_address"
 ADVERTISED_PORT		"advertised_port"
 DISABLE_CORE		"disable_core_dump"
@@ -409,6 +416,7 @@ EAT_ABLE	[\ \t\b\r]
 <INITIAL>{FORWARD}	{count(); yylval.strval=yytext; return FORWARD; }
 <INITIAL>{FORWARD_TCP}	{count(); yylval.strval=yytext; return FORWARD_TCP; }
 <INITIAL>{FORWARD_TLS}	{count(); yylval.strval=yytext; return FORWARD_TLS; }
+<INITIAL>{FORWARD_SCTP}	{count(); yylval.strval=yytext; return FORWARD_SCTP;}
 <INITIAL>{FORWARD_UDP}	{count(); yylval.strval=yytext; return FORWARD_UDP; }
 <INITIAL>{DROP}	{ count(); yylval.strval=yytext; return DROP; }
 <INITIAL>{RETURN}	{ count(); yylval.strval=yytext; return RETURN; }
@@ -621,6 +629,17 @@ EAT_ABLE	[\ \t\b\r]
 										return TLS_HANDSHAKE_TIMEOUT; }
 <INITIAL>{TLS_SEND_TIMEOUT}	{ count(); yylval.strval=yytext;
 										return TLS_SEND_TIMEOUT; }
+<INITIAL>{DISABLE_SCTP}	{ count(); yylval.strval=yytext; return DISABLE_SCTP;}
+<INITIAL>{SCTP_CHILDREN}	{ count(); yylval.strval=yytext;
+										return SCTP_CHILDREN; }
+<INITIAL>{SCTP_SOCKET_RCVBUF}	{ count(); yylval.strval=yytext;
+										return SCTP_SOCKET_RCVBUF; }
+<INITIAL>{SCTP_SOCKET_SNDBUF}	{ count(); yylval.strval=yytext;
+										return SCTP_SOCKET_SNDBUF; }
+<INITIAL>{SCTP_AUTOCLOSE}	{ count(); yylval.strval=yytext;
+										return SCTP_AUTOCLOSE; }
+<INITIAL>{SCTP_SEND_TTL}	{ count(); yylval.strval=yytext;
+										return SCTP_SEND_TTL; }
 <INITIAL>{SERVER_SIGNATURE}	{ count(); yylval.strval=yytext; return SERVER_SIGNATURE; }
 <INITIAL>{REPLY_TO_VIA}	{ count(); yylval.strval=yytext; return REPLY_TO_VIA; }
 <INITIAL>{ADVERTISED_ADDRESS}	{	count(); yylval.strval=yytext;

+ 137 - 1
cfg.y

@@ -116,6 +116,7 @@
 #include "flags.h"
 #include "tcp_init.h"
 #include "tcp_options.h"
+#include "sctp_options.h"
 
 #include "config.h"
 #include "cfg_core.h"
@@ -208,6 +209,7 @@ static struct socket_id* mk_listen_id(char*, int, int);
 %token FORWARD
 %token FORWARD_TCP
 %token FORWARD_TLS
+%token FORWARD_SCTP
 %token FORWARD_UDP
 %token SEND
 %token SEND_TCP
@@ -369,6 +371,12 @@ static struct socket_id* mk_listen_id(char*, int, int);
 %token TLS_CERTIFICATE
 %token TLS_PRIVATE_KEY
 %token TLS_CA_LIST
+%token DISABLE_SCTP
+%token SCTP_CHILDREN
+%token SCTP_SOCKET_RCVBUF
+%token SCTP_SOCKET_SNDBUF
+%token SCTP_AUTOCLOSE
+%token SCTP_SEND_TTL
 %token ADVERTISED_ADDRESS
 %token ADVERTISED_PORT
 %token DISABLE_CORE
@@ -1039,6 +1047,54 @@ assign_stm:
 		#endif
 	}
 	| TLS_SEND_TIMEOUT EQUAL error { yyerror("number expected"); }
+	| DISABLE_SCTP EQUAL NUMBER {
+		#ifdef USE_SCTP
+			sctp_disable=$3;
+		#else
+			warn("sctp support not compiled in");
+		#endif
+	}
+	| DISABLE_SCTP EQUAL error { yyerror("boolean value expected"); }
+	| SCTP_CHILDREN EQUAL NUMBER {
+		#ifdef USE_SCTP
+			sctp_children_no=$3;
+		#else
+			warn("sctp support not compiled in");
+		#endif
+	}
+	| SCTP_CHILDREN EQUAL error { yyerror("number expected"); }
+	| SCTP_SOCKET_RCVBUF EQUAL NUMBER {
+		#ifdef USE_SCTP
+			sctp_options.sctp_so_rcvbuf=$3;
+		#else
+			warn("sctp support not compiled in");
+		#endif
+	}
+	| SCTP_SOCKET_RCVBUF EQUAL error { yyerror("number expected"); }
+	| SCTP_SOCKET_SNDBUF EQUAL NUMBER {
+		#ifdef USE_SCTP
+			sctp_options.sctp_so_sndbuf=$3;
+		#else
+			warn("sctp support not compiled in");
+		#endif
+	}
+	| SCTP_SOCKET_SNDBUF EQUAL error { yyerror("number expected"); }
+	| SCTP_AUTOCLOSE EQUAL NUMBER {
+		#ifdef USE_SCTP
+			sctp_options.sctp_autoclose=$3;
+		#else
+			warn("sctp support not compiled in");
+		#endif
+	}
+	| SCTP_AUTOCLOSE EQUAL error { yyerror("number expected"); }
+	| SCTP_SEND_TTL EQUAL NUMBER {
+		#ifdef USE_SCTP
+			sctp_options.sctp_send_ttl=$3;
+		#else
+			warn("sctp support not compiled in");
+		#endif
+	}
+	| SCTP_SEND_TTL EQUAL error { yyerror("number expected"); }
 	| SERVER_SIGNATURE EQUAL NUMBER { server_signature=$3; }
 	| SERVER_SIGNATURE EQUAL error { yyerror("boolean value expected"); }
 	| REPLY_TO_VIA EQUAL NUMBER { reply_to_via=$3; }
@@ -1965,7 +2021,87 @@ cmd:
 		#endif
 	}
 	| FORWARD_TLS error { $$=0; yyerror("missing '(' or ')' ?"); }
-	| FORWARD_TLS LPAREN error RPAREN { $$=0; yyerror("bad forward_tls argument"); }
+	| FORWARD_TLS LPAREN error RPAREN { $$=0; 
+									yyerror("bad forward_tls argument"); }
+	| FORWARD_SCTP LPAREN host RPAREN {
+		#ifdef USE_SCTP
+			$$=mk_action(FORWARD_SCTP_T, 2, STRING_ST, $3, NUMBER_ST, 0);
+		#else
+			$$=0;
+			yyerror("sctp support not compiled in");
+		#endif
+	}
+	| FORWARD_SCTP LPAREN STRING RPAREN {
+		#ifdef USE_SCTP
+			$$=mk_action(FORWARD_SCTP_T, 2, STRING_ST, $3, NUMBER_ST, 0);
+		#else
+			$$=0;
+			yyerror("sctp support not compiled in");
+		#endif
+	}
+	| FORWARD_SCTP LPAREN ip RPAREN	{
+		#ifdef USE_SCTP
+			$$=mk_action(FORWARD_SCTP_T, 2, IP_ST, (void*)$3, NUMBER_ST, 0);
+		#else
+			$$=0;
+			yyerror("sctp support not compiled in");
+		#endif
+	}
+	| FORWARD_SCTP LPAREN host COMMA NUMBER RPAREN {
+		#ifdef USE_SCTP
+			$$=mk_action(FORWARD_SCTP_T, 2, STRING_ST, $3, NUMBER_ST,
+							(void*)$5);
+		#else
+			$$=0;
+			yyerror("sctp support not compiled in");
+		#endif
+	}
+	| FORWARD_SCTP LPAREN STRING COMMA NUMBER RPAREN {
+		#ifdef USE_SCTP
+			$$=mk_action(FORWARD_SCTP_T, 2, STRING_ST, $3, NUMBER_ST,
+							(void*)$5);
+		#else
+			$$=0;
+			yyerror("sctp support not compiled in");
+		#endif
+	}
+	| FORWARD_SCTP LPAREN ip COMMA NUMBER RPAREN {
+		#ifdef USE_SCTP
+			$$=mk_action(FORWARD_SCTP_T, 2, IP_ST, (void*)$3, NUMBER_ST, 
+							(void*)$5);
+		#else
+			$$=0;
+			yyerror("sctp support not compiled in");
+		#endif
+					}
+	| FORWARD_SCTP LPAREN URIHOST COMMA URIPORT RPAREN {
+		#ifdef USE_SCTP
+			$$=mk_action(FORWARD_SCTP_T, 2, URIHOST_ST, 0, URIPORT_ST, 0);
+		#else
+			$$=0;
+			yyerror("sctp support not compiled in");
+		#endif
+	}
+	| FORWARD_SCTP LPAREN URIHOST COMMA NUMBER RPAREN {
+		#ifdef USE_SCTP
+			$$=mk_action(FORWARD_SCTP_T, 2, URIHOST_ST, 0, NUMBER_ST,
+							(void*)$5);
+		#else
+			$$=0;
+			yyerror("sctp support not compiled in");
+		#endif
+	}
+	| FORWARD_SCTP LPAREN URIHOST RPAREN {
+		#ifdef USE_SCTP
+			$$=mk_action(FORWARD_SCTP_T, 2, URIHOST_ST, 0, NUMBER_ST, 0);
+		#else
+			$$=0;
+			yyerror("tls support not compiled in");
+		#endif
+	}
+	| FORWARD_SCTP error { $$=0; yyerror("missing '(' or ')' ?"); }
+	| FORWARD_SCTP LPAREN error RPAREN { $$=0; 
+									yyerror("bad forward_tls argument"); }
 	| SEND LPAREN host RPAREN	{ $$=mk_action(SEND_T, 2, STRING_ST, $3, NUMBER_ST, 0); }
 	| SEND LPAREN STRING RPAREN { $$=mk_action(SEND_T, 2, STRING_ST, $3, NUMBER_ST, 0); }
 	| SEND LPAREN ip RPAREN		{ $$=mk_action(SEND_T, 2, IP_ST, (void*)$3, NUMBER_ST, 0); }

+ 2 - 0
config.h

@@ -199,6 +199,8 @@
 /* minimum packet size; smaller packets will be dropped silently */
 #define MIN_UDP_PACKET        32
 
+#define MIN_SCTP_PACKET  MIN_UDP_PACKET 
+
 #define DEFAULT_RADIUS_CONFIG "/usr/local/etc/radiusclient/radiusclient.conf"
 
 #define DEFAULT_DID "_default"

+ 35 - 0
core_cmd.c

@@ -39,6 +39,9 @@
 #include "tcp_info.h"
 #include "tcp_options.h"
 #include "core_cmd.h"
+#ifdef USE_SCTP
+#include "sctp_options.h"
+#endif
 
 #ifdef USE_DNS_CACHE
 void dns_cache_debug(rpc_t* rpc, void* ctx);
@@ -589,6 +592,36 @@ static void core_tcp_options(rpc_t* rpc, void* c)
 
 
 
+static const char* core_sctp_options_doc[] = {
+	"Returns active sctp options.",    /* Documentation string */
+	0                                 /* Method signature(s) */
+};
+
+static void core_sctp_options(rpc_t* rpc, void* c)
+{
+#ifdef USE_SCTP
+	void *handle;
+	struct sctp_cfg_options t;
+
+	if (!sctp_disable){
+		sctp_options_get(&t);
+		rpc->add(c, "{", &handle);
+		rpc->struct_add(handle, "dddd",
+			"sctp_autoclose",		t.sctp_autoclose,
+			"sctp_send_ttl",	t.sctp_autoclose,
+			"sctp_socket_rcvbuf",	t.sctp_so_rcvbuf,
+			"sctp_socket_sndbuf",	t.sctp_so_sndbuf
+		);
+	}else{
+		rpc->fault(c, 500, "sctp support disabled");
+	}
+#else
+	rpc->fault(c, 500, "sctp support not compiled");
+#endif
+}
+
+
+
 /*
  * RPC Methods exported by this module
  */
@@ -609,6 +642,8 @@ rpc_export_t core_rpc_methods[] = {
 #endif
 	{"core.tcp_info",          core_tcpinfo,           core_tcpinfo_doc,    0},
 	{"core.tcp_options",       core_tcp_options,       core_tcp_options_doc,0},
+	{"core.sctp_options",      core_sctp_options,      core_sctp_options_doc,
+		0},
 #ifdef USE_DNS_CACHE
 	{"dns.mem_info",          dns_cache_mem_info,     dns_cache_mem_info_doc,     0	},
 	{"dns.debug",          dns_cache_debug,           dns_cache_debug_doc,        0	},

+ 22 - 2
forward.c

@@ -233,9 +233,29 @@ not_forced:
 			}
 			break;
 #endif /* USE_TLS */
+#ifdef USE_SCTP
+		case PROTO_SCTP:
+			if ((bind_address==0) ||
+					(to->s.sa_family!=bind_address->address.af) ||
+					(bind_address->proto!=PROTO_SCTP)){
+				switch(to->s.sa_family){
+					case AF_INET:	send_sock=sendipv4_sctp;
+									break;
+#ifdef USE_IPV6
+					case AF_INET6:	send_sock=sendipv6_sctp;
+									break;
+#endif
+					default:	LOG(L_ERR, "get_send_socket: BUG: don't know"
+										" how to forward to af %d\n",
+										to->s.sa_family);
+				}
+			}else send_sock=bind_address;
+			break;
+#endif /* USE_SCTP */
 		case PROTO_UDP:
-			if ((bind_address==0)||(to->s.sa_family!=bind_address->address.af)||
-				  (bind_address->proto!=PROTO_UDP)){
+			if ((bind_address==0) ||
+					(to->s.sa_family!=bind_address->address.af) ||
+					(bind_address->proto!=PROTO_UDP)){
 				switch(to->s.sa_family){
 					case AF_INET:	send_sock=sendipv4;
 									break;

+ 19 - 0
forward.h

@@ -55,6 +55,9 @@
 #ifdef USE_TCP
 #include "tcp_server.h"
 #endif
+#ifdef USE_SCTP
+#include "sctp_server.h"
+#endif
 
 #include "compiler_opt.h"
 
@@ -147,6 +150,22 @@ static inline int msg_send(struct dest_info* dst, char* buf, int len)
 	}
 #endif /* USE_TLS */
 #endif /* USE_TCP */
+#ifdef USE_SCTP
+	else if (dst->proto==PROTO_SCTP){
+		if (unlikely(sctp_disable)){
+			STATS_TX_DROPS;
+			LOG(L_WARN, "msg_send: WARNING: attempt to send on sctp and sctp"
+					" support is disabled\n");
+			goto error;
+		}else{
+			if (unlikely(sctp_msg_send(dst, buf, len)<0)){
+				STATS_TX_DROPS;
+				LOG(L_ERR, "msg_send: ERROR: sctp_msg_send failed\n");
+				goto error;
+			}
+		}
+	}
+#endif /* USE_SCTP */
 	else{
 			LOG(L_CRIT, "BUG: msg_send: unknown proto %d\n", dst->proto);
 			goto error;

+ 9 - 0
globals.h

@@ -75,6 +75,11 @@ extern struct socket_info* sendipv4_tls; /* ipv4 socket to use when msg.
 										comes from ipv6*/
 extern struct socket_info* sendipv6_tls; /* same as above for ipv6 */
 #endif
+#ifdef USE_SCTP
+extern struct socket_info* sendipv4_sctp; /* ipv4 socket to use when msg.
+										comes from ipv6*/
+extern struct socket_info* sendipv6_sctp; /* same as above for ipv6 */
+#endif
 
 extern unsigned int maxbuffer;
 extern int children_no;
@@ -93,6 +98,10 @@ extern int tcp_max_connections;
 extern int tls_disable;
 extern unsigned short tls_port_no;
 #endif
+#ifdef USE_SCTP
+extern int sctp_disable;
+extern int sctp_children_no;
+#endif
 extern int dont_fork;
 extern int dont_daemonize;
 extern int check_via;

+ 2 - 0
ip_addr.h

@@ -52,6 +52,8 @@
 #include "dprint.h"
 
 enum sip_protos { PROTO_NONE, PROTO_UDP, PROTO_TCP, PROTO_TLS, PROTO_SCTP };
+#define PROTO_LAST PROTO_SCTP
+
 #ifdef USE_COMP
 enum comp_methods { COMP_NONE, COMP_SIGCOMP, COMP_SERGZ };
 #endif

+ 12 - 6
msg_translator.c

@@ -2035,6 +2035,7 @@ char* via_builder( unsigned int *len,
 	unsigned int  via_len, extra_len;
 	char               *line_buf;
 	int max_len;
+	int via_prefix_len;
 	str* address_str; /* address displayed in via */
 	str* port_str; /* port no displayed in via */
 	struct socket_info* send_sock;
@@ -2075,7 +2076,8 @@ char* via_builder( unsigned int *len,
 	}
 #endif /* USE_COMP */
 			
-	max_len=MY_VIA_LEN+address_str->len /* space in MY_VIA */
+	via_prefix_len=MY_VIA_LEN+(send_info->proto==PROTO_SCTP);
+	max_len=via_prefix_len +address_str->len /* space in MY_VIA */
 		+2 /* just in case it is a v6 address ... [ ] */
 		+1 /*':'*/+port_str->len
 		+(branch?(MY_BRANCH_LEN+branch->len):0)
@@ -2091,7 +2093,7 @@ char* via_builder( unsigned int *len,
 
 	extra_len=0;
 
-	via_len=MY_VIA_LEN+address_str->len; /*space included in MY_VIA*/
+	via_len=via_prefix_len+address_str->len; /*space included in MY_VIA*/
 
 	memcpy(line_buf, MY_VIA, MY_VIA_LEN);
 	if (send_info->proto==PROTO_UDP){
@@ -2100,6 +2102,8 @@ char* via_builder( unsigned int *len,
 		memcpy(line_buf+MY_VIA_LEN-4, "TCP ", 4);
 	}else if (send_info->proto==PROTO_TLS){
 		memcpy(line_buf+MY_VIA_LEN-4, "TLS ", 4);
+	}else if (send_info->proto==PROTO_SCTP){
+		memcpy(line_buf+MY_VIA_LEN-4, "SCTP ", 5);
 	}else{
 		LOG(L_CRIT, "BUG: via_builder: unknown proto %d\n", send_info->proto);
 		return 0;
@@ -2109,14 +2113,16 @@ char* via_builder( unsigned int *len,
 	 * if using pre-set no check is made */
 	if ((send_sock->address.af==AF_INET6) &&
 		(address_str==&(send_sock->address_str))) {
-		line_buf[MY_VIA_LEN]='[';
-		line_buf[MY_VIA_LEN+1+address_str->len]=']';
+		line_buf[via_prefix_len]='[';
+		line_buf[via_prefix_len+1+address_str->len]=']';
 		extra_len=1;
 		via_len+=2; /* [ ]*/
 	}
 #	endif
-	memcpy(line_buf+MY_VIA_LEN+extra_len, address_str->s, address_str->len);
-	if ((send_sock->port_no!=SIP_PORT) || (port_str!=&send_sock->port_no_str)){
+	memcpy(line_buf+via_prefix_len+extra_len, address_str->s,
+				address_str->len);
+	if ((send_sock->port_no!=SIP_PORT) ||
+				(port_str!=&send_sock->port_no_str)){
 		line_buf[via_len]=':'; via_len++;
 		memcpy(line_buf+via_len, port_str->s, port_str->len);
 		via_len+=port_str->len;

+ 4 - 3
pt.c

@@ -83,9 +83,10 @@ static int calc_common_open_fds_no()
 	 *  + 1 udp sock/udp proc + 1 possible dns comm. socket + 
 	 *  + 1 temporary tcp send sock.
 	 */
-	max_fds_no=estimated_proc_no*4 /* udp + tcp unix sock + tmp. tcp send +
-									  tmp dns.*/ -1 /* timer (no udp)*/ + 
-				3 /* stdin/out/err */;
+	max_fds_no=estimated_proc_no*4 /* udp|sctp + tcp unix sock +
+									  tmp. tcp send +
+									  tmp dns.*/
+				-1 /* timer (no udp)*/ + 3 /* stdin/out/err */;
 	return max_fds_no;
 }
 

+ 1 - 0
route.c

@@ -401,6 +401,7 @@ static int fix_actions(struct action* a)
 			case FORWARD_T:
 			case FORWARD_TLS_T:
 			case FORWARD_TCP_T:
+			case FORWARD_SCTP_T:
 			case FORWARD_UDP_T:
 			case SEND_T:
 			case SEND_TCP_T:

+ 4 - 4
route_struct.h

@@ -79,6 +79,7 @@ enum { FORWARD_T=1, SEND_T, DROP_T, LOG_T, ERROR_T, ROUTE_T, EXEC_T,
 		FORWARD_TCP_T,
 		FORWARD_UDP_T,
 		FORWARD_TLS_T,
+		FORWARD_SCTP_T,
 		SEND_TCP_T,
 		FORCE_RPORT_T,
 		SET_ADV_ADDR_T,
@@ -86,10 +87,9 @@ enum { FORWARD_T=1, SEND_T, DROP_T, LOG_T, ERROR_T, ROUTE_T, EXEC_T,
 		FORCE_TCP_ALIAS_T,
 		LOAD_AVP_T,
 		AVP_TO_URI_T,
-                FORCE_SEND_SOCKET_T,
-                ASSIGN_T,
-                ADD_T
-
+		FORCE_SEND_SOCKET_T,
+		ASSIGN_T,
+		ADD_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,

+ 7 - 1
version.h

@@ -57,6 +57,12 @@
 #define USE_TLS_STR ""
 #endif
 
+#ifdef USE_SCTP
+#define USE_SCTP_STR ", USE_SCTP"
+#else
+#define USE_SCTP_STR ""
+#endif
+
 #ifdef CORE_TLS
 #define CORE_TLS_STR ", CORE_TLS"
 #else 
@@ -334,7 +340,7 @@
 
 #define SER_COMPILE_FLAGS \
 	STATS_STR EXTRA_DEBUG_STR USE_IPV6_STR USE_TCP_STR USE_TLS_STR \
-	CORE_TLS_STR TLS_HOOKS_STR \
+	USE_SCTP_STR CORE_TLS_STR TLS_HOOKS_STR \
 	USE_STUN_STR DISABLE_NAGLE_STR USE_MCAST_STR NO_DEBUG_STR NO_LOG_STR \
 	NO_SIG_DEBUG_STR DNS_IP_HACK_STR  SHM_MEM_STR SHM_MMAP_STR PKG_MALLOC_STR \
 	VQ_MALLOC_STR F_MALLOC_STR DL_MALLOC_STR SF_MALLOC_STR  LL_MALLOC_STR \