瀏覽代碼

Merge commit 'origin/tmp/build_local'

* commit 'origin/tmp/build_local':
  core: init via_len to cope with no via update flag
  tm: local req. route: do not save/restore the avps
  tm: local req. route: cache route id
  tm: local req. route: always free the tmp sip msg
  tm: local req. route rcv init fix
  tm: updated execution of event route
  core: build_req_buf_from_sip_req() has a new parameter
  tm: update to new signature of build_req_buf_from_sip_req()
  tm: execute event_route[tm:local-request] if defined
Andrei Pelinescu-Onciul 16 年之前
父節點
當前提交
4bc6bf9e84
共有 9 個文件被更改,包括 167 次插入23 次删除
  1. 1 1
      forward.c
  2. 1 1
      modules/tm/t_fwd.c
  3. 6 3
      modules/tm/tm.c
  4. 89 6
      modules/tm/uac.c
  5. 6 0
      modules/tm/uac.h
  6. 48 10
      msg_translator.c
  7. 8 1
      msg_translator.h
  8. 7 0
      receive.c
  9. 1 1
      receive.h

+ 1 - 1
forward.c

@@ -433,7 +433,7 @@ int forward_request(struct sip_msg* msg, str* dst, unsigned short port,
 #endif
 			if (buf) pkg_free(buf);
 			send_info->proto=proto;
-			buf = build_req_buf_from_sip_req(msg, &len, send_info);
+			buf = build_req_buf_from_sip_req(msg, &len, send_info, 0);
 			if (!buf){
 				LOG(L_ERR, "ERROR: forward_request: building failed\n");
 				ret=E_OUT_OF_MEM; /* most probable */

+ 1 - 1
modules/tm/t_fwd.c

@@ -211,7 +211,7 @@ static char *print_uac_request( struct cell *t, struct sip_msg *i_req,
 								-i_req->REQ_METHOD);
 
 	/* ... and build it now */
-	buf=build_req_buf_from_sip_req( i_req, len, dst);
+	buf=build_req_buf_from_sip_req( i_req, len, dst, 0);
 #ifdef DBG_MSG_QA
 	if (buf[*len-1]==0) {
 		LOG(L_ERR, "ERROR: print_uac_request: sanity check failed\n");

+ 6 - 3
modules/tm/tm.c

@@ -436,7 +436,7 @@ static param_export_t params[]={
 	{"max_noninv_lifetime", PARAM_INT, &default_tm_cfg.tm_max_noninv_lifetime},
 	{"noisy_ctimer",        PARAM_INT, &default_tm_cfg.noisy_ctimer          },
 	{"auto_inv_100",        PARAM_INT, &default_tm_cfg.tm_auto_inv_100       },
-	{"auto_inv_100_reason", PARAM_STRING, &default_tm_cfg.tm_auto_inv_100_r  },    
+	{"auto_inv_100_reason", PARAM_STRING, &default_tm_cfg.tm_auto_inv_100_r  },
 	{"unix_tx_timeout",     PARAM_INT, &default_tm_cfg.tm_unix_tx_timeout    },
 	{"restart_fr_on_each_reply", PARAM_INT,
 									&default_tm_cfg.restart_fr_on_each_reply},
@@ -461,10 +461,8 @@ static param_export_t params[]={
 	{"cancel_b_method",     PARAM_INT, &default_tm_cfg.cancel_b_flags},
 	{"reparse_on_dns_failover", PARAM_INT, &default_tm_cfg.reparse_on_dns_failover},
 	{"on_sl_reply",         PARAM_STRING|PARAM_USE_FUNC, fixup_on_sl_reply   },
-
 	{"fr_inv_timer_next",   PARAM_INT, &default_tm_cfg.fr_inv_timeout_next   },
 	{"contacts_avp",        PARAM_STRING, &contacts_avp_param                },
-
 	{0,0,0}
 };
 
@@ -769,6 +767,11 @@ static int mod_init(void)
 		LOG(L_ERR,"ERROR:tm:mod_init: failed to process AVP params\n");
 		return -1;
 	}
+#ifdef WITH_EVENT_LOCAL_REQUEST
+	goto_on_local_req=route_lookup(&event_rt, "tm:local-request");
+	if (goto_on_local_req>=0 && event_rt.rlist[goto_on_local_req]==0)
+		goto_on_local_req=-1; /* disable */
+#endif /* WITH_EVENT_LOCAL_REQUEST */
 	tm_init = 1;
 	return 0;
 }

+ 89 - 6
modules/tm/uac.c

@@ -82,10 +82,19 @@
 #include "../../dns_cache.h"
 #include "../../cfg_core.h" /* cfg_get(core, core_cfg, use_dns_failover) */
 #endif
-
+#ifdef WITH_EVENT_LOCAL_REQUEST
+#include "../../receive.h"
+#include "../../route.h"
+#include "../../action.h"
+#endif
 
 #define FROM_TAG_LEN (MD5_LEN + 1 /* - */ + CRC16_LEN) /* length of FROM tags */
 
+#ifdef WITH_EVENT_LOCAL_REQUEST
+/* where to go for the local request route ("tm:local-request") */
+int goto_on_local_req=-1; /* default disabled */
+#endif /* WITH_EVEN_LOCAL_REQuEST */
+
 static char from_tag[FROM_TAG_LEN + 1];
 
 /*
@@ -187,7 +196,7 @@ static inline int t_uac_prepare(uac_req_t *uac_r,
 	struct cell *new_cell;
 	struct retr_buf *request;
 	char* buf;
-        int buf_len, ret;
+	int buf_len, ret;
 	unsigned int hi;
 	int is_ack;
 	ticks_t lifetime;
@@ -195,6 +204,13 @@ static inline int t_uac_prepare(uac_req_t *uac_r,
 	struct dns_srv_handle dns_h;
 #endif
 	long nhtype;
+#ifdef WITH_EVENT_LOCAL_REQUEST
+	static struct sip_msg lreq;
+	char *buf1;
+	int buf_len1;
+	int sflag_bk;
+	int backup_route_type;
+#endif
 
 	ret=-1;
 	hi=0; /* make gcc happy */
@@ -281,10 +297,6 @@ static inline int t_uac_prepare(uac_req_t *uac_r,
 	new_cell->rt_t2_timeout=cfg_get(tm, tm_cfg, rt_t2_timeout);
 #endif
 
-	/* better reset avp list now - anyhow, it's useless from
-	 * this point (bogdan) */
-	reset_avps();
-
 	set_kr(REQ_FWDED);
 
 	request = &new_cell->uac[0].request;
@@ -309,6 +321,77 @@ static inline int t_uac_prepare(uac_req_t *uac_r,
 		goto error1;
 	}
 
+#ifdef WITH_EVENT_LOCAL_REQUEST
+	if (unlikely(goto_on_local_req>=0)) {
+		DBG("executing event_route[tm:local-request]\n");
+		if(likely(build_sip_msg_from_buf(&lreq, buf, buf_len, inc_msg_no())
+					== 0)) {
+			/* fill some field in sip_msg */
+			if (unlikely(set_dst_uri(&lreq, uac_r->dialog->hooks.next_hop))) {
+				LM_ERR("failed to set dst_uri");
+				free_sip_msg(&lreq);
+			} else {
+				lreq.force_send_socket = uac_r->dialog->send_sock;
+				lreq.rcv.proto = dst.send_sock->proto;
+				lreq.rcv.src_ip = dst.send_sock->address;
+				lreq.rcv.src_port = dst.send_sock->port_no;
+				lreq.rcv.dst_port = su_getport(&dst.to);
+				su2ip_addr(&lreq.rcv.dst_ip, &dst.to);
+				lreq.rcv.src_su=dst.send_sock->su;
+				lreq.rcv.bind_address=dst.send_sock;
+			#ifdef USE_COMP
+				lreq.rcv.comp=dst.comp;
+			#endif /* USE_COMP */
+				/* AVPs are reset anyway afterwards, so no need to 
+				   backup/restore them*/
+				sflag_bk = getsflags();
+
+				/* run the route */
+				backup_route_type = get_route_type();
+				set_route_type(LOCAL_ROUTE);
+				run_top_route(event_rt.rlist[goto_on_local_req], &lreq, 0);
+				set_route_type( backup_route_type );
+
+				/* restore original environment */
+				setsflagsval(sflag_bk);
+
+				if (unlikely(lreq.new_uri.s))
+				{
+					pkg_free(lreq.new_uri.s);
+					lreq.new_uri.s=0;
+					lreq.new_uri.len=0;
+				}
+				if (unlikely(lreq.dst_uri.s))
+				{
+					pkg_free(lreq.dst_uri.s);
+					lreq.dst_uri.s=0;
+					lreq.dst_uri.len=0;
+				}
+
+				if (unlikely(lreq.add_rm || lreq.body_lumps)) {
+					LM_DBG("apply new updates to sip msg\n");
+					buf1 = build_req_buf_from_sip_req(&lreq,
+							(unsigned int*)&buf_len1,
+							&dst, BUILD_NO_LOCAL_VIA|BUILD_NO_VIA1_UPDATE|
+							BUILD_IN_SHM);
+					if (likely(buf1)){
+						shm_free(buf);
+						buf = buf1;
+						buf_len = buf_len1;
+						/* a possible change of the method is not handled! */
+					}
+				}
+				lreq.buf=0; /* covers the obsolete DYN_BUF */
+				free_sip_msg(&lreq);
+			}
+		}
+	}
+#endif
+
+	/* better reset avp list now - anyhow, it's useless from
+	 * this point (bogdan) */
+	reset_avps();
+
 	new_cell->method.s = buf;
 	new_cell->method.len = uac_r->method->len;
 

+ 6 - 0
modules/tm/uac.h

@@ -73,6 +73,12 @@ typedef struct uac_req {
 		(_req)->cbp = (_cbp); \
 	} while (0)
 
+
+#ifdef WITH_EVENT_LOCAL_REQUEST
+/* where to go for the local request route ("tm:local-request") */
+extern int goto_on_local_req;
+#endif /* WITH_EVEN_LOCAL_REQuEST */
+
 /*
  * Function prototypes
  */

+ 48 - 10
msg_translator.c

@@ -1522,8 +1522,8 @@ error:
   */
 char * build_req_buf_from_sip_req( struct sip_msg* msg,
 								unsigned int *returned_len,
-								struct dest_info* send_info
-								)
+								struct dest_info* send_info,
+								unsigned int mode)
 {
 	unsigned int len, new_len, received_len, rport_len, uri_len, via_len,
 				 body_delta;
@@ -1551,6 +1551,7 @@ char * build_req_buf_from_sip_req( struct sip_msg* msg,
 	received_buf=0;
 	rport_buf=0;
 	line_buf=0;
+	via_len=0;
 
 	flags=msg->msg_flags|global_req_flags;
 	/* Calculate message body difference and adjust Content-Length */
@@ -1561,6 +1562,9 @@ char * build_req_buf_from_sip_req( struct sip_msg* msg,
 		goto error00;
 	}
 
+	if(unlikely(mode&BUILD_NO_LOCAL_VIA))
+		goto after_local_via;
+
 	/* create the via header */
 	branch.s=msg->add_to_branch_s;
 	branch.len=msg->add_to_branch_len;
@@ -1571,6 +1575,9 @@ char * build_req_buf_from_sip_req( struct sip_msg* msg,
 					"memory allocation failure\n");
 		goto error00;
 	}
+after_local_via:
+	if(unlikely(mode&BUILD_NO_VIA1_UPDATE))
+		goto after_update_via1;
 	/* check if received needs to be added */
 	if ( received_test(msg) ) {
 		if ((received_buf=received_builder(msg,&received_len))==0){
@@ -1645,6 +1652,7 @@ char * build_req_buf_from_sip_req( struct sip_msg* msg,
 
 	}
 
+after_update_via1:
 	/* compute new msg len and fix overlapping zones*/
 	new_len=len+body_delta+lumps_len(msg, msg->add_rm, send_info)+via_len;
 #ifdef XL_DEBUG
@@ -1653,7 +1661,8 @@ char * build_req_buf_from_sip_req( struct sip_msg* msg,
 	udp_mtu=cfg_get(core, core_cfg, udp_mtu);
 	di.proto=PROTO_NONE;
 	if (unlikely((send_info->proto==PROTO_UDP) && udp_mtu && 
-					(flags & FL_MTU_FB_MASK) && (new_len>udp_mtu))){
+					(flags & FL_MTU_FB_MASK) && (new_len>udp_mtu)
+					&& (!(mode&BUILD_NO_LOCAL_VIA)))){
 
 		di=*send_info; /* copy whole struct - will be used in the Via builder */
 		di.proto=PROTO_NONE; /* except the proto */
@@ -1681,7 +1690,7 @@ char * build_req_buf_from_sip_req( struct sip_msg* msg,
 		
 		if (di.proto!=PROTO_NONE){
 			new_len-=via_len;
-			pkg_free(line_buf);
+			if(likely(line_buf)) pkg_free(line_buf);
 			line_buf = create_via_hf( &via_len, msg, &di, &branch);
 			if (!line_buf){
 				LOG(L_ERR,"ERROR: build_req_buf_from_sip_req: "
@@ -1694,17 +1703,21 @@ char * build_req_buf_from_sip_req( struct sip_msg* msg,
 	/* add via header to the list */
 	/* try to add it before msg. 1st via */
 	/* add first via, as an anchor for second via*/
-	via_anchor=anchor_lump(msg, msg->via1->hdr.s-buf, 0, HDR_VIA_T);
-	if (via_anchor==0) goto error04;
-	if ((via_lump=insert_new_lump_before(via_anchor, line_buf, via_len,
+	if(likely(line_buf)) {
+		via_anchor=anchor_lump(msg, msg->via1->hdr.s-buf, 0, HDR_VIA_T);
+		if (via_anchor==0) goto error04;
+		if ((via_lump=insert_new_lump_before(via_anchor, line_buf, via_len,
 											HDR_VIA_T))==0)
-		goto error04;
-
+			goto error04;
+	}
 	if (msg->new_uri.s){
 		uri_len=msg->new_uri.len;
 		new_len=new_len-msg->first_line.u.request.uri.len+uri_len;
 	}
-	new_buf=(char*)pkg_malloc(new_len+1);
+	if(unlikely(mode&BUILD_IN_SHM))
+		new_buf=(char*)shm_malloc(new_len+1);
+	else
+		new_buf=(char*)pkg_malloc(new_len+1);
 	if (new_buf==0){
 		ser_error=E_OUT_OF_MEM;
 		LOG(L_ERR, "ERROR: build_req_buf_from_sip_req: out of memory\n");
@@ -2543,3 +2556,28 @@ char * build_all( struct sip_msg* msg, int touch_clen,
 	*returned_len = offset;
 	return new_buf;	
 }
+
+
+
+/**
+ * parse buf in msg and fill several fields
+ */
+int build_sip_msg_from_buf(struct sip_msg *msg, char *buf, int len,
+		unsigned int id)
+{
+	if(msg==0 || buf==0)
+		return -1;
+
+	memset(msg, 0, sizeof(sip_msg_t));
+	msg->id = id;
+	msg->buf = buf;
+	msg->len = len;
+	if (parse_msg(buf, len, msg)!=0) {
+		LM_ERR("parsing failed");
+		return -1;
+	}
+	msg->set_global_address=default_global_address;
+	msg->set_global_port=default_global_port;
+	return 0;
+}
+

+ 8 - 1
msg_translator.h

@@ -48,6 +48,10 @@
 
 /*#define MAX_CONTENT_LEN_BUF INT2STR_MAX_LEN *//* see ut.h/int2str() */
 
+#define BUILD_NO_LOCAL_VIA		(1<<0)
+#define BUILD_NO_VIA1_UPDATE	(1<<1)
+#define BUILD_IN_SHM			(1<<2)
+
 #include "parser/msg_parser.h"
 #include "ip_addr.h"
 
@@ -76,7 +80,8 @@ struct hostport {
 	}while(0)
 
 char * build_req_buf_from_sip_req (	struct sip_msg* msg, 
-				unsigned int *returned_len, struct dest_info* send_info);
+				unsigned int *returned_len, struct dest_info* send_info,
+				unsigned int mode);
 
 char * build_res_buf_from_sip_res(	struct sip_msg* msg,
 				unsigned int *returned_len);
@@ -152,4 +157,6 @@ char * build_all( struct sip_msg* msg, int adjust_clen,
 /** cfg framework fixup */
 void fix_global_req_flags(str* gname, str* name);
 
+int build_sip_msg_from_buf(struct sip_msg *msg, char *buf, int len,
+		unsigned int id);
 #endif

+ 7 - 0
receive.c

@@ -76,6 +76,13 @@ str default_global_port={0,0};
 str default_via_address={0,0};
 str default_via_port={0,0};
 
+/**
+ * increment msg_no and return the new value
+ */
+unsigned int inc_msg_no(void)
+{
+	return ++msg_no;
+}
 
 
 /* WARNING: buf must be 0 terminated (buf[len]=0) or some things might 

+ 1 - 1
receive.h

@@ -33,6 +33,6 @@
 #include "ip_addr.h"
 
 int receive_msg(char* buf, unsigned int len, struct receive_info *ri);
-
+unsigned int inc_msg_no(void);
 
 #endif