浏览代码

cross-transport introduced to TM

Jiri Kuthan 22 年之前
父节点
当前提交
a7cad316a3
共有 9 个文件被更改,包括 106 次插入51 次删除
  1. 1 0
      NEWS
  2. 3 2
      modules/tm/t_funcs.c
  3. 16 13
      modules/tm/t_fwd.c
  4. 2 1
      modules/tm/t_fwd.h
  5. 15 8
      modules/tm/t_reply.c
  6. 14 22
      modules/tm/tm.c
  7. 8 3
      modules/tm/tm_load.c
  8. 2 1
      modules/tm/tm_load.h
  9. 45 1
      modules/tm/ut.h

+ 1 - 0
NEWS

@@ -107,6 +107,7 @@ tm module:
 - if you wish to do forward to another destination from 
   failure_route (reply_route formerly), you need to call t_relay
   or t_relay_to explicitely now
+- t_relay_to has been replaced with t_relay_to_udp and t_relay_to_tcp
 
 List of new modules:
 --------------------

+ 3 - 2
modules/tm/t_funcs.c

@@ -35,6 +35,7 @@
  *  2003-03-13  send_pr_buffer is called w/ file/function/line debugging
  *  2003-03-01  start_retr changed to retransmit only for UDP
  *  2003-02-13  modified send_pr_buffer to use msg_send & rb->dst (andrei)
+ *  2003-04-14  use protocol from uri (jiri)
  */
 
 
@@ -234,7 +235,7 @@ int t_relay_to( struct sip_msg  *p_msg , struct proxy_l *proxy, int proto,
 					ret=E_BAD_ADDRESS;
 					goto done;
 			}
-			ret=forward_request( p_msg , proxy, proto) ;
+			ret=forward_request( p_msg , proxy, proxy->proto) ;
 			free_proxy( proxy );	
 			pkg_free( proxy );
 #ifdef ACK_FORKING_HACK
@@ -244,7 +245,7 @@ int t_relay_to( struct sip_msg  *p_msg , struct proxy_l *proxy, int proto,
 				p_msg->new_uri=ack_uri;
 				proxy=uri2proxy(&GET_NEXT_HOP(p_msg), proto);
 				if (proxy==0) continue;
-				forward_request(p_msg, proxy, proto);
+				forward_request(p_msg, proxy, proto->proto);
 				free_proxy( proxy );	
 				pkg_free( proxy );
 			}

+ 16 - 13
modules/tm/t_fwd.c

@@ -28,16 +28,17 @@
 /*
  * History:
  * -------
- *  2003-03-30  we now watch downstream delivery and if it fails, send an
- *              error message upstream (jiri)
- *  2003-03-19  replaced all the mallocs/frees w/ pkg_malloc/pkg_free (andrei)
+ *  2003-02-13  proto support added (andrei)
+ *  2003-02-24  s/T_NULL/T_NULL_CELL/ to avoid redefinition conflict w/
+ *              nameser_compat.h (andrei)
+ *  2003-03-01  kr set through a function now (jiri)
  *  2003-03-06  callbacks renamed; "blind UAC" introduced, which makes
  *              transaction behave as if it was forwarded even if it was
  *              not -- good for local UAS, like VM (jiri)
- *  2003-03-01  kr set through a function now (jiri)
- *  2003-02-24  s/T_NULL/T_NULL_CELL/ to avoid redefinition conflict w/
- *              nameser_compat.h (andrei)
- *  2003-02-13  proto support added (andrei)
+ *  2003-03-19  replaced all the mallocs/frees w/ pkg_malloc/pkg_free (andrei)
+ *  2003-03-30  we now watch downstream delivery and if it fails, send an
+ *              error message upstream (jiri)
+ *  2003-04-14  use protocol from uri (jiri)
  */
 
 #include "defs.h"
