فهرست منبع

Merge branch 'master' of ssh://git.sip-router.org/sip-router

Jason Penton 11 سال پیش
والد
کامیت
6e23e6159c
5فایلهای تغییر یافته به همراه235 افزوده شده و 50 حذف شده
  1. 5 0
      modules/rtpproxy/rtpproxy.c
  2. 0 3
      modules/sca/sca_call_info.c
  3. 33 10
      modules/siptrace/README
  4. 32 2
      modules/siptrace/doc/siptrace_admin.xml
  5. 165 35
      modules/siptrace/siptrace.c

+ 5 - 0
modules/rtpproxy/rtpproxy.c

@@ -2454,6 +2454,11 @@ force_rtp_proxy(struct sip_msg* msg, char* str1, char* str2, int offer, int forc
 		if (to_tag.len == 0) {
 			FORCE_RTP_PROXY_RET (-1);
 		}
+		if (msg->first_line.type == SIP_REQUEST) {
+			tmp = from_tag;
+			from_tag = to_tag;
+			to_tag = tmp;
+		}
 		create = 0;
 	} else if ((msg->first_line.type == SIP_REPLY && offer != 0)
 			|| (msg->first_line.type == SIP_REQUEST && offer == 0)) {

+ 0 - 3
modules/sca/sca_call_info.c

@@ -1072,9 +1072,6 @@ sca_call_info_invite_reply_18x_handler( sip_msg_t *msg,
 
     switch ( msg->REPLY_STATUS ) {
     case 180:
-	state = SCA_APPEARANCE_STATE_ALERTING;
-	break;
-
     case 183:
 	state = SCA_APPEARANCE_STATE_PROGRESSING;
 	break;

+ 33 - 10
modules/siptrace/README

@@ -16,9 +16,9 @@ Daniel-Constantin Mierla
 
    <[email protected]>
 
-   Copyright © 2010 asipto.com
+   Copyright © 2010 asipto.com
 
-   Copyright © 2006 voice-system.ro
+   Copyright © 2006 voice-system.ro
      __________________________________________________________________
 
    Table of Contents
@@ -49,10 +49,11 @@ Daniel-Constantin Mierla
               3.14. hep_version (integer)
               3.15. hep_capture_id (integer)
               3.16. trace_delayed (integer)
+              3.17. force_send_sock (str)
 
         4. Functions
 
-              4.1. sip_trace()
+              4.1. sip_trace([address])
 
         5. MI Commands
 
@@ -83,7 +84,8 @@ Daniel-Constantin Mierla
    1.14. Set hep_version parameter
    1.15. Set hep_capture_id parameter
    1.16. Set trace_delayed parameter
-   1.17. sip_trace() usage
+   1.17. Set force_send_sock parameter
+   1.18. sip_trace() usage
 
 Chapter 1. Admin Guide
 
@@ -113,10 +115,11 @@ Chapter 1. Admin Guide
         3.14. hep_version (integer)
         3.15. hep_capture_id (integer)
         3.16. trace_delayed (integer)
+        3.17. force_send_sock (str)
 
    4. Functions
 
-        4.1. sip_trace()
+        4.1. sip_trace([address])
 
    5. MI Commands
 
@@ -186,6 +189,7 @@ Chapter 1. Admin Guide
    3.14. hep_version (integer)
    3.15. hep_capture_id (integer)
    3.16. trace_delayed (integer)
+   3.17. force_send_sock (str)
 
 3.1. db_url (str)
 
@@ -404,22 +408,41 @@ modparam("siptrace", "hep_capture_id", 234)
 modparam("siptrace", "trace_delayed", 1)
 ...
 
+3.17. force_send_sock (str)
+
+   The local interface in form of SIP uri from where to send the
+   duplicated traffic. In the absence of this parameter kamailio
+   automatically picks an interface.
+
+   Example 1.17. Set force_send_sock parameter
+...
+modparam("siptrace", "force_send_sock", "sip:10.1.1.2:5000")
+...
+
 4. Functions
 
-   4.1. sip_trace()
+   4.1. sip_trace([address])
 
-4.1.  sip_trace()
+4.1.  sip_trace([address])
 
    Store current processed SIP message in database. It is stored in the
    form prior applying chages made to it.
 
+   Meaning of the parameters is as follows:
+     * address - The address in form of SIP uri where to send a duplicate
+       of traced message. This parameter trumps duplicate_uri and allows
+       tracing to more than one server.
+
    This function can be used from REQUEST_ROUTE, FAILURE_ROUTE,
    ONREPLY_ROUTE, BRANCH_ROUTE.
+   Default value is "NULL".
 
-   Example 1.17. sip_trace() usage
+   Example 1.18. sip_trace() usage
 ...
 sip_trace();
 ...
+sip_trace("sip:10.1.1.2:5085");
+...
 
 5. MI Commands
 
@@ -434,7 +457,7 @@ sip_trace();
           + on
           + off
        The parameter is optional - if missing, the command will return the
-       status of the SIP message tracing (as string "on" or "off" )
+       status of the SIP message tracing (as string “on� or “off� )
        without changing anything.
 
    MI FIFO Command Format:
@@ -454,7 +477,7 @@ sip_trace();
      * on or off: turns on/off SIP message tracing.. Possible values are:
           + on
           + off
-     * "check" does not change siptrace status, just reports the current
+     * “check� does not change siptrace status, just reports the current
        status.
 
 7. Database setup

+ 32 - 2
modules/siptrace/doc/siptrace_admin.xml

@@ -450,29 +450,59 @@ modparam("siptrace", "trace_delayed", 1)
 </programlisting>
                 </example>
         </section>
-
+<section>
+                <title><varname>force_send_sock</varname> (str)</title>
+                <para>
+				The local interface in form of SIP uri from where to send
+				the duplicated traffic. In the absence of this parameter
+				kamailio automatically picks an interface.
+                </para>
+                <example>
+                <title>Set <varname>force_send_sock</varname>
+                parameter</title>
+                <programlisting format="linespecific">
+...
+modparam("siptrace", "force_send_sock", "sip:10.1.1.2:5000")
+...
+</programlisting>
+                </example>
+        </section>
 	</section>
 	
 	<section>
 	<title>Functions</title>
 	<section>
 		<title>
-		<function moreinfo="none">sip_trace()</function>
+		<function moreinfo="none">sip_trace([address])</function>
 		</title>
 		<para>
 		Store current processed SIP message in database. It is stored in the
 		form prior applying chages made to it.
 		</para>
+		<para>Meaning of the parameters is as follows:</para>
+		<itemizedlist>
+		<listitem>
+		<para><emphasis>address</emphasis> - The address in form of SIP uri
+		where to send a duplicate of traced message. This parameter trumps
+		duplicate_uri and allows tracing to more than one server.
+		</para>
+		</listitem>
+		</itemizedlist>
 		<para>
 		This function can be used from REQUEST_ROUTE, FAILURE_ROUTE,
 		ONREPLY_ROUTE, BRANCH_ROUTE.
 		</para>
+		<emphasis>
+			Default value is "NULL".
+		</emphasis>
 		<example>
 		<title><function>sip_trace()</function> usage</title>
 		<programlisting format="linespecific">
 ...
 sip_trace();
 ...
+sip_trace("sip:10.1.1.2:5085");
+...
 </programlisting>
 		</example>
 	</section>

+ 165 - 35
modules/siptrace/siptrace.c

@@ -91,10 +91,11 @@ static int mod_init(void);
 static int siptrace_init_rpc(void);
 static int child_init(int rank);
 static void destroy(void);
-static int sip_trace(struct sip_msg*, char*, char*);
+static int sip_trace(struct sip_msg*, struct dest_info*, char*);
+static int fixup_siptrace(void ** param, int param_no);
 
 static int sip_trace_store_db(struct _siptrace_data* sto);
-static int trace_send_duplicate(char *buf, int len);
+static int trace_send_duplicate(char *buf, int len, struct dest_info*);
 
 static void trace_onreq_in(struct cell* t, int type, struct tmcb_params *ps);
 static void trace_onreq_out(struct cell* t, int type, struct tmcb_params *ps);
@@ -103,7 +104,7 @@ static void trace_onreply_out(struct cell* t, int type, struct tmcb_params *ps);
 static void trace_sl_onreply_out(sl_cbp_t *slcb);
 static void trace_sl_ack_in(sl_cbp_t *slcb);
 
-static int trace_send_hep_duplicate(str *body, str *from, str *to);
+static int trace_send_hep_duplicate(str *body, str *from, str *to, struct dest_info*);
 static int pipport2su (char *pipport, union sockaddr_union *tmp_su, unsigned int *proto);
 
 
@@ -140,6 +141,9 @@ int hep_capture_id = 1;
 int xheaders_write = 0;
 int xheaders_read = 0;
 
+str force_send_sock_str = {0, 0};
+struct sip_uri * force_send_sock_uri = 0;
+
 str    dup_uri_str      = {0, 0};
 struct sip_uri *dup_uri = 0;
 
@@ -169,7 +173,7 @@ db_func_t db_funcs;      		/*!< Database functions */
  */
 static cmd_export_t cmds[] = {
 	{"sip_trace", (cmd_function)sip_trace, 0, 0, 0, ANY_ROUTE},
-	{"sip_trace", (cmd_function)sip_trace, 1, 0, 0, ANY_ROUTE},
+    {"sip_trace", (cmd_function)sip_trace, 1, fixup_siptrace, 0, ANY_ROUTE},
 	{0, 0, 0, 0, 0, 0}
 };
 
@@ -201,6 +205,7 @@ static param_export_t params[] = {
 	{"xheaders_write",     INT_PARAM, &xheaders_write       },
 	{"xheaders_read",      INT_PARAM, &xheaders_read        },
 	{"hep_mode_on",        INT_PARAM, &hep_mode_on          },	 
+    {"force_send_sock",    PARAM_STR, &force_send_sock_str	},
 	{"hep_version",        INT_PARAM, &hep_version          },
 	{"hep_capture_id",     INT_PARAM, &hep_capture_id       },	        
 	{"trace_delayed",      INT_PARAM, &trace_delayed        },
@@ -289,6 +294,11 @@ static int mod_init(void)
 
 	*trace_to_database_flag = trace_to_database;
 
+	if(hep_version != 1 && hep_version != 2) {
+	    LM_ERR("unsupported version of HEP");
+	    return -1;
+	}
+
 	/* Find a database module if needed */
 	if(trace_to_database_flag!=NULL && *trace_to_database_flag!=0) {
 		if (db_bind_mod(&db_url, &db_funcs))
@@ -377,6 +387,23 @@ static int mod_init(void)
 		}
 	}
 
+	if(force_send_sock_str.s!=0)
+	{
+	    force_send_sock_str.len = strlen(force_send_sock_str.s);
+	    force_send_sock_uri = (struct sip_uri *)pkg_malloc(sizeof(struct sip_uri));
+	    if(force_send_sock_uri==0)
+	    {
+	        LM_ERR("no more pkg memory left\n");
+	        return -1;
+	    }
+	    memset(force_send_sock_uri, 0, sizeof(struct sip_uri));
+	    if(parse_uri(force_send_sock_str.s, force_send_sock_str.len, force_send_sock_uri)<0)
+	    {
+	        LM_ERR("bad dup uri\n");
+	        return -1;
+	    }
+	}
+
 	if(traced_user_avp_str.s && traced_user_avp_str.len > 0)
 	{
 		if (pv_parse_spec(&traced_user_avp_str, &avp_spec)==0
@@ -687,7 +714,7 @@ static int sip_trace_xheaders_free(struct _siptrace_data *sto)
 	return 0;
 }
 
-static int sip_trace_store(struct _siptrace_data *sto)
+static int sip_trace_store(struct _siptrace_data *sto, struct dest_info *dst)
 {
 	if(sto==NULL)
 	{
@@ -704,8 +731,8 @@ static int sip_trace_store(struct _siptrace_data *sto)
 	if (sip_trace_xheaders_write(sto) != 0)
 		return -1;
 
-	if(hep_mode_on) trace_send_hep_duplicate(&sto->body, &sto->fromip, &sto->toip);
-	else trace_send_duplicate(sto->body.s, sto->body.len);
+	if(hep_mode_on) trace_send_hep_duplicate(&sto->body, &sto->fromip, &sto->toip, dst);
+    else trace_send_duplicate(sto->body.s, sto->body.len, dst);
 
 	if (sip_trace_xheaders_free(sto) != 0)
 		return -1;
@@ -844,11 +871,76 @@ error:
 	return -1;
 }
 
-static int sip_trace(struct sip_msg *msg, char *dir, char *s2)
+static int fixup_siptrace(void** param, int param_no) {
+	char *duri = (char*) *param;
+	struct sip_uri dup_uri;
+	struct dest_info *dst = NULL;
+	struct proxy_l * p = NULL;
+	str dup_uri_str = { 0, 0 };
+
+	if (param_no != 1) {
+		LM_DBG("params:%s\n", (char*)*param);
+		return 0;
+	}
+	if (!(*duri)) {
+		LM_ERR("invalid dup URI\n");
+		return -1;
+	}
+	LM_DBG("sip_trace URI:%s\n", (char*)*param);
+
+	dup_uri_str.s = duri;
+	dup_uri_str.len = strlen(dup_uri_str.s);
+	memset(&dup_uri, 0, sizeof(struct sip_uri));
+
+	if (parse_uri(dup_uri_str.s, dup_uri_str.len, &dup_uri) < 0) {
+		LM_ERR("bad dup uri\n");
+		return -1;
+	}
+
+	dst = (struct dest_info *) pkg_malloc(sizeof(struct dest_info));
+	if (dst == 0) {
+		LM_ERR("no more pkg memory left\n");
+		return -1;
+	}
+	init_dest_info(dst);
+	/* create a temporary proxy*/
+	dst->proto = PROTO_UDP;
+	p = mk_proxy(&dup_uri.host, (dup_uri.port_no) ? dup_uri.port_no : SIP_PORT,
+			dst->proto);
+	if (p == 0) {
+		LM_ERR("bad host name in uri\n");
+		pkg_free(dst);
+		return -1;
+	}
+	hostent2su(&dst->to, &p->host, p->addr_idx, (p->port) ? p->port : SIP_PORT);
+
+	pkg_free(*param);
+	/* free temporary proxy*/
+	if (p) {
+		free_proxy(p); /* frees only p content, not p itself */
+		pkg_free(p);
+	}
+
+	*param = (void*) dst;
+	return 0;
+}
+
+static int sip_trace(struct sip_msg *msg, struct dest_info * dst, char *dir)
 {
 	struct _siptrace_data sto;
 	struct onsend_info *snd_inf = NULL;
 
+	if (dst){
+	    if (dst->send_sock == 0){
+	        dst->send_sock=get_send_socket(0, &dst->to, dst->proto);
+	        if (dst->send_sock==0){
+	            LM_ERR("can't forward to af %d, proto %d no corresponding"
+	                    " listening socket\n", dst->to.s.sa_family, dst->proto);
+	            return -1;
+	        }
+	    }
+	}
+
 	if(msg==NULL) {
 		LM_DBG("nothing to trace\n");
 		return -1;
@@ -934,7 +1026,7 @@ static int sip_trace(struct sip_msg *msg, char *dir, char *s2)
 		sto.stat = siptrace_req;
 	}
 #endif
-	return sip_trace_store(&sto);
+	return sip_trace_store(&sto, dst);
 }
 
 #define trace_is_off(_msg) \
@@ -1116,7 +1208,7 @@ static void trace_onreq_out(struct cell* t, int type, struct tmcb_params *ps)
 	sto.stat = siptrace_req;
 #endif
 
-	sip_trace_store(&sto);
+	sip_trace_store(&sto, NULL);
 	return;
 }
 
@@ -1187,7 +1279,7 @@ static void trace_onreply_in(struct cell* t, int type, struct tmcb_params *ps)
 	sto.stat = siptrace_rpl;
 #endif
 
-	sip_trace_store(&sto);
+	sip_trace_store(&sto, NULL);
 	return;
 }
 
@@ -1296,7 +1388,7 @@ static void trace_onreply_out(struct cell* t, int type, struct tmcb_params *ps)
 	sto.stat = siptrace_rpl;
 #endif
 
-	sip_trace_store(&sto);
+	sip_trace_store(&sto, NULL);
 	return;
 }
 
@@ -1382,7 +1474,7 @@ static void trace_sl_onreply_out(sl_cbp_t *slcbp)
 	sto.stat = siptrace_rpl;
 #endif
 
-	sip_trace_store(&sto);
+	sip_trace_store(&sto, NULL);
 	return;
 }
 
@@ -1434,10 +1526,10 @@ static struct mi_root* sip_trace_mi(struct mi_root* cmd_tree, void* param )
 	}
 }
 
