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 87
 	ser_error=E_UNSPEC;
87 88
 
88 89
 	ret=E_BUG;
89
-	switch (a->type){
90
+	switch ((unsigned char)a->type){
90 91
 		case DROP_T:
91 92
 				ret=0;
92 93
 			break;
93 94
 		case FORWARD_T:
95
+#ifdef USE_TCP
96
+		case FORWARD_TCP_T:
97
+#endif
98
+		case FORWARD_UDP_T:
99
+
100
+			if (a->type==FORWARD_UDP_T) proto=PROTO_UDP;
101
+#ifdef USE_TCP
102
+			else if (a->type==FORWARD_TCP_T) proto= PROTO_TCP;
103
+#endif
104
+			else proto=msg->rcv.proto;
94 105
 			if (a->p1_type==URIHOST_ST){
95 106
 				/*parse uri*/
96 107
 				ret=parse_sip_msg_uri(msg);
... ...
@@ -121,13 +132,13 @@ int do_action(struct action* a, struct sip_msg* msg)
121 132
 					ret=E_BAD_ADDRESS;
122 133
 					goto error_fwd_uri;
123 134
 				}
124
-				ret=forward_request(msg, p);
135
+				ret=forward_request(msg, p, proto);
125 136
 				/*free_uri(&uri); -- no longer needed, in sip_msg*/
126 137
 				free_proxy(p); /* frees only p content, not p itself */
127 138
 				free(p);
128 139
 				if (ret>=0) ret=1;
129 140
 			}else if ((a->p1_type==PROXY_ST) && (a->p2_type==NUMBER_ST)){
130
-				ret=forward_request(msg,(struct proxy_l*)a->p1.data);
141
+				ret=forward_request(msg,(struct proxy_l*)a->p1.data, proto);
131 142
 				if (ret>=0) ret=1;
132 143
 			}else{
133 144
 				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 178
 				p->tx_bytes+=msg->len;
168 179
 				if (a->type==SEND_T){
169 180
 					/*udp*/
170
-					send_sock=get_send_socket(to);
181
+					send_sock=get_send_socket(to, PROTO_UDP);
171 182
 					if (send_sock!=0){
172 183
 						ret=udp_send(send_sock, msg->orig, msg->len, to);
173 184
 					}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 156
 
156 157
 <INITIAL>{FORWARD}	{count(); yylval.strval=yytext; return FORWARD; }
157 158
 <INITIAL>{FORWARD_TCP}	{count(); yylval.strval=yytext; return FORWARD_TCP; }
159
+<INITIAL>{FORWARD_UDP}	{count(); yylval.strval=yytext; return FORWARD_UDP; }
158 160
 <INITIAL>{DROP}	{ count(); yylval.strval=yytext; return DROP; }
159 161
 <INITIAL>{SEND}	{ count(); yylval.strval=yytext; return SEND; }
160 162
 <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 684
 		| FORWARD error { $$=0; yyerror("missing '(' or ')' ?"); }
684 685
 		| FORWARD LPAREN error RPAREN { $$=0; yyerror("bad forward"
685 686
 										"argument"); }
687
+		| FORWARD_UDP LPAREN host RPAREN	{ $$=mk_action(	FORWARD_UDP_T,
688
+														STRING_ST,
689
+														NUMBER_ST,
690
+														$3,
691
+														0);
692
+										}
693
+		| FORWARD_UDP LPAREN STRING RPAREN	{ $$=mk_action(	FORWARD_UDP_T,
694
+														STRING_ST,
695
+														NUMBER_ST,
696
+														$3,
697
+														0);
698
+										}
699
+		| FORWARD_UDP LPAREN ip RPAREN	{ $$=mk_action(	FORWARD_UDP_T,
700
+														IP_ST,
701
+														NUMBER_ST,
702
+														(void*)$3,
703
+														0);
704
+										}
705
+		| FORWARD_UDP LPAREN host COMMA NUMBER RPAREN { $$=mk_action(
706
+																FORWARD_UDP_T,
707
+																 STRING_ST,
708
+																 NUMBER_ST,
709
+																$3,
710
+																(void*)$5);
711
+												 }
712
+		| FORWARD_UDP LPAREN STRING COMMA NUMBER RPAREN {$$=mk_action(
713
+																FORWARD_UDP_T,
714
+																 STRING_ST,
715
+																 NUMBER_ST,
716
+																$3,
717
+																(void*)$5);
718
+													}
719
+		| FORWARD_UDP LPAREN ip COMMA NUMBER RPAREN { $$=mk_action(
720
+																FORWARD_UDP_T,
721
+																 IP_ST,
722
+																 NUMBER_ST,
723
+																 (void*)$3,
724
+																(void*)$5);
725
+												  }
726
+		| FORWARD_UDP LPAREN URIHOST COMMA URIPORT RPAREN {
727
+													$$=mk_action(FORWARD_UDP_T,
728
+																 URIHOST_ST,
729
+																 URIPORT_ST,
730
+																0,
731
+																0);
732
+													}
733
+													
734
+									
735
+		| FORWARD_UDP LPAREN URIHOST COMMA NUMBER RPAREN {
736
+													$$=mk_action(FORWARD_UDP_T,
737
+																 URIHOST_ST,
738
+																 NUMBER_ST,
739
+																0,
740
+																(void*)$5);
741
+													}
742
+		| FORWARD_UDP LPAREN URIHOST RPAREN {
743
+													$$=mk_action(FORWARD_UDP_T,
744
+																 URIHOST_ST,
745
+																 NUMBER_ST,
746
+																0,
747
+																0);
748
+										}
749
+		| FORWARD_UDP error { $$=0; yyerror("missing '(' or ')' ?"); }
750
+		| FORWARD_UDP LPAREN error RPAREN { $$=0; yyerror("bad forward_udp"
751
+										"argument"); }
752
+		| FORWARD_TCP LPAREN host RPAREN	{ $$=mk_action(	FORWARD_TCP_T,
753
+														STRING_ST,
754
+														NUMBER_ST,
755
+														$3,
756
+														0);
757
+										}
758
+		| FORWARD_TCP LPAREN STRING RPAREN	{ $$=mk_action(	FORWARD_TCP_T,
759
+														STRING_ST,
760
+														NUMBER_ST,
761
+														$3,
762
+														0);
763
+										}
764
+		| FORWARD_TCP LPAREN ip RPAREN	{ $$=mk_action(	FORWARD_TCP_T,
765
+														IP_ST,
766
+														NUMBER_ST,
767
+														(void*)$3,
768
+														0);
769
+										}
770
+		| FORWARD_TCP LPAREN host COMMA NUMBER RPAREN { $$=mk_action(
771
+																FORWARD_TCP_T,
772
+																 STRING_ST,
773
+																 NUMBER_ST,
774
+																$3,
775
+																(void*)$5);
776
+												 }
777
+		| FORWARD_TCP LPAREN STRING COMMA NUMBER RPAREN {$$=mk_action(
778
+																FORWARD_TCP_T,
779
+																 STRING_ST,
780
+																 NUMBER_ST,
781
+																$3,
782
+																(void*)$5);
783
+													}
784
+		| FORWARD_TCP LPAREN ip COMMA NUMBER RPAREN { $$=mk_action(FORWARD_TCP_T,
785
+																 IP_ST,
786
+																 NUMBER_ST,
787
+																 (void*)$3,
788
+																(void*)$5);
789
+												  }
790
+		| FORWARD_TCP LPAREN URIHOST COMMA URIPORT RPAREN {
791
+													$$=mk_action(FORWARD_TCP_T,
792
+																 URIHOST_ST,
793
+																 URIPORT_ST,
794
+																0,
795
+																0);
796
+													}
797
+													
798
+									
799
+		| FORWARD_TCP LPAREN URIHOST COMMA NUMBER RPAREN {
800
+													$$=mk_action(FORWARD_TCP_T,
801
+																 URIHOST_ST,
802
+																 NUMBER_ST,
803
+																0,
804
+																(void*)$5);
805
+													}
806
+		| FORWARD_TCP LPAREN URIHOST RPAREN {
807
+													$$=mk_action(FORWARD_TCP_T,
808
+																 URIHOST_ST,
809
+																 NUMBER_ST,
810
+																0,
811
+																0);
812
+										}
813
+		| FORWARD_TCP error { $$=0; yyerror("missing '(' or ')' ?"); }
814
+		| FORWARD_TCP LPAREN error RPAREN { $$=0; yyerror("bad forward_tcp"
815
+										"argument"); }
686 816
 		| SEND LPAREN host RPAREN	{ $$=mk_action(	SEND_T,
687 817
 													STRING_ST,
688 818
 													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 66
 /* returns a socket_info pointer to the sending socket or 0 on error
64 67
  * params: destination socket_union pointer
65 68
  */
66
-struct socket_info* get_send_socket(union sockaddr_union* to)
69
+struct socket_info* get_send_socket(union sockaddr_union* to, int proto)
67 70
 {
68 71
 	struct socket_info* send_sock;
69 72
 	
70 73
 	send_sock=0;
71 74
 	/* check if we need to change the socket (different address families -
72 75
 	 * eg: ipv4 -> ipv6 or ipv6 -> ipv4) */
73
-	if ((bind_address==0) ||(to->s.sa_family!=bind_address->address.af)){
76
+#ifdef USE_TCP
77
+	if (proto==PROTO_TCP){
78
+		/* on tcp just use the "main address", we don't really now the
79
+		 * sending address (we can find it out, but we'll find also to see
80
+		 * if we listen on it, and if yes on which port -> too complicated*/
81
+		switch(to->s.sa_family){
82
+			case AF_INET:	send_sock=sendipv4_tcp;
83
+							break;
84
+#ifdef USE_IPV6
85
+			case AF_INET6:	send_sock=sendipv6_tcp;
86
+							break;
87
+#endif
88
+			default:		LOG(L_ERR, "get_send_socket: BUG: don't know how"
89
+									" to forward to af %d\n", to->s.sa_family);
90
+		}
91
+	}else
92
+#endif
93
+	      if ((bind_address==0) ||(to->s.sa_family!=bind_address->address.af)){
74 94
 		switch(to->s.sa_family){
75 95
 			case AF_INET:	send_sock=sendipv4;
76 96
 							break;
... ...
@@ -139,16 +159,18 @@ int check_self(str* host, unsigned short port)
139 159
 
140 160
 
141 161
 
142
-int forward_request( struct sip_msg* msg, struct proxy_l * p)
162
+int forward_request( struct sip_msg* msg, struct proxy_l * p, int proto)
143 163
 {
144 164
 	unsigned int len;
145 165
 	char* buf;
146 166
 	union sockaddr_union* to;
147 167
 	struct socket_info* send_sock;
148 168
 	char md5[MD5_LEN];
169
+	int id; /* used as branch for tcp! */
149 170
 	
150 171
 	to=0;
151 172
 	buf=0;
173
+	id=0;
152 174
 	
153 175
 	to=(union sockaddr_union*)malloc(sizeof(union sockaddr_union));
154 176
 	if (to==0){
... ...
@@ -172,7 +194,7 @@ int forward_request( struct sip_msg* msg, struct proxy_l * p)
172 194
 	p->tx_bytes+=len;
173 195
 	
174 196
 
175
-	send_sock=get_send_socket(to);
197
+	send_sock=get_send_socket(to, proto);
176 198
 	if (send_sock==0){
177 199
 		LOG(L_ERR, "forward_req: ERROR: cannot forward to af %d "
178 200
 				"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 212
 	   value in there; better for performance
191 213
 	*/
192 214
 
215
+#ifdef USE_TCP
216
+	if (msg->rcv.proto==PROTO_TCP) id=msg->rcv.proto_reserved1;
217
+#endif
193 218
 	if (syn_branch ) {
194 219
 		*msg->add_to_branch_s='0';
195 220
 		msg->add_to_branch_len=1;
... ...
@@ -199,31 +224,52 @@ int forward_request( struct sip_msg* msg, struct proxy_l * p)
199 224
 			goto error1;
200 225
 		}
201 226
 		msg->hash_index=hash( msg->callid->body, get_cseq(msg)->number);
202
-		if (!branch_builder( msg->hash_index, 0, md5, 0 /* 0-th branch */,
227
+		if (!branch_builder( msg->hash_index, 0, md5, id /* 0-th branch */,
203 228
 					msg->add_to_branch_s, &msg->add_to_branch_len )) {
204 229
 			LOG(L_ERR, "ERROR: forward_request: branch_builder failed\n");
205 230
 			goto error1;
206 231
 		}
207 232
 	}
208 233
 
209
-	buf = build_req_buf_from_sip_req( msg, &len, send_sock);
234
+	buf = build_req_buf_from_sip_req( msg, &len, send_sock,  proto);
210 235
 	if (!buf){
211 236
 		LOG(L_ERR, "ERROR: forward_request: building failed\n");
212 237
 		goto error1;
213 238
 	}
214 239
 	 /* send it! */
215 240
 	DBG("Sending:\n%s.\n", buf);
216
-	DBG("orig. len=%d, new_len=%d\n", msg->len, len );
241
+	DBG("orig. len=%d, new_len=%d, proto=%d\n", msg->len, len, proto );
217 242
 	
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;
243
+	
244
+	if (proto==PROTO_UDP){
245
+		if (udp_send(send_sock, buf, len,  to)==-1){
246
+				ser_error=E_SEND;
247
+				p->errors++;
248
+				p->ok=0;
249
+				STATS_TX_DROPS;
250
+				goto error1;
251
+		}
252
+	}
253
+#ifdef USE_TCP
254
+	 else if (proto==PROTO_TCP){
255
+		if (tcp_send(buf, len, to, 0)==-1){
256
+				ser_error=E_SEND;
257
+				p->errors++;
258
+				p->ok=0;
259
+				STATS_TX_DROPS;
260
+				goto error1;
261
+		}
262
+	}
263
+#endif
264
+	 else{
265
+		LOG(L_CRIT, "BUG: forward_request: unknown proto %d\n", proto);
266
+		ser_error=E_SEND;
267
+		STATS_TX_DROPS;
268
+		goto error1;
224 269
 	}
270
+
225 271
 	/* sent requests stats */
226
-	else STATS_TX_REQUEST(  msg->first_line.u.request.method_value );
272
+	STATS_TX_REQUEST(  msg->first_line.u.request.method_value );
227 273
 	
228 274
 	pkg_free(buf);
229 275
 	free(to);
... ...
@@ -238,14 +284,6 @@ error:
238 284
 }
239 285
 
240 286
 
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 287
 
250 288
 int update_sock_struct_from_via( union sockaddr_union* to,
251 289
 								 struct via_body* via )
... ...
@@ -310,6 +348,13 @@ int forward_reply(struct sip_msg* msg)
310 348
 	struct socket_info* send_sock;
311 349
 	unsigned int new_len;
312 350
 	struct sr_module *mod;
351
+	int proto;
352
+#ifdef USE_TCP
353
+	char* s;
354
+	char* p;
355
+	int len;
356
+	int id;
357
+#endif
313 358
 	
314 359
 	to=0;
315 360
 	new_buf=0;
... ...
@@ -355,22 +400,57 @@ int forward_reply(struct sip_msg* msg)
355 400
 	}
356 401
 
357 402
 	if (update_sock_struct_from_via( to, msg->via2 )==-1) goto error;
358
-	send_sock=get_send_socket(to);
403
+	send_sock=get_send_socket(to, msg->rcv.proto);
359 404
 	if (send_sock==0){
360 405
 		LOG(L_ERR, "forward_reply: ERROR: no sending socket found\n");
361 406
 		goto error;
362 407
 	}
363 408
 
364
-	if (udp_send(send_sock, new_buf,new_len,  to)==-1)
365
-	{
366
-		STATS_TX_DROPS;
409
+	proto=msg->via2->proto;
410
+	if (proto==PROTO_UDP){
411
+		if (udp_send(send_sock, new_buf,new_len,  to)==-1)
412
+		{
413
+			STATS_TX_DROPS;
414
+			goto error;
415
+		}
416
+	}
417
+#ifdef USE_TCP
418
+	 else if (proto==PROTO_TCP){
419
+		 id=0;
420
+		/* find id in branch if it exists */
421
+		if ((msg->via1->branch)&&(msg->via1->branch->value.len>MCOOKIE_LEN) &&
422
+			(memcmp(msg->via1->branch->value.s, MCOOKIE, MCOOKIE_LEN)==0)){
423
+			DBG("forward_reply: found branch\n");
424
+			s=msg->via1->branch->value.s+MCOOKIE_LEN;
425
+			len=msg->via1->branch->value.len-MCOOKIE_LEN;
426
+			for (p=s; p<s+len  && *p!=BRANCH_SEPARATOR; p++);
427
+			p++;
428
+			for(;p<s+len && *p!=BRANCH_SEPARATOR; p++);
429
+			p++;
430
+			if (p<s+len){
431
+				/* we found the second BRANCH_SEPARATOR, p points after it */
432
+				len-=(int)(p-s);
433
+				id=reverse_hex2int(p, len);
434
+				DBG("forward_reply: id= %x\n", id);
435
+			}else{
436
+				DBG("forward_reply: no id in branch\n");
437
+			}
438
+		}		
439
+				
440
+		if (tcp_send(new_buf, new_len,  to, id)==-1)
441
+		{
442
+			STATS_TX_DROPS;
443
+			goto error;
444
+		}
445
+	} 
446
+#endif
447
+	else{
448
+		LOG(L_CRIT, "BUG: forward_reply: unknown proto %d\n", proto);
367 449
 		goto error;
368
-	} else {
450
+	}
369 451
 #ifdef STATS
370
-		int j = msg->first_line.u.reply.statuscode/100;
371
-		STATS_TX_RESPONSE(  j );
452
+		STATS_TX_RESPONSE(  (msg->first_line.u.reply.statuscode/100) );
372 453
 #endif
373
-	}
374 454
 
375 455
 	DBG(" reply forwarded to %s:%d\n", msg->via2->host.s,
376 456
 		(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 284
 int bind_idx; /* same as above but index in the bound[] array */
282 285
 struct socket_info* sendipv4; /* ipv4 socket to use when msg. comes from ipv6*/
283 286
 struct socket_info* sendipv6; /* same as above for ipv6 */
287
+#ifdef USE_TCP
288
+struct socket_info* sendipv4_tcp; 
289
+struct socket_info* sendipv6_tcp; 
290
+#endif
284 291
 
285 292
 unsigned short port_no=0; /* default port*/
286 293
 
... ...
@@ -623,6 +630,7 @@ int main_loop()
623 630
 		*/
624 631
 		for(r=0;r<sock_no;r++){
625 632
 			/* create the listening socket (for each address)*/
633
+			/* udp */
626 634
 			if (udp_init(&sock_info[r])==-1) goto error;
627 635
 			/* get first ipv4/ipv6 socket*/
628 636
 			if ((sock_info[r].address.af==AF_INET)&&
... ...
@@ -632,6 +640,19 @@ int main_loop()
632 640
 			if((sendipv6==0)&&(sock_info[r].address.af==AF_INET6))
633 641
 				sendipv6=&sock_info[r];
634 642
 	#endif
643
+#ifdef USE_TCP
644
+			tcp_info[r]=sock_info[r]; /* copy the sockets */
645
+			/* same thing for tcp */
646
+			if (tcp_init(&tcp_info[r])==-1)  goto error;
647
+			/* get first ipv4/ipv6 socket*/
648
+			if ((tcp_info[r].address.af==AF_INET)&&
649
+					((sendipv4_tcp==0)||(sendipv4_tcp->is_lo)))
650
+				sendipv4_tcp=&tcp_info[r];
651
+	#ifdef USE_IPV6
652
+			if((sendipv6_tcp==0)&&(tcp_info[r].address.af==AF_INET6))
653
+				sendipv6_tcp=&tcp_info[r];
654
+	#endif
655
+#endif
635 656
 			/* all procs should have access to all the sockets (for sending)
636 657
 			 * so we open all first*/
637 658
 		}
... ...
@@ -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 53
 
53 54
 char* via_builder( unsigned int *len,
54 55
 	struct socket_info* send_sock,
55
-	char *branch, int branch_len );
56
+	char *branch, int branch_len, int proto );
56 57
 
57 58
 #ifdef _OBSOLETED
58 59
 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 117
 
117 118
 	char* eoh;        /* pointer to the end of header (if found) or null */
118 119
 	char* unparsed;   /* here we stopped parsing*/
119
-
120
-	struct ip_addr src_ip;
121
-	struct ip_addr dst_ip;
120
+	
121
+	struct receive_info rcv; /* source & dest ip, ports, proto a.s.o*/
122 122
 	
123 123
 	char* orig;       /* original message copy */
124 124
 	char* buf;        /* scratch pad, holds a modfied message,
125
-			   *  via, etc. point into it 
126
-			   */
125
+					   *  via, etc. point into it */
127 126
 	unsigned int len; /* message len (orig) */
128 127
 
129 128
 	     /* modifications */
... ...
@@ -214,13 +213,18 @@ inline static int char_msg_val( struct sip_msg *msg, char *cv )
214 213
 inline static char* get_body(struct sip_msg *msg)
215 214
 {
216 215
 	int offset;
216
+	int len;
217 217
 
218 218
 	if ( parse_headers(msg,HDR_EOH, 0)==-1 )
219 219
 		return 0;
220 220
 
221
-	if ( strncmp(CRLF,msg->unparsed,CRLF_LEN)==0 )
221
+	if (msg->unparsed){
222
+		len=(int)(msg->unparsed-msg->buf);
223
+	}else return 0;
224
+	if ((len+2<=msg->len) && (strncmp(CRLF,msg->unparsed,CRLF_LEN)==0) )
222 225
 		offset = CRLF_LEN;
223
-	else if (*(msg->unparsed)=='\n' || *(msg->unparsed)=='\r' )
226
+	else if ( (len+1<=msg->len) &&
227
+				(*(msg->unparsed)=='\n' || *(msg->unparsed)=='\r' ) )
224 228
 		offset = 1;
225 229
 	else
226 230
 		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 73
 	SIP1, SIP2, FIN_SIP,
73 74
 	L_VER, F_VER,
74 75
 	VER1, VER2, FIN_VER,
75
-	L_PROTO, F_PROTO, P_PROTO
76
+	UDP1, UDP2, FIN_UDP,
77
+	TCP1, TCP2, FIN_TCP,
78
+	L_PROTO, F_PROTO
76 79
 };
77 80
 
78 81
 
... ...
@@ -99,12 +102,14 @@ enum {
99 102
  * output state = L_PARAM or F_PARAM or END_OF_HEADER
100 103
  * (and saved_state= last state); everything else => error 
101 104
  */
102
-static /*inline*/ char* parse_via_param(char* p, char* end, int* pstate, 
103
-				    int* psaved_state, struct via_param* param)
105
+static /*inline*/ char* parse_via_param(char* p, char* end,
106
+										unsigned char* pstate, 
107
+				    					unsigned char* psaved_state,
108
+										struct via_param* param)
104 109
 {
105 110
 	char* tmp;
106
-	register int state;
107
-	int saved_state;
111
+	register unsigned char state;
112
+	unsigned char saved_state;
108 113
 
109 114
 	state=*pstate;
110 115
 	saved_state=*psaved_state;
... ...
@@ -866,8 +871,8 @@ static /*inline*/ char* parse_via_param(char* p, char* end, int* pstate,
866 871
 char* parse_via(char* buffer, char* end, struct via_body *vb)
867 872
 {
868 873
 	char* tmp;
869
-	int state;
870
-	int saved_state;
874
+	unsigned char state;
875
+	unsigned char saved_state;
871 876
 	int c_nest;
872 877
 	int err;
873 878
 
... ...
@@ -888,9 +893,16 @@ parse_again:
888 893
 					case F_VER:
889 894
 					case F_PROTO:
890 895
 						break;
891
-					case P_PROTO:
896
+					case FIN_UDP:
892 897
 						*tmp=0;  /* finished proto parsing */
893 898
 						vb->transport.len=tmp-vb->transport.s;
899
+						vb->proto=PROTO_UDP;
900
+						state=F_HOST; /* start looking for host*/
901
+						goto main_via;
902
+					case FIN_TCP:
903
+						*tmp=0;  /* finished proto parsing */
904
+						vb->transport.len=tmp-vb->transport.s;
905
+						vb->proto=PROTO_TCP;
894 906
 						state=F_HOST; /* start looking for host*/
895 907
 						goto main_via;
896 908
 					case FIN_SIP:
... ...
@@ -924,9 +936,17 @@ parse_again:
924 936
 						saved_state=state;
925 937
 						state=F_LF;
926 938
 						break;
927
-					case P_PROTO:
939
+					case FIN_UDP:
940
+						*tmp=0;
941
+						vb->transport.len=tmp-vb->transport.s;
942
+						vb->proto=PROTO_UDP;
943
+						state=F_LF;
944
+						saved_state=F_HOST; /* start looking for host*/
945
+						goto main_via;
946
+					case FIN_TCP:
928 947
 						*tmp=0;
929 948
 						vb->transport.len=tmp-vb->transport.s;
949
+						vb->proto=PROTO_TCP;
930 950
 						state=F_LF;
931 951
 						saved_state=F_HOST; /* start looking for host*/
932 952
 						goto main_via;
... ...
@@ -965,9 +985,17 @@ parse_again:
965 985
 						saved_state=state;
966 986
 						state=F_CR;
967 987
 						break;
968
-					case P_PROTO:
988
+					case FIN_UDP:
969 989
 						*tmp=0;
970 990
 						vb->transport.len=tmp-vb->transport.s;
991
+						vb->proto=PROTO_UDP;
992
+						state=F_CR;
993
+						saved_state=F_HOST;
994
+						goto main_via;
995
+					case FIN_TCP:
996
+						*tmp=0;
997
+						vb->transport.len=tmp-vb->transport.s;
998
+						vb->proto=PROTO_TCP;
971 999
 						state=F_CR;
972 1000
 						saved_state=F_HOST;
973 1001
 						goto main_via;
... ...
@@ -1027,13 +1055,6 @@ parse_again:
1027 1055
 						state=SIP1;
1028 1056
 						vb->name.s=tmp;
1029 1057
 						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 1058
 					default:
1038 1059
 						LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
1039 1060
 								" state %d\n", *tmp, state);
... ...
@@ -1046,13 +1067,6 @@ parse_again:
1046 1067
 					case SIP1:
1047 1068
 						state=SIP2;
1048 1069
 						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 1070
 					default:
1057 1071
 						LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
1058 1072
 								" state %d\n", *tmp, state);
... ...
@@ -1066,11 +1080,59 @@ parse_again:
1066 1080
 						state=FIN_SIP;
1067 1081
 						break;
1068 1082
 					/* allow p in PROTO */
1083
+					case UDP2:
1084
+						state=FIN_UDP;
1085
+						break;
1086
+					case TCP2:
1087
+						state=FIN_TCP;
1088
+						break;
1089
+					default:
1090
+						LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
1091
+								" state %d\n", *tmp, state);
1092
+						goto error;
1093
+				}
1094
+				break;
1095
+			case 'U':
1096
+			case 'u':
1097
+				switch(state){
1098
+					case F_PROTO:
1099
+						state=UDP1;
1100
+						break;
1101
+					default:
1102
+						LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
1103
+								" state %d\n", *tmp, state);
1104
+						goto error;
1105
+				}
1106
+				break;
1107
+			case 'D':
1108
+			case 'd':
1109
+				switch(state){
1110
+					case UDP1:
1111
+						state=UDP2;
1112
+						break;
1113
+					default:
1114
+						LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
1115
+								" state %d\n", *tmp, state);
1116
+						goto error;
1117
+				}
1118
+				break;
1119
+			case 'T':
1120
+			case 't':
1121
+				switch(state){
1069 1122
 					case F_PROTO:
1070
-						state=P_PROTO;
1071
-						vb->transport.s=tmp;
1123
+						state=TCP1;
1072 1124
 						break;
1073
-					case P_PROTO:
1125
+					default:
1126
+						LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
1127
+								" state %d\n", *tmp, state);
1128
+						goto error;
1129
+				}
1130
+				break;
1131
+			case 'C':
1132
+			case 'c':
1133
+				switch(state){
1134
+					case TCP1:
1135
+						state=TCP2;
1074 1136
 						break;
1075 1137
 					default:
1076 1138
 						LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
... ...
@@ -1085,13 +1147,6 @@ parse_again:
1085 1147
 						state=VER1;
1086 1148
 						vb->version.s=tmp;
1087 1149
 						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 1150
 					default:
1096 1151
 						LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
1097 1152
 								" state %d\n", *tmp, state);
... ...
@@ -1103,13 +1158,6 @@ parse_again:
1103 1158
 					case VER1:
1104 1159
 						state=VER2;
1105 1160
 						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 1161
 					default:
1114 1162
 						LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
1115 1163
 								" state %d\n", *tmp, state);
... ...
@@ -1121,13 +1169,6 @@ parse_again:
1121 1169
 					case VER2:
1122 1170
 						state=FIN_VER;
1123 1171
 						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 1172
 					default:
1132 1173
 						LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
1133 1174
 								" state %d\n", *tmp, state);
... ...
@@ -1136,18 +1177,9 @@ parse_again:
1136 1177
 				break;
1137 1178
 			
1138 1179
 			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 1180
 						LOG(L_ERR, "ERROR: parse_via: bad char <%c> on"
1148 1181
 								" state %d\n", *tmp, state);
1149 1182
 						goto error;
1150
-				}
1151 1183
 				break;
1152 1184
 		}
1153 1185
 	} /* 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 58
 	str name;
58 59
 	str version;   
59 60
 	str transport;
61
+	int proto; /* transport */
60 62
 	str host;
61 63
 	int port;
62 64
 	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 361
 				}
361 362
 				break;
362 363
 		case SRCIP_O:
363
-				ret=comp_ip(&msg->src_ip, e->r.param, e->op, e->subtype);
364
+				ret=comp_ip(&msg->rcv.src_ip, e->r.param, e->op, e->subtype);
364 365
 				break;
365 366
 		case DSTIP_O:
366
-				ret=comp_ip(&msg->dst_ip, e->r.param, e->op, e->subtype);
367
+				ret=comp_ip(&msg->rcv.dst_ip, e->r.param, e->op, e->subtype);
367 368
 				break;
368 369
 		case NUMBER_O:
369 370
 				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 @@
1
+/*
2
+ * $Id$
3
+ *
4
+ * Copyright (C) 2001-2003 Fhg Fokus
5
+ *
6
+ * This file is part of ser, a free SIP server.
7
+ *
8
+ * ser is free software; you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation; either version 2 of the License, or
11
+ * (at your option) any later version
12
+ *
13
+ * For a license to use the ser software under conditions
14
+ * other than those described here, or to purchase support for this
15
+ * software, please contact iptel.org by e-mail at the following addresses:
16
+ *    info@iptel.org
17
+ *
18
+ * ser is distributed in the hope that it will be useful,
19
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
20
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21
+ * GNU General Public License for more details.
22
+ *
23
+ * You should have received a copy of the GNU General Public License 
24
+ * along with this program; if not, write to the Free Software 
25
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26
+ */
27
+
28
+#ifndef tcp_init_h
29
+#define tcp_init_h
30
+#include "ip_addr.h"
31
+
32
+int init_tcp();
33
+int tcp_init(struct socket_info* sock_info);
34
+int tcp_init_children();
35
+void tcp_main_loop();
36
+void tcp_receive_loop(int unix_sock);
37
+
38
+
39
+#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 82
 
82 83
 
83 84
 
84
-struct tcp_connection* tcpconn_new(int sock, union sockaddr_union* su, int i)
85
+struct tcp_connection* tcpconn_new(int sock, union sockaddr_union* su,
86
+									struct socket_info* ba)
85 87
 {
86 88
 	struct tcp_connection *c;
87 89
 	
... ...
@@ -93,14 +95,22 @@ struct tcp_connection* tcpconn_new(int sock, union sockaddr_union* su, int i)
93 95
 	}
94 96
 	c->s=sock;
95 97
 	c->fd=sock;
96
-	c->su=*su;
97
-	c->sock_idx=i;
98
+	c->rcv.src_su=*su;
99
+	
98 100
 	c->refcnt=0;
99
-	su2ip_addr(&c->ip, su);
100
-	c->port=su_getport(su);
101
+	su2ip_addr(&c->rcv.src_ip, su);
102
+	c->rcv.src_port=su_getport(su);
103
+	c->rcv.proto=PROTO_TCP;
104
+	c->rcv.bind_address=ba;
105
+	if (ba){
106
+		c->rcv.dst_ip=ba->address;
107
+		c->rcv.dst_port=ba->port_no;
108
+	}
101 109
 	init_tcp_req(&c->req);
102 110
 	c->timeout=get_ticks()+TCP_CON_TIMEOUT;
103 111
 	c->id=connection_id++;
112
+	c->rcv.proto_reserved1=0; /* this will be filled before receive_message*/
113
+	c->rcv.proto_reserved2=0;
104 114
 	return c;
105 115
 	
106 116
 error:
... ...
@@ -157,14 +167,16 @@ struct tcp_connection* tcpconn_find(int id, struct ip_addr* ip, int port)
157 167
 
158 168
 	struct tcp_connection *c;
159 169
 	
160
-	DBG("tcpconn_find: %d ",id ); print_ip(ip); DBG(" %d\n", port);
170
+	DBG("tcpconn_find: %d ",id ); print_ip(ip); DBG(" %d\n", ntohs(port));
161 171
 	for (c=*conn_list; c; c=c->next){
162 172
 		DBG("c=%p, c->id=%d, ip=",c, c->id);
163
-		print_ip(&c->ip);
164
-		DBG(" port=%d\n", c->port);
173
+		print_ip(&c->rcv.src_ip);
174
+		DBG(" port=%d\n", ntohs(c->rcv.src_port));
165 175
 		if (id){
166 176
 			if (id==c->id) return c;
167
-		}else if ((port==c->port)&&(ip_addr_cmp(ip, &c->ip))) return c;
177
+		}else if (ip &&	(port==c->rcv.src_port)&&
178
+					(ip_addr_cmp(ip, &c->rcv.src_ip)))
179
+			return c;
168 180
 	}
169 181
 	return 0;
170 182
 }
... ...
@@ -199,17 +211,31 @@ int tcp_send(char* buf, unsigned len, union sockaddr_union* to, int id)
199 211
 	long response[2];
200 212
 	int n;
201 213
 	
202
-	su2ip_addr(&ip, to);
203
-	port=su_getport(to);
214
+	port=0;
215
+	if (to){
216
+		su2ip_addr(&ip, to);
217
+		port=su_getport(to);
218
+		c=tcpconn_get(id, &ip, port); /* lock ;inc refcnt; unlock */
219
+	}else if (id){
220
+		c=tcpconn_get(id, 0, 0);
221
+	}else{
222
+		LOG(L_CRIT, "BUG: tcp_send called with null id & to\n");
223
+		return -1;
224
+	}
204 225
 	
205
-	c=tcpconn_get(id, &ip, port); /* lock ;inc refcnt; unlock */
206 226
 	if (id){
207 227
 		if (c==0) {
208
-		LOG(L_ERR, "ERROR: tcp_send: id %d not found, dropping\n",
209
-					id);
210
-			return -1;
211
-		}
212
-	}else{
228
+			if (to){
229
+				c=tcpconn_get(0, &ip, port); /* try again w/o id */
230
+				goto no_id;
231
+			}else{
232
+				LOG(L_ERR, "ERROR: tcp_send: id %d not found, dropping\n",
233
+						id);
234
+				return -1;
235
+			}
236
+		}else goto get_fd;
237
+	}
238
+no_id:
213 239
 		if (c==0){
214 240
 			DBG("tcp_send: no open tcp connection found, opening new one\n");
215 241
 			/* create tcp connection */
... ...
@@ -224,18 +250,24 @@ int tcp_send(char* buf, unsigned len, union sockaddr_union* to, int id)
224 250
 			response[1]=CONN_NEW;
225 251
 			n=write(unix_tcp_sock, response, sizeof(response));
226 252
 			n=send_fd(unix_tcp_sock, &c, sizeof(c), c->s);
227
-		}else{
253
+			goto send_it;
254
+		}
255
+get_fd:
228 256
 			DBG("tcp_send: tcp connection found, acquiring fd\n");
229 257
 			/* get the fd */
230 258
 			response[0]=(long)c;
231 259
 			response[1]=CONN_GET_FD;
232 260
 			n=write(unix_tcp_sock, response, sizeof(response));
261
+			DBG("tcp_send, c= %p, n=%d\n", c, n);
233 262
 			n=receive_fd(unix_tcp_sock, &c, sizeof(c), &c->fd);
234
-		}
263
+			DBG("tcp_send: after receive_fd: c= %p n=%d fd=%d\n",c, n, c->fd);
264
+		
235 265
 	
236
-	}
266
+	
267
+send_it:
237 268
 	DBG("tcp_send: sending...\n");
238 269
 	n=write(c->fd, buf, len);
270
+	DBG("tcp_send: after write: c= %p n=%d fd=%d\n",c, n, c->fd);
239 271
 	close(c->fd);
240 272
 	tcpconn_put(c); /* release c (lock; dec refcnt; unlock) */
241 273
 	return n;
... ...
@@ -269,12 +301,12 @@ void tcpconn_timeout(fd_set* set)
269 301
 
270 302
 
271 303
 
272
-int tcp_init_sock(struct socket_info* sock_info)
304
+int tcp_init(struct socket_info* sock_info)
273 305
 {
274 306
 	union sockaddr_union* addr;
275 307
 	
276 308
 	addr=&sock_info->su;
277
-	sock_info->proto=SOCKET_TCP;
309
+	sock_info->proto=PROTO_TCP;
278 310
 	if (init_su(addr, &sock_info->address, htons(sock_info->port_no))<0){
279 311
 		LOG(L_ERR, "ERROR: tcp_init: could no init sockaddr_union\n");
280 312
 		goto error;
... ...
@@ -369,14 +401,14 @@ void tcp_main_loop()
369 401
 	FD_ZERO(&master_set);
370 402
 	/* set all the listen addresses */
371 403
 	for (r=0; r<sock_no; r++){
372
-		if ((tcp_info[r].proto==SOCKET_TCP) &&(tcp_info[r].socket!=-1)){
404
+		if ((tcp_info[r].proto==PROTO_TCP) &&(tcp_info[r].socket!=-1)){
373 405
 			FD_SET(tcp_info[r].socket, &master_set);
374 406
 			if (tcp_info[r].socket>maxfd) maxfd=tcp_info[r].socket;
375 407
 		}
376 408
 	}
377 409
 	/* set all the unix sockets used for child comm */
378
-	for (r=0; r<process_no; r++){
379
-		if (pt[r].unix_sock>=0){
410
+	for (r=1; r<process_no; r++){
411
+		if (pt[r].unix_sock>0){ /* we can't have 0, we never close it!*/
380 412
 			FD_SET(pt[r].unix_sock, &master_set);
381 413
 			if (pt[r].unix_sock>maxfd) maxfd=pt[r].unix_sock;
382 414
 		}
... ...
@@ -399,8 +431,7 @@ void tcp_main_loop()
399 431
 		}
400 432
 		
401 433
 		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))){
434
+			if ((FD_ISSET(tcp_info[r].socket, &sel_set))){
404 435
 				/* got a connection on r */
405 436
 				su_len=sizeof(su);
406 437
 				new_sock=accept(tcp_info[r].socket, &(su.s), &su_len);
... ...
@@ -412,7 +443,7 @@ void tcp_main_loop()
412 443
 				}
413 444
 				
414 445
 				/* add socket to list */
415
-				tcpconn=tcpconn_new(new_sock, &su, r);
446
+				tcpconn=tcpconn_new(new_sock, &su, &tcp_info[r]);
416 447
 				if (tcpconn){
417 448
 					tcpconn_add(tcpconn);
418 449
 					DBG("tcp_main_loop: new connection: %p %d\n",
... ...
@@ -449,7 +480,8 @@ void tcp_main_loop()
449 480
 		/* check unix sockets & listen | destroy connections */
450 481
 		/* start from 1, the "main" process does not transmit anything*/
451 482
 		for (r=1; r<process_no && n; r++){
452
-			if ( (pt[r].unix_sock>=0) && FD_ISSET(pt[r].unix_sock, &sel_set)){
483
+			if ( (pt[r].unix_sock>0) && FD_ISSET(pt[r].unix_sock, &sel_set)){
484
+				/* (we can't have a fd==0, 0 i s never closed )*/
453 485
 				n--;
454 486
 				/* errno==EINTR !!! TODO*/
455 487
 read_again:
... ...
@@ -560,7 +592,7 @@ int init_tcp()
560 592
 	/* allocate list head*/
561 593
 	conn_list=shm_malloc(sizeof(struct tcp_connection*));
562 594
 	if (conn_list==0){
563
-		LOG(L_CRIT, "ERROR: tcp_init: memory allocation failure\n");
595
+		LOG(L_CRIT, "ERROR: init_tcp: memory allocation failure\n");
564 596
 		goto error;
565 597
 	}
566 598
 	*conn_list=0;
... ...
@@ -580,11 +612,7 @@ int tcp_init_children()
580 612
 	
581 613
 	
582 614
 	/* 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
-	}
615
+	/* copy the sockets --moved to main_loop*/
588 616
 	
589 617
 	/* fork children & create the socket pairs*/
590 618
 	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 279
 
279 280
 	union sockaddr_union* from;
280 281
 	unsigned int fromlen;
282
+	struct receive_info ri;
281 283
 
282 284
 
283 285
 	from=(union sockaddr_union*) malloc(sizeof(union sockaddr_union));
... ...
@@ -286,7 +288,11 @@ int udp_rcv_loop()
286 288
 		goto error;
287 289
 	}
288 290
 	memset(from, 0 , sizeof(union sockaddr_union));
289
-
291
+	ri.bind_address=bind_address; /* this will not change, we do it only once*/
292
+	ri.dst_port=bind_address->port_no;
293
+	ri.dst_ip=bind_address->address;
294
+	ri.proto=PROTO_UDP;
295
+	ri.proto_reserved1=ri.proto_reserved2=0;
290 296
 	for(;;){
291 297
 #ifdef DYN_BUF
292 298
 		buf=pkg_malloc(BUF_SIZE+1);
... ...
@@ -327,9 +333,13 @@ int udp_rcv_loop()
327 333
 			continue;
328 334
 		}
329 335
 #endif
336
+		ri.src_su=*from;
337
+		su2ip_addr(&ri.src_ip, from);
338
+		ri.src_port=su_getport(from);
339
+		
330 340