@@ -64,7 +65,8 @@
 
 
 char *print_uac_request( struct cell *t, struct sip_msg *i_req,
-	int branch, str *uri, unsigned int *len, struct socket_info *send_sock )
+	int branch, str *uri, unsigned int *len, struct socket_info *send_sock,
+	enum sip_protos proto )
 {
 	char *buf, *shbuf;
 
@@ -85,7 +87,7 @@ char *print_uac_request( struct cell *t, struct sip_msg *i_req,
 	callback_event( TMCB_REQUEST_FWDED, t, i_req, -i_req->REQ_METHOD);
 
 	/* ... and build it now */
-	buf=build_req_buf_from_sip_req( i_req, len, send_sock, i_req->rcv.proto );
+	buf=build_req_buf_from_sip_req( i_req, len, send_sock, proto );
 #ifdef DBG_MSG_QA
 	if (buf[*len-1]==0) {
 		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,
 	hostent2su( &to, &proxy->host, proxy->addr_idx, 
 		proxy->port ? proxy->port:SIP_PORT);
 
-	send_sock=get_send_socket( &to , proto);
+	send_sock=get_send_socket( &to , proxy->proto);
 	if (send_sock==0) {
 		LOG(L_ERR, "ERROR: add_uac: can't fwd to af %d "
 			" (no corresponding listening socket)\n",
@@ -217,7 +219,7 @@ int add_uac( struct cell *t, struct sip_msg *request, str *uri, str* next_hop,
 
 	/* now message printing starts ... */
 	shbuf=print_uac_request( t, request, branch, uri, 
-		&len, send_sock );
+		&len, send_sock, proxy->proto);
 	if (!shbuf) {
 		ret=ser_error=E_OUT_OF_MEM;
 		goto error01;
@@ -226,7 +228,7 @@ int add_uac( struct cell *t, struct sip_msg *request, str *uri, str* next_hop,
 	/* things went well, move ahead and install new buffer! */
 	t->uac[branch].request.dst.to=to;
 	t->uac[branch].request.dst.send_sock=send_sock;
-	t->uac[branch].request.dst.proto=proto;
+	t->uac[branch].request.dst.proto=proxy->proto;
 	t->uac[branch].request.dst.proto_reserved1=0;
 	t->uac[branch].request.buffer=shbuf;
 	t->uac[branch].request.buffer_len=len;
@@ -271,7 +273,8 @@ int e2e_cancel_branch( struct sip_msg *cancel_msg, struct cell *t_cancel,
 	/* print */
 	shbuf=print_uac_request( t_cancel, cancel_msg, branch, 
 		&t_invite->uac[branch].uri, &len, 
-		t_invite->uac[branch].request.dst.send_sock);
+		t_invite->uac[branch].request.dst.send_sock,
+		t_invite->uac[branch].request.dst.proto);
 	if (!shbuf) {
 		LOG(L_ERR, "ERROR: e2e_cancel_branch: printing e2e cancel failed\n");
 		ret=ser_error=E_OUT_OF_MEM;

+ 2 - 1
modules/tm/t_fwd.h

@@ -44,7 +44,8 @@ typedef int (*taddblind_f)( /*struct cell *t */ );
 
 int t_replicate(struct sip_msg *p_msg, struct proxy_l * proxy, int proto);
 char *print_uac_request( struct cell *t, struct sip_msg *i_req,
-    int branch, str *uri, unsigned int *len, struct socket_info *send_sock );
+    int branch, str *uri, unsigned int *len, struct socket_info *send_sock,
+	enum sip_protos proto);
 void e2e_cancel( struct sip_msg *cancel_msg, struct cell *t_cancel, struct cell *t_invite );
 int e2e_cancel_branch( struct sip_msg *cancel_msg, struct cell *t_cancel, struct cell *t_invite, int branch );
 int add_uac(	struct cell *t, struct sip_msg *request, str *uri, str* next_hop,

+ 15 - 8
modules/tm/t_reply.c

@@ -42,6 +42,9 @@
  *  2003-03-31  200 for INVITE/UAS resent even for UDP (jiri)
  *  2003-03-31  removed msg->repl_add_rm (andrei)
  *  2003-04-05  s/reply_route/failure_route, onreply_route introduced (jiri)
+ *  2003-04-14  local acks generated before reply processing to avoid
+ *              delays in length reply processing (like opening TCP
+ *              connnection to an unavailable destination) (jiri)
  */
 
 
@@ -1093,6 +1096,17 @@ int reply_received( struct sip_msg  *p_msg )
 	/* stop final response timer only if I got a final response */
 	if ( msg_status >= 200 )
 		reset_timer( &uac->request.fr_timer);
+	/* acknowledge negative INVITE replies (do it before detailed
+	   on_reply processing, which may take very long, like if it
+	   is attempted to establish a TCP connection to a fail-over dst
+	*/
+	if (t->is_invite && (msg_status>=300 || (t->local && msg_status>=200))) {
+		ack = build_ack( p_msg, t, branch , &ack_len);
+		if (ack) {
+			SEND_PR_BUFFER( &uac->request, ack, ack_len );
+			shm_free(ack);
+		}
+	} /* ack-ing negative INVITE replies */
 
 	/* processing of on_reply block */
 	if (t->on_reply) {
@@ -1101,6 +1115,7 @@ int reply_received( struct sip_msg  *p_msg )
 			LOG(L_ERR, "ERROR: on_reply processing failed\n");
 	}
 
+
 	LOCK_REPLIES( t );
 	if (t->local) {
 		reply_status=local_reply( t, p_msg, branch, msg_status, &cancel_bitmap );
@@ -1112,14 +1127,6 @@ int reply_received( struct sip_msg  *p_msg )
 	if (reply_status==RPS_ERROR)
 		goto done;
 
-	/* acknowledge negative INVITE replies */	
-	if (t->is_invite && (msg_status>=300 || (t->local && msg_status>=200))) {
-		ack = build_ack( p_msg, t, branch , &ack_len);
-		if (ack) {
-			SEND_PR_BUFFER( &uac->request, ack, ack_len );
-			shm_free(ack);
-		}
-	} /* ack-ing negative INVITE replies */
 
 	/* clean-up the transaction when transaction completed */
 	if (reply_status==RPS_COMPLETED) {

+ 14 - 22
modules/tm/tm.c

@@ -63,6 +63,7 @@
  *  2003-03-19  replaced all mallocs/frees w/ pkg_malloc/pkg_free (andrei)
  *  2003-03-30  set_kr for requests only (jiri)
  *  2003-04-05  s/reply_route/failure_route, onreply_route introduced (jiri)
+ *  2003-04-14  use protocol from uri (jiri)
  */
 
 
@@ -105,9 +106,6 @@ inline static int w_t_retransmit_reply(struct sip_msg* p_msg, char* foo, char* b
 inline static int w_t_newtran(struct sip_msg* p_msg, char* foo, char* bar );
 inline static int w_t_newdlg( struct sip_msg* p_msg, char* foo, char* bar );
 inline static int w_t_relay( struct sip_msg  *p_msg , char *_foo, char *_bar);
-inline static int w_t_relay_udp( struct sip_msg  *p_msg,char *_foo,char *_bar);
-inline static int w_t_relay_tcp( struct sip_msg  *p_msg,char *_foo,char *_bar);
-inline static int w_t_relay_to( struct sip_msg  *p_msg , char *proxy, char *);
 inline static int w_t_relay_to_udp( struct sip_msg  *p_msg , char *proxy, 
 									char *);
 inline static int w_t_relay_to_tcp( struct sip_msg  *p_msg , char *proxy,
@@ -141,17 +139,13 @@ static cmd_export_t cmds[]={
 			REQUEST_ROUTE | FAILURE_ROUTE },
 	{"t_retransmit_reply", w_t_retransmit_reply,    0, 0,                    REQUEST_ROUTE},
 	{"t_release",          w_t_release,             0, 0,                    REQUEST_ROUTE},
-	{T_RELAY_TO,           w_t_relay_to,            2, fixup_hostport2proxy, 
-			REQUEST_ROUTE | FAILURE_ROUTE },
-	{T_RELAY_TO_UDP,       w_t_relay_to_udp,        2, fixup_hostport2proxy, REQUEST_ROUTE},
-	{T_RELAY_TO_TCP,       w_t_relay_to_tcp,        2, fixup_hostport2proxy, REQUEST_ROUTE},
+	{T_RELAY_TO_UDP,       w_t_relay_to_udp,        2, fixup_hostport2proxy, REQUEST_ROUTE|FAILURE_ROUTE},
+	{T_RELAY_TO_TCP,       w_t_relay_to_tcp,        2, fixup_hostport2proxy, REQUEST_ROUTE|FAILURE_ROUTE},
 	{"t_replicate",        w_t_replicate,           2, fixup_hostport2proxy, REQUEST_ROUTE},
 	{"t_replicate_udp",    w_t_replicate_udp,       2, fixup_hostport2proxy, REQUEST_ROUTE},
 	{"t_replicate_tcp",    w_t_replicate_tcp,       2, fixup_hostport2proxy, REQUEST_ROUTE},
 	{T_RELAY,              w_t_relay,               0, 0,                    
 			REQUEST_ROUTE | FAILURE_ROUTE },
-	{T_RELAY_UDP,          w_t_relay_udp,           0, 0,                    REQUEST_ROUTE},
-	{T_RELAY_TCP,          w_t_relay_tcp,           0, 0,                    REQUEST_ROUTE},
 	{T_FORWARD_NONACK,     w_t_forward_nonack,      2, fixup_hostport2proxy, REQUEST_ROUTE},
 	{T_FORWARD_NONACK_UDP, w_t_forward_nonack_udp,  2, fixup_hostport2proxy, REQUEST_ROUTE},
 	{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,
 inline static int w_t_forward_nonack( struct sip_msg* msg, char* proxy,
 										char* foo)
 {
-	return _w_t_forward_nonack(msg, proxy, foo, msg->rcv.proto);
+	return _w_t_forward_nonack(msg, proxy, foo, PROTO_NONE);
 }
 
 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 )
 	return -1;
 }
 
-inline static int w_t_relay_to( struct sip_msg  *p_msg , 
-	char *proxy, /* struct proxy_l *proxy expected */
-	char *_foo       /* nothing expected */ )
+inline static int _w_t_relay_to( struct sip_msg  *p_msg , 
+	struct proxy_l *proxy )
 {
 	struct cell *t;
 
@@ -586,15 +579,14 @@ inline static int w_t_relay_to( struct sip_msg  *p_msg ,
 			LOG(L_CRIT, "BUG: w_t_relay_to: undefined T\n");
 			return -1;
 		}
-		if (t_forward_nonack(t, p_msg, 
-				( struct proxy_l *) proxy, p_msg->rcv.proto)<=0 ) {
+		if (t_forward_nonack(t, p_msg, proxy, PROTO_NONE)<=0 ) {
 			LOG(L_ERR, "ERROR: failure_route: t_relay_to failed\n");
 			return -1;
 		}
 		return 1;
 	}
 	if (rmode==MODE_REQUEST) 
-		return t_relay_to( p_msg, ( struct proxy_l *) proxy, p_msg->rcv.proto,
+		return t_relay_to( p_msg, proxy, PROTO_NONE,
 			0 /* no replication */ );
 	LOG(L_CRIT, "ERROR: w_t_relay_to: unsupported mode: %d\n", rmode);
 	return 0;
@@ -604,16 +596,16 @@ inline static int w_t_relay_to_udp( struct sip_msg  *p_msg ,
 	char *proxy, /* struct proxy_l *proxy expected */
 	char *_foo       /* nothing expected */ )
 {
-	return t_relay_to( p_msg, ( struct proxy_l *) proxy, PROTO_UDP,
-	0 /* no replication */ );
+	((struct proxy_l *)proxy)->proto=PROTO_UDP;
+	return _w_t_relay_to( p_msg, ( struct proxy_l *) proxy);
 }
 
 inline static int w_t_relay_to_tcp( struct sip_msg  *p_msg , 
 	char *proxy, /* struct proxy_l *proxy expected */
 	char *_foo       /* nothing expected */ )
 {
-	return t_relay_to( p_msg, ( struct proxy_l *) proxy, PROTO_TCP,
-	0 /* no replication */ );
+	((struct proxy_l *)proxy)->proto=PROTO_TCP;
+	return _w_t_relay_to( p_msg, ( struct proxy_l *) proxy);
 }
 
 
@@ -652,7 +644,7 @@ inline static int w_t_relay( struct sip_msg  *p_msg ,
 			LOG(L_CRIT, "BUG: w_t_relay: undefined T\n");
 			return -1;
 		} 
-		if (t_forward_nonack(t, p_msg, ( struct proxy_l *) 0, p_msg->rcv.proto)<=0) {
+		if (t_forward_nonack(t, p_msg, ( struct proxy_l *) 0, PROTO_NONE)<=0) {
 			LOG(L_ERR, "ERROR: w_t_relay (failure mode): forwarding failed\n");
 			return -1;
 		}
@@ -660,7 +652,7 @@ inline static int w_t_relay( struct sip_msg  *p_msg ,
 	}
 	if (rmode==MODE_REQUEST) 
 		return t_relay_to( p_msg, 
-		(struct proxy_l *) 0 /* no proxy */, p_msg->rcv.proto,
+		(struct proxy_l *) 0 /* no proxy */, PROTO_NONE,
 		0 /* no replication */ );
 	LOG(L_CRIT, "ERROR: w_t_relay_to: unsupported mode: %d\n", rmode);
 	return 0;

+ 8 - 3
modules/tm/tm_load.c

@@ -26,7 +26,8 @@
  *
  * History:
  * --------
- * 2003-03-06  voicemail changes accepted
+ * 2003-03-06  voicemail changes accepted (jiri)
+ * 2003-04-14  t_relay_to split in udp and tcp (jiri)
  */
 
 #include "defs.h"
@@ -45,8 +46,12 @@ int load_tm( struct tm_binds *tmb)
 		return -1;
 	}
 
-	if (!( tmb->t_relay_to=find_export(T_RELAY_TO, 2, 0)) ) {
-		LOG(L_ERR, LOAD_ERROR "'t_relay_to' not found\n");
+	if (!( tmb->t_relay_to_tcp=find_export(T_RELAY_TO_TCP, 2, 0)) ) {
+		LOG(L_ERR, LOAD_ERROR "'t_relay_to_tcp' not found\n");
+		return -1;
+	}
+	if (!( tmb->t_relay_to_udp=find_export(T_RELAY_TO_UDP, 2, 0)) ) {
+		LOG(L_ERR, LOAD_ERROR "'t_relay_to_udp' not found\n");
 		return -1;
 	}
 	if (!( tmb->t_relay=find_export(T_RELAY, 0, 0)) ) {

+ 2 - 1
modules/tm/tm_load.h

@@ -71,7 +71,8 @@
 
 struct tm_binds {
 	register_tmcb_f	register_tmcb;
-	cmd_function	t_relay_to;
+	cmd_function	t_relay_to_udp;
+	cmd_function	t_relay_to_tcp;
 	cmd_function 	t_relay;
 	tuacdlg_f		t_uac_dlg;
 	treply_f		t_reply;

+ 45 - 1
modules/tm/ut.h

@@ -31,6 +31,8 @@
  * History:
  * -------
  *  2003-02-13  added proto to uri2proxy (andrei)
+ *  2003-04-14  added get_proto to determine protocol from uri unless
+ *              specified explicitely (jiri)
 */
 
 
@@ -38,6 +40,7 @@
 #define _TM_UT_H
 
 #include "defs.h"
+#include "../../ip_addr.h"
 
 
 #include "../../dprint.h"
@@ -46,12 +49,45 @@
 #include "../../str.h"
 #include "../../parser/msg_parser.h"
 
+
+inline static enum sip_protos get_proto(enum sip_protos force_proto,
+	struct sip_uri *u)
+{
+	/* calculate transport protocol */
+	switch(force_proto) {
+		case PROTO_NONE: 	/* no protocol has been forced -- look at uri */
+			switch(u->proto) {
+				case PROTO_NONE: /* uri default to UDP */
+					return PROTO_UDP;
+				case PROTO_UDP: /* transport specified explicitely */
+#ifdef USE_TCP
+				case PROTO_TCP:
+#endif
+					return u->proto;
+				default:
+					LOG(L_ERR, "ERROR: get_proto: unsupported transport: %d\n",
+						u->proto );
+					return PROTO_NONE;
+			}
+		case PROTO_UDP: /* some protocol has been forced -- take it */
+#ifdef USE_TCP
+		case PROTO_TCP:
+#endif
+			return force_proto;
+		default:
+			LOG(L_ERR, "ERROR: get_proto: unsupported forced protocol: "
+				"%d\n", force_proto);
+			return PROTO_NONE;
+	}
+}
+
 inline static struct proxy_l *uri2proxy( str *uri, int proto )
 {
 	struct sip_uri parsed_uri;
 	unsigned int  port; 
 	struct proxy_l *p;
 	int err;
+	enum sip_protos out_proto;
 
 	if (parse_uri(uri->s, uri->len, &parsed_uri)<0) {
 		LOG(L_ERR, "ERROR: t_relay: bad_uri: %.*s\n",
@@ -68,7 +104,15 @@ inline static struct proxy_l *uri2proxy( str *uri, int proto )
 	/* fixed use of SRV resolver
 	} else port=SIP_PORT; */
 	} else port=0;
-	p=mk_proxy(&(parsed_uri.host), port, proto);
+
+	out_proto=get_proto(proto,&parsed_uri);
+	if (out_proto==PROTO_NONE) {
+		LOG(L_ERR, "ERROR: uri2proxy: transport can't be determined "
+			"for URI <%.*s>\n", uri->len, uri->s );
+		return 0;
+	}
+
+	p=mk_proxy(&(parsed_uri.host), port, out_proto);
 	if (p==0) {
 		LOG(L_ERR, "ERROR: t_relay: bad host name in URI <%.*s>\n",
 			uri->len, uri->s);