-static int trace_send_duplicate(char *buf, int len)
+static int trace_send_duplicate(char *buf, int len, struct dest_info *dst2)
 {
 	struct dest_info dst;
-	struct proxy_l * p;
+	struct proxy_l * p = NULL;
 
 	if(buf==NULL || len <= 0)
 		return -1;
@@ -1456,34 +1548,50 @@ static int trace_send_duplicate(char *buf, int len)
 		return -1;
 	}
 
-	hostent2su(&dst.to, &p->host, p->addr_idx, (p->port)?p->port:SIP_PORT);
+	if (!dst2){
+	    init_dest_info(&dst);
+	    /* create a temporary proxy*/
+	    dst.proto = PROTO_UDP;
+	    p=mk_proxy(&dup_uri->host, (dup_uri->port_no)?dup_uri->port_no:SIP_PORT,
+	             dst.proto);
+	    if (p==0){
+	        LM_ERR("bad host name in uri\n");
+	        return -1;
+	    }
+	    hostent2su(&dst.to, &p->host, p->addr_idx, (p->port)?p->port:SIP_PORT);
 
-	dst.send_sock=get_send_socket(0, &dst.to, dst.proto);
-	if (dst.send_sock==0)
-	{
-		LM_ERR("can't forward to af %d, proto %d no corresponding"
-				" listening socket\n", dst.to.s.sa_family, dst.proto);
-		goto error;
+	    dst.send_sock=get_send_socket(0, &dst.to, dst.proto);
+	    if (dst.send_sock==0){
+	        LM_ERR("can't forward to af %d, proto %d no corresponding"
+	                " listening socket\n", dst.to.s.sa_family, dst.proto);
+	        goto error;
+	    }
 	}
 
-	if (msg_send(&dst, buf, len)<0)
+	if (msg_send((dst2)?dst2:&dst, buf, len)<0)
 	{
 		LM_ERR("cannot send duplicate message\n");
 		goto error;
 	}
 
-	free_proxy(p); /* frees only p content, not p itself */
-	pkg_free(p);
+	if (p){
+	    free_proxy(p); /* frees only p content, not p itself */
+	    pkg_free(p);
+	}
 	return 0;
 error:
+    if (p){
 	free_proxy(p); /* frees only p content, not p itself */
 	pkg_free(p);
+    }
 	return -1;
 }
 
