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 235
 					ret=E_BAD_ADDRESS;
235 236
 					goto done;
236 237
 			}
237
-			ret=forward_request( p_msg , proxy, proto) ;
238
+			ret=forward_request( p_msg , proxy, proxy->proto) ;
238 239
 			free_proxy( proxy );	
239 240
 			pkg_free( proxy );
240 241
 #ifdef ACK_FORKING_HACK
... ...
@@ -244,7 +245,7 @@ int t_relay_to( struct sip_msg  *p_msg , struct proxy_l *proxy, int proto,
244 245
 				p_msg->new_uri=ack_uri;
245 246
 				proxy=uri2proxy(&GET_NEXT_HOP(p_msg), proto);
246 247
 				if (proxy==0) continue;
247
-				forward_request(p_msg, proxy, proto);
248
+				forward_request(p_msg, proxy, proto->proto);
248 249
 				free_proxy( proxy );	
249 250
 				pkg_free( proxy );
250 251
 			}
... ...
@@ -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 65
 
65 66
 
66 67
 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 )
68
+	int branch, str *uri, unsigned int *len, struct socket_info *send_sock,
69
+	enum sip_protos proto )
68 70
 {
69 71
 	char *buf, *shbuf;
70 72
 
... ...
@@ -85,7 +87,7 @@ char *print_uac_request( struct cell *t, struct sip_msg *i_req,
85 87
 	callback_event( TMCB_REQUEST_FWDED, t, i_req, -i_req->REQ_METHOD);
86 88
 
87 89
 	/* ... and build it now */
88
-	buf=build_req_buf_from_sip_req( i_req, len, send_sock, i_req->rcv.proto );
90
+	buf=build_req_buf_from_sip_req( i_req, len, send_sock, proto );
89 91
 #ifdef DBG_MSG_QA
90 92
 	if (buf[*len-1]==0) {
91 93
 		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 208
 	hostent2su( &to, &proxy->host, proxy->addr_idx, 
207 209
 		proxy->port ? proxy->port:SIP_PORT);
208 210
 
209
-	send_sock=get_send_socket( &to , proto);
211
+	send_sock=get_send_socket( &to , proxy->proto);
210 212
 	if (send_sock==0) {
211 213
 		LOG(L_ERR, "ERROR: add_uac: can't fwd to af %d "
212 214
 			" (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 219
 
218 220
 	/* now message printing starts ... */
219 221
 	shbuf=print_uac_request( t, request, branch, uri, 
220
-		&len, send_sock );
222
+		&len, send_sock, proxy->proto);
221 223
 	if (!shbuf) {
222 224
 		ret=ser_error=E_OUT_OF_MEM;
223 225
 		goto error01;
... ...
@@ -226,7 +228,7 @@ int add_uac( struct cell *t, struct sip_msg *request, str *uri, str* next_hop,
226 228
 	/* things went well, move ahead and install new buffer! */
227 229
 	t->uac[branch].request.dst.to=to;
228 230
 	t->uac[branch].request.dst.send_sock=send_sock;
229
-	t->uac[branch].request.dst.proto=proto;
231
+	t->uac[branch].request.dst.proto=proxy->proto;
230 232
 	t->uac[branch].request.dst.proto_reserved1=0;
231 233
 	t->uac[branch].request.buffer=shbuf;
232 234
 	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 273
 	/* print */
272 274
 	shbuf=print_uac_request( t_cancel, cancel_msg, branch, 
273 275
 		&t_invite->uac[branch].uri, &len, 
274
-		t_invite->uac[branch].request.dst.send_sock);
276
+		t_invite->uac[branch].request.dst.send_sock,
277
+		t_invite->uac[branch].request.dst.proto);
275 278
 	if (!shbuf) {
276 279
 		LOG(L_ERR, "ERROR: e2e_cancel_branch: printing e2e cancel failed\n");
277 280
 		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 1096
 	/* stop final response timer only if I got a final response */
1094 1097
 	if ( msg_status >= 200 )
1095 1098
 		reset_timer( &uac->request.fr_timer);
1099
+	/* acknowledge negative INVITE replies (do it before detailed
1100
+	   on_reply processing, which may take very long, like if it
1101
+	   is attempted to establish a TCP connection to a fail-over dst
1102
+	*/
1103
+	if (t->is_invite && (msg_status>=300 || (t->local && msg_status>=200))) {
1104
+		ack = build_ack( p_msg, t, branch , &ack_len);
1105
+		if (ack) {
1106
+			SEND_PR_BUFFER( &uac->request, ack, ack_len );
1107
+			shm_free(ack);
1108
+		}
1109
+	} /* ack-ing negative INVITE replies */
1096 1110
 
1097 1111
 	/* processing of on_reply block */
1098 1112
 	if (t->on_reply) {
... ...
@@ -1101,6 +1115,7 @@ int reply_received( struct sip_msg  *p_msg )
1101 1115
 			LOG(L_ERR, "ERROR: on_reply processing failed\n");
1102 1116
 	}
1103 1117
 
1118
+
1104 1119
 	LOCK_REPLIES( t );
1105 1120
 	if (t->local) {
1106 1121
 		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 1127
 	if (reply_status==RPS_ERROR)
1113 1128
 		goto done;
1114 1129
 
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 1130
 
1124 1131
 	/* clean-up the transaction when transaction completed */
1125 1132
 	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 106
 inline static int w_t_newtran(struct sip_msg* p_msg, char* foo, char* bar );
106 107
 inline static int w_t_newdlg( struct sip_msg* p_msg, char* foo, char* bar );
107 108
 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 109
 inline static int w_t_relay_to_udp( struct sip_msg  *p_msg , char *proxy, 
112 110
 									char *);
113 111
 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 139
 			REQUEST_ROUTE | FAILURE_ROUTE },
142 140
 	{"t_retransmit_reply", w_t_retransmit_reply,    0, 0,                    REQUEST_ROUTE},
143 141
 	{"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},
142
+	{T_RELAY_TO_UDP,       w_t_relay_to_udp,        2, fixup_hostport2proxy, REQUEST_ROUTE|FAILURE_ROUTE},
143
+	{T_RELAY_TO_TCP,       w_t_relay_to_tcp,        2, fixup_hostport2proxy, REQUEST_ROUTE|FAILURE_ROUTE},
148 144
 	{"t_replicate",        w_t_replicate,           2, fixup_hostport2proxy, REQUEST_ROUTE},
149 145
 	{"t_replicate_udp",    w_t_replicate_udp,       2, fixup_hostport2proxy, REQUEST_ROUTE},
150 146
 	{"t_replicate_tcp",    w_t_replicate_tcp,       2, fixup_hostport2proxy, REQUEST_ROUTE},
151 147
 	{T_RELAY,              w_t_relay,               0, 0,                    
152 148
 			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 149
 	{T_FORWARD_NONACK,     w_t_forward_nonack,      2, fixup_hostport2proxy, REQUEST_ROUTE},
156 150
 	{T_FORWARD_NONACK_UDP, w_t_forward_nonack_udp,  2, fixup_hostport2proxy, REQUEST_ROUTE},
157 151
 	{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 425
 inline static int w_t_forward_nonack( struct sip_msg* msg, char* proxy,
432 426
 										char* foo)
433 427
 {
434
-	return _w_t_forward_nonack(msg, proxy, foo, msg->rcv.proto);
428
+	return _w_t_forward_nonack(msg, proxy, foo, PROTO_NONE);
435 429
 }
436 430
 
437 431
 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 568
 	return -1;
575 569
 }
576 570
 
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 */ )
571
+inline static int _w_t_relay_to( struct sip_msg  *p_msg , 
572
+	struct proxy_l *proxy )
580 573
 {
581 574
 	struct cell *t;
582 575
 
... ...
@@ -586,15 +579,14 @@ inline static int w_t_relay_to( struct sip_msg  *p_msg ,
586 579
 			LOG(L_CRIT, "BUG: w_t_relay_to: undefined T\n");
587 580
 			return -1;
588 581
 		}
589
-		if (t_forward_nonack(t, p_msg, 
590
-				( struct proxy_l *) proxy, p_msg->rcv.proto)<=0 ) {
582
+		if (t_forward_nonack(t, p_msg, proxy, PROTO_NONE)<=0 ) {
591 583
 			LOG(L_ERR, "ERROR: failure_route: t_relay_to failed\n");
592 584
 			return -1;
593 585
 		}
594 586
 		return 1;
595 587
 	}
596 588
 	if (rmode==MODE_REQUEST) 
597
-		return t_relay_to( p_msg, ( struct proxy_l *) proxy, p_msg->rcv.proto,
589
+		return t_relay_to( p_msg, proxy, PROTO_NONE,
598 590
 			0 /* no replication */ );
599 591
 	LOG(L_CRIT, "ERROR: w_t_relay_to: unsupported mode: %d\n", rmode);
600 592
 	return 0;
... ...
@@ -604,16 +596,16 @@ inline static int w_t_relay_to_udp( struct sip_msg  *p_msg ,
604 596
 	char *proxy, /* struct proxy_l *proxy expected */
605 597
 	char *_foo       /* nothing expected */ )
606 598
 {
607
-	return t_relay_to( p_msg, ( struct proxy_l *) proxy, PROTO_UDP,
608
-	0 /* no replication */ );
599
+	((struct proxy_l *)proxy)->proto=PROTO_UDP;
600
+	return _w_t_relay_to( p_msg, ( struct proxy_l *) proxy);
609 601
 }
610 602
 
611 603
 inline static int w_t_relay_to_tcp( struct sip_msg  *p_msg , 
612 604
 	char *proxy, /* struct proxy_l *proxy expected */
613 605
 	char *_foo       /* nothing expected */ )
614 606
 {
615
-	return t_relay_to( p_msg, ( struct proxy_l *) proxy, PROTO_TCP,
616
-	0 /* no replication */ );
607
+	((struct proxy_l *)proxy)->proto=PROTO_TCP;
608
+	return _w_t_relay_to( p_msg, ( struct proxy_l *) proxy);
617 609
 }
618 610
 
619 611
 
... ...
@@ -652,7 +644,7 @@ inline static int w_t_relay( struct sip_msg  *p_msg ,
652 644
 			LOG(L_CRIT, "BUG: w_t_relay: undefined T\n");
653 645
 			return -1;
654 646
 		} 
655
-		if (t_forward_nonack(t, p_msg, ( struct proxy_l *) 0, p_msg->rcv.proto)<=0) {
647
+		if (t_forward_nonack(t, p_msg, ( struct proxy_l *) 0, PROTO_NONE)<=0) {
656 648
 			LOG(L_ERR, "ERROR: w_t_relay (failure mode): forwarding failed\n");
657 649
 			return -1;
658 650
 		}
... ...
@@ -660,7 +652,7 @@ inline static int w_t_relay( struct sip_msg  *p_msg ,
660 652
 	}
661 653
 	if (rmode==MODE_REQUEST) 
662 654
 		return t_relay_to( p_msg, 
663
-		(struct proxy_l *) 0 /* no proxy */, p_msg->rcv.proto,
655
+		(struct proxy_l *) 0 /* no proxy */, PROTO_NONE,
664 656
 		0 /* no replication */ );
665 657
 	LOG(L_CRIT, "ERROR: w_t_relay_to: unsupported mode: %d\n", rmode);
666 658
 	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 46
 		return -1;
46 47
 	}
47 48
 
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");
49
+	if (!( tmb->t_relay_to_tcp=find_export(T_RELAY_TO_TCP, 2, 0)) ) {
50
+		LOG(L_ERR, LOAD_ERROR "'t_relay_to_tcp' not found\n");
51
+		return -1;
52
+	}
53
+	if (!( tmb->t_relay_to_udp=find_export(T_RELAY_TO_UDP, 2, 0)) ) {
54
+		LOG(L_ERR, LOAD_ERROR "'t_relay_to_udp' not found\n");
50 55
 		return -1;
51 56
 	}
52 57
 	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 40
 #define _TM_UT_H
39 41
 
40 42
 #include "defs.h"
43
+#include "../../ip_addr.h"
41 44
 
42 45
 
43 46
 #include "../../dprint.h"
... ...
@@ -46,12 +49,45 @@
46 49
 #include "../../str.h"
47 50
 #include "../../parser/msg_parser.h"
48 51
 
52
+
53
+inline static enum sip_protos get_proto(enum sip_protos force_proto,
54
+	struct sip_uri *u)
55
+{
56
+	/* calculate transport protocol */
57
+	switch(force_proto) {
58
+		case PROTO_NONE: 	/* no protocol has been forced -- look at uri */
59
+			switch(u->proto) {
60
+				case PROTO_NONE: /* uri default to UDP */
61
+					return PROTO_UDP;
62
+				case PROTO_UDP: /* transport specified explicitely */
63
+#ifdef USE_TCP
64
+				case PROTO_TCP:
65
+#endif
66
+					return u->proto;
67
+				default:
68
+					LOG(L_ERR, "ERROR: get_proto: unsupported transport: %d\n",
69
+						u->proto );
70
+					return PROTO_NONE;
71
+			}
72
+		case PROTO_UDP: /* some protocol has been forced -- take it */
73
+#ifdef USE_TCP
74
+		case PROTO_TCP:
75
+#endif
76
+			return force_proto;
77
+		default:
78
+			LOG(L_ERR, "ERROR: get_proto: unsupported forced protocol: "
79
+				"%d\n", force_proto);
80
+			return PROTO_NONE;
81
+	}
82
+}
83
+
49 84
 inline static struct proxy_l *uri2proxy( str *uri, int proto )
50 85
 {
51 86
 	struct sip_uri parsed_uri;
52 87
 	unsigned int  port; 
53 88
 	struct proxy_l *p;
54 89
 	int err;
90
+	enum sip_protos out_proto;
55 91
 
56 92
 	if (parse_uri(uri->s, uri->len, &parsed_uri)<0) {
57 93
 		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 104
 	/* fixed use of SRV resolver
69 105
 	} else port=SIP_PORT; */
70 106
 	} else port=0;
71
-	p=mk_proxy(&(parsed_uri.host), port, proto);
107
+
108
+	out_proto=get_proto(proto,&parsed_uri);
109
+	if (out_proto==PROTO_NONE) {
110
+		LOG(L_ERR, "ERROR: uri2proxy: transport can't be determined "
111
+			"for URI <%.*s>\n", uri->len, uri->s );
112
+		return 0;
113
+	}
114
+
115
+	p=mk_proxy(&(parsed_uri.host), port, out_proto);
72 116
 	if (p==0) {
73 117
 		LOG(L_ERR, "ERROR: t_relay: bad host name in URI <%.*s>\n",
74 118
 			uri->len, uri->s);