diff --git a/src/modules/sipcapture/hep.h b/src/modules/sipcapture/hep.h index 10812a20f57..e4ff77b0493 100644 --- a/src/modules/sipcapture/hep.h +++ b/src/modules/sipcapture/hep.h @@ -177,5 +177,52 @@ struct hep_generic_recv { typedef struct hep_generic_recv hep_generic_recv_t; +#define HEP3_PACK_INIT(buf) \ + union { \ + hep_chunk_uint8_t chunk8; \ + hep_chunk_uint16_t chunk16; \ + hep_chunk_uint32_t chunk32; \ + hep_chunk_t chunkpl; \ + uint16_t len; \ + } _tmpu; \ + char *_tmp_p = (buf); \ + memcpy(_tmp_p, "HEP3", 4); \ + _tmp_p += 4 + 2/* skip length */; + +#define HEP3_PACK_FINALIZE(buf, lenp) \ + do { \ + _tmpu.len = htons(_tmp_p - (char *)(buf)); \ + memcpy((void *)(&(((hep_ctrl_t *)(buf))->length)), (void*)&_tmpu.len, 2); \ + *lenp = _tmp_p - (char *)(buf); \ + } while (0) + +#define _HEP3_PACK_CHUNK_GENERIC(type, tmpvar, vid, tid, val) \ + do { \ + (tmpvar).chunk.vendor_id = htons(vid); \ + (tmpvar).chunk.type_id = htons(tid); \ + (tmpvar).chunk.length = htons(sizeof(type)); \ + (tmpvar).data = (val); \ + memcpy(_tmp_p, (void *) &(tmpvar), sizeof(type)); \ + _tmp_p += sizeof(type); \ + } while (0) + +#define HEP3_PACK_CHUNK_UINT8(vid, tid, val) _HEP3_PACK_CHUNK_GENERIC(hep_chunk_uint8_t, _tmpu.chunk8, vid, tid, val) +#define HEP3_PACK_CHUNK_UINT16(vid, tid, val) _HEP3_PACK_CHUNK_GENERIC(hep_chunk_uint16_t, _tmpu.chunk16, vid, tid, htons(val)) +#define HEP3_PACK_CHUNK_UINT16_NBO(vid, tid, val) _HEP3_PACK_CHUNK_GENERIC(hep_chunk_uint16_t, _tmpu.chunk16, vid, tid, (val)) +#define HEP3_PACK_CHUNK_UINT32(vid, tid, val) _HEP3_PACK_CHUNK_GENERIC(hep_chunk_uint32_t, _tmpu.chunk32, vid, tid, htonl(val)) +#define HEP3_PACK_CHUNK_UINT32_NBO(vid, tid, val) _HEP3_PACK_CHUNK_GENERIC(hep_chunk_uint32_t, _tmpu.chunk32, vid, tid, (val)) + +#define HEP3_PACK_CHUNK_DATA(vid, tid, val, len) \ + do { \ + _tmpu.chunkpl.vendor_id = htons(vid); \ + _tmpu.chunkpl.type_id = htons(tid); \ + _tmpu.chunkpl.length = htons(sizeof(hep_chunk_t) + (len)); \ + memcpy(_tmp_p, (void *) &_tmpu.chunkpl, sizeof(hep_chunk_t)); \ + _tmp_p += sizeof(hep_chunk_t); \ + memcpy(_tmp_p, (void *) (val), len); \ + _tmp_p += len; \ + } while (0) + +#define HEP3_PACK_CHUNK_IP6(vid, tid, paddr) HEP3_PACK_CHUNK_DATA(vid, tid, paddr, sizeof(struct in6_addr)) #endif diff --git a/src/modules/siptrace/doc/siptrace.xml b/src/modules/siptrace/doc/siptrace.xml index 3d2014fb489..427eed6742e 100644 --- a/src/modules/siptrace/doc/siptrace.xml +++ b/src/modules/siptrace/doc/siptrace.xml @@ -28,6 +28,11 @@ Mierla miconda@gmail.com + + Giacomo + Vacca + giacomo.vacca@gmail.com + 2010 diff --git a/src/modules/siptrace/doc/siptrace_admin.xml b/src/modules/siptrace/doc/siptrace_admin.xml index f121946ce15..f1924abe94d 100644 --- a/src/modules/siptrace/doc/siptrace_admin.xml +++ b/src/modules/siptrace/doc/siptrace_admin.xml @@ -17,8 +17,8 @@ Overview The SIPtrace module offer a possibility to store incoming and outgoing SIP - messages in a database and/or duplicate to the capturing server (using HEP - the Homer encapsulation protocol or plain SIP mode) + messages in a database and/or duplicate to the capturing server (using HEP, + the Homer encapsulation protocol, or plain SIP mode) There are two ways of storing information: @@ -42,8 +42,7 @@ - The tracing can be turned on/off using Kamailio mi or RPC - commands. + The tracing can be turned on/off using Kamailio RPC commands. &ctltool; fifo sip_trace on @@ -57,12 +56,12 @@
&kamailio; Modules - The following modules must be loaded before this module: + The following modules must be conditionally loaded before this module: A database module - Mysql, Postgres, - dbtext, unixODBC... + dbtext, unixODBC... Optional, if tracing to DB is enabled. @@ -199,7 +198,7 @@ modparam("siptrace", "traced_user_avp", "$avp(s:user)") store the SIP messages. If it is not set, the value of table parameter is used. In this way one can select dynamically where to store the traced messages. The table - must exists, and must have the same structure as the sip_trace + must exist, and must have the same structure as the sip_trace table. @@ -395,8 +394,9 @@ modparam("siptrace", "hep_mode_on", 1) <varname>hep_version</varname> (integer) The parameter indicate the version of the HEP protocol. - Can be 1 or 2. In HEPv2 the timestamp and capture agent ID - will be included to HEP header. + Can be 1, 2 or 3. + In HEPv2 and HEPv3 the timestamp and capture agent ID will be + included in the HEP header. @@ -407,7 +407,7 @@ modparam("siptrace", "hep_mode_on", 1) Set <varname>hep_version</varname> parameter ... -modparam("siptrace", "hep_version", 2) +modparam("siptrace", "hep_version", 3) ... @@ -416,8 +416,8 @@ modparam("siptrace", "hep_version", 2) <varname>hep_capture_id</varname> (integer) The parameter indicate the capture agent ID for the HEPv2 - protocol. - Limitation: 16-bit integer. + or HEPv3 protocol. + Limitation: 16-bit integer for HEPv2, 32-bit for HEPv3. @@ -425,8 +425,7 @@ modparam("siptrace", "hep_version", 2) - Set <varname>hep_capture_id</varname> - parameter + Set <varname>hep_capture_id</varname> parameter ... modparam("siptrace", "hep_capture_id", 234) @@ -456,7 +455,7 @@ modparam("siptrace", "trace_delayed", 1)
<varname>force_send_sock</varname> (str) - The local interface in the form of SIP uri from where to send + The local interface in the form of SIP URI from where to send the duplicated traffic. In the absence of this parameter &kamailio; automatically picks an interface. @@ -490,6 +489,25 @@ modparam("siptrace", "force_send_sock", "sip:10.1.1.2:5000") ... modparam("siptrace", "trace_mode", 1) ... + + +
+
+ <varname>auth_key</varname> (integer) + +A string with an authorization key. +Supported on HEPv3 only. + + + Default value is empty. + + + Set <varname>auth_key</varname> + parameter + +... +modparam("siptrace", "auth_key", "spoihepuirthpeuia") +...
@@ -499,7 +517,7 @@ modparam("siptrace", "trace_mode", 1) Functions
- <function moreinfo="none">sip_trace([address])</function> + <function moreinfo="none">sip_trace([address][, correlation_id])</function> Store or forward the current processed SIP message in database. It is stored in the @@ -508,10 +526,14 @@ modparam("siptrace", "trace_mode", 1) Meaning of the parameters is as follows: - address - The address in form of SIP uri + 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. + correlation_id - A string with a correlation ID + to be added to the HEP header when using HEPv3. + It's possible to use PVs. + @@ -529,6 +551,8 @@ sip_trace(); ... sip_trace("sip:10.1.1.2:5085"); ... +sip_trace("sip:10.1.1.2:5085", "$ci-abc"); +...
@@ -549,7 +573,7 @@ sip_trace("sip:10.1.1.2:5085");
Parameters: - on or off: turns on/off SIP message tracing.. + on or off: turns on/off SIP message tracing. Possible values are: on diff --git a/src/modules/siptrace/siptrace.c b/src/modules/siptrace/siptrace.c index cf7d922bce4..cfe281d086f 100644 --- a/src/modules/siptrace/siptrace.c +++ b/src/modules/siptrace/siptrace.c @@ -33,6 +33,7 @@ #include #include #include "../../core/sr_module.h" +#include "../../core/mod_fix.h" #include "../../core/dprint.h" #include "../../core/ut.h" #include "../../core/ip_addr.h" @@ -90,7 +91,8 @@ 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*, struct dest_info*, char*); +static int sip_trace(struct sip_msg*, struct dest_info*, str *correlation_id_str, char*); +static int sip_trace2(struct sip_msg *, char *dest, char *correlation_id); static int fixup_siptrace(void ** param, int param_no); static int sip_trace_store_db(struct _siptrace_data* sto); @@ -103,7 +105,9 @@ 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, struct dest_info*); +static int trace_send_hep_duplicate(str *body, str *from, str *to, struct dest_info*, str *correlation_id); +static int trace_send_hep2_duplicate(str *body, str *from, str *to, struct dest_info*); +static int trace_send_hep3_duplicate(str *body, str *from, str *to, struct dest_info*, str *correlation_id); static int pipport2su (char *pipport, union sockaddr_union *tmp_su, unsigned int *proto); int siptrace_net_data_recv(void *data); @@ -140,6 +144,8 @@ int trace_delayed = 0; int hep_version = 1; int hep_capture_id = 1; +int hep_vendor_id = 0; +str auth_key_str = {0, 0}; int xheaders_write = 0; int xheaders_read = 0; @@ -177,6 +183,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, fixup_siptrace, 0, ANY_ROUTE}, + {"sip_trace", (cmd_function)sip_trace2, 2, fixup_spve_spve, 0, ANY_ROUTE}, {0, 0, 0, 0, 0, 0} }; @@ -185,6 +192,7 @@ static cmd_export_t cmds[] = { * Exported parameters */ static param_export_t params[] = { + {"auth_key", PARAM_STR, &auth_key_str }, {"db_url", PARAM_STR, &db_url }, {"table", PARAM_STR, &siptrace_table }, {"date_column", PARAM_STR, &date_column }, @@ -285,7 +293,7 @@ static int mod_init(void) *trace_to_database_flag = trace_to_database; - if(hep_version != 1 && hep_version != 2) { + if(hep_version != 1 && hep_version != 2 && hep_version != 3) { LM_ERR("unsupported version of HEP"); return -1; } @@ -305,8 +313,7 @@ static int mod_init(void) } } - if(hep_version != 1 && hep_version != 2) { - + if(hep_version != 1 && hep_version != 2 && hep_version != 3) { LM_ERR("unsupported version of HEP"); return -1; } @@ -726,7 +733,7 @@ static int sip_trace_xheaders_free(struct _siptrace_data *sto) return 0; } -static int sip_trace_store(struct _siptrace_data *sto, struct dest_info *dst) +static int sip_trace_store(struct _siptrace_data *sto, struct dest_info *dst, str *correlation_id_str) { if(sto==NULL) { @@ -743,7 +750,7 @@ static int sip_trace_store(struct _siptrace_data *sto, struct dest_info *dst) if (sip_trace_xheaders_write(sto) != 0) return -1; - if(hep_mode_on) trace_send_hep_duplicate(&sto->body, &sto->fromip, &sto->toip, dst); + if(hep_mode_on) trace_send_hep_duplicate(&sto->body, &sto->fromip, &sto->toip, dst, correlation_id_str); else trace_send_duplicate(sto->body.s, sto->body.len, dst); if (sip_trace_xheaders_free(sto) != 0) @@ -894,8 +901,8 @@ static int sip_trace_store_db(struct _siptrace_data *sto) } static int fixup_siptrace(void** param, int param_no) { - char *duri = (char*) *param; - struct sip_uri dup_uri; + char *duri; + struct sip_uri uri; struct dest_info *dst = NULL; struct proxy_l * p = NULL; str dup_uri_str = { 0, 0 }; @@ -904,19 +911,35 @@ static int fixup_siptrace(void** param, int param_no) { LM_DBG("params:%s\n", (char*)*param); return 0; } - if (!(*duri)) { - LM_ERR("invalid dup URI\n"); - return -1; + + if (((char*)(*param))[0] == '\0') { + // Empty URI, use the URI set at module level (dup_uri) + if (dup_uri) { + uri = *dup_uri; + } + else { + LM_ERR("Missing duplicate URI\n"); + return -1; + } } - LM_DBG("sip_trace URI:%s\n", (char*)*param); + else { + duri = (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 (!(*duri)) { + LM_ERR("invalid dup URI\n"); + return -1; + } - if (parse_uri(dup_uri_str.s, dup_uri_str.len, &dup_uri) < 0) { - LM_ERR("bad dup uri\n"); - return -1; + LM_DBG("sip_trace URI:%s\n", duri); + + dup_uri_str.s = duri; + dup_uri_str.len = strlen(dup_uri_str.s); + memset(&uri, 0, sizeof(struct sip_uri)); + + if (parse_uri(dup_uri_str.s, dup_uri_str.len, &uri) < 0) { + LM_ERR("bad dup uri\n"); + return -1; + } } dst = (struct dest_info *) pkg_malloc(sizeof(struct dest_info)); @@ -927,7 +950,7 @@ static int fixup_siptrace(void** param, int param_no) { 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, + p = mk_proxy(&uri.host, (uri.port_no) ? uri.port_no : SIP_PORT, dst->proto); if (p == 0) { LM_ERR("bad host name in uri\n"); @@ -947,7 +970,71 @@ static int fixup_siptrace(void** param, int param_no) { return 0; } -static int sip_trace(struct sip_msg *msg, struct dest_info * dst, char *dir) +static int sip_trace2(struct sip_msg *msg, char *dest, char *correlation_id) +{ + struct dest_info *dst = NULL; + struct sip_uri uri; + struct proxy_l * p = NULL; + str dup_uri_str = { 0, 0 }; + str correlation_id_str = {0, 0};; + + if(fixup_get_svalue(msg, (gparam_t*)dest, &dup_uri_str)!=0) { + LM_ERR("unable to parse the dest URI string\n"); + return -1; + } + + // If the dest is empty, use the module parameter, if set + if (dup_uri_str.len == 0) { + if (dup_uri) { + uri = *dup_uri; + } + else { + LM_ERR("Missing duplicate URI\n"); + return -1; + } + } + else { + memset(&uri, 0, sizeof(struct sip_uri)); + if (parse_uri(dup_uri_str.s, dup_uri_str.len, &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(&uri.host, (uri.port_no) ? 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); + + /* free temporary proxy*/ + if (p) { + free_proxy(p); /* frees only p content, not p itself */ + pkg_free(p); + } + + if(fixup_get_svalue(msg, (gparam_t*)correlation_id, &correlation_id_str)!=0) { + LM_ERR("unable to parse the correlation id\n"); + return -1; + } + + return sip_trace(msg, dst, &correlation_id_str, NULL); +} + +static int sip_trace(struct sip_msg *msg, struct dest_info * dst, str *correlation_id_str, char *dir) { struct _siptrace_data sto; struct onsend_info *snd_inf = NULL; @@ -1061,7 +1148,7 @@ static int sip_trace(struct sip_msg *msg, struct dest_info * dst, char *dir) sto.stat = siptrace_req; } #endif - return sip_trace_store(&sto, dst); + return sip_trace_store(&sto, dst, correlation_id_str); } #define trace_is_off(_msg) \ @@ -1244,7 +1331,7 @@ static void trace_onreq_out(struct cell* t, int type, struct tmcb_params *ps) sto.stat = siptrace_req; #endif - sip_trace_store(&sto, NULL); + sip_trace_store(&sto, NULL, NULL); return; } @@ -1316,7 +1403,7 @@ static void trace_onreply_in(struct cell* t, int type, struct tmcb_params *ps) sto.stat = siptrace_rpl; #endif - sip_trace_store(&sto, NULL); + sip_trace_store(&sto, NULL, NULL); return; } @@ -1426,7 +1513,7 @@ static void trace_onreply_out(struct cell* t, int type, struct tmcb_params *ps) sto.stat = siptrace_rpl; #endif - sip_trace_store(&sto, NULL); + sip_trace_store(&sto, NULL, NULL); return; } @@ -1435,7 +1522,7 @@ static void trace_sl_ack_in(sl_cbp_t *slcbp) sip_msg_t *req; LM_DBG("storing ack...\n"); req = slcbp->req; - sip_trace(req, 0, 0); + sip_trace(req, 0, NULL, 0); } static void trace_sl_onreply_out(sl_cbp_t *slcbp) @@ -1513,7 +1600,7 @@ static void trace_sl_onreply_out(sl_cbp_t *slcbp) sto.stat = siptrace_rpl; #endif - sip_trace_store(&sto, NULL); + sip_trace_store(&sto, NULL, NULL); return; } @@ -1579,7 +1666,181 @@ static int trace_send_duplicate(char *buf, int len, struct dest_info *dst2) return -1; } -static int trace_send_hep_duplicate(str *body, str *from, str *to, struct dest_info * dst2) +static int trace_send_hep_duplicate(str *body, str *from, str *to, struct dest_info * dst2, str *correlation_id_str) +{ + switch (hep_version) { + case 1: + case 2: + return trace_send_hep2_duplicate(body, from, to, dst2); + case 3: + return trace_send_hep3_duplicate(body, from, to, dst2, correlation_id_str); + default: + LM_ERR("Unsupported HEP version\n"); + return -1; + } +} + +static int trace_send_hep3_duplicate(str *body, str *from, str *to, struct dest_info * dst2, str *correlation_id_str) +{ + struct socket_info *si; + void* buffer = NULL; + unsigned int len, proto; + struct dest_info dst; + struct dest_info* dst_fin = NULL; + struct proxy_l* p = NULL; + union sockaddr_union from_su; + union sockaddr_union to_su; + struct timeval tvb; + struct timezone tz; + + gettimeofday( &tvb, &tz ); + + if (pipport2su(from->s, &from_su, &proto)==-1 || (pipport2su(to->s, &to_su, &proto)==-1)) + goto error; + + if(from_su.s.sa_family != to_su.s.sa_family) { + LM_ERR("interworking detected ?\n"); + goto error; + } + + len = sizeof(struct hep_ctrl); // header + len += sizeof(struct hep_chunk_uint8); // proto_family + len += sizeof(struct hep_chunk_uint8); // proto_id + if (from_su.s.sa_family == AF_INET6) { + len += sizeof(struct hep_chunk_ip6); // src IPv6 address + len += sizeof(struct hep_chunk_ip6); // dst IPv6 address + } + else { + len += sizeof(struct hep_chunk_ip4); // src IPv4 address + len += sizeof(struct hep_chunk_ip4); // dst IPv4 address + } + len += sizeof(struct hep_chunk_uint16); // source port + len += sizeof(struct hep_chunk_uint16); // destination port + len += sizeof(struct hep_chunk_uint32); // timestamp + len += sizeof(struct hep_chunk_uint32); // timestamp us + len += sizeof(struct hep_chunk_uint8); // proto_type (SIP) + len += sizeof(struct hep_chunk_uint32); // capture ID + len += sizeof(struct hep_chunk); // payload + + if (auth_key_str.s && auth_key_str.len > 0) { + len += sizeof(struct hep_chunk) + auth_key_str.len; + } + + if (correlation_id_str) { + if (correlation_id_str->len > 0) { + len += sizeof(struct hep_chunk) + correlation_id_str->len; + } + } + + len += body->len; + + if (unlikely(len>BUF_SIZE)){ + goto error; + } + + buffer = (void *)pkg_malloc(len); + if (!buffer) { + LM_ERR("out of memory\n"); + goto error; + } + + HEP3_PACK_INIT(buffer); + HEP3_PACK_CHUNK_UINT8 (0, 0x0001, from_su.s.sa_family); + HEP3_PACK_CHUNK_UINT8 (0, 0x0002, proto); + if (from_su.s.sa_family == AF_INET) { + HEP3_PACK_CHUNK_UINT32_NBO(0, 0x0003, from_su.sin.sin_addr.s_addr); + HEP3_PACK_CHUNK_UINT32_NBO(0, 0x0004, to_su.sin.sin_addr.s_addr); + HEP3_PACK_CHUNK_UINT16_NBO(0, 0x0007, htons(from_su.sin.sin_port)); + HEP3_PACK_CHUNK_UINT16_NBO(0, 0x0008, htons(to_su.sin.sin_port)); + } else if (from_su.s.sa_family == AF_INET6) { + HEP3_PACK_CHUNK_IP6 (0, 0x0005, &from_su.sin6.sin6_addr); + HEP3_PACK_CHUNK_IP6 (0, 0x0006, &to_su.sin6.sin6_addr); + HEP3_PACK_CHUNK_UINT16_NBO(0, 0x0007, htons(from_su.sin6.sin6_port)); + HEP3_PACK_CHUNK_UINT16_NBO(0, 0x0008, htons(to_su.sin6.sin6_port)); + } else { + LM_ERR("unknown address family [%u]\n", dst.send_sock->address.af); + goto error; + } + + HEP3_PACK_CHUNK_UINT32(0, 0x0009, tvb.tv_sec); + HEP3_PACK_CHUNK_UINT32(0, 0x000a, tvb.tv_usec); + HEP3_PACK_CHUNK_UINT8 (0, 0x000b, 0x01); /* protocol type: SIP */ + HEP3_PACK_CHUNK_UINT32(0, 0x000c, hep_capture_id); + + if (correlation_id_str) { + if (correlation_id_str->len > 0) { + HEP3_PACK_CHUNK_DATA (0, 0x0011, correlation_id_str->s, correlation_id_str->len); + } + } + if (auth_key_str.len) { + HEP3_PACK_CHUNK_DATA(0, 0x000e, auth_key_str.s, auth_key_str.len); + } + HEP3_PACK_CHUNK_DATA (0, 0x000f, body->s, body->len); + HEP3_PACK_FINALIZE(buffer, &len); + + if (!dst2){ + init_dest_info(&dst); + 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"); + goto error; + } + + hostent2su(&dst.to, &p->host, p->addr_idx, (p->port)?p->port:SIP_PORT); + 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; + } + } + + if (msg_send_buffer(dst_fin, buffer, len, 1)<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: + if(p) + { + free_proxy(p); /* frees only p content, not p itself */ + pkg_free(p); + } + if(buffer) pkg_free(buffer); + return -1; +} + +static int trace_send_hep2_duplicate(str *body, str *from, str *to, struct dest_info * dst2) { struct dest_info dst; struct socket_info *si; @@ -1901,7 +2162,7 @@ int siptrace_net_data_recv(void *data) sto.dir = "in"; - trace_send_hep_duplicate(&sto.body, &sto.fromip, &sto.toip, NULL); + trace_send_hep_duplicate(&sto.body, &sto.fromip, &sto.toip, NULL, NULL); return 0; } @@ -1949,7 +2210,7 @@ int siptrace_net_data_send(void *data) sto.dir = "out"; - trace_send_hep_duplicate(&sto.body, &sto.fromip, &sto.toip, NULL); + trace_send_hep_duplicate(&sto.body, &sto.fromip, &sto.toip, NULL, NULL); return 0; }