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 50
     set_advertised_port(no)
43 51
        same as advertised_port but it affects only the current
44 52
        message; see set_advertised_address & s/address/port/g
53
+   force_tcp_alias()
54
+   force_tcp_alias(port)
55
+       adds a tcp port alias for the current connection (if tcp).
56
+       Usefull if you want to send all the trafic to port_alias through
57
+       the same connection this request came from [it could help 
58
+       for firewall or nat traversal].
59
+       With no parameters adds the port from the message via as the alias.
60
+       When the "aliased" connection is closed (e.g. it's idle for too
61
+       much time), all the port aliases are removed.
62
+       Note: by default ser closes idle connection after 3 minutes (stable)
63
+       or 1 minute (unstable) so to take full advantage of tcp aliases for
64
+       things like firewall and nat traversal, redefine TCP_CON_*TIMEOUT
65
+       in tcp_conn.h and recompile. Also right now there can be maximum
66
+       3 port aliases to a connection (you shouldn't need more than one).
67
+       To change this redefine TCP_CON_MAX_ALIASES in the same file
68
+       (set it to you desired value + 1; 1 is needed for the real port).
69
+
70
+
45 71
 
46 72
 
47 73
 
... ...
@@ -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 18
 - add BUG checks for  fd > 0 && fd <= maxfd to all selects?
18 19
 x tcp_main_loop: BUG cases should "conitnue;"
19 20
 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
21
+x sipit: uri == myself doesn't match tls port = 5061 
22
+  -- updated: new socket_info list code should fix it
23
+x sipit: fix check_self & *_alias to work with tcp & tls
24
+  -- updated: new socket_info list code should fix it
22 25
 x sipit: fix ipv6 references in check_self
23 26
 x regex subst on uris?
24 27
 x port receive.c pre_script_cb fix from stable
25
-- extend alias to include port numbers :
28
+x extend alias to include port numbers :
26 29
     something like alias= foo1.bar:5080 foo2.bar foo3.bar:*
27
-- extend listen and alias to include port numbers and protocol:
30
+x extend listen and alias to include port numbers and protocol:
28 31
        tcp foo.bar:5063, udp foo.bar:5062, foo2.bar
29 32
 x added set_advertised_{address,port} -- was: add force_via, force_srcip a.s.o
30 33
 (the advertised addresses should be overwritable from the script).
... ...
@@ -123,7 +126,7 @@ x man page
123 126
 - autoconf scripts
124 127
 x Debian package build files
125 128
 x the same for rpm
126
-- the same for FreeBSD and Slackware
129
+x the same for *BSD
127 130
 
128 131
 
129 132
 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 630
 			msg->set_global_port=*((str*)a->p1.data);
630 631
 			ret=1; /* continue processing */
631 632
 			break;
633
+#ifdef USE_TCP
634
+		case FORCE_TCP_ALIAS_T:
635
+			if ( msg->rcv.proto==PROTO_TCP
636
+#ifdef USE_TLS
637
+					|| msg->rcv.proto==PROTO_TLS
638
+#endif
639
+			   ){
640
+				
641
+				if (a->p1_type==NOSUBTYPE)	port=msg->via1->port;
642
+				else if (a->p1_type==NUMBER_ST) port=(int)a->p1.number;
643
+				else{
644
+					LOG(L_CRIT, "BUG: do_action: bad force_tcp_alias"
645
+							" port type %d\n", a->p1_type);
646
+					ret=E_BUG;
647
+					break;
648
+				}
649
+						
650
+				if (tcpconn_add_alias(msg->rcv.proto_reserved1, port,
651
+									msg->rcv.proto)!=0){
652
+					LOG(L_ERR, " ERROR: receive_msg: tcp alias failed\n");
653
+					ret=E_UNSPEC;
654
+					break;
655
+				}
656
+			}
657
+#endif
658
+			ret=1; /* continue processing */
659
+			break;
632 660
 		default:
633 661
 			LOG(L_CRIT, "BUG: do_action: unknown type %d\n", a->type);
634 662
 	}
... ...
@@ -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 94
 ROUTE_ONREPLY onreply_route
94 95
 EXEC	exec
95 96
 FORCE_RPORT		"force_rport"|"add_rport"
97
+FORCE_TCP_ALIAS		"force_tcp_alias"|"add_tcp_alias"
96 98
 SETFLAG		setflag
97 99
 RESETFLAG	resetflag
98 100
 ISFLAGSET	isflagset
