Browse code

cross-transport introduced to TM

Jiri Kuthan authored on 14/04/2003 02:01:06
Showing 9 changed files
... ...
@@ -107,6 +107,7 @@ tm module:
107 107
 - if you wish to do forward to another destination from 
108 108
   failure_route (reply_route formerly), you need to call t_relay
109 109
   or t_relay_to explicitely now
110
+- t_relay_to has been replaced with t_relay_to_udp and t_relay_to_tcp
110 111
 
111 112
 List of new modules:
112 113
 --------------------
... ...
@@ -35,6 +35,7 @@
35 35
  *  2003-03-13  send_pr_buffer is called w/ file/function/line debugging
36 36
  *  2003-03-01  start_retr changed to retransmit only for UDP
37 37
  *  2003-02-13  modified send_pr_buffer to use msg_send & rb->dst (andrei)
38
+ *  2003-04-14  use protocol from uri (jiri)
38 39
  */
39 40
 
40 41
 
... ...
@@ -234,7 +235,7 @@ int t_relay_to( struct sip_msg  *p_msg , struct proxy_l *proxy, int proto,
234 234
 					ret=E_BAD_ADDRESS;
235 235
 					goto done;
236 236
 			}
237
-			ret=forward_request( p_msg , proxy, proto) ;
237
+			ret=forward_request( p_msg , proxy, proxy->proto) ;
238 238
 			free_proxy( proxy );	
239 239
 			pkg_free( proxy );
240 240
 #ifdef ACK_FORKING_HACK
... ...
@@ -244,7 +245,7 @@ int t_relay_to( struct sip_msg  *p_msg , struct proxy_l *proxy, int proto,
244 244
 				p_msg->new_uri=ack_uri;
245 245
 				proxy=uri2proxy(&GET_NEXT_HOP(p_msg), proto);
246 246
 				if (proxy==0) continue;
247
-				forward_request(p_msg, proxy, proto);
247
+				forward_request(p_msg, proxy, proto->proto);
248 248
 				free_proxy( proxy );	
249 249
 				pkg_free( proxy );
250 250
 			}
... ...
@@ -28,16 +28,17 @@
28 28
 /*
29 29
  * History:
30 30
  * -------
31
- *  2003-03-30  we now watch downstream delivery and if it fails, send an
32
- *              error message upstream (jiri)
33
- *  2003-03-19  replaced all the mallocs/frees w/ pkg_malloc/pkg_free (andrei)
31
+ *  2003-02-13  proto support added (andrei)
32
+ *  2003-02-24  s/T_NULL/T_NULL_CELL/ to avoid redefinition conflict w/
33
+ *              nameser_compat.h (andrei)
34
+ *  2003-03-01  kr set through a function now (jiri)
34 35
  *  2003-03-06  callbacks renamed; "blind UAC" introduced, which makes
35 36
  *              transaction behave as if it was forwarded even if it was
36 37
  *              not -- good for local UAS, like VM (jiri)
37
- *  2003-03-01  kr set through a function now (jiri)
38
- *  2003-02-24  s/T_NULL/T_NULL_CELL/ to avoid redefinition conflict w/
39
- *              nameser_compat.h (andrei)
40
- *  2003-02-13  proto support added (andrei)
38
+ *  2003-03-19  replaced all the mallocs/frees w/ pkg_malloc/pkg_free (andrei)
39
+ *  2003-03-30  we now watch downstream delivery and if it fails, send an
40
+ *              error message upstream (jiri)
41
+ *  2003-04-14  use protocol from uri (jiri)
41 42
  */
42 43
 
43 44
 #include "defs.h"
... ...
@@ -64,7 +65,8 @@
64 64
 
65 65
 