-static int trace_send_hep_duplicate(str *body, str *from, str *to)
+static int trace_send_hep_duplicate(str *body, str *from, str *to, struct dest_info * dst2)
 {
 	struct dest_info dst;
+	struct socket_info *si;
+	struct dest_info* dst_fin = NULL;
 	struct proxy_l * p=NULL /* make gcc happy */;
 	void* buffer = NULL;
 	union sockaddr_union from_su;
@@ -1528,6 +1636,7 @@ static int trace_send_hep_duplicate(str *body, str *from, str *to)
 		goto error;
 	}
 
+    if (!dst2){
 	init_dest_info(&dst);
 	/* create a temporary proxy*/
 	dst.proto = PROTO_UDP;
@@ -1540,14 +1649,33 @@ static int trace_send_hep_duplicate(str *body, str *from, str *to)
 	}
 
 	hostent2su(&dst.to, &p->host, p->addr_idx, (p->port)?p->port:SIP_PORT);
-
-	dst.send_sock=get_send_socket(0, &dst.to, dst.proto);
-	if (dst.send_sock==0)
-	{
-		LM_ERR("can't forward to af %d, proto %d no corresponding"
-				" listening socket\n", dst.to.s.sa_family, dst.proto);
-		goto error;
-	}
+	LM_DBG("setting up the socket_info\n");
+	dst_fin = &dst;
+    } else {
+        dst_fin = dst2;
+    }
+
+    if (force_send_sock_str.s) {
+        LM_DBG("force_send_sock activated, grep for the sock_info\n");
+        si = grep_sock_info(&force_send_sock_uri->host,
+                (force_send_sock_uri->port_no)?force_send_sock_uri->port_no:SIP_PORT,
+                PROTO_UDP);
+        if (!si) {
+             LM_WARN("cannot grep socket info\n");
+        } else {
+            LM_DBG("found socket while grep: [%.*s] [%.*s]\n", si->name.len, si->name.s, si->address_str.len, si->address_str.s);
+            dst_fin->send_sock = si;
+        }
+    }
+
+    if (dst_fin->send_sock == 0) {
+        dst_fin->send_sock=get_send_socket(0, &dst_fin->to, dst_fin->proto);
+        if (dst_fin->send_sock == 0) {
+            LM_ERR("can't forward to af %d, proto %d no corresponding"
+                    " listening socket\n", dst_fin->to.s.sa_family, dst_fin->proto);
+            goto error;
+        }
+    }
 
 	/* Version && proto && length */
 	hdr.hp_l = sizeof(struct hep_hdr);
@@ -1627,14 +1755,16 @@ static int trace_send_hep_duplicate(str *body, str *from, str *to)
 	memcpy((void*)(buffer + buflen) , (void*)body->s, body->len);
 	buflen +=body->len;
 
-	if (msg_send(&dst, buffer, buflen)<0)
+	if (msg_send(dst_fin, buffer, buflen)<0)
 	{
 		LM_ERR("cannot send hep duplicate message\n");
 		goto error;
 	}
 
+    if (p) {
 	free_proxy(p); /* frees only p content, not p itself */
 	pkg_free(p);
+    }
 	pkg_free(buffer);
 	return 0;
 error: