Browse code

- changed sip_msg (new rcv member containing all the ips, ports, protocol) - added a "proto" parameter to forward_request, via_builder, get_send_sock etc. - added 2 new script commands: forward_udp & forward_tcp - lots of tcp bloat - changed parse_via to recognize TCP - more functions added to ip_addr.h (cmp for ips & sockaddrs etc.)

Andrei Pelinescu-Onciul authored on 12/12/2002 21:46:37
Showing 25 changed files
... ...
@@ -8,7 +8,7 @@
8 8
 VERSION = 0
9 9
 PATCHLEVEL = 8
10 10
 SUBLEVEL =   11
11
-EXTRAVERSION = pre2
11
+EXTRAVERSION = pre3-tcp0
12 12
 
13 13
 RELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
14 14
 OS = $(shell uname -s | sed -e s/SunOS/solaris/ | tr "[A-Z]" "[a-z]")
... ...
@@ -63,4 +63,6 @@ x jku: branch hash computation over canonical values
63 63
 
64 64
 
65 65
 x freopen stdin, stdout, stderr to /dev/null
66
-
66
+- add a section on building ser & configuring it for maximum performance
67
+ (-DF_MALLOC, -DNO_DBG, ... sip_warning=0, a.s.o)
68
+- add src_port, dst_port, proto to cfg.{y,lex}
... ...
@@ -77,6 +77,7 @@ int do_action(struct action* a, struct sip_msg* msg)
77 77
 	struct sip_uri uri;
78 78
 	struct sip_uri* u;
79 79
 	unsigned short port;
80
+	int proto;
80 81
 
81 82
 	/* reset the value of error to E_UNSPEC so avoid unknowledgable
82 83
 	   functions to return with errror (status<0) and not setting it
... ...
@@ -86,11 +87,21 @@ int do_action(struct action* a, struct sip_msg* msg)
86 86
 	ser_error=E_UNSPEC;
87 87
 
88 88
 	ret=E_BUG;
89
-	switch (a->type){
89
+	switch ((unsigned char)a->type){
90 90
 		case DROP_T:
91 91
 				ret=0;
92 92
 			break;
93 93
 		case FORWARD_T:
94
+#ifdef USE_TCP
95
+		case FORWARD_TCP_T:
96
+#endif
97
+		case FORWARD_UDP_T:
98
+
99
+			if (a->type==FORWARD_UDP_T) proto=PROTO_UDP;
100
+#ifdef USE_TCP
101
+			else if (a->type==FORWARD_TCP_T) proto= PROTO_TCP;
102
+#endif
103
+			else proto=msg->rcv.proto;
94 104
 			if (a->p1_type==URIHOST_ST){
95 105
 				/*parse uri*/
96 106
 				ret=parse_sip_msg_uri(msg);
... ...
@@ -121,13 +132,13 @@ int do_action(struct action* a, struct sip_msg* msg)
121 121
 					ret=E_BAD_ADDRESS;
122 122
 					goto error_fwd_uri;
123 123
 				}
124
-				ret=forward_request(msg, p);
124
+				ret=forward_request(msg, p, proto);
125 125
 				/*free_uri(&uri); -- no longer needed, in sip_msg*/
126 126
 				free_proxy(p); /* frees only p content, not p itself */
127 127
 				free(p);
128 128
 				if (ret>=0) ret=1;