66 66
 char *print_uac_request( struct cell *t, struct sip_msg *i_req,
67
-	int branch, str *uri, unsigned int *len, struct socket_info *send_sock )
67
+	int branch, str *uri, unsigned int *len, struct socket_info *send_sock,
68
+	enum sip_protos proto )
68 69
 {
69 70
 	char *buf, *shbuf;
70 71
 
... ...
@@ -85,7 +87,7 @@ char *print_uac_request( struct cell *t, struct sip_msg *i_req,
85 85
 	callback_event( TMCB_REQUEST_FWDED, t, i_req, -i_req->REQ_METHOD);
86 86
 
87 87
 	/* ... and build it now */
88
-	buf=build_req_buf_from_sip_req( i_req, len, send_sock, i_req->rcv.proto );
88
+	buf=build_req_buf_from_sip_req( i_req, len, send_sock, proto );
89 89
 #ifdef DBG_MSG_QA
90 90
 	if (buf[*len-1]==0) {
91 91
 		LOG(L_ERR, "ERROR: print_uac_request: sanity check failed\n");
... ...
@@ -206,7 +208,7 @@ int add_uac( struct cell *t, struct sip_msg *request, str *uri, str* next_hop,
206 206
 	hostent2su( &to, &proxy->host, proxy->addr_idx, 
207 207
 		proxy->port ? proxy->port:SIP_PORT);
208 208
 
209
-	send_sock=get_send_socket( &to , proto);
209
+	send_sock=get_send_socket( &to , proxy->proto);
210 210
 	if (send_sock==0) {
211 211
 		LOG(L_ERR, "ERROR: add_uac: can't fwd to af %d "
212 212
 			" (no corresponding listening socket)\n",
... ...
@@ -217,7 +219,7 @@ int add_uac( struct cell *t, struct sip_msg *request, str *uri, str* next_hop,
217 217
 
218 218
 	/* now message printing starts ... */
219 219
 	shbuf=print_uac_request( t, request, branch, uri, 
220
-		&len, send_sock );
220
+		&len, send_sock, proxy->proto);
221 221
 	if (!shbuf) {
222 222
 		ret=ser_error=E_OUT_OF_MEM;
223 223
 		goto error01;
... ...
@@ -226,7 +228,7 @@ int add_uac( struct cell *t, struct sip_msg *request, str *uri, str* next_hop,
226 226
 	/* things went well, move ahead and install new buffer! */
227 227
 	t->uac[branch].request.dst.to=to;
228 228
 	t->uac[branch].request.dst.send_sock=send_sock;
229
-	t->uac[branch].request.dst.proto=proto;
229
+	t->uac[branch].request.dst.proto=proxy->proto;
230 230
 	t->uac[branch].request.dst.proto_reserved1=0;
231 231
 	t->uac[branch].request.buffer=shbuf;
232 232
 	t->uac[branch].request.buffer_len=len;
... ...
@@ -271,7 +273,8 @@ int e2e_cancel_branch( struct sip_msg *cancel_msg, struct cell *t_cancel,
271 271
 	/* print */
272 272
 	shbuf=print_uac_request( t_cancel, cancel_msg, branch, 
273 273
 		&t_invite->uac[branch].uri, &len, 
274
-		t_invite->uac[branch].request.dst.send_sock);
274
+		t_invite->uac[branch].request.dst.send_sock,
275
+		t_invite->uac[branch].request.dst.proto);
275 276
 	if (!shbuf) {
276 277
 		LOG(L_ERR, "ERROR: e2e_cancel_branch: printing e2e cancel failed\n");
277 278
 		ret=ser_error=E_OUT_OF_MEM;
... ...
@@ -44,7 +44,8 @@ typedef int (*taddblind_f)( /*struct cell *t */ );
44 44
 
45 45
 int t_replicate(struct sip_msg *p_msg, struct proxy_l * proxy, int proto);
46 46
 char *print_uac_request( struct cell *t, struct sip_msg *i_req,
47
-    int branch, str *uri, unsigned int *len, struct socket_info *send_sock );
47
+    int branch, str *uri, unsigned int *len, struct socket_info *send_sock,
48
+	enum sip_protos proto);
48 49
 void e2e_cancel( struct sip_msg *cancel_msg, struct cell *t_cancel, struct cell *t_invite );
49 50
 int e2e_cancel_branch( struct sip_msg *cancel_msg, struct cell *t_cancel, struct cell *t_invite, int branch );
50 51
 int add_uac(	struct cell *t, struct sip_msg *request, str *uri, str* next_hop,
... ...
@@ -42,6 +42,9 @@
42 42
  *  2003-03-31  200 for INVITE/UAS resent even for UDP (jiri)
43 43
  *  2003-03-31  removed msg->repl_add_rm (andrei)
44 44
  *  2003-04-05  s/reply_route/failure_route, onreply_route introduced (jiri)
45
+ *  2003-04-14  local acks generated before reply processing to avoid
46
+ *              delays in length reply processing (like opening TCP
47
+ *              connnection to an unavailable destination) (jiri)
45 48
  */
46 49
 
47 50
 
... ...
@@ -1093,6 +1096,17 @@ int reply_received( struct sip_msg  *p_msg )
1093 1093
 	/* stop final response timer only if I got a final response */
1094 1094
 	if ( msg_status >= 200 )
1095 1095
 		reset_timer( &uac->request.fr_timer);
1096
+	/* acknowledge negative INVITE replies (do it before detailed
1097
+	   on_reply processing, which may take very long, like if it
1098
+	   is attempted to establish a TCP connection to a fail-over dst
1099
+	*/
1100
+	if (t->is_invite && (msg_status>=300 || (t->local && msg_status>=200))) {
1101
+		ack = build_ack( p_msg, t, branch , &ack_len);
1102
+		if (ack) {
1103
+			SEND_PR_BUFFER( &uac->request, ack, ack_len );
1104
+			shm_free(ack);
1105
+		}
1106
+	} /* ack-ing negative INVITE replies */
1096 1107
 
1097 1108
 	/* processing of on_reply block */
1098 1109
 	if (t->on_reply) {
... ...
@@ -1101,6 +1115,7 @@ int reply_received( struct sip_msg  *p_msg )
1101 1101
 			LOG(L_ERR, "ERROR: on_reply processing failed\n");
1102 1102
 	}
1103 1103
 
1104
+
1104 1105
 	LOCK_REPLIES( t );
1105 1106
 	if (t->local) {
1106 1107
 		reply_status=local_reply( t, p_msg, branch, msg_status, &cancel_bitmap );
... ...
@@ -1112,14 +1127,6 @@ int reply_received( struct sip_msg  *p_msg )
1112 1112
 	if (reply_status==RPS_ERROR)
1113 1113
 		goto done;
1114 1114
 
1115
-	/* acknowledge negative INVITE replies */	
1116
-	if (t->is_invite && (msg_status>=300 || (t->local && msg_status>=200))) {
1117
-		ack = build_ack( p_msg, t, branch , &ack_len);
1118
-		if (ack) {
1119
-			SEND_PR_BUFFER( &uac->request, ack, ack_len );
1120
-			shm_free(ack);
1121
-		}
1122
-	} /* ack-ing negative INVITE replies */
1123 1115
 
1124 1116
 	/* clean-up the transaction when transaction completed */
1125 1117
 	if (reply_status==RPS_COMPLETED) {
... ...
@@ -63,6 +63,7 @@
63 63
  *  2003-03-19  replaced all mallocs/frees w/ pkg_malloc/pkg_free (andrei)
64 64
  *  2003-03-30  set_kr for requests only (jiri)
65 65
  *  2003-04-05  s/reply_route/failure_route, onreply_route introduced (jiri)
66
+ *  2003-04-14  use protocol from uri (jiri)
66 67
  */
67 68
 
68 69
 
... ...
@@ -105,9 +106,6 @@ inline static int w_t_retransmit_reply(struct sip_msg* p_msg, char* foo, char* b
105 105
 inline static int w_t_newtran(struct sip_msg* p_msg, char* foo, char* bar );
106 106
 inline static int w_t_newdlg( struct sip_msg* p_msg, char* foo, char* bar );
107 107
 inline static int w_t_relay( struct sip_msg  *p_msg , char *_foo, char *_bar);
108
-inline static int w_t_relay_udp( struct sip_msg  *p_msg,char *_foo,char *_bar);
109
-inline static int w_t_relay_tcp( struct sip_msg  *p_msg,char *_foo,char *_bar);
110
-inline static int w_t_relay_to( struct sip_msg  *p_msg , char *proxy, char *);
111 108
 inline static int w_t_relay_to_udp( struct sip_msg  *p_msg , char *proxy, 
112 109
 									char *);
113 110
 inline static int w_t_relay_to_tcp( struct sip_msg  *p_msg , char *proxy,
... ...
@@ -141,17 +139,13 @@ static cmd_export_t cmds[]={
141 141
 			REQUEST_ROUTE | FAILURE_ROUTE },
142 142
 	{"t_retransmit_reply", w_t_retransmit_reply,    0, 0,                    REQUEST_ROUTE},
143 143
 	{"t_release",          w_t_release,             0, 0,                    REQUEST_ROUTE},
144
-	{T_RELAY_TO,           w_t_relay_to,            2, fixup_hostport2proxy, 
145
-			REQUEST_ROUTE | FAILURE_ROUTE },
146
-	{T_RELAY_TO_UDP,       w_t_relay_to_udp,        2, fixup_hostport2proxy, REQUEST_ROUTE},
147
-	{T_RELAY_TO_TCP,       w_t_relay_to_tcp,        2, fixup_hostport2proxy, REQUEST_ROUTE},
144
+	{T_RELAY_TO_UDP,       w_t_relay_to_udp,        2, fixup_hostport2proxy, REQUEST_ROUTE|FAILURE_ROUTE},
145
+	{T_RELAY_TO_TCP,       w_t_relay_to_tcp,        2, fixup_hostport2proxy, REQUEST_ROUTE|FAILURE_ROUTE},
148 146
 	{"t_replicate",        w_t_replicate,           2, fixup_hostport2proxy, REQUEST_ROUTE},
149 147
 	{"t_replicate_udp",    w_t_replicate_udp,       2, fixup_hostport2proxy, REQUEST_ROUTE},
150 148
 	{"t_replicate_tcp",    w_t_replicate_tcp,       2, fixup_hostport2proxy, REQUEST_ROUTE},
151 149
 	{T_RELAY,              w_t_relay,               0, 0,                    
152 150
 			REQUEST_ROUTE | FAILURE_ROUTE },
153
-	{T_RELAY_UDP,          w_t_relay_udp,           0, 0,                    REQUEST_ROUTE},
154
-	{T_RELAY_TCP,          w_t_relay_tcp,           0, 0,                    REQUEST_ROUTE},
155 151
 	{T_FORWARD_NONACK,     w_t_forward_nonack,      2, fixup_hostport2proxy, REQUEST_ROUTE},
156 152
 	{T_FORWARD_NONACK_UDP, w_t_forward_nonack_udp,  2, fixup_hostport2proxy, REQUEST_ROUTE},
157 153
 	{T_FORWARD_NONACK_TCP, w_t_forward_nonack_tcp,  2, fixup_hostport2proxy, REQUEST_ROUTE},
... ...
@@ -431,7 +425,7 @@ inline static int _w_t_forward_nonack(struct sip_msg* msg, char* proxy,
431 431
 inline static int w_t_forward_nonack( struct sip_msg* msg, char* proxy,
432 432
 										char* foo)
433 433
 {
434
-	return _w_t_forward_nonack(msg, proxy, foo, msg->rcv.proto);
434
+	return _w_t_forward_nonack(msg, proxy, foo, PROTO_NONE);
435 435
 }
436 436
 
437 437
 inline static int w_t_forward_nonack_udp( struct sip_msg* msg, char* proxy,
... ...
@@ -574,9 +568,8 @@ inline static int w_t_on_reply( struct sip_msg* msg, char *go_to, char *foo )
574 574
 	return -1;
575 575
 }
576 576
 
577
-inline static int w_t_relay_to( struct sip_msg  *p_msg , 
578
-	char *proxy, /* struct proxy_l *proxy expected */
579
-	char *_foo       /* nothing expected */ )
577
+inline static int _w_t_relay_to( struct sip_msg  *p_msg , 
578
+	struct proxy_l *proxy )
580 579
 {
581 580
 	struct cell *t;
582 581
 
... ...
@@ -586,15 +579,14 @@ inline static int w_t_relay_to( struct sip_msg  *p_msg ,
586 586
 			LOG(L_CRIT, "BUG: w_t_relay_to: undefined T\n");
587 587
 			return -1;
588 588
 		}
589
-		if (t_forward_nonack(t, p_msg, 
590
-				( struct proxy_l *) proxy, p_msg->rcv.proto)<=0 ) {
589
+		if (t_forward_nonack(t, p_msg, proxy, PROTO_NONE)<=0 ) {
591 590
 			LOG(L_ERR, "ERROR: failure_route: t_relay_to failed\n");
592 591
 			return -1;
593 592
 		}
594 593
 		return 1;
595 594
 	}
596 595
 	if (rmode==MODE_REQUEST) 
597
-		return t_relay_to( p_msg, ( struct proxy_l *) proxy, p_msg->rcv.proto,
596
+		return t_relay_to( p_msg, proxy, PROTO_NONE,
598 597
 			0 /* no replication */ );
599 598
 	LOG(L_CRIT, "ERROR: w_t_relay_to: unsupported mode: %d\n", rmode);
600 599
 	return 0;
... ...
@@ -604,16 +596,16 @@ inline static int w_t_relay_to_udp( struct sip_msg  *p_msg ,
604 604
 	char *proxy, /* struct proxy_l *proxy expected */
605 605
 	char *_foo       /* nothing expected */ )
606 606
 {
607
-	return t_relay_to( p_msg, ( struct proxy_l *) proxy, PROTO_UDP,
608
-	0 /* no replication */ );
607
+	((struct proxy_l *)proxy)->proto=PROTO_UDP;
608
+	return _w_t_relay_to( p_msg, ( struct proxy_l *) proxy);
609 609
 }
610 610
 
611 611
 inline static int w_t_relay_to_tcp( struct sip_msg  *p_msg , 
612 612
 	char *proxy, /* struct proxy_l *proxy expected */
613 613
 	char *_foo       /* nothing expected */ )
614 614
 {
615
-	return t_relay_to( p_msg, ( struct proxy_l *) proxy, PROTO_TCP,
616
-	0 /* no replication */ );
615
+	((struct proxy_l *)proxy)->proto=PROTO_TCP;
616
+	return _w_t_relay_to( p_msg, ( struct proxy_l *) proxy);
617 617
 }
618 618
 
619 619
 
... ...
@@ -652,7 +644,7 @@ inline static int w_t_relay( struct sip_msg  *p_msg ,
652 652
 			LOG(L_CRIT, "BUG: w_t_relay: undefined T\n");
653 653
 			return -1;
654 654
 		} 
655
-		if (t_forward_nonack(t, p_msg, ( struct proxy_l *) 0, p_msg->rcv.proto)<=0) {
655
+		if (t_forward_nonack(t, p_msg, ( struct proxy_l *) 0, PROTO_NONE)<=0) {
656 656
 			LOG(L_ERR, "ERROR: w_t_relay (failure mode): forwarding failed\n");
657 657
 			return -1;
658 658
 		}
... ...
@@ -660,7 +652,7 @@ inline static int w_t_relay( struct sip_msg  *p_msg ,
660 660
 	}
661 661
 	if (rmode==MODE_REQUEST) 
662 662
 		return t_relay_to( p_msg, 
663
-		(struct proxy_l *) 0 /* no proxy */, p_msg->rcv.proto,
663
+		(struct proxy_l *) 0 /* no proxy */, PROTO_NONE,
664 664
 		0 /* no replication */ );
665 665
 	LOG(L_CRIT, "ERROR: w_t_relay_to: unsupported mode: %d\n", rmode);
666 666
 	return 0;
... ...
@@ -26,7 +26,8 @@
26 26
  *
27 27
  * History:
28 28
  * --------
29
- * 2003-03-06  voicemail changes accepted
29
+ * 2003-03-06  voicemail changes accepted (jiri)
30
+ * 2003-04-14  t_relay_to split in udp and tcp (jiri)
30 31
  */
31 32
 
32 33
 #include "defs.h"
... ...
@@ -45,8 +46,12 @@ int load_tm( struct tm_binds *tmb)
45 45
 		return -1;
46 46
 	}
47 47
 
48
-	if (!( tmb->t_relay_to=find_export(T_RELAY_TO, 2, 0)) ) {
49
-		LOG(L_ERR, LOAD_ERROR "'t_relay_to' not found\n");
48
+	if (!( tmb->t_relay_to_tcp=find_export(T_RELAY_TO_TCP, 2, 0)) ) {
49
+		LOG(L_ERR, LOAD_ERROR "'t_relay_to_tcp' not found\n");
50
+		return -1;
51
+	}
52
+	if (!( tmb->t_relay_to_udp=find_export(T_RELAY_TO_UDP, 2, 0)) ) {
53
+		LOG(L_ERR, LOAD_ERROR "'t_relay_to_udp' not found\n");
50 54
 		return -1;
51 55
 	}
52 56
 	if (!( tmb->t_relay=find_export(T_RELAY, 0, 0)) ) {
... ...
@@ -71,7 +71,8 @@
71 71
 
72 72
 struct tm_binds {
73 73
 	register_tmcb_f	register_tmcb;
74
-	cmd_function	t_relay_to;
74
+	cmd_function	t_relay_to_udp;
75
+	cmd_function	t_relay_to_tcp;
75 76
 	cmd_function 	t_relay;
76 77
 	tuacdlg_f		t_uac_dlg;
77 78
 	treply_f		t_reply;
... ...
@@ -31,6 +31,8 @@
31 31
  * History:
32 32
  * -------
33 33
  *  2003-02-13  added proto to uri2proxy (andrei)
34
+ *  2003-04-14  added get_proto to determine protocol from uri unless
35
+ *              specified explicitely (jiri)
34 36
 */
35 37
 
36 38
 
... ...
@@ -38,6 +40,7 @@
38 38
 #define _TM_UT_H
39 39
 
40 40
 #include "defs.h"
41
+#include "../../ip_addr.h"
41 42
 
42 43
 
43 44
 #include "../../dprint.h"
... ...
@@ -46,12 +49,45 @@
46 46
 #include "../../str.h"
47 47
 #include "../../parser/msg_parser.h"
48 48
 
49
+
50
+inline static enum sip_protos get_proto(enum sip_protos force_proto,
51
+	struct sip_uri *u)
52
+{
53
+	/* calculate transport protocol */
54
+	switch(force_proto) {
55
+		case PROTO_NONE: 	/* no protocol has been forced -- look at uri */
56
+			switch(u->proto) {
57
+				case PROTO_NONE: /* uri default to UDP */
58
+					return PROTO_UDP;
59
+				case PROTO_UDP: /* transport specified explicitely */
60
+#ifdef USE_TCP
61
+				case PROTO_TCP:
62
+#endif
63
+					return u->proto;
64
+				default:
65
+					LOG(L_ERR, "ERROR: get_proto: unsupported transport: %d\n",
66
+						u->proto );
67
+					return PROTO_NONE;
68
+			}
69
+		case PROTO_UDP: /* some protocol has been forced -- take it */
70
+#ifdef USE_TCP
71
+		case PROTO_TCP:
72
+#endif
73
+			return force_proto;
74
+		default:
75
+			LOG(L_ERR, "ERROR: get_proto: unsupported forced protocol: "
76
+				"%d\n", force_proto);
77
+			return PROTO_NONE;
78
+	}
79
+}
80
+
49 81
 inline static struct proxy_l *uri2proxy( str *uri, int proto )
50 82
 {
51 83
 	struct sip_uri parsed_uri;
52 84
 	unsigned int  port; 
53 85
 	struct proxy_l *p;
54 86
 	int err;
87
+	enum sip_protos out_proto;
55 88
 
56 89
 	if (parse_uri(uri->s, uri->len, &parsed_uri)<0) {
57 90
 		LOG(L_ERR, "ERROR: t_relay: bad_uri: %.*s\n",
... ...
@@ -68,7 +104,15 @@ inline static struct proxy_l *uri2proxy( str *uri, int proto )
68 68
 	/* fixed use of SRV resolver
69 69
 	} else port=SIP_PORT; */
70 70
 	} else port=0;
71
-	p=mk_proxy(&(parsed_uri.host), port, proto);
71
+
72
+	out_proto=get_proto(proto,&parsed_uri);
73
+	if (out_proto==PROTO_NONE) {
74
+		LOG(L_ERR, "ERROR: uri2proxy: transport can't be determined "
75
+			"for URI <%.*s>\n", uri->len, uri->s );
76
+		return 0;
77
+	}
78
+
79
+	p=mk_proxy(&(parsed_uri.host), port, out_proto);
72 80
 	if (p==0) {
73 81
 		LOG(L_ERR, "ERROR: t_relay: bad host name in URI <%.*s>\n",
74 82
 			uri->len, uri->s);