Browse code

- 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 authored on 29/10/2003 17:41:27
Showing 17 changed files
... ...
@@ -43,7 +43,7 @@ export makefile_defs
43 43
 VERSION = 0
44 44
 PATCHLEVEL = 8
45 45
 SUBLEVEL =   12
46
-EXTRAVERSION = dev-21-sock_info
46
+EXTRAVERSION = dev-22-tcp_aliases
47 47
 
48 48
 RELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
49 49
 OS = $(shell uname -s | sed -e s/SunOS/solaris/ | tr "[A-Z]" "[a-z]")
... ...
@@ -34,6 +34,14 @@ core:
34 34
        This is the default value, if empty (default) the socket
35 35
        port will be used.
36 36
        Same warnings as above.
37
+   tcp_accept_aliases= yes|no
38
+       if a message received over a tcp connection has "alias" in its via
39
+       a new tcp alias port will be created for the connection the message
40
+       came from (the alias port will be set to the via one).
41
+       Based on draft-ietf-sip-connect-reuse-00.txt, but using only the port
42
+       (host aliases are too dangerous IMHO, involve extra DNS
43
+        lookups and the need for them is questionable)
44
+       See force_tcp_alias for more details.
37 45
  - new script commands:
38 46
     set_advertised_address(ip|string)
39 47
        same as advertised_address but it affects only the current message:
... ...
@@ -42,6 +50,24 @@ core:
42 42
     set_advertised_port(no)
43 43
        same as advertised_port but it affects only the current
44 44
        message; see set_advertised_address & s/address/port/g
45
+   force_tcp_alias()
46
+   force_tcp_alias(port)
47
+       adds a tcp port alias for the current connection (if tcp).
48
+       Usefull if you want to send all the trafic to port_alias through
49
+       the same connection this request came from [it could help 
50
+       for firewall or nat traversal].
51
+       With no parameters adds the port from the message via as the alias.
52
+       When the "aliased" connection is closed (e.g. it's idle for too
53
+       much time), all the port aliases are removed.
54
+       Note: by default ser closes idle connection after 3 minutes (stable)
55
+       or 1 minute (unstable) so to take full advantage of tcp aliases for
56
+       things like firewall and nat traversal, redefine TCP_CON_*TIMEOUT
57
+       in tcp_conn.h and recompile. Also right now there can be maximum
58
+       3 port aliases to a connection (you shouldn't need more than one).
59
+       To change this redefine TCP_CON_MAX_ALIASES in the same file
60
+       (set it to you desired value + 1; 1 is needed for the real port).
61
+
62
+
45 63
 
46 64
 
47 65
 
... ...
@@ -2,13 +2,14 @@ $Id$
2 2
 
3 3
 ( - todo, x - done)
4 4
 
5
-- fix aliases for tls_port (add_them?)
5
+- nathelper: extract_body broken-> uses content_length value form the 
6
+ message instead of recalculating it + duplicate code for get_body()
6 7
 - fix check_sel_op -- add proto for uri proto checks
7
-- add via alias for tcp port & infinite tcp conn life
8
+- add setting for infinite tcp conn life?
8 9
 
9 10
 - fix 2 different fixups for diff. no of parameter
10
- (add no of params ot struct action?) -- linked to var. no. of params
11
-- alias support fot tcp/tls port numbers
11
+ (add no of params to struct action?) -- linked to var. no. of params
12
+x alias support fot tcp/tls port numbers
12 13
 - warning builder set_advertised address support
13 14
 - grep parse_uri & replace with parse_sip_msg_uri (e.g do_action!)
14 15
 x update AUTHORS, debian/copyright, ser.8, ser.cfg.5 from stable
... ...
@@ -17,14 +18,16 @@ x update all package specs from stable
17 17
 - add BUG checks for  fd > 0 && fd <= maxfd to all selects?
18 18
 x tcp_main_loop: BUG cases should "conitnue;"
19 19
 x change len_gt into and expr (e.g msg:len).
20
-- sipit: uri == myself doesn't match tls port = 5061
21
-- sipit: fix check_self & *_alias to work with tcp & tls
20
+x sipit: uri == myself doesn't match tls port = 5061 
21
+  -- updated: new socket_info list code should fix it
22
+x sipit: fix check_self & *_alias to work with tcp & tls
23
+  -- updated: new socket_info list code should fix it
22 24
 x sipit: fix ipv6 references in check_self
23 25
 x regex subst on uris?
24 26
 x port receive.c pre_script_cb fix from stable
25
-- extend alias to include port numbers :
27
+x extend alias to include port numbers :
26 28
     something like alias= foo1.bar:5080 foo2.bar foo3.bar:*
27
-- extend listen and alias to include port numbers and protocol:
29
+x extend listen and alias to include port numbers and protocol:
28 30
        tcp foo.bar:5063, udp foo.bar:5062, foo2.bar
29 31
 x added set_advertised_{address,port} -- was: add force_via, force_srcip a.s.o
30 32
 (the advertised addresses should be overwritable from the script).
... ...
@@ -123,7 +126,7 @@ x man page
123 123
 - autoconf scripts
124 124
 x Debian package build files
125 125
 x the same for rpm
126
-- the same for FreeBSD and Slackware
126
+x the same for *BSD
127 127
 
128 128
 
129 129
 x jku: branch hash computation over canonical values
... ...
@@ -35,6 +35,7 @@
35 35
  *  2003-04-12  FORCE_RPORT_T added (andrei)
36 36
  *  2003-04-22  strip_tail added (jiri)
37 37
  *  2003-10-02  added SET_ADV_ADDR_T & SET_ADV_PORT_T (andrei)
38
+ *  2003-10-29  added FORCE_TCP_ALIAS_T (andrei)
38 39
  */
39 40
 
40 41
 
... ...
@@ -629,6 +630,33 @@ int do_action(struct action* a, struct sip_msg* msg)
629 629
 			msg->set_global_port=*((str*)a->p1.data);
630 630
 			ret=1; /* continue processing */
631 631
 			break;
632
+#ifdef USE_TCP
633
+		case FORCE_TCP_ALIAS_T:
634
+			if ( msg->rcv.proto==PROTO_TCP
635
+#ifdef USE_TLS
636
+					|| msg->rcv.proto==PROTO_TLS
637
+#endif
638
+			   ){
639
+				
640
+				if (a->p1_type==NOSUBTYPE)	port=msg->via1->port;
641
+				else if (a->p1_type==NUMBER_ST) port=(int)a->p1.number;
642
+				else{
643
+					LOG(L_CRIT, "BUG: do_action: bad force_tcp_alias"
644
+							" port type %d\n", a->p1_type);
645
+					ret=E_BUG;
646
+					break;
647
+				}
648
+						
649
+				if (tcpconn_add_alias(msg->rcv.proto_reserved1, port,
650
+									msg->rcv.proto)!=0){
651
+					LOG(L_ERR, " ERROR: receive_msg: tcp alias failed\n");
652
+					ret=E_UNSPEC;
653
+					break;
654
+				}
655
+			}
656
+#endif
657
+			ret=1; /* continue processing */
658
+			break;
632 659
 		default:
633 660
 			LOG(L_CRIT, "BUG: do_action: unknown type %d\n", a->type);
634 661
 	}
