plugin_trunk wip
This commit is contained in:
parent
36231e5d5c
commit
9c3dad1eb8
@ -83,8 +83,8 @@ static redirected_cache_element_t redirected_cache;
|
||||
static int plugin_regex_init(void);
|
||||
static int plugin_regex_process(sip_ticket_t *ticket);
|
||||
static int plugin_regex_redirect(sip_ticket_t *ticket);
|
||||
regmatch_t * rmatch (char *buf, int size, regex_t *re);
|
||||
int rreplace (char *buf, int size, regex_t *re, regmatch_t pmatch[], char *rp);
|
||||
static regmatch_t * rmatch (char *buf, int size, regex_t *re);
|
||||
static int rreplace (char *buf, int size, regex_t *re, regmatch_t pmatch[], char *rp);
|
||||
|
||||
|
||||
/*
|
||||
@ -124,7 +124,7 @@ int PLUGIN_END(plugin_def_t *plugin_def){
|
||||
/*
|
||||
* Workload code
|
||||
*/
|
||||
int plugin_regex_init(void) {
|
||||
static int plugin_regex_init(void) {
|
||||
int i;
|
||||
int sts, retsts;
|
||||
int num_entries;
|
||||
@ -370,7 +370,7 @@ static int plugin_regex_redirect(sip_ticket_t *ticket) {
|
||||
* if a match is actually there.
|
||||
*/
|
||||
#define NMATCHES 10
|
||||
regmatch_t * rmatch (char *buf, int size, regex_t *re) {
|
||||
static regmatch_t * rmatch (char *buf, int size, regex_t *re) {
|
||||
static regmatch_t pm[NMATCHES]; /* regoff_t is int so size is int */
|
||||
|
||||
/* perform the match */
|
||||
@ -380,7 +380,7 @@ regmatch_t * rmatch (char *buf, int size, regex_t *re) {
|
||||
return &pm[0];
|
||||
}
|
||||
|
||||
int rreplace (char *buf, int size, regex_t *re, regmatch_t pmatch[], char *rp) {
|
||||
static int rreplace (char *buf, int size, regex_t *re, regmatch_t pmatch[], char *rp) {
|
||||
char *pos;
|
||||
int sub, so, n;
|
||||
|
||||
|
||||
@ -24,6 +24,7 @@
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <regex.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
@ -48,19 +49,26 @@ extern struct siproxd_config configuration;
|
||||
static struct plugin_config {
|
||||
stringa_t trunk_name;
|
||||
stringa_t trunk_account;
|
||||
stringa_t trunk_numbers;
|
||||
stringa_t trunk_numbers_regex;
|
||||
} plugin_cfg;
|
||||
|
||||
/* Instructions for config parser */
|
||||
static cfgopts_t plugin_cfg_opts[] = {
|
||||
{ "plugin_siptrunk_name", TYP_STRINGA,&plugin_cfg.trunk_name, {0, NULL} },
|
||||
{ "plugin_siptrunk_account", TYP_STRINGA,&plugin_cfg.trunk_account, {0, NULL} },
|
||||
{ "plugin_siptrunk_numbers", TYP_STRINGA,&plugin_cfg.trunk_numbers, {0, NULL} },
|
||||
{ "plugin_siptrunk_numbers_regex", TYP_STRINGA,&plugin_cfg.trunk_numbers_regex, {0, NULL} },
|
||||
{0, 0, 0}
|
||||
};
|
||||
|
||||
/* local storage needed for regular expression handling */
|
||||
static regex_t *re;
|
||||
|
||||
/* Prototypes */
|
||||
static int sip_fix_topvia(sip_ticket_t *ticket);
|
||||
static int plugin_siptrunk_init(void);
|
||||
static int plugin_siptrunk_process(sip_ticket_t *ticket);
|
||||
static regmatch_t * rmatch (char *buf, int size, regex_t *re);
|
||||
//static int rreplace (char *buf, int size, regex_t *re, regmatch_t pmatch[], char *rp);
|
||||
|
||||
|
||||
/*&&&+++
|
||||
1) register
|
||||
@ -119,8 +127,7 @@ int PLUGIN_INIT(plugin_def_t *plugin_def) {
|
||||
return STS_FAILURE;
|
||||
}
|
||||
|
||||
INFO("plugin_siptrunk is initialized");
|
||||
return STS_SUCCESS;
|
||||
return plugin_siptrunk_init();
|
||||
}
|
||||
|
||||
/*
|
||||
@ -129,43 +136,7 @@ int PLUGIN_INIT(plugin_def_t *plugin_def) {
|
||||
*/
|
||||
int PLUGIN_PROCESS(int stage, sip_ticket_t *ticket){
|
||||
/* stage contains the PLUGIN_* value - the stage of SIP processing. */
|
||||
int type;
|
||||
osip_via_t *via;
|
||||
struct sockaddr_in from;
|
||||
|
||||
type = ticket->direction;
|
||||
|
||||
DEBUGC(DBCLASS_PLUGIN, "plugin_siptrunk: type=%i", type);
|
||||
|
||||
/* Incoming SIP response? */
|
||||
if (type == RESTYP_INCOMING) {
|
||||
/* a Via header needs to be present in response */
|
||||
if((via = osip_list_get(&(ticket->sipmsg->vias), 0)) == NULL) {
|
||||
WARN("no Via header found in incoming SIP message");
|
||||
return STS_SUCCESS;
|
||||
}
|
||||
|
||||
/* check for Via IP in configured range */
|
||||
DEBUGC(DBCLASS_PLUGIN, "plugin_siptrunk: processing VIA host [%s]",
|
||||
via->host);
|
||||
get_ip_by_host(via->host, &(from.sin_addr));
|
||||
if ((plugin_cfg.networks != NULL) &&
|
||||
(strcmp(plugin_cfg.networks, "") !=0) &&
|
||||
(process_aclist(plugin_cfg.networks, ticket->from) == STS_SUCCESS) &&
|
||||
(process_aclist(plugin_cfg.networks, from) == STS_SUCCESS)) {
|
||||
|
||||
/* VIA & Sender IP are in list, fix Via header */
|
||||
DEBUGC(DBCLASS_PLUGIN, "plugin_siptrunk: replacing a bogus via");
|
||||
|
||||
if (sip_fix_topvia(ticket) == STS_FAILURE) {
|
||||
ERROR("patching inbound Via failed!");
|
||||
}
|
||||
} else {
|
||||
DEBUGC(DBCLASS_PLUGIN, "plugin_siptrunk: not match, returning.");
|
||||
}
|
||||
DEBUGC(DBCLASS_PLUGIN, "plugin_siptrunk: done");
|
||||
}
|
||||
return STS_SUCCESS;
|
||||
return plugin_siptrunk_process(ticket);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -175,39 +146,165 @@ DEBUGC(DBCLASS_PLUGIN, "plugin_siptrunk: type=%i", type);
|
||||
* connections, whatever the plugin messes around with)
|
||||
*/
|
||||
int PLUGIN_END(plugin_def_t *plugin_def){
|
||||
INFO("plugin_siptrunk ends here");
|
||||
return STS_SUCCESS;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------*/
|
||||
static int sip_fix_topvia(sip_ticket_t *ticket) {
|
||||
osip_via_t *via;
|
||||
int sts;
|
||||
/*
|
||||
* Workload code
|
||||
*/
|
||||
static int plugin_siptrunk_init(void) {
|
||||
int i;
|
||||
int sts, retsts;
|
||||
int num_entries;
|
||||
char errbuf[256];
|
||||
|
||||
if((via = osip_list_get(&(ticket->sipmsg->vias), 0)) != NULL) {
|
||||
/* 1) IP of Via has been checked beforehand. */
|
||||
retsts = STS_SUCCESS;
|
||||
|
||||
/* 2) remove broken via header */
|
||||
DEBUGC(DBCLASS_PLUGIN, "plugin_siptrunk: removing topmost via");
|
||||
sts = osip_list_remove(&(ticket->sipmsg->vias), 0);
|
||||
osip_via_free (via);
|
||||
via = NULL;
|
||||
|
||||
/* 3) add my via header */
|
||||
DEBUGC(DBCLASS_PLUGIN, "plugin_siptrunk: adding new via");
|
||||
if (ticket->direction == RESTYP_INCOMING) {
|
||||
sts = sip_add_myvia(ticket, IF_OUTBOUND);
|
||||
if (sts == STS_FAILURE) {
|
||||
ERROR("adding my outbound via failed!");
|
||||
}
|
||||
} else {
|
||||
sts = sip_add_myvia(ticket, IF_INBOUND);
|
||||
if (sts == STS_FAILURE) {
|
||||
ERROR("adding my inbound via failed!");
|
||||
}
|
||||
}
|
||||
/* check for equal entries of trunk_name and trunk_account */
|
||||
if (plugin_cfg.trunk_name.used != plugin_cfg.trunk_account.used) {
|
||||
ERROR("Plugin '%s': number of trunks (%i) and number of "
|
||||
"accounts (%i) differ!", name,
|
||||
plugin_cfg.trunk_name.used, plugin_cfg.trunk_account.used);
|
||||
return STS_FAILURE;
|
||||
}
|
||||
|
||||
if (plugin_cfg.trunk_name.used != plugin_cfg.trunk_numbers_regex.used) {
|
||||
ERROR("Plugin '%s': number of trunks (%i) and number of "
|
||||
"number blocks (%i) differ!", name,
|
||||
plugin_cfg.trunk_name.used, plugin_cfg.trunk_numbers_regex.used);
|
||||
return STS_FAILURE;
|
||||
}
|
||||
|
||||
/* allocate space for regexes and compile them */
|
||||
num_entries = plugin_cfg.trunk_numbers_regex.used;
|
||||
re = malloc(num_entries*sizeof(re[0]));
|
||||
for (i=0; i < num_entries; i++) {
|
||||
sts = regcomp (&re[i], plugin_cfg.trunk_numbers_regex.string[i],
|
||||
REG_ICASE|REG_EXTENDED);
|
||||
if (sts != 0) {
|
||||
regerror(sts, &re[i], errbuf, sizeof(errbuf));
|
||||
ERROR("Regular expression [%s] failed to compile: %s",
|
||||
plugin_cfg.trunk_numbers_regex.string[i], errbuf);
|
||||
retsts = STS_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
return retsts;
|
||||
}
|
||||
|
||||
static int plugin_siptrunk_process(sip_ticket_t *ticket) {
|
||||
// int sts=STS_SUCCESS;
|
||||
int i;
|
||||
#define WORKSPACE_SIZE 128
|
||||
// static char in[WORKSPACE_SIZE+1], rp[WORKSPACE_SIZE+1];
|
||||
|
||||
/* plugin loaded and not configured, return with success */
|
||||
if (plugin_cfg.trunk_numbers_regex.used==0) return STS_SUCCESS;
|
||||
|
||||
|
||||
DEBUGC(DBCLASS_PLUGIN, "plugin_siptrunk: type=%i", ticket->direction);
|
||||
DEBUGC(DBCLASS_PLUGIN, "plugin_siptrunk: next hop was %s:%i",
|
||||
utils_inet_ntoa(ticket->next_hop.sin_addr),
|
||||
ticket->next_hop.sin_port);
|
||||
|
||||
#if 0
|
||||
/* SIP request? && direction undetermined? */
|
||||
if ((ticket->direction == DIRTYP_UNKNOWN)
|
||||
&& MSG_IS_REQUEST(ticket->sipmsg)) {
|
||||
DEBUGC(DBCLASS_PLUGIN, "plugin_siptrunk: processing DIRTYP_UNKNOWN REQ...");
|
||||
|
||||
// Loop through config array
|
||||
for (i = 0; i < plugin_cfg.trunk_numbers_regex.used; i++) {
|
||||
regmatch_t *pmatch = NULL;
|
||||
|
||||
// and check for regex match in To: header (or SIP URI?)
|
||||
// if regex match, assume incoming request
|
||||
pmatch = rmatch(url_string, WORKSPACE_SIZE, &re[i]);
|
||||
if (pmatch == NULL) continue; /* no match, next */
|
||||
|
||||
/* have a match */
|
||||
// set ticket->direction == REQTYPE_INCOMING
|
||||
// eval next_hop (lookup internal UA) and set
|
||||
// lookup internal target by account name from registration DB
|
||||
// - ticket->next_hop.sin_addr
|
||||
// - ticket->next_hop.sin_port
|
||||
DEBUGC(DBCLASS_PLUGIN, "plugin_siptrunk: matched trunk on rule [%s]",
|
||||
plugin_cfg.trunk_numbers_regex.string[i] );
|
||||
/* only do first match, then break */
|
||||
break;
|
||||
}
|
||||
|
||||
DEBUGC(DBCLASS_PLUGIN, "plugin_siptrunk: next hop is now %s:%i",
|
||||
utils_inet_ntoa(ticket->next_hop.sin_addr),
|
||||
ticket->next_hop.sin_port);
|
||||
|
||||
} else {
|
||||
DEBUGC(DBCLASS_PLUGIN, "plugin_siptrunk: not processing SIP message");
|
||||
}
|
||||
#endif
|
||||
return STS_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* This regex replacement code has been proudly borrowed from
|
||||
* http://www.daniweb.com/software-development/c/code/216955#
|
||||
*
|
||||
* buf: input string + output result
|
||||
* rp: replacement string, will be destroyed during processing!
|
||||
* size: size of buf and rp
|
||||
* re: regex to process
|
||||
*
|
||||
* rmatch() performs the initial regexec match, and if a match is found
|
||||
* it returns a pointer to the regmatch array which contains the result
|
||||
* of the match.
|
||||
* Afterwards rreplace() is to be called, providing this regmatch array.
|
||||
*
|
||||
* This eliminates the need to copy the 'rp' string before knowing
|
||||
* if a match is actually there.
|
||||
*/
|
||||
#define NMATCHES 10
|
||||
static regmatch_t * rmatch (char *buf, int size, regex_t *re) {
|
||||
static regmatch_t pm[NMATCHES]; /* regoff_t is int so size is int */
|
||||
|
||||
/* perform the match */
|
||||
if (regexec (re, buf, NMATCHES, pm, 0)) {
|
||||
return NULL;
|
||||
}
|
||||
return &pm[0];
|
||||
}
|
||||
|
||||
#if 0
|
||||
static int rreplace (char *buf, int size, regex_t *re, regmatch_t pmatch[], char *rp) {
|
||||
char *pos;
|
||||
int sub, so, n;
|
||||
|
||||
/* match(es) found: */
|
||||
for (pos = rp; *pos; pos++) {
|
||||
/* back references \1 ... \9: expand them in 'rp' */
|
||||
if (*pos == '\\' && *(pos + 1) > '0' && *(pos + 1) <= '9') {
|
||||
so = pmatch[*(pos + 1) - 48].rm_so; /* pmatch[1..9] */
|
||||
n = pmatch[*(pos + 1) - 48].rm_eo - so;
|
||||
if (so < 0 || strlen (rp) + n - 1 > size) return STS_FAILURE;
|
||||
memmove (pos + n, pos + 2, strlen (pos) - 1);
|
||||
memmove (pos, buf + so, n);
|
||||
pos = pos + n - 2;
|
||||
}
|
||||
}
|
||||
|
||||
sub = pmatch[1].rm_so; /* no repeated replace when sub >= 0 */
|
||||
/* and replace rp in the input buffer */
|
||||
for (pos = buf; !regexec (re, pos, 1, pmatch, 0); ) {
|
||||
n = pmatch[0].rm_eo - pmatch[0].rm_so;
|
||||
pos += pmatch[0].rm_so;
|
||||
if (strlen (buf) - n + strlen (rp) > size) {
|
||||
return STS_FAILURE;
|
||||
}
|
||||
memmove (pos + strlen (rp), pos + n, strlen (pos) - n + 1);
|
||||
memmove (pos, rp, strlen (rp));
|
||||
pos += strlen (rp);
|
||||
if (sub >= 0) break;
|
||||
}
|
||||
return STS_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
83
src/proxy.c
83
src/proxy.c
@ -79,8 +79,6 @@ int proxy_request (sip_ticket_t *ticket) {
|
||||
int i;
|
||||
int sts;
|
||||
int type;
|
||||
struct in_addr sendto_addr;
|
||||
int port;
|
||||
char *buffer;
|
||||
size_t buflen;
|
||||
osip_message_t *request;
|
||||
@ -345,30 +343,37 @@ sts=sip_obscure_callid(ticket);
|
||||
* Proxy Behavior - Determine Next-Hop Address
|
||||
*/
|
||||
/*&&&& priority probably should be:
|
||||
* 1) Route header
|
||||
* 2) fixed outbound proxy
|
||||
* 3) SIP URI
|
||||
* 1) an already defined next-hop in ticket->next_hop
|
||||
* 2) Route header
|
||||
* 3) fixed outbound proxy
|
||||
* 4) SIP URI
|
||||
*/
|
||||
|
||||
/* predefined next-hop present? */
|
||||
if (is_empty_sockaddr(&ticket->next_hop) == STS_FAILURE) {
|
||||
DEBUGC(DBCLASS_PROXY, "proxy_request: pre-set next-hop: %s:%i",
|
||||
utils_inet_ntoa(ticket->next_hop.sin_addr), ticket->next_hop.sin_port);
|
||||
/*
|
||||
* Route present?
|
||||
* If so, fetch address from topmost Route: header and remove it.
|
||||
*/
|
||||
if ((type == REQTYP_OUTGOING) &&
|
||||
} else if ((type == REQTYP_OUTGOING) &&
|
||||
(!osip_list_eol(&(request->routes), 0))) {
|
||||
sts=route_determine_nexthop(ticket, &sendto_addr, &port);
|
||||
sts=route_determine_nexthop(ticket, &ticket->next_hop.sin_addr,
|
||||
&ticket->next_hop.sin_port);
|
||||
if (sts == STS_FAILURE) {
|
||||
DEBUGC(DBCLASS_PROXY, "proxy_request: route_determine_nexthop failed");
|
||||
return STS_FAILURE;
|
||||
}
|
||||
DEBUGC(DBCLASS_PROXY, "proxy_request: have Route header to %s:%i",
|
||||
utils_inet_ntoa(sendto_addr), port);
|
||||
utils_inet_ntoa(ticket->next_hop.sin_addr), ticket->next_hop.sin_port);
|
||||
/*
|
||||
* fixed or domain outbound proxy defined ?
|
||||
*/
|
||||
} else if ((type == REQTYP_OUTGOING) &&
|
||||
(sip_find_outbound_proxy(ticket, &sendto_addr, &port) == STS_SUCCESS)) {
|
||||
(sip_find_outbound_proxy(ticket, &ticket->next_hop.sin_addr, &ticket->next_hop.sin_port) == STS_SUCCESS)) {
|
||||
DEBUGC(DBCLASS_PROXY, "proxy_request: have outbound proxy %s:%i",
|
||||
utils_inet_ntoa(sendto_addr), port);
|
||||
utils_inet_ntoa(ticket->next_hop.sin_addr), ticket->next_hop.sin_port);
|
||||
/*
|
||||
* destination from SIP URI
|
||||
*/
|
||||
@ -379,7 +384,7 @@ In a first implementation we may just try to get the lowest priority,
|
||||
max weighted '_sip._udp.domain' entry and port number.
|
||||
No load balancing and no failover are supported with this.
|
||||
&&&*/
|
||||
sts = get_ip_by_host(request->req_uri->host, &sendto_addr);
|
||||
sts = get_ip_by_host(request->req_uri->host, &ticket->next_hop.sin_addr);
|
||||
if (sts == STS_FAILURE) {
|
||||
DEBUGC(DBCLASS_PROXY, "proxy_request: cannot resolve URI [%s]",
|
||||
request->req_uri->host);
|
||||
@ -387,13 +392,15 @@ No load balancing and no failover are supported with this.
|
||||
}
|
||||
|
||||
if (request->req_uri->port) {
|
||||
port=atoi(request->req_uri->port);
|
||||
if ((port<=0) || (port>65535)) port=SIP_PORT;
|
||||
ticket->next_hop.sin_port=atoi(request->req_uri->port);
|
||||
if (ticket->next_hop.sin_port != 0) {
|
||||
ticket->next_hop.sin_port=SIP_PORT;
|
||||
}
|
||||
} else {
|
||||
port=SIP_PORT;
|
||||
ticket->next_hop.sin_port=SIP_PORT;
|
||||
}
|
||||
DEBUGC(DBCLASS_PROXY, "proxy_request: have SIP URI to %s:%i",
|
||||
request->req_uri->host, port);
|
||||
utils_inet_ntoa(ticket->next_hop.sin_addr), ticket->next_hop.sin_port);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -432,7 +439,8 @@ No load balancing and no failover are supported with this.
|
||||
return STS_FAILURE;
|
||||
}
|
||||
|
||||
sipsock_send(sendto_addr, port, ticket->protocol, buffer, buflen);
|
||||
sipsock_send(ticket->next_hop.sin_addr, ticket->next_hop.sin_port,
|
||||
ticket->protocol, buffer, buflen);
|
||||
osip_free (buffer);
|
||||
|
||||
/*
|
||||
@ -469,9 +477,7 @@ No load balancing and no failover are supported with this.
|
||||
int proxy_response (sip_ticket_t *ticket) {
|
||||
int sts;
|
||||
int type;
|
||||
struct in_addr sendto_addr;
|
||||
osip_via_t *via;
|
||||
int port;
|
||||
char *buffer;
|
||||
size_t buflen;
|
||||
osip_message_t *response;
|
||||
@ -663,38 +669,45 @@ sts=sip_obscure_callid(ticket);
|
||||
* Determine Next-Hop Address
|
||||
*/
|
||||
/*&&&& priority probably should be:
|
||||
* 0) rport=;received= header (TCP only for now)
|
||||
* 1) Route header
|
||||
* 2) fixed outbound proxy
|
||||
* 3) Via header
|
||||
* 1) an already defined next-hop in ticket->next_hop
|
||||
* 2) rport=;received= header (TCP only for now)
|
||||
* 3) Route header
|
||||
* 4) fixed outbound proxy
|
||||
* 5) Via header
|
||||
*/
|
||||
/* predefined next-hop present? */
|
||||
if (is_empty_sockaddr(&ticket->next_hop) == STS_FAILURE) {
|
||||
DEBUGC(DBCLASS_PROXY, "proxy_request: pre-set next-hop: %s:%i",
|
||||
utils_inet_ntoa(ticket->next_hop.sin_addr), ticket->next_hop.sin_port);
|
||||
/*
|
||||
* IF TCP, check for rport=x;received=y parameters in VIA
|
||||
*/
|
||||
if ((ticket->protocol == PROTO_TCP) &&
|
||||
(sip_get_received_param(ticket, &sendto_addr, &port) == STS_SUCCESS)) {
|
||||
} else if ((ticket->protocol == PROTO_TCP) &&
|
||||
(sip_get_received_param(ticket, &ticket->next_hop.sin_addr, &ticket->next_hop.sin_port) == STS_SUCCESS)) {
|
||||
DEBUGC(DBCLASS_PROXY, "proxy_response: have received/rport to %s:%i",
|
||||
utils_inet_ntoa(sendto_addr), port);
|
||||
utils_inet_ntoa(ticket->next_hop.sin_addr),
|
||||
ticket->next_hop.sin_port);
|
||||
/*
|
||||
* Route present?
|
||||
* If so, fetch address from topmost Route: header and remove it.
|
||||
*/
|
||||
} else if ((type == RESTYP_OUTGOING) &&
|
||||
(!osip_list_eol(&(response->routes), 0))) {
|
||||
sts=route_determine_nexthop(ticket, &sendto_addr, &port);
|
||||
sts=route_determine_nexthop(ticket, &ticket->next_hop.sin_addr, &ticket->next_hop.sin_port);
|
||||
if (sts == STS_FAILURE) {
|
||||
DEBUGC(DBCLASS_PROXY, "proxy_response: route_determine_nexthop failed");
|
||||
return STS_FAILURE;
|
||||
}
|
||||
DEBUGC(DBCLASS_PROXY, "proxy_response: have Route header to %s:%i",
|
||||
utils_inet_ntoa(sendto_addr), port);
|
||||
utils_inet_ntoa(ticket->next_hop.sin_addr),
|
||||
ticket->next_hop.sin_port);
|
||||
/*
|
||||
* check if we need to send to an outbound proxy
|
||||
*/
|
||||
} else if ((type == RESTYP_OUTGOING) &&
|
||||
(sip_find_outbound_proxy(ticket, &sendto_addr, &port) == STS_SUCCESS)) {
|
||||
(sip_find_outbound_proxy(ticket, &ticket->next_hop.sin_addr, &ticket->next_hop.sin_port) == STS_SUCCESS)) {
|
||||
DEBUGC(DBCLASS_PROXY, "proxy_response: have outbound proxy %s:%i",
|
||||
utils_inet_ntoa(sendto_addr), port);
|
||||
utils_inet_ntoa(ticket->next_hop.sin_addr), ticket->next_hop.sin_port);
|
||||
} else {
|
||||
/* get target address and port from VIA header */
|
||||
via = (osip_via_t *) osip_list_get (&(response->vias), 0);
|
||||
@ -703,7 +716,7 @@ sts=sip_obscure_callid(ticket);
|
||||
return STS_FAILURE;
|
||||
}
|
||||
|
||||
sts = get_ip_by_host(via->host, &sendto_addr);
|
||||
sts = get_ip_by_host(via->host, &ticket->next_hop.sin_addr);
|
||||
if (sts == STS_FAILURE) {
|
||||
DEBUGC(DBCLASS_PROXY, "proxy_response: cannot resolve VIA [%s]",
|
||||
via->host);
|
||||
@ -711,10 +724,12 @@ sts=sip_obscure_callid(ticket);
|
||||
}
|
||||
|
||||
if (via->port) {
|
||||
port=atoi(via->port);
|
||||
if ((port<=0) || (port>65535)) port=SIP_PORT;
|
||||
ticket->next_hop.sin_port=atoi(via->port);
|
||||
if (ticket->next_hop.sin_port != 0) {
|
||||
ticket->next_hop.sin_port=SIP_PORT;
|
||||
}
|
||||
} else {
|
||||
port=SIP_PORT;
|
||||
ticket->next_hop.sin_port=SIP_PORT;
|
||||
}
|
||||
}
|
||||
|
||||
@ -730,7 +745,7 @@ sts=sip_obscure_callid(ticket);
|
||||
return STS_FAILURE;
|
||||
}
|
||||
|
||||
sipsock_send(sendto_addr, port, ticket->protocol, buffer, buflen);
|
||||
sipsock_send(ticket->next_hop.sin_addr, ticket->next_hop.sin_port, ticket->protocol, buffer, buflen);
|
||||
osip_free (buffer);
|
||||
return STS_SUCCESS;
|
||||
}
|
||||
|
||||
@ -365,7 +365,7 @@ int route_purge_recordroute(sip_ticket_t *ticket){
|
||||
* STS_SUCCESS on success
|
||||
*/
|
||||
int route_determine_nexthop(sip_ticket_t *ticket,
|
||||
struct in_addr *dest, int *port){
|
||||
struct in_addr *dest, in_port_t *port){
|
||||
int sts;
|
||||
osip_message_t *mymsg=ticket->sipmsg;
|
||||
osip_route_t *route=NULL;
|
||||
|
||||
@ -883,7 +883,7 @@ int sip_calculate_branch_id (sip_ticket_t *ticket, char *id) {
|
||||
* STS_FAILURE if no outbound proxy to be used
|
||||
*/
|
||||
int sip_find_outbound_proxy(sip_ticket_t *ticket, struct in_addr *addr,
|
||||
int *port) {
|
||||
in_port_t *port) {
|
||||
int i, sts;
|
||||
char *domain=NULL;
|
||||
osip_message_t *sipmsg;
|
||||
@ -1450,7 +1450,7 @@ int sip_add_received_param(sip_ticket_t *ticket){
|
||||
* STS_SUCCESS on success
|
||||
*/
|
||||
int sip_get_received_param(sip_ticket_t *ticket,
|
||||
struct in_addr *dest, int *port) {
|
||||
struct in_addr *dest, in_port_t *port) {
|
||||
osip_via_t *via;
|
||||
osip_generic_param_t *received=NULL;
|
||||
osip_generic_param_t *rport=NULL;
|
||||
|
||||
@ -386,6 +386,7 @@ int main (int argc, char *argv[])
|
||||
buflen = (size_t)sts;
|
||||
DEBUGC(DBCLASS_BABBLE,"received %zd bytes of data", buflen);
|
||||
ticket.direction=0;
|
||||
memset(&ticket.next_hop, 0, sizeof(ticket.next_hop));
|
||||
buff[buflen]='\0';
|
||||
|
||||
/* pointers in ticket to raw message */
|
||||
|
||||
@ -138,6 +138,7 @@ typedef struct {
|
||||
#define RESTYP_INCOMING 3
|
||||
#define RESTYP_OUTGOING 4
|
||||
int direction; /* direction as determined by proxy */
|
||||
struct sockaddr_in next_hop; /* next hop as determined by plugin or proxy */
|
||||
} sip_ticket_t;
|
||||
|
||||
|
||||
@ -191,7 +192,7 @@ int route_add_recordroute(sip_ticket_t *ticket); /*X*/
|
||||
int route_purge_recordroute(sip_ticket_t *ticket); /*X*/
|
||||
int route_postprocess(sip_ticket_t *ticket); /*X*/
|
||||
int route_determine_nexthop(sip_ticket_t *ticket,
|
||||
struct in_addr *dest, int *port); /*X*/
|
||||
struct in_addr *dest, in_port_t *port); /*X*/
|
||||
|
||||
/* utils.c */
|
||||
int get_ip_by_host(char *hostname, struct in_addr *addr); /*X*/
|
||||
@ -203,6 +204,7 @@ char *utils_inet_ntoa(struct in_addr in);
|
||||
int utils_inet_aton(const char *cp, struct in_addr *inp);
|
||||
int createpidfile(char *pidfilename); /*X*/
|
||||
int compare_client_id(client_id_t cid1, client_id_t cid2); /*X*/
|
||||
int is_empty_sockaddr(struct sockaddr_in *sockaddr); /*X*/
|
||||
|
||||
/* sip_utils.c */
|
||||
osip_message_t * msg_make_template_reply (sip_ticket_t *ticket, int code);
|
||||
@ -217,13 +219,13 @@ int sip_del_myvia (sip_ticket_t *ticket); /*X*/
|
||||
int sip_rewrite_contact (sip_ticket_t *ticket, int direction); /*X*/
|
||||
int sip_calculate_branch_id (sip_ticket_t *ticket, char *id); /*X*/
|
||||
int sip_find_outbound_proxy(sip_ticket_t *ticket, struct in_addr *addr,
|
||||
int *port); /*X*/
|
||||
in_port_t *port); /*X*/
|
||||
int sip_find_direction(sip_ticket_t *ticket, int *urlidx); /*X*/
|
||||
int sip_fixup_asterisk(char *buff, size_t *buflen); /*X*/
|
||||
int sip_obscure_callid(sip_ticket_t *ticket); /*X*/
|
||||
int sip_add_received_param(sip_ticket_t *ticket); /*X*/
|
||||
int sip_get_received_param(sip_ticket_t *ticket,
|
||||
struct in_addr *dest, int *port); /*X*/
|
||||
struct in_addr *dest, in_port_t *port); /*X*/
|
||||
|
||||
/* readconf.c */
|
||||
int read_config(char *name, int search, cfgopts_t cfgopts[], char *filter); /*X*/
|
||||
|
||||
14
src/utils.c
14
src/utils.c
@ -678,3 +678,17 @@ int compare_client_id(client_id_t cid1, client_id_t cid2) {
|
||||
DEBUGC(DBCLASS_BABBLE, "compare_client_id: no match");
|
||||
return STS_FAILURE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* check a sockaddr_in structure for bein zero / non-zero
|
||||
*/
|
||||
int is_empty_sockaddr(struct sockaddr_in *sockaddr) {
|
||||
int i;
|
||||
char *p=(char*)sockaddr;
|
||||
|
||||
for (i=0; i < sizeof(struct sockaddr_in); i++) {
|
||||
if (p[i] != 0x00) { return STS_FAILURE; }
|
||||
}
|
||||
return STS_SUCCESS;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user