... ...
@@ -176,6 +178,7 @@ WDIR		"workdir"|"wdir"
176 178
 MHOMED		mhomed
177 179
 DISABLE_TCP		"disable_tcp"
178 180
 TCP_CHILDREN	"tcp_children"
181
+TCP_ACCEPT_ALIASES	"tcp_accept_aliases"
179 182
 DISABLE_TLS		"disable_tls"
180 183
 TLSLOG			"tlslog"|"tls_log"
181 184
 TLS_PORT_NO		"tls_port_no"
... ...
@@ -275,6 +278,8 @@ EAT_ABLE	[\ \t\b\r]
275 278
 <INITIAL>{APPEND_BRANCH}	{ count(); yylval.strval=yytext; 
276 279
 								return APPEND_BRANCH; }
277 280
 <INITIAL>{FORCE_RPORT}	{ count(); yylval.strval=yytext; return FORCE_RPORT; }
281
+<INITIAL>{FORCE_TCP_ALIAS}	{ count(); yylval.strval=yytext;
282
+								return FORCE_TCP_ALIAS; }
278 283
 	
279 284
 <INITIAL>{IF}	{ count(); yylval.strval=yytext; return IF; }
280 285
 <INITIAL>{ELSE}	{ count(); yylval.strval=yytext; return ELSE; }
... ...
@@ -321,6 +326,8 @@ EAT_ABLE	[\ \t\b\r]
321 326
 <INITIAL>{MHOMED}	{ count(); yylval.strval=yytext; return MHOMED; }
322 327
 <INITIAL>{DISABLE_TCP}	{ count(); yylval.strval=yytext; return DISABLE_TCP; }
323 328
 <INITIAL>{TCP_CHILDREN}	{ count(); yylval.strval=yytext; return TCP_CHILDREN; }
329
+<INITIAL>{TCP_ACCEPT_ALIASES}	{ count(); yylval.strval=yytext;
330
+									return TCP_ACCEPT_ALIASES; }
324 331
 <INITIAL>{DISABLE_TLS}	{ count(); yylval.strval=yytext; return DISABLE_TLS; }
325 332
 <INITIAL>{TLSLOG}		{ count(); yylval.strval=yytext; return TLS_PORT_NO; }
326 333
 <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 149
 %token SET_URI
149 150
 %token REVERT_URI
150 151
 %token FORCE_RPORT
152
+%token FORCE_TCP_ALIAS
151 153
 %token IF
152 154
 %token ELSE
153 155
 %token SET_ADV_ADDRESS
... ...
@@ -202,6 +204,7 @@ static struct id_list* mk_listen_id(char*, int, int);
202 204
 %token WDIR
203 205
 %token MHOMED
204 206
 %token DISABLE_TCP
207
+%token TCP_ACCEPT_ALIASES
205 208
 %token TCP_CHILDREN
206 209
 %token DISABLE_TLS
207 210
 %token TLSLOG
... ...
@@ -409,6 +412,14 @@ assign_stm:	DEBUG EQUAL NUMBER { debug=$3; }
409 412
 									#endif
410 413
 									}
411 414
 		| DISABLE_TCP EQUAL error { yyerror("boolean value expected"); }
415
+		| TCP_ACCEPT_ALIASES EQUAL NUMBER {
416
+									#ifdef USE_TCP
417
+										tcp_accept_aliases=$3;
418
+									#else
419
+										warn("tcp support not compiled in");
420
+									#endif
421
+									}
422
+		| TCP_ACCEPT_ALIASES EQUAL error { yyerror("boolean value expected"); }
412 423
 		| TCP_CHILDREN EQUAL NUMBER {
413 424
 									#ifdef USE_TCP
414 425
 										tcp_children_no=$3;
... ...
@@ -1373,8 +1384,40 @@ cmd:		FORWARD LPAREN host RPAREN	{ $$=mk_action(	FORWARD_T,
1373 1384
 										"string expected"); }
1374 1385
 		| REVERT_URI LPAREN RPAREN { $$=mk_action( REVERT_URI_T, 0,0,0,0); }
1375 1386
 		| 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); }
1387
+		| FORCE_RPORT LPAREN RPAREN	{
1388
+							#ifdef USE_TCP
1389
+								$$=mk_action(FORCE_RPORT_T,0, 0, 0, 0); 
1390
+							#else
1391
+								yyerror("tcp support not compiled in");
1392
+							#endif
1393
+							}
1377 1394
 		| FORCE_RPORT				{$$=mk_action(FORCE_RPORT_T,0, 0, 0, 0); }