... ...
@@ -42,6 +42,7 @@
42 42
  *  2003-10-07  added hex and octal numbers support (andrei)
43 43
  *  2003-10-10  replaced len_gt w/ msg:len (andrei)
44 44
  *  2003-10-13  added fifo_dir (andrei)
45
+ *  2003-10-28  added tcp_accept_aliases (andrei)
45 46
  */
46 47
 
47 48
 
... ...
@@ -93,6 +94,7 @@ ROUTE_FAILURE failure_route
93 93
 ROUTE_ONREPLY onreply_route
94 94
 EXEC	exec
95 95
 FORCE_RPORT		"force_rport"|"add_rport"
96
+FORCE_TCP_ALIAS		"force_tcp_alias"|"add_tcp_alias"
96 97
 SETFLAG		setflag
97 98
 RESETFLAG	resetflag
98 99
 ISFLAGSET	isflagset
... ...
@@ -176,6 +178,7 @@ WDIR		"workdir"|"wdir"
176 176
 MHOMED		mhomed
177 177
 DISABLE_TCP		"disable_tcp"
178 178
 TCP_CHILDREN	"tcp_children"
179
+TCP_ACCEPT_ALIASES	"tcp_accept_aliases"
179 180
 DISABLE_TLS		"disable_tls"
180 181
 TLSLOG			"tlslog"|"tls_log"
181 182
 TLS_PORT_NO		"tls_port_no"
... ...
@@ -275,6 +278,8 @@ EAT_ABLE	[\ \t\b\r]
275 275
 <INITIAL>{APPEND_BRANCH}	{ count(); yylval.strval=yytext; 
276 276
 								return APPEND_BRANCH; }
277 277
 <INITIAL>{FORCE_RPORT}	{ count(); yylval.strval=yytext; return FORCE_RPORT; }
278
+<INITIAL>{FORCE_TCP_ALIAS}	{ count(); yylval.strval=yytext;
279
+								return FORCE_TCP_ALIAS; }
278 280
 	
279 281
 <INITIAL>{IF}	{ count(); yylval.strval=yytext; return IF; }
280 282
 <INITIAL>{ELSE}	{ count(); yylval.strval=yytext; return ELSE; }
... ...
@@ -321,6 +326,8 @@ EAT_ABLE	[\ \t\b\r]
321 321
 <INITIAL>{MHOMED}	{ count(); yylval.strval=yytext; return MHOMED; }
322 322
 <INITIAL>{DISABLE_TCP}	{ count(); yylval.strval=yytext; return DISABLE_TCP; }
323 323
 <INITIAL>{TCP_CHILDREN}	{ count(); yylval.strval=yytext; return TCP_CHILDREN; }
324
+<INITIAL>{TCP_ACCEPT_ALIASES}	{ count(); yylval.strval=yytext;
325
+									return TCP_ACCEPT_ALIASES; }
324 326
 <INITIAL>{DISABLE_TLS}	{ count(); yylval.strval=yytext; return DISABLE_TLS; }
325 327
 <INITIAL>{TLSLOG}		{ count(); yylval.strval=yytext; return TLS_PORT_NO; }
326 328
 <INITIAL>{TLS_PORT_NO}	{ count(); yylval.strval=yytext; return TLS_PORT_NO; }
... ...
@@ -48,6 +48,7 @@
48 48
  * 2003-10-11  if(){} doesn't require a ';' after it anymore (andrei)
49 49
  * 2003-10-13  added FIFO_DIR & proto:host:port listen/alias support (andrei)
50 50
  * 2003-10-24  converted to the new socket_info lists (andrei)
51
+ * 2003-10-28  added tcp_accept_aliases (andrei)
51 52
  */
52 53
 
53 54
 
... ...
@@ -148,6 +149,7 @@ static struct id_list* mk_listen_id(char*, int, int);
148 148
 %token SET_URI
149 149
 %token REVERT_URI
150 150
 %token FORCE_RPORT
151
+%token FORCE_TCP_ALIAS
151 152
 %token IF
152 153
 %token ELSE
153 154
 %token SET_ADV_ADDRESS
... ...
@@ -202,6 +204,7 @@ static struct id_list* mk_listen_id(char*, int, int);
202 202
 %token WDIR
203 203
 %token MHOMED
204 204
 %token DISABLE_TCP
205
+%token TCP_ACCEPT_ALIASES
205 206
 %token TCP_CHILDREN
206 207
 %token DISABLE_TLS
207 208
 %token TLSLOG
... ...
@@ -409,6 +412,14 @@ assign_stm:	DEBUG EQUAL NUMBER { debug=$3; }
409 409
 									#endif
410 410
 									}