129 129
 			}else if ((a->p1_type==PROXY_ST) && (a->p2_type==NUMBER_ST)){
130
-				ret=forward_request(msg,(struct proxy_l*)a->p1.data);
130
+				ret=forward_request(msg,(struct proxy_l*)a->p1.data, proto);
131 131
 				if (ret>=0) ret=1;
132 132
 			}else{
133 133
 				LOG(L_CRIT, "BUG: do_action: bad forward() types %d, %d\n",
... ...
@@ -167,7 +178,7 @@ int do_action(struct action* a, struct sip_msg* msg)
167 167
 				p->tx_bytes+=msg->len;
168 168
 				if (a->type==SEND_T){
169 169
 					/*udp*/
170
-					send_sock=get_send_socket(to);
170
+					send_sock=get_send_socket(to, PROTO_UDP);
171 171
 					if (send_sock!=0){
172 172
 						ret=udp_send(send_sock, msg->orig, msg->len, to);
173 173
 					}else{
... ...
@@ -42,6 +42,7 @@
42 42
 /* action keywords */
43 43
 FORWARD	forward
44 44
 FORWARD_TCP	forward_tcp
45
+FORWARD_UDP	forward_udp
45 46
 DROP	"drop"|"break"
46 47
 SEND	send
47 48
 SEND_TCP	send_tcp
... ...
@@ -155,6 +156,7 @@ EAT_ABLE	[\ \t\b\r]
155 155
 
156 156
 <INITIAL>{FORWARD}	{count(); yylval.strval=yytext; return FORWARD; }
157 157
 <INITIAL>{FORWARD_TCP}	{count(); yylval.strval=yytext; return FORWARD_TCP; }
158
+<INITIAL>{FORWARD_UDP}	{count(); yylval.strval=yytext; return FORWARD_UDP; }
158 159
 <INITIAL>{DROP}	{ count(); yylval.strval=yytext; return DROP; }
159 160
 <INITIAL>{SEND}	{ count(); yylval.strval=yytext; return SEND; }
160 161
 <INITIAL>{SEND_TCP}	{ count(); yylval.strval=yytext; return SEND_TCP; }
... ...
@@ -64,6 +64,7 @@ struct id_list* lst_tmp;
64 64
 /* keywords */
65 65
 %token FORWARD
66 66
 %token FORWARD_TCP
67
+%token FORWARD_UDP
67 68
 %token SEND
68 69
 %token SEND_TCP
69 70
 %token DROP
... ...
@@ -683,6 +684,135 @@ cmd:		FORWARD LPAREN host RPAREN	{ $$=mk_action(	FORWARD_T,
683 683
 		| FORWARD error { $$=0; yyerror("missing '(' or ')' ?"); }
684 684
 		| FORWARD LPAREN error RPAREN { $$=0; yyerror("bad forward"
685 685
 										"argument"); }
686
+		| FORWARD_UDP LPAREN host RPAREN	{ $$=mk_action(	FORWARD_UDP_T,
687
+														STRING_ST,
688
+														NUMBER_ST,
689
+														$3,
690
+														0);
691
+										}
692
+		| FORWARD_UDP LPAREN STRING RPAREN	{ $$=mk_action(	FORWARD_UDP_T,
693
+														STRING_ST,
694
+														NUMBER_ST,
695
+														$3,
696
+														0);
697
+										}
698
+		| FORWARD_UDP LPAREN ip RPAREN	{ $$=mk_action(	FORWARD_UDP_T,
699
+														IP_ST,
700
+														NUMBER_ST,
701
+														(void*)$3,
702
+														0);
703
+										}
704
+		| FORWARD_UDP LPAREN host COMMA NUMBER RPAREN { $$=mk_action(
705
+																FORWARD_UDP_T,
706
+																 STRING_ST,
707
+																 NUMBER_ST,
708
+																$3,
709
+																(void*)$5);
710
+												 }
711
+		| FORWARD_UDP LPAREN STRING COMMA NUMBER RPAREN {$$=mk_action(
712
+																FORWARD_UDP_T,
713
+																 STRING_ST,
714
+																 NUMBER_ST,
715
+																$3,
716
+																(void*)$5);
717
+													}
718
+		| FORWARD_UDP LPAREN ip COMMA NUMBER RPAREN { $$=mk_action(
719
+																FORWARD_UDP_T,
720
+																 IP_ST,
721
+																 NUMBER_ST,
722
+																 (void*)$3,
723
+																(void*)$5);
724
+												  }
725
+		| FORWARD_UDP LPAREN URIHOST COMMA URIPORT RPAREN {
726
+													$$=mk_action(FORWARD_UDP_T,
727
+																 URIHOST_ST,
728
+																 URIPORT_ST,
729
+																0,
730
+																0);
731
+													}
732
+													
733
+									
734
+		| FORWARD_UDP LPAREN URIHOST COMMA NUMBER RPAREN {
735
+													$$=mk_action(FORWARD_UDP_T,
736
+																 URIHOST_ST,
737
+																 NUMBER_ST,
738
+																0,
739
+																(void*)$5);
740
+													}
741
+		| FORWARD_UDP LPAREN URIHOST RPAREN {
742
+													$$=mk_action(FORWARD_UDP_T,
743
+																 URIHOST_ST,
744
+																 NUMBER_ST,
745
+																0,
746
+																0);
747
+										}
748
+		| FORWARD_UDP error { $$=0; yyerror("missing '(' or ')' ?"); }
749
+		| FORWARD_UDP LPAREN error RPAREN { $$=0; yyerror("bad forward_udp"
750
+										"argument"); }
751
+		| FORWARD_TCP LPAREN host RPAREN	{ $$=mk_action(	FORWARD_TCP_T,
752
+														STRING_ST,
753
+														NUMBER_ST,
754
+														$3,
755
+														0);
756
+										}
757
+		| FORWARD_TCP LPAREN STRING RPAREN	{ $$=mk_action(	FORWARD_TCP_T,
758
+														STRING_ST,
759
+														NUMBER_ST,
760
+														$3,
761
+														0);
762
+										}
763
+		| FORWARD_TCP LPAREN ip RPAREN	{ $$=mk_action(	FORWARD_TCP_T,
764
+														IP_ST,
765
+														NUMBER_ST,
766
+														(void*)$3,
767
+														0);
768
+										}
769
+		| FORWARD_TCP LPAREN host COMMA NUMBER RPAREN { $$=mk_action(
770
+																FORWARD_TCP_T,
771
+																 STRING_ST,
772
+																 NUMBER_ST,
773
+																$3,
774
+																(void*)$5);
775
+												 }
776
+		| FORWARD_TCP LPAREN STRING COMMA NUMBER RPAREN {$$=mk_action(
777
+																FORWARD_TCP_T,
778
+																 STRING_ST,
779
+																 NUMBER_ST,
780
+																$3,
781
+																(void*)$5);
782
+													}
783
+		| FORWARD_TCP LPAREN ip COMMA NUMBER RPAREN { $$=mk_action(FORWARD_TCP_T,
784
+																 IP_ST,
785
+																 NUMBER_ST,
786
+																 (void*)$3,
787
+																(void*)$5);
788
+												  }
789
+		| FORWARD_TCP LPAREN URIHOST COMMA URIPORT RPAREN {
790
+													$$=mk_action(FORWARD_TCP_T,
791
+																 URIHOST_ST,
792
+																 URIPORT_ST,
793
+																0,
794
+																0);
795
+													}
796
+													
797
+									
798
+		| FORWARD_TCP LPAREN URIHOST COMMA NUMBER RPAREN {
799
+													$$=mk_action(FORWARD_TCP_T,
800
+																 URIHOST_ST,
801
+																 NUMBER_ST,
802
+																0,
803
+																(void*)$5);
804
+													}
805
+		| FORWARD_TCP LPAREN URIHOST RPAREN {
806
+													$$=mk_action(FORWARD_TCP_T,
807
+																 URIHOST_ST,
808
+																 NUMBER_ST,
809
+																0,
810
+																0);
811
+										}
812
+		| FORWARD_TCP error { $$=0; yyerror("missing '(' or ')' ?"); }
813
+		| FORWARD_TCP LPAREN error RPAREN { $$=0; yyerror("bad forward_tcp"
814
+										"argument"); }
686 815
 		| SEND LPAREN host RPAREN	{ $$=mk_action(	SEND_T,
687 816
 													STRING_ST,
688 817
 													NUMBER_ST,
... ...
@@ -53,6 +53,9 @@
53 53
 #include "ip_addr.h"
54 54
 #include "resolve.h"
55 55
 #include "name_alias.h"
56
+#ifdef USE_TCP
57
+#include "tcp_server.h"
58
+#endif
56 59
 
57 60
 #ifdef DEBUG_DMALLOC
58 61
 #include <dmalloc.h>
... ...
@@ -63,14 +66,31 @@
63 63
 /* returns a socket_info pointer to the sending socket or 0 on error
64 64
  * params: destination socket_union pointer
65 65
  */
66
-struct socket_info* get_send_socket(union sockaddr_union* to)
66
+struct socket_info* get_send_socket(union sockaddr_union* to, int proto)
67 67
 {
68 68
 	struct socket_info* send_sock;
69 69
 	
70 70
 	send_sock=0;
71 71
 	/* check if we need to change the socket (different address families -
72 72
 	 * eg: ipv4 -> ipv6 or ipv6 -> ipv4) */
73
-	if ((bind_address==0) ||(to->s.sa_family!=bind_address->address.af)){
73
+#ifdef USE_TCP
74
+	if (proto==PROTO_TCP){
75
+		/* on tcp just use the "main address", we don't really now the
76
+		 * sending address (we can find it out, but we'll find also to see
77
+		 * if we listen on it, and if yes on which port -> too complicated*/
78
+		switch(to->s.sa_family){
79
+			case AF_INET:	send_sock=sendipv4_tcp;
80
+							break;
81
+#ifdef USE_IPV6
82
+			case AF_INET6:	send_sock=sendipv6_tcp;
83
+							break;
84
+#endif
85
+			default:		LOG(L_ERR, "get_send_socket: BUG: don't know how"
86
+									" to forward to af %d\n", to->s.sa_family);
87
+		}
88
+	}else
89
+#endif
90
+	      if ((bind_address==0) ||(to->s.sa_family!=bind_address->address.af)){
74 91
 		switch(to->s.sa_family){
75 92
 			case AF_INET:	send_sock=sendipv4;
76 93
 							break;
... ...
@@ -139,16 +159,18 @@ int check_self(str* host, unsigned short port)
139 139
 
140 140
 
141 141
 
142
-int forward_request( struct sip_msg* msg, struct proxy_l * p)
142
+int forward_request( struct sip_msg* msg, struct proxy_l * p, int proto)
143 143
 {
144 144
 	unsigned int len;
145 145
 	char* buf;
146 146
 	union sockaddr_union* to;
147 147
 	struct socket_info* send_sock;
148 148
 	char md5[MD5_LEN];
149
+	int id; /* used as branch for tcp! */
149 150
 	
150 151
 	to=0;
151 152
 	buf=0;
153
+	id=0;
152 154
 	
153 155
 	to=(union sockaddr_union*)malloc(sizeof(union sockaddr_union));
154 156
 	if (to==0){
... ...
@@ -172,7 +194,7 @@ int forward_request( struct sip_msg* msg, struct proxy_l * p)
172 172
 	p->tx_bytes+=len;
173 173
 	
174 174
 
175
-	send_sock=get_send_socket(to);
175
+	send_sock=get_send_socket(to, proto);
176 176
 	if (send_sock==0){
177 177
 		LOG(L_ERR, "forward_req: ERROR: cannot forward to af %d "
178 178
 				"no coresponding listening socket\n", to->s.sa_family);
... ...
@@ -190,6 +212,9 @@ int forward_request( struct sip_msg* msg, struct proxy_l * p)
190 190
 	   value in there; better for performance
191 191
 	*/
192 192
 
193
+#ifdef USE_TCP
194
+	if (msg->rcv.proto==PROTO_TCP) id=msg->rcv.proto_reserved1;
195
+#endif
193 196
 	if (syn_branch ) {
194 197
 		*msg->add_to_branch_s='0';
195 198
 		msg->add_to_branch_len=1;
... ...
@@ -199,31 +224,52 @@ int forward_request( struct sip_msg* msg, struct proxy_l * p)
199 199
 			goto error1;
200 200
 		}
201 201
 		msg->hash_index=hash( msg->callid->body, get_cseq(msg)->number);
202
-		if (!branch_builder( msg->hash_index, 0, md5, 0 /* 0-th branch */,
202
+		if (!branch_builder( msg->hash_index, 0, md5, id /* 0-th branch */,
203 203
 					msg->add_to_branch_s, &msg->add_to_branch_len )) {
204 204
 			LOG(L_ERR, "ERROR: forward_request: branch_builder failed\n");
205 205
 			goto error1;
206 206
 		}
207 207
 	}
208 208
 
209
-	buf = build_req_buf_from_sip_req( msg, &len, send_sock);
209
+	buf = build_req_buf_from_sip_req( msg, &len, send_sock,  proto);
210 210
 	if (!buf){
211 211
 		LOG(L_ERR, "ERROR: forward_request: building failed\n");
212 212
 		goto error1;
213 213
 	}
214 214
 	 /* send it! */
215 215
 	DBG("Sending:\n%s.\n", buf);
216
-	DBG("orig. len=%d, new_len=%d\n", msg->len, len );
216
+	DBG("orig. len=%d, new_len=%d, proto=%d\n", msg->len, len, proto );
217 217
 	
218
-	if (udp_send(send_sock, buf, len,  to)==-1){
219
-			ser_error=E_SEND;
220
-			p->errors++;
221
-			p->ok=0;
222
-			STATS_TX_DROPS;
223
-			goto error1;
218
+	
219
+	if (proto==PROTO_UDP){
220
+		if (udp_send(send_sock, buf, len,  to)==-1){
221
+				ser_error=E_SEND;
222
+				p->errors++;
223
+				p->ok=0;
224
+				STATS_TX_DROPS;
225
+				goto error1;
226
+		}
227
+	}
228
+#ifdef USE_TCP
229
+	 else if (proto==PROTO_TCP){
230
+		if (tcp_send(buf, len, to, 0)==-1){
231
+				ser_error=E_SEND;
232
+				p->errors++;
233
+				p->ok=0;
234
+				STATS_TX_DROPS;
235
+				goto error1;
236
+		}
237
+	}
238
+#endif
239
+	 else{
240
+		LOG(L_CRIT, "BUG: forward_request: unknown proto %d\n", proto);
241
+		ser_error=E_SEND;
242
+		STATS_TX_DROPS;
243
+		goto error1;
224 244
 	}
245
+
225 246
 	/* sent requests stats */
226
-	else STATS_TX_REQUEST(  msg->first_line.u.request.method_value );
247
+	STATS_TX_REQUEST(  msg->first_line.u.request.method_value );
227 248
 	
228 249
 	pkg_free(buf);
229 250
 	free(to);
... ...
@@ -238,14 +284,6 @@ error:
238 238
 }
239 239
 
240 240
 
241
-int update_sock_struct_from_ip( union sockaddr_union* to,
242
-	struct sip_msg *msg )
243
-{
244
-
245
-	init_su(to, &msg->src_ip, 
246
-		(msg->via1->port)?htons(msg->via1->port): htons(SIP_PORT) );
247
-	return 1;
248
-}
249 241
 
250 242
 int update_sock_struct_from_via( union sockaddr_union* to,
251 243
 								 struct via_body* via )
... ...
@@ -310,6 +348,13 @@ int forward_reply(struct sip_msg* msg)
310 310
 	struct socket_info* send_sock;
311 311
 	unsigned int new_len;
312 312
 	struct sr_module *mod;
313
+	int proto;
314
+#ifdef USE_TCP
315
+	char* s;
316
+	char* p;
317
+	int len;
318
+	int id;
319
+#endif
313 320
 	
314 321
 	to=0;
315 322
 	new_buf=0;
... ...
@@ -355,22 +400,57 @@ int forward_reply(struct sip_msg* msg)
355 355
 	}
356 356
 
357 357
 	if (update_sock_struct_from_via( to, msg->via2 )==-1) goto error;
358
-	send_sock=get_send_socket(to);
358
+	send_sock=get_send_socket(to, msg->rcv.proto);
359 359
 	if (send_sock==0){
360 360
 		LOG(L_ERR, "forward_reply: ERROR: no sending socket found\n");
361 361
 		goto error;
362 362
 	}
363 363
 
364
-	if (udp_send(send_sock, new_buf,new_len,  to)==-1)
365
-	{
366
-		STATS_TX_DROPS;
364
+	proto=msg->via2->proto;
365
+	if (proto==PROTO_UDP){
366
+		if (udp_send(send_sock, new_buf,new_len,  to)==-1)
367
+		{
368
+			STATS_TX_DROPS;
369
+			goto error;
370
+		}
371
+	}
372
+#ifdef USE_TCP
373
+	 else if (proto==PROTO_TCP){
374
+		 id=0;
375
+		/* find id in branch if it exists */
376
+		if ((msg->via1->branch)&&(msg->via1->branch->value.len>MCOOKIE_LEN) &&
377
+			(memcmp(msg->via1->branch->value.s, MCOOKIE, MCOOKIE_LEN)==0)){
378
+			DBG("forward_reply: found branch\n");
379
+			s=msg->via1->branch->value.s+MCOOKIE_LEN;
380
+			len=msg->via1->branch->value.len-MCOOKIE_LEN;
381
+			for (p=s; p<s+len  && *p!=BRANCH_SEPARATOR; p++);
382
+			p++;
383
+			for(;p<s+len && *p!=BRANCH_SEPARATOR; p++);
384
+			p++;
385
+			if (p<s+len){
386
+				/* we found the second BRANCH_SEPARATOR, p points after it */
387
+				len-=(int)(p-s);
388
+				id=reverse_hex2int(p, len);
389
+				DBG("forward_reply: id= %x\n", id);
390
+			}else{
391
+				DBG("forward_reply: no id in branch\n");
392
+			}
393
+		}		
394
+				
395
+		if (tcp_send(new_buf, new_len,  to, id)==-1)
396
+		{
397
+			STATS_TX_DROPS;
398
+			goto error;
399
+		}
400
+	} 
401
+#endif
402
+	else{
403
+		LOG(L_CRIT, "BUG: forward_reply: unknown proto %d\n", proto);
367 404
 		goto error;
368
-	} else {
405
+	}
369 406
 #ifdef STATS
370
-		int j = msg->first_line.u.reply.statuscode/100;
371
-		STATS_TX_RESPONSE(  j );
407
+		STATS_TX_RESPONSE(  (msg->first_line.u.reply.statuscode/100) );
372 408
 #endif
373
-	}
374 409
 
375 410
 	DBG(" reply forwarded to %s:%d\n", msg->via2->host.s,
376 411
 		(unsigned short) msg->via2->port);
... ...
@@ -36,13 +36,15 @@
36 36
 #include "ip_addr.h"
37 37
 
38 38
 
39
-struct socket_info* get_send_socket(union sockaddr_union* su);
39
+struct socket_info* get_send_socket(union sockaddr_union* su, int proto);
40 40
 int check_self(str* host, unsigned short port);
41
-int forward_request( struct sip_msg* msg,  struct proxy_l* p);
41
+int forward_request( struct sip_msg* msg,  struct proxy_l* p, int proto);
42 42
 int update_sock_struct_from_via( union sockaddr_union* to,
43 43
 								struct via_body* via );
44
-int update_sock_struct_from_ip( union sockaddr_union* to,
45
-    struct sip_msg *msg );
44
+#define update_sock_struct_from_ip(  to, msg ) \
45
+	init_su((to), &(msg)->rcv.src_ip, \
46
+			((msg)->via1->port)?htons((msg)->via1->port): htons(SIP_PORT) )
47
+
46 48
 int forward_reply( struct sip_msg* msg);
47 49
 
48 50
 #endif
... ...
@@ -65,8 +65,10 @@ extern int bind_idx; /* same as above but index in the bound[] array */
65 65
 extern struct socket_info* sendipv4; /* ipv4 socket to use when msg.
66 66
 										comes from ipv6*/
67 67
 extern struct socket_info* sendipv6; /* same as above for ipv6 */
68
-
69 68
 #ifdef USE_TCP
69
+extern struct socket_info* sendipv4_tcp; /* ipv4 socket to use when msg.
70
+										comes from ipv6*/
71
+extern struct socket_info* sendipv6_tcp; /* same as above for ipv6 */
70 72
 extern int unix_tcp_sock; /* socket used for communication with tcp main*/
71 73
 #endif
72 74
 
... ...
@@ -40,8 +40,8 @@
40 40
 
41 41
 #include "dprint.h"
42 42
 
43
-#define SOCKET_TCP	1
44
-#define SOCKET_UDP	0
43
+enum sip_protos { PROTO_UDP, PROTO_TCP, PROTO_TLS };
44
+
45 45
 
46 46
 struct ip_addr{
47 47
 	unsigned int af; /* address family: AF_INET6 or AF_INET */
... ...
@@ -85,6 +85,21 @@ struct socket_info{
85 85
 };
86 86
 
87 87
 
88
+struct receive_info{
89
+	struct ip_addr src_ip;
90
+	struct ip_addr dst_ip;
91
+	short src_port;
92
+	short dst_port;
93
+	int proto;
94
+	int proto_reserved1;
95
+	int proto_reserved2;
96
+	union sockaddr_union src_su; /* usefull for replies*/
97
+	struct socket_info* bind_address; /* sock_info structure on which 
98
+									  the msg was received*/
99
+	/* no need for dst_su yet */
100
+};
101
+
102
+
88 103
 /* len of the sockaddr */
89 104
 #ifdef HAVE_SOCKADDR_SA_LEN
90 105
 #define sockaddru_len(su)	((su).s.sa_len)
... ...
@@ -73,6 +73,9 @@
73 73
 #include "name_alias.h"
74 74
 #include "hash_func.h"
75 75
 #include "pt.h"
76
+#ifdef USE_TCP
77
+#include "tcp_init.h"
78
+#endif
76 79
 
77 80
 
78 81
 #include "stats.h"
... ...
@@ -281,6 +284,10 @@ struct socket_info* bind_address=0; /* pointer to the crt. proc.
281 281
 int bind_idx; /* same as above but index in the bound[] array */
282 282
 struct socket_info* sendipv4; /* ipv4 socket to use when msg. comes from ipv6*/
283 283
 struct socket_info* sendipv6; /* same as above for ipv6 */
284
+#ifdef USE_TCP
285
+struct socket_info* sendipv4_tcp; 
286
+struct socket_info* sendipv6_tcp; 
287
+#endif
284 288
 
285 289
 unsigned short port_no=0; /* default port*/
286 290
 
... ...
@@ -623,6 +630,7 @@ int main_loop()
623 623
 		*/
624 624
 		for(r=0;r<sock_no;r++){
625 625
 			/* create the listening socket (for each address)*/
626
+			/* udp */
626 627
 			if (udp_init(&sock_info[r])==-1) goto error;
627 628
 			/* get first ipv4/ipv6 socket*/
628 629
 			if ((sock_info[r].address.af==AF_INET)&&
... ...
@@ -632,6 +640,19 @@ int main_loop()
632 632
 			if((sendipv6==0)&&(sock_info[r].address.af==AF_INET6))
633 633
 				sendipv6=&sock_info[r];
634 634
 	#endif
635
+#ifdef USE_TCP
636
+			tcp_info[r]=sock_info[r]; /* copy the sockets */
637
+			/* same thing for tcp */
638
+			if (tcp_init(&tcp_info[r])==-1)  goto error;
639
+			/* get first ipv4/ipv6 socket*/
640
+			if ((tcp_info[r].address.af==AF_INET)&&
641
+					((sendipv4_tcp==0)||(sendipv4_tcp->is_lo)))
642
+				sendipv4_tcp=&tcp_info[r];
643
+	#ifdef USE_IPV6
644
+			if((sendipv6_tcp==0)&&(tcp_info[r].address.af==AF_INET6))
645
+				sendipv6_tcp=&tcp_info[r];
646
+	#endif
647
+#endif
635 648
 			/* all procs should have access to all the sockets (for sending)
636 649
 			 * so we open all first*/
637 650
 		}
... ...
@@ -147,7 +147,7 @@ char * warning_builder( struct sip_msg *msg, unsigned int *returned_len)
147 147
 	print_len=snprintf(buf+fix_len, MAX_WARNING_LEN-fix_len,
148 148
 		"pid=%d req_src_ip=%s in_uri=%.*s out_uri=%.*s via_cnt%c=%d\"",
149 149
 		my_pid(),
150
-		ip_addr2a(&msg->src_ip),
150
+		ip_addr2a(&msg->rcv.src_ip),
151 151
 		msg->first_line.u.request.uri.len, msg->first_line.u.request.uri.s,
152 152
 		foo->len, foo->s, 
153 153
 		msg->parsed_flag & HDR_EOH ? '=' : '>', /* should be = */
... ...
@@ -175,7 +175,7 @@ char* received_builder(struct sip_msg *msg, unsigned int *received_len)
175 175
 	int extra_len;
176 176
 
177 177
 	extra_len = 0;
178
-	source_ip=&msg->src_ip;
178
+	source_ip=&msg->rcv.src_ip;
179 179
 	buf = 0;
180 180
 
181 181
 	buf=pkg_malloc(sizeof(char)*MAX_RECEIVED_SIZE);
... ...
@@ -393,7 +393,7 @@ static inline void process_lumps(	struct lump* l,	char* new_buf,
393 393
 
394 394
 char * build_req_buf_from_sip_req( struct sip_msg* msg,
395 395
 								unsigned int *returned_len,
396
-								struct socket_info* send_sock)
396
+								struct socket_info* send_sock, int proto)
397 397
 {
398 398
 	unsigned int len, new_len, received_len, uri_len, via_len;
399 399
 	char* line_buf;
... ...
@@ -416,7 +416,7 @@ char * build_req_buf_from_sip_req( struct sip_msg* msg,
416 416
 
417 417
 
418 418
 	line_buf = via_builder( &via_len, send_sock, 
419
-		msg->add_to_branch_s, msg->add_to_branch_len);
419
+		msg->add_to_branch_s, msg->add_to_branch_len, proto);
420 420
 	if (!line_buf){
421 421
 		LOG(L_ERR,"ERROR: build_req_buf_from_sip_req: no via received!\n");
422 422
 		goto error00;
... ...
@@ -424,7 +424,7 @@ char * build_req_buf_from_sip_req( struct sip_msg* msg,
424 424
 	/* check if received needs to be added */
425 425
 	backup = msg->via1->host.s[msg->via1->host.len];
426 426
 	msg->via1->host.s[msg->via1->host.len] = 0;
427
-	r=check_address(&msg->src_ip, msg->via1->host.s, received_dns);
427
+	r=check_address(&msg->rcv.src_ip, msg->via1->host.s, received_dns);
428 428
 	msg->via1->host.s[msg->via1->host.len] = backup;
429 429
 	if (r!=0){
430 430
 		if ((received_buf=received_builder(msg,&received_len))==0)
... ...
@@ -612,7 +612,7 @@ char * build_res_buf_from_sip_req( unsigned int code, char *text,
612 612
 	/* check if received needs to be added */
613 613
 	backup = msg->via1->host.s[msg->via1->host.len];
614 614
 	msg->via1->host.s[msg->via1->host.len] = 0;
615
-	r=check_address(&msg->src_ip, msg->via1->host.s, received_dns);
615
+	r=check_address(&msg->rcv.src_ip, msg->via1->host.s, received_dns);
616 616
 	msg->via1->host.s[msg->via1->host.len] = backup;
617 617
 	if (r!=0) {
618 618
 		if ((received_buf=received_builder(msg,&received_len))==0) {
... ...
@@ -843,7 +843,7 @@ int branch_builder( unsigned int hash_index,
843 843
 
844 844
 char* via_builder( unsigned int *len, 
845 845
 	struct socket_info* send_sock,
846
-	char *branch, int branch_len )
846
+	char *branch, int branch_len, int proto )
847 847
 {
848 848
 	unsigned int  via_len, extra_len;
849 849
 	char               *line_buf;
... ...
@@ -865,7 +865,15 @@ char* via_builder( unsigned int *len,
865 865
 
866 866
 	via_len=MY_VIA_LEN+send_sock->address_str.len; /*space included in MY_VIA*/
867 867
 
868
-	memcpy(line_buf, MY_VIA, MY_VIA_LEN);
868
+	memcpy(line_buf, MY_VIA, MY_VIA_LEN-4); /* without "UPD " */
869
+	if (proto==PROTO_UDP)
870
+		memcpy(line_buf+MY_VIA_LEN-4, "UDP ", 4);
871
+	else if (proto==PROTO_TCP)
872
+		memcpy(line_buf+MY_VIA_LEN-4, "TCP ", 4);
873
+	else{
874
+		LOG(L_CRIT, "BUG: via_builder: unknown proto %d\n", proto);
875
+		return 0;
876
+	}
869 877
 #	ifdef USE_IPV6
870 878
 	if (send_sock->address.af==AF_INET6) {
871 879
 		line_buf[MY_VIA_LEN]='[';
... ...
@@ -38,7 +38,8 @@
38 38
 #include "ip_addr.h"
39 39
 
40 40
 char * build_req_buf_from_sip_req (	struct sip_msg* msg, 
41
-				unsigned int *returned_len, struct socket_info* send_sock);
41
+				unsigned int *returned_len, struct socket_info* send_sock,
42
+				int proto);
42 43
 
43 44
 char * build_res_buf_from_sip_res(	struct sip_msg* msg,
44 45
 				unsigned int *returned_len);
... ...
@@ -52,7 +53,7 @@ char * build_res_buf_from_sip_req(	unsigned int code ,
52 52
 
53 53
 char* via_builder( unsigned int *len,
54 54
 	struct socket_info* send_sock,
55
-	char *branch, int branch_len );
55
+	char *branch, int branch_len, int proto );
56 56
 
57 57
 #ifdef _OBSOLETED
58 58
 char* via_builder( struct sip_msg *msg ,
... ...
@@ -53,6 +53,7 @@
53 53
 enum request_method { METHOD_INVITE=1, METHOD_CANCEL=2, METHOD_ACK=4, 
54 54
 	METHOD_BYE=8, METHOD_OTHER=16 };
55 55
 
56
+
56 57
 #define IFISMETHOD(methodname,firstchar)                                  \
57 58
 if (  (*tmp==(firstchar) || *tmp==((firstchar) | 32)) &&                  \
58 59
         strncasecmp( tmp+1, #methodname +1, methodname##_LEN-1)==0 &&     \
... ...
@@ -116,14 +117,12 @@ struct sip_msg {
116 116
 
117 117
 	char* eoh;        /* pointer to the end of header (if found) or null */
118 118
 	char* unparsed;   /* here we stopped parsing*/
119
-
120
-	struct ip_addr src_ip;
121
-	struct ip_addr dst_ip;
119
+	
120
+	struct receive_info rcv; /* source & dest ip, ports, proto a.s.o*/
122 121
 	
123 122
 	char* orig;       /* original message copy */
124 123
 	char* buf;        /* scratch pad, holds a modfied message,
125
-			   *  via, etc. point into it 
126
-			   */
124
+					   *  via, etc. point into it */
127 125
 	unsigned int len; /* message len (orig) */
128 126
 
129 127
 	     /* modifications */
... ...
@@ -214,13 +213,18 @@ inline static int char_msg_val( struct sip_msg *msg, char *cv )
214 214
 inline static char* get_body(struct sip_msg *msg)
215 215
 {
216 216
 	int offset;
217
+	int len;
217 218
 
218 219
 	if ( parse_headers(msg,HDR_EOH, 0)==-1 )
219 220
 		return 0;
220 221
 
221
-	if ( strncmp(CRLF,msg->unparsed,CRLF_LEN)==0 )
222
+	if (msg->unparsed){
223
+		len=(int)(msg->unparsed-msg->buf);
224
+	}else return 0;
225
+	if ((len+2<=msg->len) && (strncmp(CRLF,msg->unparsed,CRLF_LEN)==0) )
222 226
 		offset = CRLF_LEN;
223
-	else if (*(msg->unparsed)=='\n' || *(msg->unparsed)=='\r' )
227
+	else if ( (len+1<=msg->len) &&
228
+				(*(msg->unparsed)=='\n' || *(msg->unparsed)=='\r' ) )
224 229
 		offset = 1;
225 230
 	else
226 231
 		return 0;
... ...
@@ -46,6 +46,7 @@
46 46
 #include "../dprint.h"
47 47
 #include "../ut.h"
48 48
 #include "../mem/mem.h"
49
+#include "../ip_addr.h"
49 50
 #include "parse_via.h"
50 51
 #include "parse_def.h"
51 52
 
... ...
@@ -72,7 +73,9 @@ enum {
72 72
 	SIP1, SIP2, FIN_SIP,
73 73
 	L_VER, F_VER,
74 74
 	VER1, VER2, FIN_VER,
75
-	L_PROTO, F_PROTO, P_PROTO
75
+	UDP1, UDP2, FIN_UDP,
76
+	TCP1, TCP2, FIN_TCP,
77
+	L_PROTO, F_PROTO
76 78
 };
77 79
 
78 80
 
... ...
@@ -99,12 +102,14 @@ enum {
99 99
  * output state = L_PARAM or F_PARAM or END_OF_HEADER
100 100
  * (and saved_state= last state); everything else => error 
101 101
  */
102
-static /*inline*/ char* parse_via_param(char* p, char* end, int* pstate, 
103
-				    int* psaved_state, struct via_param* param)
102
+static /*inline*/ char* parse_via_param(char* p, char* end,
103
+										unsigned char* pstate, 
104
+				    					unsigned char* psaved_state,
105
+										struct via_param* param)
104 106
 {
105 107
 	char* tmp;
106
-	register int state;
107
-	int saved_state;
108
+	register unsigned char state;
109
+	unsigned char saved_state;
108 110
 
109 111
 	state=*pstate;
110 112
 	saved_state=*psaved_state;
... ...
@@ -866,8 +871,8 @@ static /*inline*/ char* parse_via_param(char* p, char* end, int* pstate,
866 866
 char* parse_via(char* buffer, char* end, struct via_body *vb)
867 867
 {
868 868
 	char* tmp;
869
-	int state;
870
-	int saved_state;
869
+	unsigned char state;
870
+	unsigned char saved_state;
871 871
 	int c_nest;
872 872
 	int err;
873 873
 
... ...
@@ -888,9 +893,16 @@ parse_again:
888 888
 					case F_VER:
889 889
 					case F_PROTO:
890 890
 						break;
891
-					case P_PROTO:
891
+					case FIN_UDP:
892 892
 						*tmp=0;  /* finished proto parsing */
893 893
 						vb->transport.len=tmp-vb->transport.s;
894
+						vb->proto=PROTO_UDP;
895
+						state=F_HOST; /* start looking for host*/
896
+						goto main_via;
897
+					case FIN_TCP:
898
+						*tmp=0;  /* finished proto parsing */
899
+						vb->transport.len=tmp-vb->transport.s;
900
+						vb->proto=PROTO_TCP;
894 901
 						state=F_HOST; /* start looking for host*/
895 902
 						goto main_via;
896 903
 					case FIN_SIP:
... ...
@@ -924,9 +936,17 @@ parse_again:
924 924
 						saved_state=state;
925 925
 						state=F_LF;
926 926
 						break;
927
-					case P_PROTO:
927
+					case FIN_UDP:
928
+						*tmp=0;
929
+						vb->transport.len=tmp-vb->transport.s;
930
+						vb->proto=PROTO_UDP;
931
+						state=F_LF;
932
+						saved_state=F_HOST; /* start looking for host*/
933
+						goto main_via;
934
+					case FIN_TCP:
928 935
 						*tmp=0;
929 936
 						vb->transport.len=tmp-vb->transport.s;
937
+						vb->proto=PROTO_TCP;
930 938
 						state=F_LF;
931 939
 						saved_state=F_HOST; /* start looking for host*/
932 940
 						goto main_via;
... ...
@@ -965,9 +985,17 @@ parse_again:
965 965
 						saved_state=state;
966 966
 						state=F_CR;
967 967
 						break;
968
-					case P_PROTO:
968
+					case FIN_UDP:
969 969
 						*tmp=0;
970 970
 						vb->transport.len=tmp-vb->transport.s;
971
+						vb->proto=PROTO_UDP;
972
+						state=F_CR;
973
+						saved_state=F_HOST;
974
+						goto main_via;
975
+					case FIN_TCP:
976
+						*tmp=0;
977
+						vb->transport.len=tmp-vb->transport.s;
978
+						vb->proto=PROTO_TCP;
971 979
 						state=F_CR;
972 980
 						saved_state=F_HOST;
973 981
 						goto main_via;
... ...
@@ -1027,13 +1055,6 @@ parse_again:
1027 1027
 						state=SIP1;
1028 1028
 						vb->name.s=tmp;
1029 1029
 						break;
1030
-					/* allow S in PROTO */
1031
-					case F_PROTO:
1032
-						state=P_PROTO;
1033
-						vb->transport.s=tmp;
1034
-						break;
1035
-					case P_PROTO:
1036
-						break;
1037 1030
 					default:
1038 1031
 						LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
1039 1032
 								" state %d\n", *tmp, state);
... ...
@@ -1046,13 +1067,6 @@ parse_again:
1046 1046
 					case SIP1:
1047 1047
 						state=SIP2;
1048 1048
 						break;
1049
-					/* allow i in PROTO */
1050
-					case F_PROTO:
1051
-						vb->transport.s=tmp;
1052
-						state=P_PROTO;
1053
-						break;
1054
-					case P_PROTO:
1055
-						break;
1056 1049
 					default:
1057 1050
 						LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
1058 1051
 								" state %d\n", *tmp, state);
... ...
@@ -1066,11 +1080,59 @@ parse_again:
1066 1066
 						state=FIN_SIP;
1067 1067
 						break;
1068 1068
 					/* allow p in PROTO */
1069
+					case UDP2:
1070
+						state=FIN_UDP;
1071
+						break;
1072
+					case TCP2:
1073
+						state=FIN_TCP;
1074
+						break;
1075
+					default:
1076
+						LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
1077
+								" state %d\n", *tmp, state);
1078
+						goto error;
1079
+				}
1080
+				break;
1081
+			case 'U':
1082
+			case 'u':
1083
+				switch(state){
1084
+					case F_PROTO:
1085
+						state=UDP1;
1086
+						break;
1087
+					default:
1088
+						LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
1089
+								" state %d\n", *tmp, state);
1090
+						goto error;
1091
+				}
1092
+				break;
1093
+			case 'D':
1094
+			case 'd':
1095
+				switch(state){
1096
+					case UDP1:
1097
+						state=UDP2;
1098
+						break;
1099
+					default:
1100
+						LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
1101
+								" state %d\n", *tmp, state);
1102
+						goto error;
1103
+				}
1104
+				break;
1105
+			case 'T':
1106
+			case 't':
1107
+				switch(state){
1069 1108
 					case F_PROTO:
1070
-						state=P_PROTO;
1071
-						vb->transport.s=tmp;
1109
+						state=TCP1;
1072 1110
 						break;
1073
-					case P_PROTO:
1111
+					default:
1112
+						LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
1113
+								" state %d\n", *tmp, state);
1114
+						goto error;
1115
+				}
1116
+				break;
1117
+			case 'C':
1118
+			case 'c':
1119
+				switch(state){
1120
+					case TCP1:
1121
+						state=TCP2;
1074 1122
 						break;
1075 1123
 					default:
1076 1124
 						LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
... ...
@@ -1085,13 +1147,6 @@ parse_again:
1085 1085
 						state=VER1;
1086 1086
 						vb->version.s=tmp;
1087 1087
 						break;
1088
-					/* allow 2 in PROTO*/
1089
-					case F_PROTO:
1090
-						vb->transport.s=tmp;
1091
-						state=P_PROTO;
1092
-						break;
1093
-					case P_PROTO:
1094
-						break;
1095 1088
 					default:
1096 1089
 						LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
1097 1090
 								" state %d\n", *tmp, state);
... ...
@@ -1103,13 +1158,6 @@ parse_again:
1103 1103
 					case VER1:
1104 1104
 						state=VER2;
1105 1105
 						break;
1106
-					/* allow . in PROTO */
1107
-					case F_PROTO:
1108
-						vb->transport.s=tmp;
1109
-						state=P_PROTO;
1110
-						break;
1111
-					case P_PROTO:
1112
-						break;
1113 1106
 					default:
1114 1107
 						LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
1115 1108
 								" state %d\n", *tmp, state);
... ...
@@ -1121,13 +1169,6 @@ parse_again:
1121 1121
 					case VER2:
1122 1122
 						state=FIN_VER;
1123 1123
 						break;
1124
-					/* allow 0 in PROTO*/
1125
-					case F_PROTO:
1126
-						vb->transport.s=tmp;
1127
-						state=P_PROTO;
1128
-						break;
1129
-					case P_PROTO:
1130
-						break;
1131 1124
 					default:
1132 1125
 						LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
1133 1126
 								" state %d\n", *tmp, state);
... ...
@@ -1136,18 +1177,9 @@ parse_again:
1136 1136
 				break;
1137 1137
 			
1138 1138
 			default:
1139
-				switch(state){
1140
-					case F_PROTO:
1141
-						vb->transport.s=tmp;
1142
-						state=P_PROTO;
1143
-						break;
1144
-					case P_PROTO:
1145
-						break;
1146
-					default:
1147 1139
 						LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
1148 1140
 								" state %d\n", *tmp, state);
1149 1141
 						goto error;
1150
-				}
1151 1142
 				break;
1152 1143
 		}
1153 1144
 	} /* for tmp*/
... ...
@@ -41,6 +41,7 @@ enum {
41 41
 };
42 42
 
43 43
 
44
+
44 45
 struct via_param {
45 46
 	int type;               /* Type of the parameter */
46 47
 	str name;               /* Name of the parameter */
... ...
@@ -57,6 +58,7 @@ struct via_body {
57 57
 	str name;
58 58
 	str version;   
59 59
 	str transport;
60
+	int proto; /* transport */
60 61
 	str host;
61 62
 	int port;
62 63
 	str port_str;
... ...
@@ -50,7 +50,7 @@
50 50
 
51 51
 unsigned int msg_no=0;
52 52
 
53
-int receive_msg(char* buf, unsigned int len, union sockaddr_union* src_su)
53
+int receive_msg(char* buf, unsigned int len, struct receive_info* rcv_info) 
54 54
 {
55 55
 	struct sip_msg* msg;
56 56
 #ifdef STATS
... ...
@@ -76,8 +76,7 @@ int receive_msg(char* buf, unsigned int len, union sockaddr_union* src_su)
76 76
 	/* zero termination (termination of orig message bellow not that
77 77
 	   useful as most of the work is done with scrath-pad; -jiri  */
78 78
 	/* buf[len]=0; */ /* WARNING: zero term removed! */
79
-	su2ip_addr(&msg->src_ip, src_su);
80
-	msg->dst_ip=bind_address->address; /* won't work if listening on 0.0.0.0 */
79
+	msg->rcv=*rcv_info;
81 80
 	msg->id=msg_no;
82 81
 	/* make a copy of the message */
83 82
 	msg->orig=(char*) pkg_malloc(len+1);
... ...
@@ -32,7 +32,7 @@
32 32
 
33 33
 #include "ip_addr.h"
34 34
 
35
-int receive_msg(char* buf, unsigned int len, union sockaddr_union *src_su);
35
+int receive_msg(char* buf, unsigned int len, struct receive_info *ri);
36 36
 
37 37
 
38 38
 #endif
... ...
@@ -146,6 +146,7 @@ static int fix_actions(struct action* a)
146 146
 		switch(t->type){
147 147
 			case FORWARD_T:
148 148
 			case FORWARD_TCP_T:
149
+			case FORWARD_UDP_T:
149 150
 			case SEND_T:
150 151
 			case SEND_TCP_T:
151 152
 					switch(t->p1_type){
... ...
@@ -360,10 +361,10 @@ static int eval_elem(struct expr* e, struct sip_msg* msg)
360 360
 				}
361 361
 				break;
362 362
 		case SRCIP_O:
363
-				ret=comp_ip(&msg->src_ip, e->r.param, e->op, e->subtype);
363
+				ret=comp_ip(&msg->rcv.src_ip, e->r.param, e->op, e->subtype);
364 364
 				break;
365 365
 		case DSTIP_O:
366
-				ret=comp_ip(&msg->dst_ip, e->r.param, e->op, e->subtype);
366
+				ret=comp_ip(&msg->rcv.dst_ip, e->r.param, e->op, e->subtype);
367 367
 				break;
368 368
 		case NUMBER_O:
369 369
 				ret=!(!e->r.intval); /* !! to transform it in {0,1} */
... ...
@@ -235,6 +235,9 @@ void print_action(struct action* a)
235 235
 			case FORWARD_TCP_T:
236 236
 					DBG("forward_tcp(");
237 237
 					break;
238
+			case FORWARD_UDP_T:
239
+					DBG("forward_udp(");
240
+					break;
238 241
 			case SEND_T:
239 242
 					DBG("send(");
240 243
 					break;
... ...
@@ -56,6 +56,7 @@ enum { FORWARD_T=1, SEND_T, DROP_T, LOG_T, ERROR_T, ROUTE_T, EXEC_T,
56 56
 		APPEND_BRANCH_T,
57 57
 		REVERT_URI_T,
58 58
 		FORWARD_TCP_T,
59
+		FORWARD_UDP_T,
59 60
 		SEND_TCP_T};
60 61
 enum { NOSUBTYPE=0, STRING_ST, NET_ST, NUMBER_ST, IP_ST, RE_ST, PROXY_ST,
61 62
 		EXPR_ST, ACTIONS_ST, CMDF_ST, MODFIXUP_ST, URIHOST_ST, URIPORT_ST,
... ...
@@ -41,9 +41,9 @@
41 41
 #define TCP_CHILD_SELECT_TIMEOUT 2 /* the same as above but for children */
42 42
 
43 43
 
44
-enum {	TCP_REQ_INIT, TCP_REQ_OK, TCP_READ_ERROR, TCP_REQ_OVERRUN, 
45
-	 	TCP_REQ_BAD_LEN };
46
-enum {	H_SKIP, H_LF, H_LFCR,  H_BODY, H_STARTWS,
44
+enum tcp_req_errors {	TCP_REQ_INIT, TCP_REQ_OK, TCP_READ_ERROR,
45
+						TCP_REQ_OVERRUN, TCP_REQ_BAD_LEN };
46
+enum tcp_req_states {	H_SKIP, H_LF, H_LFCR,  H_BODY, H_STARTWS,
47 47
 		H_CONT_LEN1, H_CONT_LEN2, H_CONT_LEN3, H_CONT_LEN4, H_CONT_LEN5,
48 48
 		H_CONT_LEN6, H_CONT_LEN7, H_CONT_LEN8, H_CONT_LEN9, H_CONT_LEN10,
49 49
 		H_CONT_LEN11, H_CONT_LEN12, H_CONT_LEN13, H_L_COLON, 
... ...
@@ -51,8 +51,8 @@ enum {	H_SKIP, H_LF, H_LFCR,  H_BODY, H_STARTWS,
51 51
 	};
52 52
 
53 53
 /* fd communication commands */
54
-enum { CONN_DESTROY=-3, CONN_ERROR=-2, CONN_EOF=-1, CONN_RELEASE, CONN_GET_FD,
55
-	   CONN_NEW };
54
+enum conn_cmds { CONN_DESTROY=-3, CONN_ERROR=-2, CONN_EOF=-1, CONN_RELEASE, 
55
+					CONN_GET_FD, CONN_NEW };
56 56
 
57 57
 struct tcp_req{
58 58
 	struct tcp_req* next;
... ...
@@ -65,8 +65,8 @@ struct tcp_req{
65 65
 	int has_content_len; /* 1 if content_length was parsed ok*/
66 66
 	int complete; /* 1 if one req has been fully read, 0 otherwise*/
67 67
 	int bytes_to_go; /* how many bytes we have still to read from the body*/
68
-	int error;
69
-	int state;
68
+	enum tcp_req_errors error;
69
+	enum tcp_req_states state;
70 70
 };
71 71
 
72 72
 
... ...
@@ -77,10 +77,13 @@ struct tcp_connection{
77 77
 	int fd; /* used only by "children" */
78 78
 	int id; /* id (unique!) used to retrieve a specific connection when
79 79
 	           reply-ing*/
80
+	struct receive_info rcv; /* src & dst ip, ports, proto a.s.o*/
81
+#if 0
80 82
 	struct ip_addr ip; /* peer ip */
81 83
 	int port; /* peer port */
82 84
 	int sock_idx; /* receiving socket index in the tcp_info array */
83 85
 	union sockaddr_union su;
86
+#endif
84 87
 	struct tcp_req req; /* request data */
85 88
 	int refcnt;
86 89
 	int timeout; /* connection timeout, after this it will be removed*/
87 90
new file mode 100644
... ...
@@ -0,0 +1,39 @@
0
+/*
1
+ * $Id$
2
+ *
3
+ * Copyright (C) 2001-2003 Fhg Fokus
4
+ *
5
+ * This file is part of ser, a free SIP server.
6
+ *
7
+ * ser is free software; you can redistribute it and/or modify
8
+ * it under the terms of the GNU General Public License as published by
9
+ * the Free Software Foundation; either version 2 of the License, or
10
+ * (at your option) any later version
11
+ *
12
+ * For a license to use the ser software under conditions
13
+ * other than those described here, or to purchase support for this
14
+ * software, please contact iptel.org by e-mail at the following addresses:
15
+ *    info@iptel.org
16
+ *
17
+ * ser is distributed in the hope that it will be useful,
18
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
+ * GNU General Public License for more details.
21
+ *
22
+ * You should have received a copy of the GNU General Public License 
23
+ * along with this program; if not, write to the Free Software 
24
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
25
+ */
26
+
27
+#ifndef tcp_init_h
28
+#define tcp_init_h
29
+#include "ip_addr.h"
30
+
31
+int init_tcp();
32
+int tcp_init(struct socket_info* sock_info);
33
+int tcp_init_children();
34
+void tcp_main_loop();
35
+void tcp_receive_loop(int unix_sock);
36
+
37
+
38
+#endif
... ...
@@ -55,6 +55,7 @@
55 55
 #include "mem/shm_mem.h"
56 56
 #include "timer.h"
57 57
 #include "tcp_server.h"
58
+#include "tcp_init.h"
58 59
 
59 60
 
60 61
 
... ...
@@ -81,7 +82,8 @@ int unix_tcp_sock;
81 81
 
82 82
 
83 83
 
84
-struct tcp_connection* tcpconn_new(int sock, union sockaddr_union* su, int i)
84
+struct tcp_connection* tcpconn_new(int sock, union sockaddr_union* su,
85
+									struct socket_info* ba)
85 86
 {
86 87
 	struct tcp_connection *c;
87 88
 	
... ...
@@ -93,14 +95,22 @@ struct tcp_connection* tcpconn_new(int sock, union sockaddr_union* su, int i)
93 93
 	}
94 94
 	c->s=sock;
95 95
 	c->fd=sock;
96
-	c->su=*su;
97
-	c->sock_idx=i;
96
+	c->rcv.src_su=*su;
97
+	
98 98
 	c->refcnt=0;
99
-	su2ip_addr(&c->ip, su);
100
-	c->port=su_getport(su);
99
+	su2ip_addr(&c->rcv.src_ip, su);
100
+	c->rcv.src_port=su_getport(su);
101
+	c->rcv.proto=PROTO_TCP;
102
+	c->rcv.bind_address=ba;
103
+	if (ba){
104
+		c->rcv.dst_ip=ba->address;
105
+		c->rcv.dst_port=ba->port_no;
106
+	}
101 107
 	init_tcp_req(&c->req);
102 108
 	c->timeout=get_ticks()+TCP_CON_TIMEOUT;
103 109
 	c->id=connection_id++;
110
+	c->rcv.proto_reserved1=0; /* this will be filled before receive_message*/
111
+	c->rcv.proto_reserved2=0;
104 112
 	return c;
105 113
 	
106 114
 error:
... ...
@@ -157,14 +167,16 @@ struct tcp_connection* tcpconn_find(int id, struct ip_addr* ip, int port)
157 157
 
158 158
 	struct tcp_connection *c;
159 159
 	
160
-	DBG("tcpconn_find: %d ",id ); print_ip(ip); DBG(" %d\n", port);
160
+	DBG("tcpconn_find: %d ",id ); print_ip(ip); DBG(" %d\n", ntohs(port));
161 161
 	for (c=*conn_list; c; c=c->next){
162 162
 		DBG("c=%p, c->id=%d, ip=",c, c->id);
163
-		print_ip(&c->ip);
164
-		DBG(" port=%d\n", c->port);
163
+		print_ip(&c->rcv.src_ip);
164
+		DBG(" port=%d\n", ntohs(c->rcv.src_port));
165 165
 		if (id){
166 166
 			if (id==c->id) return c;
167
-		}else if ((port==c->port)&&(ip_addr_cmp(ip, &c->ip))) return c;
167
+		}else if (ip &&	(port==c->rcv.src_port)&&
168
+					(ip_addr_cmp(ip, &c->rcv.src_ip)))
169
+			return c;
168 170
 	}
169 171
 	return 0;
170 172
 }
... ...
@@ -199,17 +211,31 @@ int tcp_send(char* buf, unsigned len, union sockaddr_union* to, int id)
199 199
 	long response[2];
200 200
 	int n;
201 201
 	
202
-	su2ip_addr(&ip, to);
203
-	port=su_getport(to);
202
+	port=0;
203
+	if (to){
204
+		su2ip_addr(&ip, to);
205
+		port=su_getport(to);
206
+		c=tcpconn_get(id, &ip, port); /* lock ;inc refcnt; unlock */
207
+	}else if (id){
208
+		c=tcpconn_get(id, 0, 0);
209
+	}else{
210
+		LOG(L_CRIT, "BUG: tcp_send called with null id & to\n");
211
+		return -1;
212
+	}
204 213
 	
205
-	c=tcpconn_get(id, &ip, port); /* lock ;inc refcnt; unlock */
206 214
 	if (id){
207 215
 		if (c==0) {
208
-		LOG(L_ERR, "ERROR: tcp_send: id %d not found, dropping\n",
209
-					id);
210
-			return -1;
211
-		}
212
-	}else{
216
+			if (to){
217
+				c=tcpconn_get(0, &ip, port); /* try again w/o id */
218
+				goto no_id;
219
+			}else{
220
+				LOG(L_ERR, "ERROR: tcp_send: id %d not found, dropping\n",
221
+						id);
222
+				return -1;
223
+			}
224
+		}else goto get_fd;
225
+	}
226
+no_id:
213 227
 		if (c==0){
214 228
 			DBG("tcp_send: no open tcp connection found, opening new one\n");
215 229
 			/* create tcp connection */
... ...
@@ -224,18 +250,24 @@ int tcp_send(char* buf, unsigned len, union sockaddr_union* to, int id)
224 224
 			response[1]=CONN_NEW;
225 225
 			n=write(unix_tcp_sock, response, sizeof(response));
226 226
 			n=send_fd(unix_tcp_sock, &c, sizeof(c), c->s);
227
-		}else{
227
+			goto send_it;
228
+		}
229
+get_fd:
228 230
 			DBG("tcp_send: tcp connection found, acquiring fd\n");
229 231
 			/* get the fd */
230 232
 			response[0]=(long)c;
231 233
 			response[1]=CONN_GET_FD;
232 234
 			n=write(unix_tcp_sock, response, sizeof(response));
235
+			DBG("tcp_send, c= %p, n=%d\n", c, n);
233 236
 			n=receive_fd(unix_tcp_sock, &c, sizeof(c), &c->fd);
234
-		}
237
+			DBG("tcp_send: after receive_fd: c= %p n=%d fd=%d\n",c, n, c->fd);
238
+		
235 239
 	
236
-	}
240
+	
241
+send_it:
237 242
 	DBG("tcp_send: sending...\n");
238 243
 	n=write(c->fd, buf, len);
244
+	DBG("tcp_send: after write: c= %p n=%d fd=%d\n",c, n, c->fd);
239 245
 	close(c->fd);
240 246
 	tcpconn_put(c); /* release c (lock; dec refcnt; unlock) */
241 247
 	return n;
... ...
@@ -269,12 +301,12 @@ void tcpconn_timeout(fd_set* set)
269 269
 
270 270
 
271 271
 
272
-int tcp_init_sock(struct socket_info* sock_info)
272
+int tcp_init(struct socket_info* sock_info)
273 273
 {
274 274
 	union sockaddr_union* addr;
275 275
 	
276 276
 	addr=&sock_info->su;
277
-	sock_info->proto=SOCKET_TCP;
277
+	sock_info->proto=PROTO_TCP;
278 278
 	if (init_su(addr, &sock_info->address, htons(sock_info->port_no))<0){
279 279
 		LOG(L_ERR, "ERROR: tcp_init: could no init sockaddr_union\n");
280 280
 		goto error;
... ...
@@ -369,14 +401,14 @@ void tcp_main_loop()
369 369
 	FD_ZERO(&master_set);
370 370
 	/* set all the listen addresses */
371 371
 	for (r=0; r<sock_no; r++){
372
-		if ((tcp_info[r].proto==SOCKET_TCP) &&(tcp_info[r].socket!=-1)){
372
+		if ((tcp_info[r].proto==PROTO_TCP) &&(tcp_info[r].socket!=-1)){
373 373
 			FD_SET(tcp_info[r].socket, &master_set);
374 374
 			if (tcp_info[r].socket>maxfd) maxfd=tcp_info[r].socket;
375 375
 		}
376 376
 	}
377 377
 	/* set all the unix sockets used for child comm */
378
-	for (r=0; r<process_no; r++){
379
-		if (pt[r].unix_sock>=0){
378
+	for (r=1; r<process_no; r++){
379
+		if (pt[r].unix_sock>0){ /* we can't have 0, we never close it!*/
380 380
 			FD_SET(pt[r].unix_sock, &master_set);
381 381
 			if (pt[r].unix_sock>maxfd) maxfd=pt[r].unix_sock;
382 382
 		}
... ...
@@ -399,8 +431,7 @@ void tcp_main_loop()
399 399
 		}
400 400
 		
401 401
 		for (r=0; r<sock_no && n; r++){
402
-			if ((tcp_info[r].proto==SOCKET_TCP) &&
403
-					(FD_ISSET(tcp_info[r].socket, &sel_set))){
402
+			if ((FD_ISSET(tcp_info[r].socket, &sel_set))){
404 403
 				/* got a connection on r */
405 404
 				su_len=sizeof(su);
406 405
 				new_sock=accept(tcp_info[r].socket, &(su.s), &su_len);
... ...
@@ -412,7 +443,7 @@ void tcp_main_loop()
412 412
 				}
413 413
 				
414 414
 				/* add socket to list */
415
-				tcpconn=tcpconn_new(new_sock, &su, r);
415
+				tcpconn=tcpconn_new(new_sock, &su, &tcp_info[r]);
416 416
 				if (tcpconn){
417 417
 					tcpconn_add(tcpconn);
418 418
 					DBG("tcp_main_loop: new connection: %p %d\n",
... ...
@@ -449,7 +480,8 @@ void tcp_main_loop()
449 449
 		/* check unix sockets & listen | destroy connections */
450 450
 		/* start from 1, the "main" process does not transmit anything*/
451 451
 		for (r=1; r<process_no && n; r++){
452
-			if ( (pt[r].unix_sock>=0) && FD_ISSET(pt[r].unix_sock, &sel_set)){
452
+			if ( (pt[r].unix_sock>0) && FD_ISSET(pt[r].unix_sock, &sel_set)){
453
+				/* (we can't have a fd==0, 0 i s never closed )*/
453 454
 				n--;
454 455
 				/* errno==EINTR !!! TODO*/
455 456
 read_again:
... ...
@@ -560,7 +592,7 @@ int init_tcp()
560 560
 	/* allocate list head*/
561 561
 	conn_list=shm_malloc(sizeof(struct tcp_connection*));
562 562
 	if (conn_list==0){
563
-		LOG(L_CRIT, "ERROR: tcp_init: memory allocation failure\n");
563
+		LOG(L_CRIT, "ERROR: init_tcp: memory allocation failure\n");
564 564
 		goto error;
565 565
 	}
566 566
 	*conn_list=0;
... ...
@@ -580,11 +612,7 @@ int tcp_init_children()
580 580
 	
581 581
 	
582 582
 	/* create the tcp sock_info structures */
583
-	/* copy the sockets*/
584
-	for (r=0; r<sock_no ; r++){
585
-		tcp_info[r]=sock_info[r];
586
-		tcp_init_sock(&tcp_info[r]);
587
-	}
583
+	/* copy the sockets --moved to main_loop*/
588 584
 	
589 585
 	/* fork children & create the socket pairs*/
590 586
 	for(r=0; r<tcp_children_no; r++){
... ...
@@ -366,7 +366,8 @@ int tcp_read_req(struct tcp_connection* con)
366 366
 			DBG("calling receive_msg(%p, %d, )\n",
367 367
 					req->buf, (int)(req->parsed-req->buf));
368 368
 			bind_address=sendipv4; /*&tcp_info[con->sock_idx];*/
369
-			if (receive_msg(req->buf, req->parsed-req->buf, &con->su)<0){
369
+			con->rcv.proto_reserved1=con->id; /* copy the id */
370
+			if (receive_msg(req->buf, req->parsed-req->buf, &con->rcv)<0){
370 371
 				resp=CONN_ERROR;
371 372
 				goto end_req;
372 373
 			}
... ...
@@ -213,6 +213,7 @@ int udp_init(struct socket_info* sock_info)
213 213
 		goto error;
214 214
 	}
215 215
 */
216
+	sock_info->proto=PROTO_UDP;
216 217
 	if (init_su(addr, &sock_info->address, htons(sock_info->port_no))<0){
217 218
 		LOG(L_ERR, "ERROR: udp_init: could not init sockaddr_union\n");
218 219
 		goto error;
... ...
@@ -278,6 +279,7 @@ int udp_rcv_loop()
278 278
 
279 279
 	union sockaddr_union* from;
280 280
 	unsigned int fromlen;
281
+	struct receive_info ri;
281 282
 
282 283
 
283 284
 	from=(union sockaddr_union*) malloc(sizeof(union sockaddr_union));
... ...
@@ -286,7 +288,11 @@ int udp_rcv_loop()
286 286
 		goto error;
287 287
 	}
288 288
 	memset(from, 0 , sizeof(union sockaddr_union));
289
-
289
+	ri.bind_address=bind_address; /* this will not change, we do it only once*/
290
+	ri.dst_port=bind_address->port_no;
291
+	ri.dst_ip=bind_address->address;
292
+	ri.proto=PROTO_UDP;
293
+	ri.proto_reserved1=ri.proto_reserved2=0;
290 294
 	for(;;){
291 295
 #ifdef DYN_BUF
292 296
 		buf=pkg_malloc(BUF_SIZE+1);
... ...
@@ -327,9 +333,13 @@ int udp_rcv_loop()
327 327
 			continue;
328 328
 		}
329 329
 #endif
330
+		ri.src_su=*from;
331
+		su2ip_addr(&ri.src_ip, from);
332
+		ri.src_port=su_getport(from);
333
+		
330 334
 		
331 335