1395
+		| FORCE_TCP_ALIAS LPAREN NUMBER RPAREN	{
1396
+					#ifdef USE_TCP
1397
+						$$=mk_action(FORCE_TCP_ALIAS_T,NUMBER_ST, 0,
1398
+										(void*)$3, 0);
1399
+					#else
1400
+						yyerror("tcp support not compiled in");
1401
+					#endif
1402
+												}
1403
+		| FORCE_TCP_ALIAS LPAREN RPAREN	{
1404
+					#ifdef USE_TCP
1405
+						$$=mk_action(FORCE_TCP_ALIAS_T,0, 0, 0, 0); 
1406
+					#else
1407
+						yyerror("tcp support not compiled in");
1408
+					#endif
1409
+										}
1410
+		| FORCE_TCP_ALIAS				{
1411
+					#ifdef USE_TCP
1412
+						$$=mk_action(FORCE_TCP_ALIAS_T,0, 0, 0, 0);
1413
+					#else
1414
+						yyerror("tcp support not compiled in");
1415
+					#endif
1416
+										}
1417
+		| FORCE_TCP_ALIAS LPAREN error RPAREN	{$$=0; 
1418
+												yyerror("bad argument,"
1419
+														" number expected");
1420
+												}
1378 1421
 		| SET_ADV_ADDRESS LPAREN listen_id RPAREN {
1379 1422
 								$$=0;
1380 1423
 								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 102
 	RECEIVED1, RECEIVED2, RECEIVED3, RECEIVED4, RECEIVED5, RECEIVED6,
101 103
 	RECEIVED7,
102 104
 	RPORT1, RPORT2, RPORT3,
105
+	ALIAS1, ALIAS2, ALIAS3, ALIAS4,
103 106
 	     /* fin states (227-...)*/
104
-	FIN_HIDDEN = 230, FIN_TTL, FIN_BRANCH, FIN_MADDR, FIN_RECEIVED,
105
-	FIN_RPORT, FIN_I
107
+	FIN_HIDDEN = 230, FIN_TTL, FIN_BRANCH,
108
+	FIN_MADDR, FIN_RECEIVED, FIN_RPORT, FIN_I, FIN_ALIAS
106 109
 	     /*GEN_PARAM,
107 110
 	       PARAM_ERROR*/ /* declared in msg_parser.h*/
108 111
 };
... ...
@@ -134,6 +137,7 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
134 137
 			case '\t':