411 411
 		| DISABLE_TCP EQUAL error { yyerror("boolean value expected"); }
412
+		| TCP_ACCEPT_ALIASES EQUAL NUMBER {
413
+									#ifdef USE_TCP
414
+										tcp_accept_aliases=$3;
415
+									#else
416
+										warn("tcp support not compiled in");
417
+									#endif
418
+									}
419
+		| TCP_ACCEPT_ALIASES EQUAL error { yyerror("boolean value expected"); }
412 420
 		| TCP_CHILDREN EQUAL NUMBER {
413 421
 									#ifdef USE_TCP
414 422
 										tcp_children_no=$3;
... ...
@@ -1373,8 +1384,40 @@ cmd:		FORWARD LPAREN host RPAREN	{ $$=mk_action(	FORWARD_T,
1373 1373
 										"string expected"); }
1374 1374
 		| REVERT_URI LPAREN RPAREN { $$=mk_action( REVERT_URI_T, 0,0,0,0); }
1375 1375
 		| REVERT_URI { $$=mk_action( REVERT_URI_T, 0,0,0,0); }
1376
-		| FORCE_RPORT LPAREN RPAREN	{$$=mk_action(FORCE_RPORT_T,0, 0, 0, 0); }
1376
+		| FORCE_RPORT LPAREN RPAREN	{
1377
+							#ifdef USE_TCP
1378
+								$$=mk_action(FORCE_RPORT_T,0, 0, 0, 0); 
1379
+							#else
1380
+								yyerror("tcp support not compiled in");
1381
+							#endif
1382
+							}
1377 1383
 		| FORCE_RPORT				{$$=mk_action(FORCE_RPORT_T,0, 0, 0, 0); }
1384
+		| FORCE_TCP_ALIAS LPAREN NUMBER RPAREN	{
1385
+					#ifdef USE_TCP
1386
+						$$=mk_action(FORCE_TCP_ALIAS_T,NUMBER_ST, 0,
1387
+										(void*)$3, 0);
1388
+					#else
1389
+						yyerror("tcp support not compiled in");
1390
+					#endif
1391
+												}
1392
+		| FORCE_TCP_ALIAS LPAREN RPAREN	{
1393
+					#ifdef USE_TCP
1394
+						$$=mk_action(FORCE_TCP_ALIAS_T,0, 0, 0, 0); 
1395
+					#else
1396
+						yyerror("tcp support not compiled in");
1397
+					#endif
1398
+										}
1399
+		| FORCE_TCP_ALIAS				{
1400
+					#ifdef USE_TCP
1401
+						$$=mk_action(FORCE_TCP_ALIAS_T,0, 0, 0, 0);
1402
+					#else
1403
+						yyerror("tcp support not compiled in");
1404
+					#endif
1405
+										}
1406
+		| FORCE_TCP_ALIAS LPAREN error RPAREN	{$$=0; 
1407
+												yyerror("bad argument,"
1408
+														" number expected");
1409
+												}
1378 1410
 		| SET_ADV_ADDRESS LPAREN listen_id RPAREN {
1379 1411
 								$$=0;
1380 1412
 								if ((str_tmp=pkg_malloc(sizeof(str)))==0){
... ...
@@ -39,7 +39,7 @@
39 39
  *  2003-04-03  added su_setport (andrei)
40 40
  *  2003-04-04  update_sock_struct_from_via now differentiates between
41 41
  *               local replies  & "normal" replies (andrei)
42
- *  2003-04-12  update_sock_struct_form via uses also FL_FORCE_RPORT for
42
+ *  2003-04-12  update_sock_struct_from via uses also FL_FORCE_RPORT for
43 43
  *               local replies (andrei)
44 44
  *  2003-08-21  check_self properly handles ipv6 addresses & refs   (andrei)
45 45
  *  2003-10-21  check_self updated to handle proto (andrei)
... ...
@@ -70,6 +70,7 @@ extern int children_no;
70 70
 #ifdef USE_TCP
71 71
 extern int tcp_children_no;
72 72
 extern int tcp_disable;
73
+extern int tcp_accept_aliases;
73 74
 #endif
74 75
 #ifdef USE_TLS
75 76
 extern int tls_disable;
... ...
@@ -44,6 +44,8 @@
44 44
  *  2003-04-26  ZSW (jiri)
45 45
  *  2003-06-23  fixed  parse_via_param [op].* param. parsing bug (andrei)
46 46
  *  2003-07-02  added support for TLS parsing in via (andrei)
47
+ *  2003-10-27  added support for alias via param parsing [see
48
+ *               draft-ietf-sip-connect-reuse-00.txt.]  (andrei)
47 49
  */
48 50
 
49 51
 
... ...
@@ -100,9 +102,10 @@ enum {
100 100
 	RECEIVED1, RECEIVED2, RECEIVED3, RECEIVED4, RECEIVED5, RECEIVED6,
101 101
 	RECEIVED7,
102 102
 	RPORT1, RPORT2, RPORT3,
103
+	ALIAS1, ALIAS2, ALIAS3, ALIAS4,
103 104
 	     /* fin states (227-...)*/
104
-	FIN_HIDDEN = 230, FIN_TTL, FIN_BRANCH, FIN_MADDR, FIN_RECEIVED,
105
-	FIN_RPORT, FIN_I
105
+	FIN_HIDDEN = 230, FIN_TTL, FIN_BRANCH,
106
+	FIN_MADDR, FIN_RECEIVED, FIN_RPORT, FIN_I, FIN_ALIAS
106 107
 	     /*GEN_PARAM,
107 108
 	       PARAM_ERROR*/ /* declared in msg_parser.h*/
108 109
 };
... ...
@@ -134,6 +137,7 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
134 134
 			case '\t':
135 135
 				switch(state){
136 136
 					case FIN_HIDDEN:
137
+					case FIN_ALIAS:
137 138
 						param->type=state;
138 139
 						param->name.len=tmp-param->name.s;
139 140
 						state=L_PARAM;
... ...
@@ -167,6 +171,7 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
167 167
 			case '\n':
168 168
 				switch(state){
169 169
 					case FIN_HIDDEN:
170
+					case FIN_ALIAS:
170 171
 						param->type=state;
171 172
 						param->name.len=tmp-param->name.s;
172 173
 						param->size=tmp-param->start; 
... ...
@@ -209,6 +214,7 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
209 209
 			case '\r':
210 210
 				switch(state){
211 211
 					case FIN_HIDDEN:
212
+					case FIN_ALIAS:
212 213
 						param->type=state;
213 214
 						param->name.len=tmp-param->name.s;
214 215
 						param->size=tmp-param->start; 
... ...
@@ -260,6 +266,7 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
260 260
 						goto find_value;
261 261
 					case F_PARAM:
262 262
 					case FIN_HIDDEN:
263
+					case FIN_ALIAS:
263 264
 						LOG(L_ERR, "ERROR: parse_via: invalid char <%c> in"
264 265
 								" state %d\n", *tmp, state);
265 266
 						goto error;
... ...
@@ -280,6 +287,7 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
280 280
 				switch(state){
281 281
 					case FIN_HIDDEN:
282 282
 					case FIN_RPORT: /* rport can appear w/o a value */
283
+					case FIN_ALIAS:
283 284
 						param->type=state;
284 285
 						param->name.len=tmp-param->name.s;
285 286
 						state=F_PARAM;
... ...
@@ -309,6 +317,7 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
309 309
 				switch(state){
310 310
 					case FIN_HIDDEN:
311 311
 					case FIN_RPORT:
312
+					case FIN_ALIAS:
312 313
 						param->type=state;
313 314
 						param->name.len=tmp-param->name.s;
314 315
 						state=F_VIA;
... ...
@@ -371,6 +380,9 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
371 371
 					case RECEIVED4:
372 372
 						state=RECEIVED5;
373 373
 						break;
374
+					case ALIAS2:
375
+						state=ALIAS3;
376
+						break;
374 377
 					case GEN_PARAM:
375 378
 						break;
376 379
 					case F_CR:
... ...
@@ -503,6 +515,9 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
503 503
 					case TTL2:
504 504
 						state=FIN_TTL;
505 505
 						break;
506
+					case ALIAS1:
507
+						state=ALIAS2;
508
+						break;
506 509
 					case GEN_PARAM:
507 510
 						break;
508 511
 					case F_CR:
... ...
@@ -536,7 +551,7 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
536 536
 			case 'A':
537 537
 				switch(state){
538 538
 					case F_PARAM:
539
-						state=GEN_PARAM;
539
+						state=ALIAS1;
540 540
 						param->name.s=tmp;
541 541
 						break;
542 542
 					case MADDR1:
... ...
@@ -545,6 +560,9 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
545 545
 					case BRANCH2:
546 546
 						state=BRANCH3;
547 547
 						break;
548
+					case ALIAS3:
549
+						state=ALIAS4;
550
+						break;
548 551
 					case GEN_PARAM:
549 552
 						break;
550 553
 					case F_CR:
... ...
@@ -684,6 +702,25 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
684 684
 						state=GEN_PARAM;
685 685
 				}
686 686
 				break;
687
+			case 's':
688
+			case 'S':
689
+				switch(state){
690
+					case F_PARAM:
691
+						state=GEN_PARAM;
692
+						param->name.s=tmp;
693
+						break;
694
+					case ALIAS4:
695
+						state=FIN_ALIAS;
696
+						break;
697
+					case F_CR:
698
+					case F_LF:
699
+					case F_CRLF:
700
+						state=END_OF_HEADER;
701
+						goto end_via;
702
+					default:
703
+						state=GEN_PARAM;
704
+				}
705
+				break;
687 706
 			default:
688 707
 				switch(state){
689 708
 					case F_PARAM:
... ...
@@ -1814,14 +1851,24 @@ parse_again:
1814 1814
 						if (vb->last_param)	vb->last_param->next=param;
1815 1815
 						else				vb->param_lst=param;
1816 1816
 						vb->last_param=param;
1817
-						if (param->type==PARAM_BRANCH)
1818
-							vb->branch=param;
1819
-						else if (param->type==PARAM_RECEIVED)
1820
-							vb->received=param;
1821
-						else if (param->type==PARAM_RPORT)
1822
-							vb->rport=param;
1823
-						else if (param->type==PARAM_I)
1824
-							vb->i=param;
1817
+						/* update param. shortcuts */
1818
+						switch(param->type){
1819
+							case PARAM_BRANCH:
1820
+								vb->branch=param;
1821
+								break;
1822
+							case PARAM_RECEIVED:
1823
+								vb->received=param;
1824
+								break;
1825
+							case PARAM_RPORT:
1826
+								vb->rport=param;
1827
+								break;
1828
+							case PARAM_I:
1829
+								vb->rport=param;
1830
+								break;
1831
+							case PARAM_ALIAS:
1832
+								vb->alias=param;
1833
+								break;
1834
+						}
1825 1835
 						
1826 1836
 						if (state==END_OF_HEADER){
1827 1837
 							state=saved_state;
... ...
@@ -31,6 +31,7 @@
31 31
  *  2003-01-21  added extra via param parsing code (i=...), used
32 32
  *               by tcp to identify the sending socket, by andrei
33 33
  *  2003-01-27  added a new member (start) to via_param, by andrei
34
+ *  2003-10-27  added alias to via && PARAM_ALIAS (andrei)
34 35
  */
35 36
 
36 37
 
... ...
@@ -45,7 +46,8 @@
45 45
  */
46 46
 enum {
47 47
 	PARAM_HIDDEN=230, PARAM_TTL, PARAM_BRANCH, 
48
-	PARAM_MADDR, PARAM_RECEIVED, PARAM_RPORT, PARAM_I, GEN_PARAM,
48
+	PARAM_MADDR, PARAM_RECEIVED, PARAM_RPORT, PARAM_I, PARAM_ALIAS,
49
+	GEN_PARAM,
49 50
 	PARAM_ERROR
50 51
 };
51 52
 
... ...
@@ -86,7 +88,7 @@ struct via_body {
86 86
 	struct via_param* received;
87 87
 	struct via_param* rport;
88 88
 	struct via_param* i;
89
-	
89
+	struct via_param* alias; /* alias see draft-ietf-sip-connect-reuse-00 */
90 90
 	struct via_body* next; /* pointer to next via body string if
91 91
 				  compact via or null */
92 92
 };
... ...
@@ -53,6 +53,8 @@
53 53
 #include "script_cb.h"
54 54
 #include "dset.h"
55 55
 
56
+#include "tcp_server.h" /* for tcpconn_add_alias */
57
+
56 58
 
57 59
 #ifdef DEBUG_DMALLOC
58 60
 #include <mem/dmalloc.h>
... ...
@@ -129,6 +131,22 @@ int receive_msg(char* buf, unsigned int len, struct receive_info* rcv_info)
129 129
 			goto error;
130 130
 		}
131 131
 		/* check if neccesarry to add receive?->moved to forward_req */
132
+		/* check for the alias stuff */
133
+#ifdef USE_TCP
134
+		if (msg->via1->alias && tcp_accept_aliases && 
135
+				(((rcv_info->proto==PROTO_TCP) && !tcp_disable)
136
+#ifdef USE_TLS
137
+					|| ((rcv_info->proto==PROTO_TLS) && !tls_disable)
138
+#endif
139
+				)
140
+			){
141
+			if (tcpconn_add_alias(rcv_info->proto_reserved1, msg->via1->port,
142
+									rcv_info->proto)!=0){
143
+				LOG(L_ERR, " ERROR: receive_msg: tcp alias failed\n");
144
+				/* continue */
145
+			}
146
+		}
147
+#endif
132 148
 
133 149
 		/* exec routing script */
134 150
 		DBG("preparing to run routing scripts...\n");
... ...
@@ -324,6 +324,9 @@ void print_action(struct action* a)
324 324
 			case SET_ADV_PORT_T:
325 325
 					DBG("set_advertised_port(");
326 326
 					break;
327
+			case FORCE_TCP_ALIAS_T:
328
+					DBG("force_tcp_alias(");
329
+					break;
327 330
 			default:
328 331
 					DBG("UNKNOWN(");
329 332
 		}
... ...
@@ -31,6 +31,7 @@
31 31
  *  2003-04-12  FORCE_RPORT_T added (andrei)
32 32
  *  2003-04-22  strip_tail added (jiri)
33 33
  *  2003-10-10  >,<,>=,<=, != and MSGLEN_O added (andrei)
34
+ *  2003-10-28  FORCE_TCP_ALIAS added (andrei)
34 35
  */
35 36
 
36 37
 
... ...
@@ -70,7 +71,8 @@ enum { FORWARD_T=1, SEND_T, DROP_T, LOG_T, ERROR_T, ROUTE_T, EXEC_T,
70 70
 		SEND_TCP_T,
71 71
 		FORCE_RPORT_T,
72 72
 		SET_ADV_ADDR_T,
73
-		SET_ADV_PORT_T
73
+		SET_ADV_PORT_T,
74
+		FORCE_TCP_ALIAS_T
74 75
 };
75 76
 enum { NOSUBTYPE=0, STRING_ST, NET_ST, NUMBER_ST, IP_ST, RE_ST, PROXY_ST,
76 77
 		EXPR_ST, ACTIONS_ST, CMDF_ST, MODFIXUP_ST, URIHOST_ST, URIPORT_ST,
... ...
@@ -29,6 +29,7 @@
29 29
  * --------
30 30
  *  2003-01-29  tcp buffer size ++-ed to allow for 0-terminator
31 31
  *  2003-06-30  added tcp_connection flags & state (andrei) 
32
+ *  2003-10-27  tcp port aliases support added (andrei)
32 33
  */
33 34
 
34 35
 
... ...
@@ -40,6 +41,8 @@
40 40
 #include "locking.h"
41 41
 
42 42
 
43
+#define TCP_CON_MAX_ALIASES 4 /* maximum number of port aliases */
44
+
43 45
 #define TCP_BUF_SIZE 65535
44 46
 #define TCP_CON_TIMEOUT 60 /* in  seconds */
45 47
 #define TCP_CON_SEND_TIMEOUT 30 /* timeout after a send */
... ...
@@ -90,6 +93,18 @@ struct tcp_req{
90 90
 
91 91
 
92 92
 
93
+struct tcp_connection;
94
+
95
+/* tcp port alias structure */
96
+struct tcp_conn_alias{
97
+	struct tcp_connection* parent;
98
+	struct tcp_conn_alias* next;
99
+	struct tcp_conn_alias* prev;
100
+	unsigned short port; /* alias port */
101
+	unsigned short hash; /* hash index in the address hash */
102
+};
103
+
104
+
93 105
 
94 106
 struct tcp_connection{
95 107
 	int s; /*socket, used by "tcp main" */
... ...
@@ -105,10 +120,9 @@ struct tcp_connection{
105 105
 	enum tcp_conn_states state; /* connection state */
106 106
 	void* extra_data; /* extra data associated to the connection, 0 for tcp*/
107 107
 	int timeout; /* connection timeout, after this it will be removed*/
108
-	unsigned addr_hash; /* hash indexes in the 2 tables */
109
-	unsigned id_hash;
110
-	struct tcp_connection* next; /* next, prev in hash table, used by "main" */
111
-	struct tcp_connection* prev;
108
+	unsigned id_hash; /* hash index in the id_hash */
109
+	int aliases; /* aliases number, at least 1 */
110
+	struct tcp_conn_alias con_aliases[TCP_CON_MAX_ALIASES];
112 111
 	struct tcp_connection* id_next; /* next, prev in id hash table */
113 112
 	struct tcp_connection* id_prev;
114 113
 	struct tcp_connection* c_next; /* child next prev (use locally) */
... ...
@@ -118,6 +132,8 @@ struct tcp_connection{
118 118
 
119 119
 
120 120
 
121
+
122
+
121 123
 #define init_tcp_req( r) \
122 124
 	do{ \
123 125
 		memset( (r), 0, sizeof(struct tcp_req)); \
... ...
@@ -151,15 +167,15 @@ struct tcp_connection{
151 151
 #define TCPCONN_LOCK lock_get(tcpconn_lock);
152 152
 #define TCPCONN_UNLOCK lock_release(tcpconn_lock);
153 153
 
154
-#define TCP_ADDR_HASH_SIZE 1024
154
+#define TCP_ALIAS_HASH_SIZE 1024
155 155
 #define TCP_ID_HASH_SIZE 1024
156 156
 
157 157
 static inline unsigned tcp_addr_hash(struct ip_addr* ip, unsigned short port)
158 158
 {
159
-	if(ip->len==4) return (ip->u.addr32[0]^port)&(TCP_ADDR_HASH_SIZE-1);
159
+	if(ip->len==4) return (ip->u.addr32[0]^port)&(TCP_ALIAS_HASH_SIZE-1);
160 160
 	else if (ip->len==16) 
161 161
 			return (ip->u.addr32[0]^ip->u.addr32[1]^ip->u.addr32[2]^
162
-					ip->u.addr32[3]^port) & (TCP_ADDR_HASH_SIZE-1);
162
+					ip->u.addr32[3]^port) & (TCP_ALIAS_HASH_SIZE-1);
163 163
 	else{
164 164
 		LOG(L_CRIT, "tcp_addr_hash: BUG: bad len %d for an ip address\n",
165 165
 				ip->len);
... ...
@@ -43,6 +43,7 @@
43 43
  *               handle_new_connect (andrei)
44 44
  *  2003-07-09  tls_close called before closing the tcp connection (andrei)
45 45
  *  2003-10-24  converted to the new socket_info lists (andrei)
46
+ *  2003-10-27  tcp port aliases support added (andrei)
46 47
  */
47 48
 
48 49
 
... ...
@@ -105,9 +106,10 @@ struct tcp_child{
105 105
 };
106 106
 
107 107
 
108
+int tcp_accept_aliases=0; /* by default don't accept aliases */
108 109
 
109
-/* connection hash table (after ip&port) */
110
-struct tcp_connection** tcpconn_addr_hash=0;
110
+/* connection hash table (after ip&port) , includes also aliases */
111
+struct tcp_conn_alias** tcpconn_aliases_hash=0;
111 112
 /* connection hash table (after connection id) */
112 113
 struct tcp_connection** tcpconn_id_hash=0;
113 114
 gen_lock_t* tcpconn_lock=0;
... ...
@@ -132,6 +134,7 @@ struct tcp_connection* tcpconn_new(int sock, union sockaddr_union* su,
132 132
 		LOG(L_ERR, "ERROR: tcpconn_new: mem. allocation failure\n");
133 133
 		goto error;
134 134
 	}
135
+	memset(c, 0, sizeof(struct tcp_connection)); /* zero init */
135 136
 	c->s=sock;
136 137
 	c->fd=-1; /* not initialized */
137 138
 	if (lock_init(&c->write_lock)==0){
... ...
@@ -263,14 +266,20 @@ struct tcp_connection*  tcpconn_add(struct tcp_connection *c)
263 263
 	if (c){
264 264
 		TCPCONN_LOCK;
265 265
 		/* add it at the begining of the list*/
266
-		hash=tcp_addr_hash(&c->rcv.src_ip, c->rcv.src_port);
267
-		c->addr_hash=hash;
268
-		tcpconn_listadd(tcpconn_addr_hash[hash], c, next, prev);
269 266
 		hash=tcp_id_hash(c->id);
270 267
 		c->id_hash=hash;
271 268
 		tcpconn_listadd(tcpconn_id_hash[hash], c, id_next, id_prev);
269
+		
270
+		hash=tcp_addr_hash(&c->rcv.src_ip, c->rcv.src_port);
271
+		/* set the first alias */
272
+		c->con_aliases[0].port=c->rcv.src_port;
273
+		c->con_aliases[0].hash=hash;
274
+		c->con_aliases[0].parent=c;
275
+		tcpconn_listadd(tcpconn_aliases_hash[hash], &c->con_aliases[0],
276
+						next, prev);
277
+		c->aliases++;
272 278
 		TCPCONN_UNLOCK;
273
-		DBG("tcpconn_add: hashes: %d, %d\n", c->addr_hash, c->id_hash);
279
+		DBG("tcpconn_add: hashes: %d, %d\n", hash, c->id_hash);
274 280
 		return c;
275 281
 	}else{
276 282
 		LOG(L_CRIT, "tcpconn_add: BUG: null connection pointer\n");
... ...
@@ -282,8 +291,12 @@ struct tcp_connection*  tcpconn_add(struct tcp_connection *c)
282 282
 /* unsafe tcpconn_rm version (nolocks) */
283 283
 void _tcpconn_rm(struct tcp_connection* c)
284 284
 {
285
-	tcpconn_listrm(tcpconn_addr_hash[c->addr_hash], c, next, prev);
285
+	int r;
286 286
 	tcpconn_listrm(tcpconn_id_hash[c->id_hash], c, id_next, id_prev);
287
+	/* remove all the aliases */
288
+	for (r=0; r<c->aliases; r++)
289
+		tcpconn_listrm(tcpconn_aliases_hash[c->con_aliases[r].hash], 
290
+						&c->con_aliases[r], next, prev);
287 291
 	lock_destroy(&c->write_lock);
288 292
 #ifdef USE_TLS
289 293
 	if (c->type==PROTO_TLS) tls_tcpconn_clean(c);
... ...
@@ -295,9 +308,13 @@ void _tcpconn_rm(struct tcp_connection* c)
295 295
 
296 296
 void tcpconn_rm(struct tcp_connection* c)
297 297
 {
298
+	int r;
298 299
 	TCPCONN_LOCK;
299
-	tcpconn_listrm(tcpconn_addr_hash[c->addr_hash], c, next, prev);
300 300
 	tcpconn_listrm(tcpconn_id_hash[c->id_hash], c, id_next, id_prev);
301
+	/* remove all the aliases */
302
+	for (r=0; r<c->aliases; r++)
303
+		tcpconn_listrm(tcpconn_aliases_hash[c->con_aliases[r].hash], 
304
+						&c->con_aliases[r], next, prev);
301 305
 	TCPCONN_UNLOCK;
302 306
 	lock_destroy(&c->write_lock);
303 307
 #ifdef USE_TLS
... ...
@@ -314,11 +331,12 @@ struct tcp_connection* _tcpconn_find(int id, struct ip_addr* ip, int port)
314 314
 {
315 315
 
316 316
 	struct tcp_connection *c;
317
+	struct tcp_conn_alias* a;
317 318
 	unsigned hash;
318 319
 	
319 320
 #ifdef EXTRA_DEBUG
320 321
 	DBG("tcpconn_find: %d  port %d\n",id, port);
321
-	print_ip("tcpconn_find: ip ", ip, "\n");
322
+	if (ip) print_ip("tcpconn_find: ip ", ip, "\n");
322 323
 #endif
323 324
 	if (id){
324 325
 		hash=tcp_id_hash(id);
... ...
@@ -331,14 +349,15 @@ struct tcp_connection* _tcpconn_find(int id, struct ip_addr* ip, int port)
331 331
 		}
332 332
 	}else if (ip){
333 333
 		hash=tcp_addr_hash(ip, port);
334
-		for (c=tcpconn_addr_hash[hash]; c; c=c->next){
334
+		for (a=tcpconn_aliases_hash[hash]; a; a=a->next){
335 335
 #ifdef EXTRA_DEBUG
336
-			DBG("c=%p, c->id=%d, port=%d\n",c, c->id, c->rcv.src_port);
337
-			print_ip("ip=",&c->rcv.src_ip,"\n");
336
+			DBG("a=%p, c=%p, c->id=%d, alias port= %d port=%d\n", a, a->parent,
337
+					a->parent->id, a->port, a->parent->rcv.src_port);
338
+			print_ip("ip=",&a->parent->rcv.src_ip,"\n");
338 339
 #endif
339
-			if ( (c->state!=S_CONN_BAD) && (port==c->rcv.src_port) &&
340
-					(ip_addr_cmp(ip, &c->rcv.src_ip)) )
341
-				return c;
340
+			if ( (a->parent->state!=S_CONN_BAD) && (port==a->port) &&
341
+					(ip_addr_cmp(ip, &a->parent->rcv.src_ip)) )
342
+				return a->parent;
342 343
 		}
343 344
 	}
344 345
 	return 0;
... ...
@@ -363,6 +382,67 @@ struct tcp_connection* tcpconn_get(int id, struct ip_addr* ip, int port,
363 363
 
364 364
 
365 365
 
366
+/* add port as an alias for the "id" connection
367
+ * returns 0 on success,-1 on failure */
368
+int tcpconn_add_alias(int id, int port, int proto)
369
+{
370
+	struct tcp_connection* c;
371
+	unsigned hash;
372
+	struct tcp_conn_alias* a;
373
+	
374
+	a=0;
375
+	/* fix the port */
376
+	port=port?port:((proto==PROTO_TLS)?SIPS_PORT:SIP_PORT);
377
+	TCPCONN_LOCK;
378
+	/* check if alias already exists */
379
+	c=_tcpconn_find(id, 0, 0);
380
+	if (c){
381
+		hash=tcp_addr_hash(&c->rcv.src_ip, port);
382
+		/* search the aliases for an already existing one */
383
+		for (a=tcpconn_aliases_hash[hash]; a; a=a->next){
384
+			if ( (a->parent->state!=S_CONN_BAD) && (port==a->port) &&
385
+					(ip_addr_cmp(&c->rcv.src_ip, &a->parent->rcv.src_ip)) ){
386
+				/* found */
387
+				if (a->parent!=c) goto error_sec;
388
+				else goto ok;
389
+			}
390
+		}
391
+		if (c->aliases>=TCP_CON_MAX_ALIASES) goto error_aliases;
392
+		c->con_aliases[c->aliases].parent=c;
393
+		c->con_aliases[c->aliases].port=port;
394
+		c->con_aliases[c->aliases].hash=hash;
395
+		tcpconn_listadd(tcpconn_aliases_hash[hash], 
396
+								&c->con_aliases[c->aliases], next, prev);
397
+		c->aliases++;
398
+	}else goto error_not_found;
399
+ok:
400
+	TCPCONN_UNLOCK;
401
+#ifdef EXTRA_DEBUG
402
+	if (a) DBG("tcpconn_add_alias: alias already present\n");
403
+	else   DBG("tcpconn_add_alias: alias port %d for hash %d, id %d\n",
404
+			port, hash, c->id);
405
+#endif
406
+	return 0;
407
+error_aliases:
408
+	TCPCONN_UNLOCK;
409
+	LOG(L_ERR, "ERROR: tcpconn_add_alias: too many aliases for connection %p"
410
+				" (%d)\n", c, c->id);
411
+	return -1;
412
+error_not_found:
413
+	TCPCONN_UNLOCK;
414
+	LOG(L_ERR, "ERROR: tcpconn_add_alias: no connection found for id %d\n",id);
415
+	return -1;
416
+error_sec:
417
+	TCPCONN_UNLOCK;
418
+	LOG(L_ERR, "ERROR: tcpconn_add_alias: possible port hijack attemp\n");
419
+	LOG(L_ERR, "ERROR: tcpconn_add_alias: alias already present and points"
420
+			" to another connection (%d : %d and %d : %d)\n",
421
+			a->parent->id,  port, c->id, port);
422
+	return -1;
423
+}
424
+
425
+
426
+
366 427
 void tcpconn_put(struct tcp_connection* c)
367 428
 {
368 429
 	c->refcnt--; /* FIXME: atomic_dec */
... ...
@@ -516,10 +596,10 @@ void tcpconn_timeout(fd_set* set)
516 516
 	
517 517
 	ticks=get_ticks();
518 518
 	TCPCONN_LOCK; /* fixme: we can lock only on delete IMO */
519
-	for(h=0; h<TCP_ADDR_HASH_SIZE; h++){
520
-		c=tcpconn_addr_hash[h];
519
+	for(h=0; h<TCP_ID_HASH_SIZE; h++){
520
+		c=tcpconn_id_hash[h];
521 521
 		while(c){
522
-			next=c->next;
522
+			next=c->id_next;
523 523
 			if ((c->refcnt==0) && (ticks>c->timeout)) {
524 524
 				DBG("tcpconn_timeout: timeout for hash=%d - %p (%d > %d)\n",
525 525
 						h, c, ticks, c->timeout);
... ...
@@ -789,9 +869,9 @@ void tcp_main_loop()
789 789
 #endif
790 790
 		
791 791
 		/* check all the read fds (from the tcpconn_addr_hash ) */
792
-		for (h=0; h<TCP_ADDR_HASH_SIZE; h++){
793
-			for(tcpconn=tcpconn_addr_hash[h]; tcpconn && n; 
794
-					tcpconn=tcpconn->next){
792
+		for (h=0; h<TCP_ID_HASH_SIZE; h++){
793
+			for(tcpconn=tcpconn_id_hash[h]; tcpconn && n; 
794
+					tcpconn=tcpconn->id_next){
795 795
 				if ((tcpconn->refcnt==0)&&(FD_ISSET(tcpconn->s, &sel_set))){
796 796
 					/* new data available */
797 797
 					n--;
... ...
@@ -967,10 +1047,9 @@ int init_tcp()
967 967
 	}
968 968
 	*connection_id=1;
969 969
 	/* alloc hashtables*/
970
-	tcpconn_addr_hash=(struct tcp_connection**)shm_malloc(TCP_ADDR_HASH_SIZE*
971
-								sizeof(struct tcp_connection*));
972
-
973
-	if (tcpconn_addr_hash==0){
970
+	tcpconn_aliases_hash=(struct tcp_conn_alias**)
971
+			shm_malloc(TCP_ALIAS_HASH_SIZE* sizeof(struct tcp_conn_alias*));
972
+	if (tcpconn_aliases_hash==0){
974 973
 		LOG(L_CRIT, "ERROR: init_tcp: could not alloc address hashtable\n");
975 974
 		shm_free(connection_id);
976 975
 		connection_id=0;
... ...
@@ -986,16 +1065,16 @@ int init_tcp()
986 986
 		LOG(L_CRIT, "ERROR: init_tcp: could not alloc id hashtable\n");
987 987
 		shm_free(connection_id);
988 988
 		connection_id=0;
989
-		shm_free(tcpconn_addr_hash);
990
-		tcpconn_addr_hash=0;
989
+		shm_free(tcpconn_aliases_hash);
990
+		tcpconn_aliases_hash=0;
991 991
 		lock_destroy(tcpconn_lock);
992 992
 		lock_dealloc((void*)tcpconn_lock);
993 993
 		tcpconn_lock=0;
994 994
 		goto error;
995 995
 	}
996 996
 	/* init hashtables*/
997
-	memset((void*)tcpconn_addr_hash, 0, 
998
-			TCP_ADDR_HASH_SIZE * sizeof(struct tcp_connection*));
997
+	memset((void*)tcpconn_aliases_hash, 0, 
998
+			TCP_ALIAS_HASH_SIZE * sizeof(struct tcp_conn_alias*));
999 999
 	memset((void*)tcpconn_id_hash, 0, 
1000 1000
 			TCP_ID_HASH_SIZE * sizeof(struct tcp_connection*));
1001 1001
 	return 0;
... ...
@@ -1013,9 +1092,9 @@ void destroy_tcp()
1013 1013
 		lock_dealloc((void*)tcpconn_lock);
1014 1014
 		tcpconn_lock=0;
1015 1015
 	}
1016
-	if(tcpconn_addr_hash){
1017
-		shm_free(tcpconn_addr_hash);
1018
-		tcpconn_addr_hash=0;
1016
+	if(tcpconn_aliases_hash){
1017
+		shm_free(tcpconn_aliases_hash);
1018
+		tcpconn_aliases_hash=0;
1019 1019
 	}
1020 1020
 	if(tcpconn_id_hash){
1021 1021
 		shm_free(tcpconn_id_hash);
... ...
@@ -31,7 +31,6 @@
31 31
 
32 32
 
33 33
 
34
-
35 34
 /* "public" functions*/
36 35
 
37 36
 struct tcp_connection* tcpconn_get(int id, struct ip_addr* ip, int port, 
... ...
@@ -40,6 +39,7 @@ void tcpconn_put(struct tcp_connection* c);
40 40
 int tcp_send(int type, char* buf, unsigned len, union sockaddr_union* to,
41 41
 			int id);
42 42
 
43
+int tcpconn_add_alias(int id, int port, int proto);
43 44
 
44 45
 
45 46
 
... ...
@@ -28,6 +28,8 @@ alias="foo.bar"
28 28
 fifo="/tmp/ser_fifo"
29 29
 listen= tcp:10.0.0.179:5065
30 30
 alias=  tcp:all:5065
31
+tcp_accept_aliases=yes
32
+
31 33
 
32 34
 #modules
33 35
 
... ...
@@ -37,5 +39,6 @@ route{
37 37
 		log("\n\nfrom myself\n\n");
38 38
 	};
39 39
 	log(" continue \n\n");
40
+	#force_tcp_alias();
40 41
 	forward(uri:host, uri:port);
41 42
 }