浏览代码

- changed tcp to support port aliases (major changes)
- added via alias parameter parsing
- added script var. tcp_accept_aliases= yes|no (honour or not via alias param)
- added script. cmd. force_tcp_alias( <void>|port_no)
[for more info read the NEWS file]

Andrei Pelinescu-Onciul 22 年之前
父节点
当前提交
59653eb856
共有 17 个文件被更改,包括 344 次插入66 次删除
  1. 1 1
      Makefile.defs
  2. 26 0
      NEWS
  3. 12 9
      TODO
  4. 28 0
      action.c
  5. 7 0
      cfg.lex
  6. 44 1
      cfg.y
  7. 1 1
      forward.c
  8. 1 0
      globals.h
  9. 58 11
      parser/parse_via.c
  10. 4 2
      parser/parse_via.h
  11. 18 0
      receive.c
  12. 3 0
      route_struct.c
  13. 3 1
      route_struct.h
  14. 23 7
      tcp_conn.h
  15. 111 32
      tcp_main.c
  16. 1 1
      tcp_server.h
  17. 3 0
      test/test.cfg

+ 1 - 1
Makefile.defs

@@ -43,7 +43,7 @@ export makefile_defs
 VERSION = 0
 VERSION = 0
 PATCHLEVEL = 8
 PATCHLEVEL = 8
 SUBLEVEL =   12
 SUBLEVEL =   12
-EXTRAVERSION = dev-21-sock_info
+EXTRAVERSION = dev-22-tcp_aliases
 
 
 RELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 RELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 OS = $(shell uname -s | sed -e s/SunOS/solaris/ | tr "[A-Z]" "[a-z]")
 OS = $(shell uname -s | sed -e s/SunOS/solaris/ | tr "[A-Z]" "[a-z]")

+ 26 - 0
NEWS

@@ -34,6 +34,14 @@ core:
        This is the default value, if empty (default) the socket
        This is the default value, if empty (default) the socket
        port will be used.
        port will be used.
        Same warnings as above.
        Same warnings as above.
+   tcp_accept_aliases= yes|no
+       if a message received over a tcp connection has "alias" in its via
+       a new tcp alias port will be created for the connection the message
+       came from (the alias port will be set to the via one).
+       Based on draft-ietf-sip-connect-reuse-00.txt, but using only the port
+       (host aliases are too dangerous IMHO, involve extra DNS
+        lookups and the need for them is questionable)
+       See force_tcp_alias for more details.
  - new script commands:
  - new script commands:
     set_advertised_address(ip|string)
     set_advertised_address(ip|string)
        same as advertised_address but it affects only the current message:
        same as advertised_address but it affects only the current message:
@@ -42,6 +50,24 @@ core:
     set_advertised_port(no)
     set_advertised_port(no)
        same as advertised_port but it affects only the current
        same as advertised_port but it affects only the current
        message; see set_advertised_address & s/address/port/g
        message; see set_advertised_address & s/address/port/g
+   force_tcp_alias()
+   force_tcp_alias(port)
+       adds a tcp port alias for the current connection (if tcp).
+       Usefull if you want to send all the trafic to port_alias through
+       the same connection this request came from [it could help 
+       for firewall or nat traversal].
+       With no parameters adds the port from the message via as the alias.
+       When the "aliased" connection is closed (e.g. it's idle for too
+       much time), all the port aliases are removed.
+       Note: by default ser closes idle connection after 3 minutes (stable)
+       or 1 minute (unstable) so to take full advantage of tcp aliases for
+       things like firewall and nat traversal, redefine TCP_CON_*TIMEOUT
+       in tcp_conn.h and recompile. Also right now there can be maximum
+       3 port aliases to a connection (you shouldn't need more than one).
+       To change this redefine TCP_CON_MAX_ALIASES in the same file
+       (set it to you desired value + 1; 1 is needed for the real port).
+
+
 
 
 
 
 
 

+ 12 - 9
TODO

@@ -2,13 +2,14 @@ $Id$
 
 
 ( - todo, x - done)
 ( - todo, x - done)
 
 
-- fix aliases for tls_port (add_them?)
+- nathelper: extract_body broken-> uses content_length value form the 
+ message instead of recalculating it + duplicate code for get_body()
 - fix check_sel_op -- add proto for uri proto checks
 - fix check_sel_op -- add proto for uri proto checks
-- add via alias for tcp port & infinite tcp conn life
+- add setting for infinite tcp conn life?
 
 
 - fix 2 different fixups for diff. no of parameter
 - fix 2 different fixups for diff. no of parameter
- (add no of params ot struct action?) -- linked to var. no. of params
-- alias support fot tcp/tls port numbers
+ (add no of params to struct action?) -- linked to var. no. of params
+x alias support fot tcp/tls port numbers
 - warning builder set_advertised address support
 - warning builder set_advertised address support
 - grep parse_uri & replace with parse_sip_msg_uri (e.g do_action!)
 - grep parse_uri & replace with parse_sip_msg_uri (e.g do_action!)
 x update AUTHORS, debian/copyright, ser.8, ser.cfg.5 from stable
 x update AUTHORS, debian/copyright, ser.8, ser.cfg.5 from stable
@@ -17,14 +18,16 @@ x update all package specs from stable
 - add BUG checks for  fd > 0 && fd <= maxfd to all selects?
 - add BUG checks for  fd > 0 && fd <= maxfd to all selects?
 x tcp_main_loop: BUG cases should "conitnue;"
 x tcp_main_loop: BUG cases should "conitnue;"
 x change len_gt into and expr (e.g msg:len).
 x change len_gt into and expr (e.g msg:len).
-- sipit: uri == myself doesn't match tls port = 5061
-- sipit: fix check_self & *_alias to work with tcp & tls
+x sipit: uri == myself doesn't match tls port = 5061 
+  -- updated: new socket_info list code should fix it
+x sipit: fix check_self & *_alias to work with tcp & tls
+  -- updated: new socket_info list code should fix it
 x sipit: fix ipv6 references in check_self
 x sipit: fix ipv6 references in check_self
 x regex subst on uris?
 x regex subst on uris?
 x port receive.c pre_script_cb fix from stable
 x port receive.c pre_script_cb fix from stable
-- extend alias to include port numbers :
+x extend alias to include port numbers :
     something like alias= foo1.bar:5080 foo2.bar foo3.bar:*
     something like alias= foo1.bar:5080 foo2.bar foo3.bar:*
-- extend listen and alias to include port numbers and protocol:
+x extend listen and alias to include port numbers and protocol:
        tcp foo.bar:5063, udp foo.bar:5062, foo2.bar
        tcp foo.bar:5063, udp foo.bar:5062, foo2.bar
 x added set_advertised_{address,port} -- was: add force_via, force_srcip a.s.o
 x added set_advertised_{address,port} -- was: add force_via, force_srcip a.s.o
 (the advertised addresses should be overwritable from the script).
 (the advertised addresses should be overwritable from the script).
@@ -123,7 +126,7 @@ x man page
 - autoconf scripts
 - autoconf scripts
 x Debian package build files
 x Debian package build files
 x the same for rpm
 x the same for rpm
-- the same for FreeBSD and Slackware
+x the same for *BSD
 
 
 
 
 x jku: branch hash computation over canonical values
 x jku: branch hash computation over canonical values

+ 28 - 0
action.c

@@ -35,6 +35,7 @@
  *  2003-04-12  FORCE_RPORT_T added (andrei)
  *  2003-04-12  FORCE_RPORT_T added (andrei)
  *  2003-04-22  strip_tail added (jiri)
  *  2003-04-22  strip_tail added (jiri)
  *  2003-10-02  added SET_ADV_ADDR_T & SET_ADV_PORT_T (andrei)
  *  2003-10-02  added SET_ADV_ADDR_T & SET_ADV_PORT_T (andrei)
+ *  2003-10-29  added FORCE_TCP_ALIAS_T (andrei)
  */
  */
 
 
 
 
@@ -629,6 +630,33 @@ int do_action(struct action* a, struct sip_msg* msg)
 			msg->set_global_port=*((str*)a->p1.data);
 			msg->set_global_port=*((str*)a->p1.data);
 			ret=1; /* continue processing */
 			ret=1; /* continue processing */
 			break;
 			break;
+#ifdef USE_TCP
+		case FORCE_TCP_ALIAS_T:
+			if ( msg->rcv.proto==PROTO_TCP
+#ifdef USE_TLS
+					|| msg->rcv.proto==PROTO_TLS
+#endif
+			   ){
+				
+				if (a->p1_type==NOSUBTYPE)	port=msg->via1->port;
+				else if (a->p1_type==NUMBER_ST) port=(int)a->p1.number;
+				else{
+					LOG(L_CRIT, "BUG: do_action: bad force_tcp_alias"
+							" port type %d\n", a->p1_type);
+					ret=E_BUG;
+					break;
+				}
+						
+				if (tcpconn_add_alias(msg->rcv.proto_reserved1, port,
+									msg->rcv.proto)!=0){
+					LOG(L_ERR, " ERROR: receive_msg: tcp alias failed\n");
+					ret=E_UNSPEC;
+					break;
+				}
+			}
+#endif
+			ret=1; /* continue processing */
+			break;
 		default:
 		default:
 			LOG(L_CRIT, "BUG: do_action: unknown type %d\n", a->type);
 			LOG(L_CRIT, "BUG: do_action: unknown type %d\n", a->type);
 	}
 	}

