static int trace_send_hep_duplicate(str *body, str *fromproto, str *fromip, unsigned short fromport, str *toproto, str *toip, unsigned short toport) { struct proxy_l * p=NULL /* make gcc happy */; int ret; union sockaddr_union from_su; union sockaddr_union to_su; unsigned int proto; struct socket_info* send_sock; union sockaddr_union* to = NULL; int heplen; char *hepbuf; if(body->s==NULL || body->len <= 0) return -1; if(dup_uri_str.s==0 || dup_uri==NULL) return 0; /* Convert proto:ip:port to sockaddress union SRC IP */ if (pipport2su(fromproto, fromip, fromport, &from_su, &proto)==-1 || (pipport2su(toproto, toip, toport, &to_su, &proto)==-1)) goto error; /* check if from and to are in the same family*/ if(from_su.s.sa_family != to_su.s.sa_family) { LM_ERR("ERROR: trace_send_hep_duplicate: interworking detected ?\n"); goto error; } /* create a temporary proxy*/ proto = PROTO_UDP; p=mk_proxy(&dup_uri->host, (dup_uri->port_no)?dup_uri->port_no:SIP_PORT,proto, 0); if (p==0){ LM_ERR("bad host name in uri\n"); return -1; } to=(union sockaddr_union*)pkg_malloc(sizeof(union sockaddr_union)); if (to==0){ LM_ERR("out of pkg memory\n"); return -1; } hostent2su(to, &p->host, p->addr_idx, (p->port)?p->port:SIP_PORT); if (hep_api.pack_hep(&from_su, to, proto, body->s, body->len, &hepbuf, &heplen)) { LM_ERR("failed to do hep packing\n"); return -1; } ret = -1; do { send_sock=get_send_socket(0, to, proto); if (send_sock==0){ LM_ERR("can't forward to af %d, proto %d no corresponding listening socket\n", to->s.sa_family,proto); continue; } if (msg_send(send_sock, PROTO_HEP, to, 0, hepbuf, heplen, NULL)<0){ LM_ERR("cannot send duplicate message\n"); continue; } ret = 0; break; }while( get_next_su( p, to, 0)==0 ); free_proxy(p); /* frees only p content, not p itself */ pkg_free(p); pkg_free(to); pkg_free(hepbuf); return ret; error: if(p) { free_proxy(p); /* frees only p content, not p itself */ pkg_free(p); } if(to) pkg_free(to); return -1; }
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; union sockaddr_union to_su; unsigned int len, buflen, proto; struct hep_hdr hdr; struct hep_iphdr hep_ipheader; struct hep_timehdr hep_time; struct timeval tvb; struct timezone tz; struct hep_ip6hdr hep_ip6header; if(body->s==NULL || body->len <= 0) return -1; if(dup_uri_str.s==0 || dup_uri==NULL) return 0; gettimeofday( &tvb, &tz ); /* message length */ len = body->len + sizeof(struct hep_ip6hdr) + sizeof(struct hep_hdr) + sizeof(struct hep_timehdr);; /* The packet is too big for us */ if (unlikely(len>BUF_SIZE)){ goto error; } /* Convert proto:ip:port to sockaddress union SRC IP */ if (pipport2su(from->s, &from_su, &proto)==-1 || (pipport2su(to->s, &to_su, &proto)==-1)) goto error; /* check if from and to are in the same family*/ if(from_su.s.sa_family != to_su.s.sa_family) { LM_ERR("interworking detected ?\n"); goto error; } 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"); 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; } } /* Version && proto && length */ hdr.hp_l = sizeof(struct hep_hdr); hdr.hp_v = hep_version; hdr.hp_p = proto; /* AND the last */ if (from_su.s.sa_family==AF_INET){ /* prepare the hep headers */ hdr.hp_f = AF_INET; hdr.hp_sport = htons(from_su.sin.sin_port); hdr.hp_dport = htons(to_su.sin.sin_port); hep_ipheader.hp_src = from_su.sin.sin_addr; hep_ipheader.hp_dst = to_su.sin.sin_addr; len = sizeof(struct hep_iphdr); } else if (from_su.s.sa_family==AF_INET6){ /* prepare the hep6 headers */ hdr.hp_f = AF_INET6; hdr.hp_sport = htons(from_su.sin6.sin6_port); hdr.hp_dport = htons(to_su.sin6.sin6_port); hep_ip6header.hp6_src = from_su.sin6.sin6_addr; hep_ip6header.hp6_dst = to_su.sin6.sin6_addr; len = sizeof(struct hep_ip6hdr); } else { LM_ERR("Unsupported protocol family\n"); goto error;; } hdr.hp_l +=len; if (hep_version == 2){ len += sizeof(struct hep_timehdr); } len += sizeof(struct hep_hdr) + body->len; buffer = (void *)pkg_malloc(len+1); if (buffer==0){ LM_ERR("out of memory\n"); goto error; } /* Copy job */ memset(buffer, '\0', len+1); /* copy hep_hdr */ memcpy((void*)buffer, &hdr, sizeof(struct hep_hdr)); buflen = sizeof(struct hep_hdr); /* hep_ip_hdr */ if(from_su.s.sa_family==AF_INET) { memcpy((void*)buffer + buflen, &hep_ipheader, sizeof(struct hep_iphdr)); buflen += sizeof(struct hep_iphdr); } else { memcpy((void*)buffer+buflen, &hep_ip6header, sizeof(struct hep_ip6hdr)); buflen += sizeof(struct hep_ip6hdr); } if(hep_version == 2) { hep_time.tv_sec = tvb.tv_sec; hep_time.tv_usec = tvb.tv_usec; hep_time.captid = hep_capture_id; memcpy((void*)buffer+buflen, &hep_time, sizeof(struct hep_timehdr)); buflen += sizeof(struct hep_timehdr); } /* PAYLOAD */ memcpy((void*)(buffer + buflen) , (void*)body->s, body->len); buflen +=body->len; if (msg_send_buffer(dst_fin, buffer, buflen, 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; }