135 138
 				switch(state){
136 139
 					case FIN_HIDDEN:
140
+					case FIN_ALIAS:
137 141
 						param->type=state;
138 142
 						param->name.len=tmp-param->name.s;
139 143
 						state=L_PARAM;
... ...
@@ -167,6 +171,7 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
167 171
 			case '\n':
168 172
 				switch(state){
169 173
 					case FIN_HIDDEN:
174
+					case FIN_ALIAS:
170 175
 						param->type=state;
171 176
 						param->name.len=tmp-param->name.s;
172 177
 						param->size=tmp-param->start; 
... ...
@@ -209,6 +214,7 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
209 214
 			case '\r':
210 215
 				switch(state){
211 216
 					case FIN_HIDDEN:
217
+					case FIN_ALIAS:
212 218
 						param->type=state;
213 219
 						param->name.len=tmp-param->name.s;
214 220
 						param->size=tmp-param->start; 
... ...
@@ -260,6 +266,7 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
260 266
 						goto find_value;
261 267
 					case F_PARAM:
262 268
 					case FIN_HIDDEN:
269
+					case FIN_ALIAS:
263 270
 						LOG(L_ERR, "ERROR: parse_via: invalid char <%c> in"
264 271
 								" state %d\n", *tmp, state);
265 272
 						goto error;
... ...
@@ -280,6 +287,7 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
280 287
 				switch(state){
281 288
 					case FIN_HIDDEN:
282 289
 					case FIN_RPORT: /* rport can appear w/o a value */
290
+					case FIN_ALIAS:
283 291
 						param->type=state;
284 292
 						param->name.len=tmp-param->name.s;
285 293
 						state=F_PARAM;
... ...
@@ -309,6 +317,7 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
309 317
 				switch(state){
310 318
 					case FIN_HIDDEN:
311 319
 					case FIN_RPORT:
320
+					case FIN_ALIAS:
312 321
 						param->type=state;
313 322
 						param->name.len=tmp-param->name.s;
314 323
 						state=F_VIA;
... ...
@@ -371,6 +380,9 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
371 380
 					case RECEIVED4:
372 381
 						state=RECEIVED5;
373 382
 						break;
383
+					case ALIAS2:
384
+						state=ALIAS3;
385
+						break;
374 386
 					case GEN_PARAM:
375 387
 						break;
376 388
 					case F_CR:
... ...
@@ -503,6 +515,9 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
503 515
 					case TTL2:
504 516
 						state=FIN_TTL;
505 517
 						break;
518
+					case ALIAS1:
519
+						state=ALIAS2;
520
+						break;
506 521
 					case GEN_PARAM:
507 522
 						break;
508 523
 					case F_CR:
... ...
@@ -536,7 +551,7 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
536 551
 			case 'A':
537 552
 				switch(state){
538 553
 					case F_PARAM:
539
-						state=GEN_PARAM;
554
+						state=ALIAS1;
540 555
 						param->name.s=tmp;
541 556
 						break;
542 557
 					case MADDR1:
... ...
@@ -545,6 +560,9 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
545 560
 					case BRANCH2:
546 561
 						state=BRANCH3;
547 562
 						break;
563
+					case ALIAS3:
564
+						state=ALIAS4;
565
+						break;
548 566
 					case GEN_PARAM:
549 567
 						break;
550 568
 					case F_CR:
... ...
@@ -684,6 +702,25 @@ static /*inline*/ char* parse_via_param(char* p, char* end,
684 702
 						state=GEN_PARAM;
685 703
 				}
686 704
 				break;
705
+			case 's':
706
+			case 'S':
707
+				switch(state){
708
+					case F_PARAM:
709
+						state=GEN_PARAM;
710
+						param->name.s=tmp;
711
+						break;
712
+					case ALIAS4:
713
+						state=FIN_ALIAS;
714
+						break;
715
+					case F_CR:
716
+					case F_LF:
717
+					case F_CRLF:
718
+						state=END_OF_HEADER;
719
+						goto end_via;
720
+					default:
721
+						state=GEN_PARAM;
722
+				}
723
+				break;
687 724
 			default:
688 725
 				switch(state){
689 726
 					case F_PARAM:
... ...
@@ -1814,14 +1851,24 @@ parse_again:
1814 1851
 						if (vb->last_param)	vb->last_param->next=param;
1815 1852
 						else				vb->param_lst=param;
1816 1853
 						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;
1854
+						/* update param. shortcuts */
1855
+						switch(param->type){
1856
+							case PARAM_BRANCH:
1857
+								vb->branch=param;
1858
+								break;
1859
+							case PARAM_RECEIVED:
1860
+								vb->received=param;
1861
+								break;
1862
+							case PARAM_RPORT:
1863
+								vb->rport=param;
1864
+								break;
1865
+							case PARAM_I:
1866
+								vb->rport=param;
1867
+								break;
1868
+							case PARAM_ALIAS:
1869
+								vb->alias=param;
1870
+								break;
1871
+						}
1825 1872
 						
1826 1873
 						if (state==END_OF_HEADER){
1827 1874
 							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 46
  */
46 47
 enum {
47 48
 	PARAM_HIDDEN=230, PARAM_TTL, PARAM_BRANCH, 
48
-	PARAM_MADDR, PARAM_RECEIVED, PARAM_RPORT, PARAM_I, GEN_PARAM,
49
+	PARAM_MADDR, PARAM_RECEIVED, PARAM_RPORT, PARAM_I, PARAM_ALIAS,
50
+	GEN_PARAM,
49 51
 	PARAM_ERROR
50 52
 };
51 53
 
... ...
@@ -86,7 +88,7 @@ struct via_body {
86 88
 	struct via_param* received;
87 89
 	struct via_param* rport;
88 90
 	struct via_param* i;
89
-	
91
+	struct via_param* alias; /* alias see draft-ietf-sip-connect-reuse-00 */
90 92
 	struct via_body* next; /* pointer to next via body string if
91 93
 				  compact via or null */
92 94
 };
... ...
@@ -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 131
 			goto error;
130 132
 		}
131 133
 		/* check if neccesarry to add receive?->moved to forward_req */
134
+		/* check for the alias stuff */
135
+#ifdef USE_TCP
136
+		if (msg->via1->alias && tcp_accept_aliases && 
137
+				(((rcv_info->proto==PROTO_TCP) && !tcp_disable)
138
+#ifdef USE_TLS
139
+					|| ((rcv_info->proto==PROTO_TLS) && !tls_disable)
140
+#endif
141
+				)
142
+			){
143
+			if (tcpconn_add_alias(rcv_info->proto_reserved1, msg->via1->port,
144
+									rcv_info->proto)!=0){
145
+				LOG(L_ERR, " ERROR: receive_msg: tcp alias failed\n");
146
+				/* continue */
147
+			}
148
+		}
149
+#endif
132 150
 
133 151
 		/* exec routing script */
134 152
 		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 71
 		SEND_TCP_T,
71 72
 		FORCE_RPORT_T,
72 73
 		SET_ADV_ADDR_T,
73
-		SET_ADV_PORT_T
74
+		SET_ADV_PORT_T,
75
+		FORCE_TCP_ALIAS_T
74 76
 };
75 77
 enum { NOSUBTYPE=0, STRING_ST, NET_ST, NUMBER_ST, IP_ST, RE_ST, PROXY_ST,
76 78
 		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 41
 #include "locking.h"
41 42
 
42 43
 
44
+#define TCP_CON_MAX_ALIASES 4 /* maximum number of port aliases */
45
+
43 46
 #define TCP_BUF_SIZE 65535
44 47
 #define TCP_CON_TIMEOUT 60 /* in  seconds */
45 48
 #define TCP_CON_SEND_TIMEOUT 30 /* timeout after a send */
... ...
@@ -90,6 +93,18 @@ struct tcp_req{
90 93
 
91 94
 
92 95
 
96
+struct tcp_connection;
97
+
98
+/* tcp port alias structure */
99
+struct tcp_conn_alias{
100
+	struct tcp_connection* parent;
101
+	struct tcp_conn_alias* next;
102
+	struct tcp_conn_alias* prev;
103
+	unsigned short port; /* alias port */
104
+	unsigned short hash; /* hash index in the address hash */
105
+};
106
+
107
+
93 108
 
94 109
 struct tcp_connection{
95 110
 	int s; /*socket, used by "tcp main" */
... ...
@@ -105,10 +120,9 @@ struct tcp_connection{
105 120
 	enum tcp_conn_states state; /* connection state */
106 121
 	void* extra_data; /* extra data associated to the connection, 0 for tcp*/
107 122
 	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;
123
+	unsigned id_hash; /* hash index in the id_hash */
124
+	int aliases; /* aliases number, at least 1 */
125
+	struct tcp_conn_alias con_aliases[TCP_CON_MAX_ALIASES];
112 126
 	struct tcp_connection* id_next; /* next, prev in id hash table */
113 127
 	struct tcp_connection* id_prev;
114 128
 	struct tcp_connection* c_next; /* child next prev (use locally) */
... ...
@@ -118,6 +132,8 @@ struct tcp_connection{
118 132
 
119 133
 
120 134
 
135
+
136
+
121 137
 #define init_tcp_req( r) \
122 138
 	do{ \
123 139
 		memset( (r), 0, sizeof(struct tcp_req)); \
... ...
@@ -151,15 +167,15 @@ struct tcp_connection{
151 167
 #define TCPCONN_LOCK lock_get(tcpconn_lock);
152 168
 #define TCPCONN_UNLOCK lock_release(tcpconn_lock);
153 169
 
154
-#define TCP_ADDR_HASH_SIZE 1024
170
+#define TCP_ALIAS_HASH_SIZE 1024
155 171
 #define TCP_ID_HASH_SIZE 1024
156 172
 
157 173
 static inline unsigned tcp_addr_hash(struct ip_addr* ip, unsigned short port)
158 174
 {
159
-	if(ip->len==4) return (ip->u.addr32[0]^port)&(TCP_ADDR_HASH_SIZE-1);
175
+	if(ip->len==4) return (ip->u.addr32[0]^port)&(TCP_ALIAS_HASH_SIZE-1);
160 176
 	else if (ip->len==16) 
161 177
 			return (ip->u.addr32[0]^ip->u.addr32[1]^ip->u.addr32[2]^
162
-					ip->u.addr32[3]^port) & (TCP_ADDR_HASH_SIZE-1);
178
+					ip->u.addr32[3]^port) & (TCP_ALIAS_HASH_SIZE-1);
163 179
 	else{
164 180
 		LOG(L_CRIT, "tcp_addr_hash: BUG: bad len %d for an ip address\n",
165 181
 				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 106
 };
106 107
 
107 108
 
109
+int tcp_accept_aliases=0; /* by default don't accept aliases */
108 110
 
109
-/* connection hash table (after ip&port) */
110
-struct tcp_connection** tcpconn_addr_hash=0;
111
+/* connection hash table (after ip&port) , includes also aliases */
112
+struct tcp_conn_alias** tcpconn_aliases_hash=0;
111 113
 /* connection hash table (after connection id) */
112 114
 struct tcp_connection** tcpconn_id_hash=0;
113 115
 gen_lock_t* tcpconn_lock=0;
... ...
@@ -132,6 +134,7 @@ struct tcp_connection* tcpconn_new(int sock, union sockaddr_union* su,
132 134
 		LOG(L_ERR, "ERROR: tcpconn_new: mem. allocation failure\n");
133 135
 		goto error;
134 136
 	}
137
+	memset(c, 0, sizeof(struct tcp_connection)); /* zero init */
135 138
 	c->s=sock;
136 139
 	c->fd=-1; /* not initialized */
137 140
 	if (lock_init(&c->write_lock)==0){
... ...
@@ -263,14 +266,20 @@ struct tcp_connection*  tcpconn_add(struct tcp_connection *c)
263 266
 	if (c){
264 267
 		TCPCONN_LOCK;
265 268
 		/* 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 269
 		hash=tcp_id_hash(c->id);
270 270
 		c->id_hash=hash;
271 271
 		tcpconn_listadd(tcpconn_id_hash[hash], c, id_next, id_prev);
272
+		
273
+		hash=tcp_addr_hash(&c->rcv.src_ip, c->rcv.src_port);
274
+		/* set the first alias */
275
+		c->con_aliases[0].port=c->rcv.src_port;
276
+		c->con_aliases[0].hash=hash;
277
+		c->con_aliases[0].parent=c;
278
+		tcpconn_listadd(tcpconn_aliases_hash[hash], &c->con_aliases[0],
279
+						next, prev);
280
+		c->aliases++;
272 281
 		TCPCONN_UNLOCK;
273
-		DBG("tcpconn_add: hashes: %d, %d\n", c->addr_hash, c->id_hash);
282
+		DBG("tcpconn_add: hashes: %d, %d\n", hash, c->id_hash);
274 283
 		return c;
275 284
 	}else{
276 285
 		LOG(L_CRIT, "tcpconn_add: BUG: null connection pointer\n");
... ...
@@ -282,8 +291,12 @@ struct tcp_connection*  tcpconn_add(struct tcp_connection *c)
282 291
 /* unsafe tcpconn_rm version (nolocks) */
283 292
 void _tcpconn_rm(struct tcp_connection* c)
284 293
 {
285
-	tcpconn_listrm(tcpconn_addr_hash[c->addr_hash], c, next, prev);
294
+	int r;
286 295
 	tcpconn_listrm(tcpconn_id_hash[c->id_hash], c, id_next, id_prev);
296
+	/* remove all the aliases */
297
+	for (r=0; r<c->aliases; r++)
298
+		tcpconn_listrm(tcpconn_aliases_hash[c->con_aliases[r].hash], 
299
+						&c->con_aliases[r], next, prev);
287 300
 	lock_destroy(&c->write_lock);
288 301
 #ifdef USE_TLS
289 302
 	if (c->type==PROTO_TLS) tls_tcpconn_clean(c);
... ...
@@ -295,9 +308,13 @@ void _tcpconn_rm(struct tcp_connection* c)
295 308
 
296 309
 void tcpconn_rm(struct tcp_connection* c)
297 310
 {
311
+	int r;
298 312
 	TCPCONN_LOCK;
299
-	tcpconn_listrm(tcpconn_addr_hash[c->addr_hash], c, next, prev);
300 313
 	tcpconn_listrm(tcpconn_id_hash[c->id_hash], c, id_next, id_prev);
314
+	/* remove all the aliases */
315
+	for (r=0; r<c->aliases; r++)
316
+		tcpconn_listrm(tcpconn_aliases_hash[c->con_aliases[r].hash], 
317
+						&c->con_aliases[r], next, prev);
301 318
 	TCPCONN_UNLOCK;
302 319
 	lock_destroy(&c->write_lock);
303 320
 #ifdef USE_TLS
... ...
@@ -314,11 +331,12 @@ struct tcp_connection* _tcpconn_find(int id, struct ip_addr* ip, int port)
314 331
 {
315 332
 
316 333
 	struct tcp_connection *c;
334
+	struct tcp_conn_alias* a;
317 335
 	unsigned hash;
318 336
 	
319 337
 #ifdef EXTRA_DEBUG
320 338
 	DBG("tcpconn_find: %d  port %d\n",id, port);
321
-	print_ip("tcpconn_find: ip ", ip, "\n");
339
+	if (ip) print_ip("tcpconn_find: ip ", ip, "\n");
322 340
 #endif
323 341
 	if (id){
324 342
 		hash=tcp_id_hash(id);
... ...
@@ -331,14 +349,15 @@ struct tcp_connection* _tcpconn_find(int id, struct ip_addr* ip, int port)
331 349
 		}
332 350
 	}else if (ip){
333 351
 		hash=tcp_addr_hash(ip, port);
334
-		for (c=tcpconn_addr_hash[hash]; c; c=c->next){
352
+		for (a=tcpconn_aliases_hash[hash]; a; a=a->next){
335 353
 #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");
354
+			DBG("a=%p, c=%p, c->id=%d, alias port= %d port=%d\n", a, a->parent,
355
+					a->parent->id, a->port, a->parent->rcv.src_port);
356
+			print_ip("ip=",&a->parent->rcv.src_ip,"\n");
338 357
 #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;
358
+			if ( (a->parent->state!=S_CONN_BAD) && (port==a->port) &&
359
+					(ip_addr_cmp(ip, &a->parent->rcv.src_ip)) )
360
+				return a->parent;
342 361
 		}
343 362
 	}
344 363
 	return 0;
... ...
@@ -363,6 +382,67 @@ struct tcp_connection* tcpconn_get(int id, struct ip_addr* ip, int port,
363 382
 
364 383
 
365 384
 
385
+/* add port as an alias for the "id" connection
386
+ * returns 0 on success,-1 on failure */
387
+int tcpconn_add_alias(int id, int port, int proto)
388
+{
389
+	struct tcp_connection* c;
390
+	unsigned hash;
391
+	struct tcp_conn_alias* a;
392
+	
393
+	a=0;
394
+	/* fix the port */
395
+	port=port?port:((proto==PROTO_TLS)?SIPS_PORT:SIP_PORT);
396
+	TCPCONN_LOCK;
397
+	/* check if alias already exists */
398
+	c=_tcpconn_find(id, 0, 0);
399
+	if (c){
400
+		hash=tcp_addr_hash(&c->rcv.src_ip, port);
401
+		/* search the aliases for an already existing one */
402
+		for (a=tcpconn_aliases_hash[hash]; a; a=a->next){
403
+			if ( (a->parent->state!=S_CONN_BAD) && (port==a->port) &&
404
+					(ip_addr_cmp(&c->rcv.src_ip, &a->parent->rcv.src_ip)) ){
405
+				/* found */
406
+				if (a->parent!=c) goto error_sec;
407
+				else goto ok;
408
+			}
409
+		}
410
+		if (c->aliases>=TCP_CON_MAX_ALIASES) goto error_aliases;
411
+		c->con_aliases[c->aliases].parent=c;
412
+		c->con_aliases[c->aliases].port=port;
413
+		c->con_aliases[c->aliases].hash=hash;
414
+		tcpconn_listadd(tcpconn_aliases_hash[hash], 
415
+								&c->con_aliases[c->aliases], next, prev);
416
+		c->aliases++;
417
+	}else goto error_not_found;
418
+ok:
419
+	TCPCONN_UNLOCK;
420
+#ifdef EXTRA_DEBUG
421
+	if (a) DBG("tcpconn_add_alias: alias already present\n");
422
+	else   DBG("tcpconn_add_alias: alias port %d for hash %d, id %d\n",
423
+			port, hash, c->id);
424
+#endif
425
+	return 0;
426
+error_aliases:
427
+	TCPCONN_UNLOCK;
428
+	LOG(L_ERR, "ERROR: tcpconn_add_alias: too many aliases for connection %p"
429
+				" (%d)\n", c, c->id);
430
+	return -1;
431
+error_not_found:
432
+	TCPCONN_UNLOCK;
433
+	LOG(L_ERR, "ERROR: tcpconn_add_alias: no connection found for id %d\n",id);
434
+	return -1;
435
+error_sec:
436
+	TCPCONN_UNLOCK;
437
+	LOG(L_ERR, "ERROR: tcpconn_add_alias: possible port hijack attemp\n");
438
+	LOG(L_ERR, "ERROR: tcpconn_add_alias: alias already present and points"
439
+			" to another connection (%d : %d and %d : %d)\n",
440
+			a->parent->id,  port, c->id, port);
441
+	return -1;
442
+}
443
+
444
+
445
+
366 446
 void tcpconn_put(struct tcp_connection* c)
367 447
 {
368 448
 	c->refcnt--; /* FIXME: atomic_dec */
... ...
@@ -516,10 +596,10 @@ void tcpconn_timeout(fd_set* set)
516 596
 	
517 597
 	ticks=get_ticks();
518 598
 	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];
599
+	for(h=0; h<TCP_ID_HASH_SIZE; h++){
600
+		c=tcpconn_id_hash[h];
521 601
 		while(c){
522
-			next=c->next;
602
+			next=c->id_next;
523 603
 			if ((c->refcnt==0) && (ticks>c->timeout)) {
524 604
 				DBG("tcpconn_timeout: timeout for hash=%d - %p (%d > %d)\n",
525 605
 						h, c, ticks, c->timeout);
... ...
@@ -789,9 +869,9 @@ void tcp_main_loop()
789 869
 #endif
790 870
 		
791 871
 		/* 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){
872
+		for (h=0; h<TCP_ID_HASH_SIZE; h++){
873
+			for(tcpconn=tcpconn_id_hash[h]; tcpconn && n; 
874
+					tcpconn=tcpconn->id_next){
795 875
 				if ((tcpconn->refcnt==0)&&(FD_ISSET(tcpconn->s, &sel_set))){
796 876
 					/* new data available */
797 877
 					n--;
... ...
@@ -967,10 +1047,9 @@ int init_tcp()
967 1047
 	}
968 1048
 	*connection_id=1;
969 1049
 	/* 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){
1050
+	tcpconn_aliases_hash=(struct tcp_conn_alias**)
1051
+			shm_malloc(TCP_ALIAS_HASH_SIZE* sizeof(struct tcp_conn_alias*));
1052
+	if (tcpconn_aliases_hash==0){
974 1053
 		LOG(L_CRIT, "ERROR: init_tcp: could not alloc address hashtable\n");
975 1054
 		shm_free(connection_id);
976 1055
 		connection_id=0;
... ...
@@ -986,16 +1065,16 @@ int init_tcp()
986 1065
 		LOG(L_CRIT, "ERROR: init_tcp: could not alloc id hashtable\n");
987 1066
 		shm_free(connection_id);
988 1067
 		connection_id=0;
989
-		shm_free(tcpconn_addr_hash);
990
-		tcpconn_addr_hash=0;
1068
+		shm_free(tcpconn_aliases_hash);
1069
+		tcpconn_aliases_hash=0;
991 1070
 		lock_destroy(tcpconn_lock);
992 1071
 		lock_dealloc((void*)tcpconn_lock);
993 1072
 		tcpconn_lock=0;
994 1073
 		goto error;
995 1074
 	}
996 1075
 	/* init hashtables*/
997
-	memset((void*)tcpconn_addr_hash, 0, 
998
-			TCP_ADDR_HASH_SIZE * sizeof(struct tcp_connection*));
1076
+	memset((void*)tcpconn_aliases_hash, 0, 
1077
+			TCP_ALIAS_HASH_SIZE * sizeof(struct tcp_conn_alias*));
999 1078
 	memset((void*)tcpconn_id_hash, 0, 
1000 1079
 			TCP_ID_HASH_SIZE * sizeof(struct tcp_connection*));
1001 1080
 	return 0;
... ...
@@ -1013,9 +1092,9 @@ void destroy_tcp()
1013 1092
 		lock_dealloc((void*)tcpconn_lock);
1014 1093
 		tcpconn_lock=0;
1015 1094
 	}
1016
-	if(tcpconn_addr_hash){
1017
-		shm_free(tcpconn_addr_hash);
1018
-		tcpconn_addr_hash=0;
1095
+	if(tcpconn_aliases_hash){
1096
+		shm_free(tcpconn_aliases_hash);
1097
+		tcpconn_aliases_hash=0;
1019 1098
 	}
1020 1099
 	if(tcpconn_id_hash){
1021 1100
 		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 39
 int tcp_send(int type, char* buf, unsigned len, union sockaddr_union* to,
41 40
 			int id);
42 41
 
42
+int tcpconn_add_alias(int id, int port, int proto);
43 43
 
44 44
 
45 45
 
... ...
@@ -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 39
 		log("\n\nfrom myself\n\n");
38 40
 	};
39 41
 	log(" continue \n\n");
42
+	#force_tcp_alias();
40 43
 	forward(uri:host, uri:port);
41 44
 }