+ 7 - 0
cfg.lex

@@ -42,6 +42,7 @@
  *  2003-10-07  added hex and octal numbers support (andrei)
  *  2003-10-07  added hex and octal numbers support (andrei)
  *  2003-10-10  replaced len_gt w/ msg:len (andrei)
  *  2003-10-10  replaced len_gt w/ msg:len (andrei)
  *  2003-10-13  added fifo_dir (andrei)
  *  2003-10-13  added fifo_dir (andrei)
+ *  2003-10-28  added tcp_accept_aliases (andrei)
  */
  */
 
 
 
 
@@ -93,6 +94,7 @@ ROUTE_FAILURE failure_route
 ROUTE_ONREPLY onreply_route
 ROUTE_ONREPLY onreply_route
 EXEC	exec
 EXEC	exec
 FORCE_RPORT		"force_rport"|"add_rport"
 FORCE_RPORT		"force_rport"|"add_rport"
+FORCE_TCP_ALIAS		"force_tcp_alias"|"add_tcp_alias"
 SETFLAG		setflag
 SETFLAG		setflag
 RESETFLAG	resetflag
 RESETFLAG	resetflag
 ISFLAGSET	isflagset
 ISFLAGSET	isflagset
@@ -176,6 +178,7 @@ WDIR		"workdir"|"wdir"
 MHOMED		mhomed
 MHOMED		mhomed
 DISABLE_TCP		"disable_tcp"
 DISABLE_TCP		"disable_tcp"
 TCP_CHILDREN	"tcp_children"
 TCP_CHILDREN	"tcp_children"
+TCP_ACCEPT_ALIASES	"tcp_accept_aliases"
 DISABLE_TLS		"disable_tls"
 DISABLE_TLS		"disable_tls"
 TLSLOG			"tlslog"|"tls_log"
 TLSLOG			"tlslog"|"tls_log"
 TLS_PORT_NO		"tls_port_no"
 TLS_PORT_NO		"tls_port_no"
@@ -275,6 +278,8 @@ EAT_ABLE	[\ \t\b\r]
 <INITIAL>{APPEND_BRANCH}	{ count(); yylval.strval=yytext; 
 <INITIAL>{APPEND_BRANCH}	{ count(); yylval.strval=yytext; 
 								return APPEND_BRANCH; }
 								return APPEND_BRANCH; }
 <INITIAL>{FORCE_RPORT}	{ count(); yylval.strval=yytext; return FORCE_RPORT; }
 <INITIAL>{FORCE_RPORT}	{ count(); yylval.strval=yytext; return FORCE_RPORT; }
+<INITIAL>{FORCE_TCP_ALIAS}	{ count(); yylval.strval=yytext;
+								return FORCE_TCP_ALIAS; }
 	
 	
 <INITIAL>{IF}	{ count(); yylval.strval=yytext; return IF; }
 <INITIAL>{IF}	{ count(); yylval.strval=yytext; return IF; }
 <INITIAL>{ELSE}	{ count(); yylval.strval=yytext; return ELSE; }
 <INITIAL>{ELSE}	{ count(); yylval.strval=yytext; return ELSE; }
@@ -321,6 +326,8 @@ EAT_ABLE	[\ \t\b\r]
 <INITIAL>{MHOMED}	{ count(); yylval.strval=yytext; return MHOMED; }
 <INITIAL>{MHOMED}	{ count(); yylval.strval=yytext; return MHOMED; }
 <INITIAL>{DISABLE_TCP}	{ count(); yylval.strval=yytext; return DISABLE_TCP; }
 <INITIAL>{DISABLE_TCP}	{ count(); yylval.strval=yytext; return DISABLE_TCP; }
 <INITIAL>{TCP_CHILDREN}	{ count(); yylval.strval=yytext; return TCP_CHILDREN; }
 <INITIAL>{TCP_CHILDREN}	{ count(); yylval.strval=yytext; return TCP_CHILDREN; }
+<INITIAL>{TCP_ACCEPT_ALIASES}	{ count(); yylval.strval=yytext;
+									return TCP_ACCEPT_ALIASES; }
 <INITIAL>{DISABLE_TLS}	{ count(); yylval.strval=yytext; return DISABLE_TLS; }
 <INITIAL>{DISABLE_TLS}	{ count(); yylval.strval=yytext; return DISABLE_TLS; }
 <INITIAL>{TLSLOG}		{ count(); yylval.strval=yytext; return TLS_PORT_NO; }
 <INITIAL>{TLSLOG}		{ count(); yylval.strval=yytext; return TLS_PORT_NO; }
 <INITIAL>{TLS_PORT_NO}	{ count(); yylval.strval=yytext; return TLS_PORT_NO; }
 <INITIAL>{TLS_PORT_NO}	{ count(); yylval.strval=yytext; return TLS_PORT_NO; }

+ 44 - 1
cfg.y

@@ -48,6 +48,7 @@
  * 2003-10-11  if(){} doesn't require a ';' after it anymore (andrei)
  * 2003-10-11  if(){} doesn't require a ';' after it anymore (andrei)
  * 2003-10-13  added FIFO_DIR & proto:host:port listen/alias support (andrei)
  * 2003-10-13  added FIFO_DIR & proto:host:port listen/alias support (andrei)
  * 2003-10-24  converted to the new socket_info lists (andrei)
  * 2003-10-24  converted to the new socket_info lists (andrei)
+ * 2003-10-28  added tcp_accept_aliases (andrei)
  */
  */
 
 
 
 
@@ -148,6 +149,7 @@ static struct id_list* mk_listen_id(char*, int, int);
 %token SET_URI
 %token SET_URI
 %token REVERT_URI
 %token REVERT_URI
 %token FORCE_RPORT
 %token FORCE_RPORT
+%token FORCE_TCP_ALIAS
 %token IF
 %token IF
 %token ELSE
 %token ELSE
 %token SET_ADV_ADDRESS
 %token SET_ADV_ADDRESS
@@ -202,6 +204,7 @@ static struct id_list* mk_listen_id(char*, int, int);
 %token WDIR
 %token WDIR
 %token MHOMED
 %token MHOMED
 %token DISABLE_TCP
 %token DISABLE_TCP
+%token TCP_ACCEPT_ALIASES
 %token TCP_CHILDREN
 %token TCP_CHILDREN
 %token DISABLE_TLS
 %token DISABLE_TLS
 %token TLSLOG
 %token TLSLOG
@@ -409,6 +412,14 @@ assign_stm:	DEBUG EQUAL NUMBER { debug=$3; }
 									#endif
 									#endif
 									}
 									}
 		| DISABLE_TCP EQUAL error { yyerror("boolean value expected"); }
 		| DISABLE_TCP EQUAL error { yyerror("boolean value expected"); }
+		| TCP_ACCEPT_ALIASES EQUAL NUMBER {
+									#ifdef USE_TCP
+										tcp_accept_aliases=$3;
+									#else
+										warn("tcp support not compiled in");
+									#endif
+									}
+		| TCP_ACCEPT_ALIASES EQUAL error { yyerror("boolean value expected"); }
 		| TCP_CHILDREN EQUAL NUMBER {
 		| TCP_CHILDREN EQUAL NUMBER {
 									#ifdef USE_TCP
 									#ifdef USE_TCP
 										tcp_children_no=$3;
 										tcp_children_no=$3;
@@ -1373,8 +1384,40 @@ cmd:		FORWARD LPAREN host RPAREN	{ $$=mk_action(	FORWARD_T,
 										"string expected"); }
 										"string expected"); }
 		| REVERT_URI LPAREN RPAREN { $$=mk_action( REVERT_URI_T, 0,0,0,0); }
 		| REVERT_URI LPAREN RPAREN { $$=mk_action( REVERT_URI_T, 0,0,0,0); }
 		| REVERT_URI { $$=mk_action( REVERT_URI_T, 0,0,0,0); }
 		| REVERT_URI { $$=mk_action( REVERT_URI_T, 0,0,0,0); }
-		| FORCE_RPORT LPAREN RPAREN	{$$=mk_action(FORCE_RPORT_T,0, 0, 0, 0); }
+		| FORCE_RPORT LPAREN RPAREN	{
+							#ifdef USE_TCP
+								$$=mk_action(FORCE_RPORT_T,0, 0, 0, 0); 
+							#else
+								yyerror("tcp support not compiled in");
+							#endif
+							}
 		| FORCE_RPORT				{$$=mk_action(FORCE_RPORT_T,0, 0, 0, 0); }
 		| FORCE_RPORT				{$$=mk_action(FORCE_RPORT_T,0, 0, 0, 0); }
+		| FORCE_TCP_ALIAS LPAREN NUMBER RPAREN	{
+					#ifdef USE_TCP
+						$$=mk_action(FORCE_TCP_ALIAS_T,NUMBER_ST, 0,
+										(void*)$3, 0);
+					#else
+						yyerror("tcp support not compiled in");
+					#endif
+												}
+		| FORCE_TCP_ALIAS LPAREN RPAREN	{
+					#ifdef USE_TCP
+						$$=mk_action(FORCE_TCP_ALIAS_T,0, 0, 0, 0); 
+					#else
+						yyerror("tcp support not compiled in");
+					#endif
+										}
+		| FORCE_TCP_ALIAS				{
+					#ifdef USE_TCP
+						$$=mk_action(FORCE_TCP_ALIAS_T,0, 0, 0, 0);
+					#else
+						yyerror("tcp support not compiled in");
+					#endif
+										}
+		| FORCE_TCP_ALIAS LPAREN error RPAREN	{$$=0; 
+												yyerror("bad argument,"
+														" number expected");
+												}
 		| SET_ADV_ADDRESS LPAREN listen_id RPAREN {
 		| SET_ADV_ADDRESS LPAREN listen_id RPAREN {
 								$$=0;
 								$$=0;
 								if ((str_tmp=pkg_malloc(sizeof(str)))==0){
 								if ((str_tmp=pkg_malloc(sizeof(str)))==0){

+ 1 - 1
forward.c

@@ -39,7 +39,7 @@
  *  2003-04-03  added su_setport (andrei)
  *  2003-04-03  added su_setport (andrei)
  *  2003-04-04  update_sock_struct_from_via now differentiates between
  *  2003-04-04  update_sock_struct_from_via now differentiates between
  *               local replies  & "normal" replies (andrei)
  *               local replies  & "normal" replies (andrei)
- *  2003-04-12  update_sock_struct_form via uses also FL_FORCE_RPORT for
+ *  2003-04-12  update_sock_struct_from via uses also FL_FORCE_RPORT for
  *               local replies (andrei)
  *               local replies (andrei)
  *  2003-08-21  check_self properly handles ipv6 addresses & refs   (andrei)
  *  2003-08-21  check_self properly handles ipv6 addresses & refs   (andrei)
  *  2003-10-21  check_self updated to handle proto (andrei)
  *  2003-10-21  check_self updated to handle proto (andrei)

+ 1 - 0
globals.h

@@ -70,6 +70,7 @@ extern int children_no;
 #ifdef USE_TCP
 #ifdef USE_TCP
 extern int tcp_children_no;
 extern int tcp_children_no;
 extern int tcp_disable;
 extern int tcp_disable;
+extern int tcp_accept_aliases;
 #endif
 #endif
 #ifdef USE_TLS
 #ifdef USE_TLS
 extern int tls_disable;
 extern int tls_disable;

+ 58 - 11
parser/parse_via.c

@@ -44,6 +44,8 @@
  *  2003-04-26  ZSW (jiri)
  *  2003-04-26  ZSW (jiri)
  *  2003-06-23  fixed  parse_via_param [op].* param. parsing bug (andrei)
  *  2003-06-23  fixed  parse_via_param [op].* param. parsing bug (andrei)
  *  2003-07-02  added support for TLS parsing in via (andrei)
  *  2003-07-02  added support for TLS parsing in via (andrei)
+ *  2003-10-27  added support for alias via param parsing [see
+ *               draft-ietf-sip-connect-reuse-00.txt.]  (andrei)
  */
  */
 
 
 
 
@@ -100,9 +102,10 @@ enum {
 	RECEIVED1, RECEIVED2, RECEIVED3, RECEIVED4, RECEIVED5, RECEIVED6,
 	RECEIVED1, RECEIVED2, RECEIVED3, RECEIVED4, RECEIVED5, RECEIVED6,
 	RECEIVED7,
 	RECEIVED7,
 	RPORT1, RPORT2, RPORT3,
 	RPORT1, RPORT2, RPORT3,
+	ALIAS1, ALIAS2, ALIAS3, ALIAS4,
 	     /* fin states (227-...)*/
 	     /* fin states (227-...)*/
-	FIN_HIDDEN = 230, FIN_TTL, FIN_BRANCH, FIN_MADDR, FIN_RECEIVED,
-	FIN_RPORT, FIN_I
+	FIN_HIDDEN = 230, FIN_TTL, FIN_BRANCH,
+	FIN_MADDR, FIN_RECEIVED, FIN_RPORT, FIN_I, FIN_ALIAS
 	     /*GEN_PARAM,
 	     /*GEN_PARAM,
 	       PARAM_ERROR*/ /* declared in msg_parser.h*/
 	       PARAM_ERROR*/ /* declared in msg_parser.h*/
 };
 };
@@ -134,6 +137,7 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
 			case '\t':
 			case '\t':
 				switch(state){
 				switch(state){
 					case FIN_HIDDEN:
 					case FIN_HIDDEN:
+					case FIN_ALIAS:
 						param->type=state;
 						param->type=state;
 						param->name.len=tmp-param->name.s;
 						param->name.len=tmp-param->name.s;
 						state=L_PARAM;
 						state=L_PARAM;
@@ -167,6 +171,7 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
 			case '\n':
 			case '\n':
 				switch(state){
 				switch(state){
 					case FIN_HIDDEN:
 					case FIN_HIDDEN:
+					case FIN_ALIAS:
 						param->type=state;
 						param->type=state;
 						param->name.len=tmp-param->name.s;
 						param->name.len=tmp-param->name.s;
 						param->size=tmp-param->start; 
 						param->size=tmp-param->start; 
@@ -209,6 +214,7 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
 			case '\r':
 			case '\r':
 				switch(state){
 				switch(state){
 					case FIN_HIDDEN:
 					case FIN_HIDDEN:
+					case FIN_ALIAS:
 						param->type=state;
 						param->type=state;
 						param->name.len=tmp-param->name.s;
 						param->name.len=tmp-param->name.s;
 						param->size=tmp-param->start; 
 						param->size=tmp-param->start; 
@@ -260,6 +266,7 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
 						goto find_value;
 						goto find_value;
 					case F_PARAM:
 					case F_PARAM:
 					case FIN_HIDDEN:
 					case FIN_HIDDEN:
+					case FIN_ALIAS:
 						LOG(L_ERR, "ERROR: parse_via: invalid char <%c> in"
 						LOG(L_ERR, "ERROR: parse_via: invalid char <%c> in"
 								" state %d\n", *tmp, state);
 								" state %d\n", *tmp, state);
 						goto error;
 						goto error;
@@ -280,6 +287,7 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
 				switch(state){
 				switch(state){
 					case FIN_HIDDEN:
 					case FIN_HIDDEN:
 					case FIN_RPORT: /* rport can appear w/o a value */
 					case FIN_RPORT: /* rport can appear w/o a value */
+					case FIN_ALIAS:
 						param->type=state;
 						param->type=state;
 						param->name.len=tmp-param->name.s;
 						param->name.len=tmp-param->name.s;
 						state=F_PARAM;
 						state=F_PARAM;
@@ -309,6 +317,7 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
 				switch(state){
 				switch(state){
 					case FIN_HIDDEN:
 					case FIN_HIDDEN:
 					case FIN_RPORT:
 					case FIN_RPORT:
+					case FIN_ALIAS:
 						param->type=state;
 						param->type=state;
 						param->name.len=tmp-param->name.s;
 						param->name.len=tmp-param->name.s;
 						state=F_VIA;
 						state=F_VIA;
@@ -371,6 +380,9 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
 					case RECEIVED4:
 					case RECEIVED4:
 						state=RECEIVED5;
 						state=RECEIVED5;
 						break;
 						break;
+					case ALIAS2:
+						state=ALIAS3;
+						break;
 					case GEN_PARAM:
 					case GEN_PARAM:
 						break;
 						break;
 					case F_CR:
 					case F_CR:
@@ -503,6 +515,9 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
 					case TTL2:
 					case TTL2:
 						state=FIN_TTL;
 						state=FIN_TTL;
 						break;
 						break;
+					case ALIAS1:
+						state=ALIAS2;
+						break;
 					case GEN_PARAM:
 					case GEN_PARAM:
 						break;
 						break;
 					case F_CR:
 					case F_CR:
@@ -536,7 +551,7 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
 			case 'A':
 			case 'A':
 				switch(state){
 				switch(state){
 					case F_PARAM:
 					case F_PARAM:
-						state=GEN_PARAM;
+						state=ALIAS1;
 						param->name.s=tmp;
 						param->name.s=tmp;
 						break;
 						break;
 					case MADDR1:
 					case MADDR1:
@@ -545,6 +560,9 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
 					case BRANCH2:
 					case BRANCH2:
 						state=BRANCH3;
 						state=BRANCH3;
 						break;
 						break;
+					case ALIAS3:
+						state=ALIAS4;
+						break;
 					case GEN_PARAM:
 					case GEN_PARAM:
 						break;
 						break;
 					case F_CR:
 					case F_CR:
@@ -684,6 +702,25 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
 						state=GEN_PARAM;
 						state=GEN_PARAM;
 				}
 				}
 				break;
 				break;
+			case 's':
+			case 'S':
+				switch(state){
+					case F_PARAM:
+						state=GEN_PARAM;
+						param->name.s=tmp;
+						break;
+					case ALIAS4:
+						state=FIN_ALIAS;
+						break;
+					case F_CR:
+					case F_LF:
+					case F_CRLF:
+						state=END_OF_HEADER;
+						goto end_via;
+					default:
+						state=GEN_PARAM;
+				}
+				break;
 			default:
 			default:
 				switch(state){
 				switch(state){
 					case F_PARAM:
 					case F_PARAM:
@@ -1814,14 +1851,24 @@ parse_again:
 						if (vb->last_param)	vb->last_param->next=param;
 						if (vb->last_param)	vb->last_param->next=param;
 						else				vb->param_lst=param;
 						else				vb->param_lst=param;
 						vb->last_param=param;
 						vb->last_param=param;
-						if (param->type==PARAM_BRANCH)
-							vb->branch=param;
-						else if (param->type==PARAM_RECEIVED)
-							vb->received=param;
-						else if (param->type==PARAM_RPORT)
-							vb->rport=param;
-						else if (param->type==PARAM_I)
-							vb->i=param;
+						/* update param. shortcuts */
+						switch(param->type){
+							case PARAM_BRANCH:
+								vb->branch=param;
+								break;
+							case PARAM_RECEIVED:
+								vb->received=param;
+								break;
+							case PARAM_RPORT:
+								vb->rport=param;
+								break;
+							case PARAM_I:
+								vb->rport=param;
+								break;
+							case PARAM_ALIAS:
+								vb->alias=param;
+								break;
+						}
 						
 						
 						if (state==END_OF_HEADER){
 						if (state==END_OF_HEADER){
 							state=saved_state;
 							state=saved_state;

+ 4 - 2
parser/parse_via.h

@@ -31,6 +31,7 @@
  *  2003-01-21  added extra via param parsing code (i=...), used
  *  2003-01-21  added extra via param parsing code (i=...), used
  *               by tcp to identify the sending socket, by andrei
  *               by tcp to identify the sending socket, by andrei
  *  2003-01-27  added a new member (start) to via_param, by andrei
  *  2003-01-27  added a new member (start) to via_param, by andrei
+ *  2003-10-27  added alias to via && PARAM_ALIAS (andrei)
  */
  */
 
 
 
 
@@ -45,7 +46,8 @@
  */
  */
 enum {
 enum {
 	PARAM_HIDDEN=230, PARAM_TTL, PARAM_BRANCH, 
 	PARAM_HIDDEN=230, PARAM_TTL, PARAM_BRANCH, 
-	PARAM_MADDR, PARAM_RECEIVED, PARAM_RPORT, PARAM_I, GEN_PARAM,
+	PARAM_MADDR, PARAM_RECEIVED, PARAM_RPORT, PARAM_I, PARAM_ALIAS,
+	GEN_PARAM,
 	PARAM_ERROR
 	PARAM_ERROR
 };
 };
 
 
@@ -86,7 +88,7 @@ struct via_body {
 	struct via_param* received;
 	struct via_param* received;
 	struct via_param* rport;
 	struct via_param* rport;
 	struct via_param* i;
 	struct via_param* i;
-	
+	struct via_param* alias; /* alias see draft-ietf-sip-connect-reuse-00 */
 	struct via_body* next; /* pointer to next via body string if
 	struct via_body* next; /* pointer to next via body string if
 				  compact via or null */
 				  compact via or null */
 };
 };

+ 18 - 0
receive.c

@@ -53,6 +53,8 @@
 #include "script_cb.h"
 #include "script_cb.h"
 #include "dset.h"
 #include "dset.h"
 
 
+#include "tcp_server.h" /* for tcpconn_add_alias */
+
 
 
 #ifdef DEBUG_DMALLOC
 #ifdef DEBUG_DMALLOC
 #include <mem/dmalloc.h>
 #include <mem/dmalloc.h>
@@ -129,6 +131,22 @@ int receive_msg(char* buf, unsigned int len, struct receive_info* rcv_info)
 			goto error;
 			goto error;
 		}
 		}
 		/* check if neccesarry to add receive?->moved to forward_req */
 		/* check if neccesarry to add receive?->moved to forward_req */
+		/* check for the alias stuff */
+#ifdef USE_TCP
+		if (msg->via1->alias && tcp_accept_aliases && 
+				(((rcv_info->proto==PROTO_TCP) && !tcp_disable)
+#ifdef USE_TLS
+					|| ((rcv_info->proto==PROTO_TLS) && !tls_disable)
+#endif
+				)
+			){
+			if (tcpconn_add_alias(rcv_info->proto_reserved1, msg->via1->port,
+									rcv_info->proto)!=0){
+				LOG(L_ERR, " ERROR: receive_msg: tcp alias failed\n");
+				/* continue */
+			}
+		}
+#endif
 
 
 		/* exec routing script */
 		/* exec routing script */
 		DBG("preparing to run routing scripts...\n");
 		DBG("preparing to run routing scripts...\n");

+ 3 - 0
route_struct.c

@@ -324,6 +324,9 @@ void print_action(struct action* a)
 			case SET_ADV_PORT_T:
 			case SET_ADV_PORT_T:
 					DBG("set_advertised_port(");
 					DBG("set_advertised_port(");
 					break;
 					break;
+			case FORCE_TCP_ALIAS_T:
+					DBG("force_tcp_alias(");
+					break;
 			default:
 			default:
 					DBG("UNKNOWN(");
 					DBG("UNKNOWN(");
 		}
 		}

+ 3 - 1
route_struct.h

@@ -31,6 +31,7 @@
  *  2003-04-12  FORCE_RPORT_T added (andrei)
  *  2003-04-12  FORCE_RPORT_T added (andrei)
  *  2003-04-22  strip_tail added (jiri)
  *  2003-04-22  strip_tail added (jiri)
  *  2003-10-10  >,<,>=,<=, != and MSGLEN_O added (andrei)
  *  2003-10-10  >,<,>=,<=, != and MSGLEN_O added (andrei)
+ *  2003-10-28  FORCE_TCP_ALIAS added (andrei)
  */
  */
 
 
 
 
@@ -70,7 +71,8 @@ enum { FORWARD_T=1, SEND_T, DROP_T, LOG_T, ERROR_T, ROUTE_T, EXEC_T,
 		SEND_TCP_T,
 		SEND_TCP_T,
 		FORCE_RPORT_T,
 		FORCE_RPORT_T,
 		SET_ADV_ADDR_T,
 		SET_ADV_ADDR_T,
-		SET_ADV_PORT_T
+		SET_ADV_PORT_T,
+		FORCE_TCP_ALIAS_T
 };
 };
 enum { NOSUBTYPE=0, STRING_ST, NET_ST, NUMBER_ST, IP_ST, RE_ST, PROXY_ST,
 enum { NOSUBTYPE=0, STRING_ST, NET_ST, NUMBER_ST, IP_ST, RE_ST, PROXY_ST,
 		EXPR_ST, ACTIONS_ST, CMDF_ST, MODFIXUP_ST, URIHOST_ST, URIPORT_ST,
 		EXPR_ST, ACTIONS_ST, CMDF_ST, MODFIXUP_ST, URIHOST_ST, URIPORT_ST,

+ 23 - 7
tcp_conn.h

@@ -29,6 +29,7 @@
  * --------
  * --------
  *  2003-01-29  tcp buffer size ++-ed to allow for 0-terminator
  *  2003-01-29  tcp buffer size ++-ed to allow for 0-terminator
  *  2003-06-30  added tcp_connection flags & state (andrei) 
  *  2003-06-30  added tcp_connection flags & state (andrei) 
+ *  2003-10-27  tcp port aliases support added (andrei)
  */
  */
 
 
 
 
@@ -40,6 +41,8 @@
 #include "locking.h"
 #include "locking.h"
 
 
 
 
+#define TCP_CON_MAX_ALIASES 4 /* maximum number of port aliases */
+
 #define TCP_BUF_SIZE 65535
 #define TCP_BUF_SIZE 65535
 #define TCP_CON_TIMEOUT 60 /* in  seconds */
 #define TCP_CON_TIMEOUT 60 /* in  seconds */
 #define TCP_CON_SEND_TIMEOUT 30 /* timeout after a send */
 #define TCP_CON_SEND_TIMEOUT 30 /* timeout after a send */
@@ -90,6 +93,18 @@ struct tcp_req{
 
 
 
 
 
 
+struct tcp_connection;
+
+/* tcp port alias structure */
+struct tcp_conn_alias{
+	struct tcp_connection* parent;
+	struct tcp_conn_alias* next;
+	struct tcp_conn_alias* prev;
+	unsigned short port; /* alias port */
+	unsigned short hash; /* hash index in the address hash */
+};
+
+
 
 
 struct tcp_connection{
 struct tcp_connection{
 	int s; /*socket, used by "tcp main" */
 	int s; /*socket, used by "tcp main" */
@@ -105,10 +120,9 @@ struct tcp_connection{
 	enum tcp_conn_states state; /* connection state */
 	enum tcp_conn_states state; /* connection state */
 	void* extra_data; /* extra data associated to the connection, 0 for tcp*/
 	void* extra_data; /* extra data associated to the connection, 0 for tcp*/
 	int timeout; /* connection timeout, after this it will be removed*/
 	int timeout; /* connection timeout, after this it will be removed*/
-	unsigned addr_hash; /* hash indexes in the 2 tables */
-	unsigned id_hash;
-	struct tcp_connection* next; /* next, prev in hash table, used by "main" */
-	struct tcp_connection* prev;
+	unsigned id_hash; /* hash index in the id_hash */
+	int aliases; /* aliases number, at least 1 */
+	struct tcp_conn_alias con_aliases[TCP_CON_MAX_ALIASES];
 	struct tcp_connection* id_next; /* next, prev in id hash table */
 	struct tcp_connection* id_next; /* next, prev in id hash table */
 	struct tcp_connection* id_prev;
 	struct tcp_connection* id_prev;
 	struct tcp_connection* c_next; /* child next prev (use locally) */
 	struct tcp_connection* c_next; /* child next prev (use locally) */
@@ -118,6 +132,8 @@ struct tcp_connection{
 
 
 
 
 
 
+
+
 #define init_tcp_req( r) \
 #define init_tcp_req( r) \
 	do{ \
 	do{ \
 		memset( (r), 0, sizeof(struct tcp_req)); \
 		memset( (r), 0, sizeof(struct tcp_req)); \
@@ -151,15 +167,15 @@ struct tcp_connection{
 #define TCPCONN_LOCK lock_get(tcpconn_lock);
 #define TCPCONN_LOCK lock_get(tcpconn_lock);
 #define TCPCONN_UNLOCK lock_release(tcpconn_lock);
 #define TCPCONN_UNLOCK lock_release(tcpconn_lock);
 
 
-#define TCP_ADDR_HASH_SIZE 1024
+#define TCP_ALIAS_HASH_SIZE 1024
 #define TCP_ID_HASH_SIZE 1024
 #define TCP_ID_HASH_SIZE 1024
 
 
 static inline unsigned tcp_addr_hash(struct ip_addr* ip, unsigned short port)
 static inline unsigned tcp_addr_hash(struct ip_addr* ip, unsigned short port)
 {
 {
-	if(ip->len==4) return (ip->u.addr32[0]^port)&(TCP_ADDR_HASH_SIZE-1);
+	if(ip->len==4) return (ip->u.addr32[0]^port)&(TCP_ALIAS_HASH_SIZE-1);
 	else if (ip->len==16) 
 	else if (ip->len==16) 
 			return (ip->u.addr32[0]^ip->u.addr32[1]^ip->u.addr32[2]^
 			return (ip->u.addr32[0]^ip->u.addr32[1]^ip->u.addr32[2]^
-					ip->u.addr32[3]^port) & (TCP_ADDR_HASH_SIZE-1);
+					ip->u.addr32[3]^port) & (TCP_ALIAS_HASH_SIZE-1);
 	else{
 	else{
 		LOG(L_CRIT, "tcp_addr_hash: BUG: bad len %d for an ip address\n",
 		LOG(L_CRIT, "tcp_addr_hash: BUG: bad len %d for an ip address\n",
 				ip->len);
 				ip->len);

+ 111 - 32
tcp_main.c

@@ -43,6 +43,7 @@
  *               handle_new_connect (andrei)
  *               handle_new_connect (andrei)
  *  2003-07-09  tls_close called before closing the tcp connection (andrei)
  *  2003-07-09  tls_close called before closing the tcp connection (andrei)
  *  2003-10-24  converted to the new socket_info lists (andrei)
  *  2003-10-24  converted to the new socket_info lists (andrei)
+ *  2003-10-27  tcp port aliases support added (andrei)
  */
  */
 
 
 
 
@@ -105,9 +106,10 @@ struct tcp_child{
 };
 };
 
 
 
 
+int tcp_accept_aliases=0; /* by default don't accept aliases */
 
 
-/* connection hash table (after ip&port) */
-struct tcp_connection** tcpconn_addr_hash=0;
+/* connection hash table (after ip&port) , includes also aliases */
+struct tcp_conn_alias** tcpconn_aliases_hash=0;
 /* connection hash table (after connection id) */
 /* connection hash table (after connection id) */
 struct tcp_connection** tcpconn_id_hash=0;
 struct tcp_connection** tcpconn_id_hash=0;
 gen_lock_t* tcpconn_lock=0;
 gen_lock_t* tcpconn_lock=0;
@@ -132,6 +134,7 @@ struct tcp_connection* tcpconn_new(int sock, union sockaddr_union* su,
 		LOG(L_ERR, "ERROR: tcpconn_new: mem. allocation failure\n");
 		LOG(L_ERR, "ERROR: tcpconn_new: mem. allocation failure\n");
 		goto error;
 		goto error;
 	}
 	}
+	memset(c, 0, sizeof(struct tcp_connection)); /* zero init */
 	c->s=sock;
 	c->s=sock;
 	c->fd=-1; /* not initialized */
 	c->fd=-1; /* not initialized */
 	if (lock_init(&c->write_lock)==0){
 	if (lock_init(&c->write_lock)==0){
@@ -263,14 +266,20 @@ struct tcp_connection*  tcpconn_add(struct tcp_connection *c)
 	if (c){
 	if (c){
 		TCPCONN_LOCK;
 		TCPCONN_LOCK;
 		/* add it at the begining of the list*/
 		/* add it at the begining of the list*/
-		hash=tcp_addr_hash(&c->rcv.src_ip, c->rcv.src_port);
-		c->addr_hash=hash;
-		tcpconn_listadd(tcpconn_addr_hash[hash], c, next, prev);
 		hash=tcp_id_hash(c->id);
 		hash=tcp_id_hash(c->id);
 		c->id_hash=hash;
 		c->id_hash=hash;
 		tcpconn_listadd(tcpconn_id_hash[hash], c, id_next, id_prev);
 		tcpconn_listadd(tcpconn_id_hash[hash], c, id_next, id_prev);
+		
+		hash=tcp_addr_hash(&c->rcv.src_ip, c->rcv.src_port);
+		/* set the first alias */
+		c->con_aliases[0].port=c->rcv.src_port;
+		c->con_aliases[0].hash=hash;
+		c->con_aliases[0].parent=c;
+		tcpconn_listadd(tcpconn_aliases_hash[hash], &c->con_aliases[0],
+						next, prev);
+		c->aliases++;
 		TCPCONN_UNLOCK;
 		TCPCONN_UNLOCK;
-		DBG("tcpconn_add: hashes: %d, %d\n", c->addr_hash, c->id_hash);
+		DBG("tcpconn_add: hashes: %d, %d\n", hash, c->id_hash);
 		return c;
 		return c;
 	}else{
 	}else{
 		LOG(L_CRIT, "tcpconn_add: BUG: null connection pointer\n");
 		LOG(L_CRIT, "tcpconn_add: BUG: null connection pointer\n");
@@ -282,8 +291,12 @@ struct tcp_connection*  tcpconn_add(struct tcp_connection *c)
 /* unsafe tcpconn_rm version (nolocks) */
 /* unsafe tcpconn_rm version (nolocks) */
 void _tcpconn_rm(struct tcp_connection* c)
 void _tcpconn_rm(struct tcp_connection* c)
 {
 {
-	tcpconn_listrm(tcpconn_addr_hash[c->addr_hash], c, next, prev);
+	int r;
 	tcpconn_listrm(tcpconn_id_hash[c->id_hash], c, id_next, id_prev);
 	tcpconn_listrm(tcpconn_id_hash[c->id_hash], c, id_next, id_prev);
+	/* remove all the aliases */
+	for (r=0; r<c->aliases; r++)
+		tcpconn_listrm(tcpconn_aliases_hash[c->con_aliases[r].hash], 
+						&c->con_aliases[r], next, prev);
 	lock_destroy(&c->write_lock);
 	lock_destroy(&c->write_lock);
 #ifdef USE_TLS
 #ifdef USE_TLS
 	if (c->type==PROTO_TLS) tls_tcpconn_clean(c);
 	if (c->type==PROTO_TLS) tls_tcpconn_clean(c);
@@ -295,9 +308,13 @@ void _tcpconn_rm(struct tcp_connection* c)
 
 
 void tcpconn_rm(struct tcp_connection* c)
 void tcpconn_rm(struct tcp_connection* c)
 {
 {
+	int r;
 	TCPCONN_LOCK;
 	TCPCONN_LOCK;
-	tcpconn_listrm(tcpconn_addr_hash[c->addr_hash], c, next, prev);
 	tcpconn_listrm(tcpconn_id_hash[c->id_hash], c, id_next, id_prev);
 	tcpconn_listrm(tcpconn_id_hash[c->id_hash], c, id_next, id_prev);
+	/* remove all the aliases */
+	for (r=0; r<c->aliases; r++)
+		tcpconn_listrm(tcpconn_aliases_hash[c->con_aliases[r].hash], 
+						&c->con_aliases[r], next, prev);
 	TCPCONN_UNLOCK;
 	TCPCONN_UNLOCK;
 	lock_destroy(&c->write_lock);
 	lock_destroy(&c->write_lock);
 #ifdef USE_TLS
 #ifdef USE_TLS
@@ -314,11 +331,12 @@ struct tcp_connection* _tcpconn_find(int id, struct ip_addr* ip, int port)
 {
 {
 
 
 	struct tcp_connection *c;
 	struct tcp_connection *c;
+	struct tcp_conn_alias* a;
 	unsigned hash;
 	unsigned hash;
 	
 	
 #ifdef EXTRA_DEBUG
 #ifdef EXTRA_DEBUG
 	DBG("tcpconn_find: %d  port %d\n",id, port);
 	DBG("tcpconn_find: %d  port %d\n",id, port);
-	print_ip("tcpconn_find: ip ", ip, "\n");
+	if (ip) print_ip("tcpconn_find: ip ", ip, "\n");
 #endif
 #endif
 	if (id){
 	if (id){
 		hash=tcp_id_hash(id);
 		hash=tcp_id_hash(id);
@@ -331,14 +349,15 @@ struct tcp_connection* _tcpconn_find(int id, struct ip_addr* ip, int port)
 		}
 		}
 	}else if (ip){
 	}else if (ip){
 		hash=tcp_addr_hash(ip, port);
 		hash=tcp_addr_hash(ip, port);
-		for (c=tcpconn_addr_hash[hash]; c; c=c->next){
+		for (a=tcpconn_aliases_hash[hash]; a; a=a->next){
 #ifdef EXTRA_DEBUG
 #ifdef EXTRA_DEBUG
-			DBG("c=%p, c->id=%d, port=%d\n",c, c->id, c->rcv.src_port);
-			print_ip("ip=",&c->rcv.src_ip,"\n");
+			DBG("a=%p, c=%p, c->id=%d, alias port= %d port=%d\n", a, a->parent,
+					a->parent->id, a->port, a->parent->rcv.src_port);
+			print_ip("ip=",&a->parent->rcv.src_ip,"\n");
 #endif
 #endif
-			if ( (c->state!=S_CONN_BAD) && (port==c->rcv.src_port) &&
-					(ip_addr_cmp(ip, &c->rcv.src_ip)) )
-				return c;
+			if ( (a->parent->state!=S_CONN_BAD) && (port==a->port) &&
+					(ip_addr_cmp(ip, &a->parent->rcv.src_ip)) )
+				return a->parent;
 		}
 		}
 	}
 	}
 	return 0;
 	return 0;
@@ -363,6 +382,67 @@ struct tcp_connection* tcpconn_get(int id, struct ip_addr* ip, int port,
 
 
 
 
 
 
+/* add port as an alias for the "id" connection
+ * returns 0 on success,-1 on failure */
+int tcpconn_add_alias(int id, int port, int proto)
+{
+	struct tcp_connection* c;
+	unsigned hash;
+	struct tcp_conn_alias* a;
+	
+	a=0;
+	/* fix the port */
+	port=port?port:((proto==PROTO_TLS)?SIPS_PORT:SIP_PORT);
+	TCPCONN_LOCK;
+	/* check if alias already exists */
+	c=_tcpconn_find(id, 0, 0);
+	if (c){
+		hash=tcp_addr_hash(&c->rcv.src_ip, port);
+		/* search the aliases for an already existing one */
+		for (a=tcpconn_aliases_hash[hash]; a; a=a->next){
+			if ( (a->parent->state!=S_CONN_BAD) && (port==a->port) &&
+					(ip_addr_cmp(&c->rcv.src_ip, &a->parent->rcv.src_ip)) ){
+				/* found */
+				if (a->parent!=c) goto error_sec;
+				else goto ok;
+			}
+		}
+		if (c->aliases>=TCP_CON_MAX_ALIASES) goto error_aliases;
+		c->con_aliases[c->aliases].parent=c;
+		c->con_aliases[c->aliases].port=port;
+		c->con_aliases[c->aliases].hash=hash;
+		tcpconn_listadd(tcpconn_aliases_hash[hash], 
+								&c->con_aliases[c->aliases], next, prev);
+		c->aliases++;
+	}else goto error_not_found;
+ok:
+	TCPCONN_UNLOCK;
+#ifdef EXTRA_DEBUG
+	if (a) DBG("tcpconn_add_alias: alias already present\n");
+	else   DBG("tcpconn_add_alias: alias port %d for hash %d, id %d\n",
+			port, hash, c->id);
+#endif
+	return 0;
+error_aliases:
+	TCPCONN_UNLOCK;
+	LOG(L_ERR, "ERROR: tcpconn_add_alias: too many aliases for connection %p"
+				" (%d)\n", c, c->id);
+	return -1;
+error_not_found:
+	TCPCONN_UNLOCK;
+	LOG(L_ERR, "ERROR: tcpconn_add_alias: no connection found for id %d\n",id);
+	return -1;
+error_sec:
+	TCPCONN_UNLOCK;
+	LOG(L_ERR, "ERROR: tcpconn_add_alias: possible port hijack attemp\n");
+	LOG(L_ERR, "ERROR: tcpconn_add_alias: alias already present and points"
+			" to another connection (%d : %d and %d : %d)\n",
+			a->parent->id,  port, c->id, port);
+	return -1;
+}
+
+
+
 void tcpconn_put(struct tcp_connection* c)
 void tcpconn_put(struct tcp_connection* c)
 {
 {
 	c->refcnt--; /* FIXME: atomic_dec */
 	c->refcnt--; /* FIXME: atomic_dec */
@@ -516,10 +596,10 @@ void tcpconn_timeout(fd_set* set)
 	
 	
 	ticks=get_ticks();
 	ticks=get_ticks();
 	TCPCONN_LOCK; /* fixme: we can lock only on delete IMO */
 	TCPCONN_LOCK; /* fixme: we can lock only on delete IMO */
-	for(h=0; h<TCP_ADDR_HASH_SIZE; h++){
-		c=tcpconn_addr_hash[h];
+	for(h=0; h<TCP_ID_HASH_SIZE; h++){
+		c=tcpconn_id_hash[h];
 		while(c){
 		while(c){
-			next=c->next;
+			next=c->id_next;
 			if ((c->refcnt==0) && (ticks>c->timeout)) {
 			if ((c->refcnt==0) && (ticks>c->timeout)) {
 				DBG("tcpconn_timeout: timeout for hash=%d - %p (%d > %d)\n",
 				DBG("tcpconn_timeout: timeout for hash=%d - %p (%d > %d)\n",
 						h, c, ticks, c->timeout);
 						h, c, ticks, c->timeout);
@@ -789,9 +869,9 @@ void tcp_main_loop()
 #endif
 #endif
 		
 		
 		/* check all the read fds (from the tcpconn_addr_hash ) */
 		/* check all the read fds (from the tcpconn_addr_hash ) */
-		for (h=0; h<TCP_ADDR_HASH_SIZE; h++){
-			for(tcpconn=tcpconn_addr_hash[h]; tcpconn && n; 
-					tcpconn=tcpconn->next){
+		for (h=0; h<TCP_ID_HASH_SIZE; h++){
+			for(tcpconn=tcpconn_id_hash[h]; tcpconn && n; 
+					tcpconn=tcpconn->id_next){
 				if ((tcpconn->refcnt==0)&&(FD_ISSET(tcpconn->s, &sel_set))){
 				if ((tcpconn->refcnt==0)&&(FD_ISSET(tcpconn->s, &sel_set))){
 					/* new data available */
 					/* new data available */
 					n--;
 					n--;
@@ -967,10 +1047,9 @@ int init_tcp()
 	}
 	}
 	*connection_id=1;
 	*connection_id=1;
 	/* alloc hashtables*/
 	/* alloc hashtables*/
-	tcpconn_addr_hash=(struct tcp_connection**)shm_malloc(TCP_ADDR_HASH_SIZE*
-								sizeof(struct tcp_connection*));
-
-	if (tcpconn_addr_hash==0){
+	tcpconn_aliases_hash=(struct tcp_conn_alias**)
+			shm_malloc(TCP_ALIAS_HASH_SIZE* sizeof(struct tcp_conn_alias*));
+	if (tcpconn_aliases_hash==0){
 		LOG(L_CRIT, "ERROR: init_tcp: could not alloc address hashtable\n");
 		LOG(L_CRIT, "ERROR: init_tcp: could not alloc address hashtable\n");
 		shm_free(connection_id);
 		shm_free(connection_id);
 		connection_id=0;
 		connection_id=0;
@@ -986,16 +1065,16 @@ int init_tcp()
 		LOG(L_CRIT, "ERROR: init_tcp: could not alloc id hashtable\n");
 		LOG(L_CRIT, "ERROR: init_tcp: could not alloc id hashtable\n");
 		shm_free(connection_id);
 		shm_free(connection_id);
 		connection_id=0;
 		connection_id=0;
-		shm_free(tcpconn_addr_hash);
-		tcpconn_addr_hash=0;
+		shm_free(tcpconn_aliases_hash);
+		tcpconn_aliases_hash=0;
 		lock_destroy(tcpconn_lock);
 		lock_destroy(tcpconn_lock);
 		lock_dealloc((void*)tcpconn_lock);
 		lock_dealloc((void*)tcpconn_lock);
 		tcpconn_lock=0;
 		tcpconn_lock=0;
 		goto error;
 		goto error;
 	}
 	}
 	/* init hashtables*/
 	/* init hashtables*/
-	memset((void*)tcpconn_addr_hash, 0, 
-			TCP_ADDR_HASH_SIZE * sizeof(struct tcp_connection*));
+	memset((void*)tcpconn_aliases_hash, 0, 
+			TCP_ALIAS_HASH_SIZE * sizeof(struct tcp_conn_alias*));
 	memset((void*)tcpconn_id_hash, 0, 
 	memset((void*)tcpconn_id_hash, 0, 
 			TCP_ID_HASH_SIZE * sizeof(struct tcp_connection*));
 			TCP_ID_HASH_SIZE * sizeof(struct tcp_connection*));
 	return 0;
 	return 0;
@@ -1013,9 +1092,9 @@ void destroy_tcp()
 		lock_dealloc((void*)tcpconn_lock);
 		lock_dealloc((void*)tcpconn_lock);
 		tcpconn_lock=0;
 		tcpconn_lock=0;
 	}
 	}
-	if(tcpconn_addr_hash){
-		shm_free(tcpconn_addr_hash);
-		tcpconn_addr_hash=0;
+	if(tcpconn_aliases_hash){
+		shm_free(tcpconn_aliases_hash);
+		tcpconn_aliases_hash=0;
 	}
 	}
 	if(tcpconn_id_hash){
 	if(tcpconn_id_hash){
 		shm_free(tcpconn_id_hash);
 		shm_free(tcpconn_id_hash);

+ 1 - 1
tcp_server.h

@@ -31,7 +31,6 @@
 
 
 
 
 
 
-
 /* "public" functions*/
 /* "public" functions*/
 
 
 struct tcp_connection* tcpconn_get(int id, struct ip_addr* ip, int port, 
 struct tcp_connection* tcpconn_get(int id, struct ip_addr* ip, int port, 
@@ -40,6 +39,7 @@ void tcpconn_put(struct tcp_connection* c);
 int tcp_send(int type, char* buf, unsigned len, union sockaddr_union* to,
 int tcp_send(int type, char* buf, unsigned len, union sockaddr_union* to,
 			int id);
 			int id);
 
 
+int tcpconn_add_alias(int id, int port, int proto);
 
 
 
 
 
 

+ 3 - 0
test/test.cfg

@@ -28,6 +28,8 @@ alias="foo.bar"
 fifo="/tmp/ser_fifo"
 fifo="/tmp/ser_fifo"
 listen= tcp:10.0.0.179:5065
 listen= tcp:10.0.0.179:5065
 alias=  tcp:all:5065
 alias=  tcp:all:5065
+tcp_accept_aliases=yes
+
 
 
 #modules
 #modules
 
 
@@ -37,5 +39,6 @@ route{
 		log("\n\nfrom myself\n\n");
 		log("\n\nfrom myself\n\n");
 	};
 	};
 	log(" continue \n\n");
 	log(" continue \n\n");
+	#force_tcp_alias();
 	forward(uri:host, uri:port);
 	forward(uri:host, uri:port);
 }
 }