This commit is contained in:
Thomas Ries 2015-09-15 21:47:53 +00:00
parent 5e24262b93
commit 7a8309c8f7
5 changed files with 234 additions and 11 deletions

View File

@ -39,7 +39,8 @@ pkglib_LTLIBRARIES = plugin_demo.la \
plugin_prefix.la \
plugin_regex.la \
plugin_codecfilter.la \
plugin_stripheader.la
plugin_stripheader.la \
plugin_siptrunk.la
DLOPENPLUGINS = -dlopen plugin_demo.la \
-dlopen plugin_shortdial.la \
-dlopen plugin_logcall.la \
@ -50,7 +51,8 @@ DLOPENPLUGINS = -dlopen plugin_demo.la \
-dlopen plugin_prefix.la \
-dlopen plugin_regex.la \
-dlopen plugin_codecfilter.la \
-dlopen plugin_stripheader.la
-dlopen plugin_stripheader.la \
-dlopen plugin_siptrunk.la
#
plugin_demo_la_SOURCES = plugin_demo.c
plugin_demo_la_LDFLAGS = -module -avoid-version -shrext '.so'
@ -84,6 +86,9 @@ plugin_codecfilter_la_LDFLAGS = -module -avoid-version -shrext '.so'
#
plugin_stripheader_la_SOURCES = plugin_stripheader.c
plugin_stripheader_la_LDFLAGS = -module -avoid-version -shrext '.so'
#
plugin_siptrunk_la_SOURCES = plugin_siptrunk.c
plugin_siptrunk_la_LDFLAGS = -module -avoid-version -shrext '.so'
#

View File

@ -35,7 +35,7 @@
#include "plugins.h"
#include "log.h"
static char const ident[]="$Id: plugin_DTAG.c 439 2010-01-07 11:29:00Z hb9xar $";
static char const ident[]="$Id$";
/* Plug-in identification */
static char name[]="plugin_fix_DTAG";

213
src/plugin_siptrunk.c Normal file
View File

@ -0,0 +1,213 @@
/*
Copyright (C) 2015 Thomas Ries <tries@gmx.net>
This file is part of Siproxd.
Siproxd is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
Siproxd is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warrantry of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Siproxd; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* must be defined before including <plugin.h> */
#define PLUGIN_NAME plugin_siptrunk
#include "config.h"
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <osipparser2/osip_parser.h>
#include "siproxd.h"
#include "plugins.h"
#include "log.h"
static char const ident[]="$Id$";
/* Plug-in identification */
static char name[]="plugin_siptrunk";
static char desc[]="Handles SIP trunks with multiple numbers on same SIP account";
/* global configuration storage - required for config file location */
extern struct siproxd_config configuration;
/* plugin configuration storage */
static struct plugin_config {
stringa_t trunk_name;
stringa_t trunk_account;
stringa_t trunk_numbers;
} 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} },
{0, 0, 0}
};
/* Prototypes */
static int sip_fix_topvia(sip_ticket_t *ticket);
/*&&&+++
1) register
- nothing to to
2) outgoing calls
- nothing to do. Should be able to figure out direction by
Contact header, via header
3) incoming call
* need matching of incoming DID number to trunk account
- SIP URI
- To: Header
How do I pass on that matched information?
? rewriting To: header?
? rewriting SIP URI?
? new metadata in ticket structure?
Need to provide info for sip_find_direction() -nope, this has been processed
(and failed) before the plugin. I need to provide the correct drection value in
the ticket.
Then with an Route header I may set the next Hop (to the internal UA). I need to
access the registration database to get the associated IP address with the
account...
Unfortunately, the route header processing is only done for OUTGOING requests.
Probably should try with rewritung the SIP URI to the account name. However this
is bad bcoz if destroys the DID number information in the request URI.
I may need some next hop override that a plugin can use to force the next hop,
no matter what...
&&&---*/
/*
* Initialization.
* Called once suring siproxd startup.
*/
int PLUGIN_INIT(plugin_def_t *plugin_def) {
/* API version number of siproxd that this plugin is built against.
* This constant will change whenever changes to the API are made
* that require adaptions in the plugin. */
plugin_def->api_version=SIPROXD_API_VERSION;
/* Name and descriptive text of the plugin */
plugin_def->name=name;
plugin_def->desc=desc;
/* Execution mask - during what stages of SIP processing shall
* the plugin be called. */
plugin_def->exe_mask=PLUGIN_PRE_PROXY;
/* read the config file */
if (read_config(configuration.configfile,
configuration.config_search,
plugin_cfg_opts, name) == STS_FAILURE) {
ERROR("Plugin '%s': could not load config file", name);
return STS_FAILURE;
}
INFO("plugin_siptrunk is initialized");
return STS_SUCCESS;
}
/*
* Processing.
*
*/
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;
}
/*
* De-Initialization.
* Called during shutdown of siproxd. Gives the plugin the chance
* to clean up its mess (e.g. dynamic memory allocation, database
* 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;
if((via = osip_list_get(&(ticket->sipmsg->vias), 0)) != NULL) {
/* 1) IP of Via has been checked beforehand. */
/* 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!");
}
}
}
return STS_SUCCESS;
}

View File

@ -35,7 +35,7 @@
#include "redirect_cache.h"
#include "log.h"
static char const ident[]="$Id: plugin_prefix.c 484 2011-06-17 16:15:41Z hb9xar $";
static char const ident[]="$Id$";
#define CACHE_TIMEOUT 20

View File

@ -967,7 +967,7 @@ int sip_find_outbound_proxy(sip_ticket_t *ticket, struct in_addr *addr,
/*
* SIP_IS_OUTGOING
* SIP_FIND_DIRECTION
*
* Figures out if this is an outgoing or incoming request/response.
* The direction is stored in the ticket->direction property.
@ -992,14 +992,19 @@ int sip_find_direction(sip_ticket_t *ticket, int *urlidx) {
ticket->direction = DIRTYP_UNKNOWN;
/* Search order is as follows:
* - "from" IP address one of our registered local UAs
* - "To:" SIP header (Request) directed to internal UA
* - "from" IP address is one of our registered local UAs
* => OUTGOING
* - "Req: To:" SIP header (Request) directed to internal UA
* or
* "From:" SIP header (Response) coming from internal UA
* - SIP URI matches one of the registered local UAs
* - for Responses: check for bottommost "Via:" header to be
* Resp: "From:" SIP header (Response) coming from internal UA
* => INCOMING
* - Req: SIP URI matches one of the registered local UAs
* => INCOMING
* - Resp: check for bottommost "Via:" header to be
* one of our registered local UA IPs
* - "from" IP == 127.0.0.1 || inbound_IP || outbound IP
* => INCOMING
* - "from" IP == (127.0.0.1 | inbound_IP | outbound IP)
* => OUTGOING
*
* The first successful match is taken.
*/