📄 filter.c
字号:
/* The filter plugin is a GPL plugin for partysip. Copyright (C) 2002,2003 WellX Telecom - <partysip@wellx.com> Copyright (C) 2002,2003 Aymeric MOIZARD - <jack@atosc.org> The filter plugin 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. The filter plugin is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty 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 Foobar; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA*/#include <partysip/partysip.h>#include <partysip/psp_utils.h>#include <ppl/ppl_dns.h>#include "filter.h"filter_ctx_t *filter_context = NULL;extern psp_plugin_t PPL_DECLARE_DATA filter_plugin;extern char filter_name_config[50];/* This plugin can be configured to: * * mandate record-routing to stay on the path for the duration of the call. ("proxy-mode") *//* Configuration sample:. <filter> mode statefull # record-route on # tel url definitions forward ^tel:07([0-9]+)|sip:0033%1@sip.no-ip.org;user=phone forward ^tel:0[89]([0-9]+)|sip:713@192.168.1.83;user=phone forward ^tel:(1[01])([0-9]+)|sip:%1%2@g1.france.com forward ^tel:12([0-9]+)|sip:%1@g2.france.com forward ^tel:13([0-9]+)|sip:g3.france.com forward ^tel:([0-9]+)|sip:%s@world-operator.com </filter>*/#define INTERNAL_SCOPE 0x1000#define EXTERNAL_SCOPE 0x0100#define REDIRECT_MODE 0x0010#define R_ROUTE_MODE 0x0001#define ISSET_INTERNAL_FILTERSCOPE(flag) ((~flag|~INTERNAL_SCOPE)==~INTERNAL_SCOPE)#define SET_INTERNAL_FILTERSCOPE(flag) (flag=flag|INTERNAL_SCOPE)#define ISSET_EXTERNAL_FILTERSCOPE(flag) ((~flag|~EXTERNAL_SCOPE)==~EXTERNAL_SCOPE)#define SET_EXTERNAL_FILTERSCOPE(flag) (flag=flag|EXTERNAL_SCOPE)#define ISSET_REDIRECT_MODE(flag) ((~flag|~REDIRECT_MODE)==~REDIRECT_MODE)#define SET_REDIRECT_MODE(flag) (flag=flag|REDIRECT_MODE)#define ISSET_R_ROUTE_MODE(flag) ((~flag|~R_ROUTE_MODE)==~R_ROUTE_MODE)#define SET_R_ROUTE_MODE(flag) (flag=flag|R_ROUTE_MODE)#if !defined(WIN32) || defined(TRE)static int filter_load_forward_config(){ int i; config_element_t *elem; config_element_t *next_elem; char *arg1; elem = psp_config_get_sub_element("forward", filter_name_config, NULL); while (elem!=NULL) { tel_rule_t *tel_rule; /* forward ^tel:07([0-9]+)|sip:0033%1@sip.no-ip.org;user=phone forward ^tel:0[89]([0-9]+)|sip:713@192.168.1.83;user=phone forward ^tel:(1[01])([0-9]+)|sip:%1%2@g1.france.com */ arg1 = strchr(elem->value, '|'); /* find beginning of prefix */ if (arg1==NULL) return -1; arg1=arg1+1; /* only 100 length is allowed */ if (arg1-elem->value-1>100) return -1; if (strlen(arg1)>100) return -1; tel_rule = (tel_rule_t*) osip_malloc(sizeof(tel_rule_t)); memset(tel_rule, 0, sizeof(tel_rule_t)); tel_rule->next = NULL; tel_rule->parent = NULL; osip_strncpy(tel_rule->prefix, elem->value, arg1-elem->value-1); osip_strncpy(tel_rule->dnsresult, arg1, strlen(arg1)); /* pre-compile the regex */ i = regcomp(&tel_rule->cprefix, tel_rule->prefix, REG_EXTENDED|REG_ICASE); if (i!=0) { OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_ERROR,NULL, "filter plugin: Error in regex pattern: %s!\n", tel_rule->prefix)); osip_free(tel_rule); return -1; } ADD_ELEMENT(filter_context->tel_rules, tel_rule); next_elem = elem; elem = psp_config_get_sub_element("forward", filter_name_config, next_elem); } return 0;}#endifintfilter_ctx_init(){ config_element_t *elem; int i;#if defined(WIN32) && !defined(TRE) OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO4,NULL, "filter plugin: NOT IMPLEMENTED ON WIN32!\n")); return 0;#else filter_context = (filter_ctx_t*)osip_malloc(sizeof(filter_ctx_t)); if (filter_context==NULL) return -1; filter_context->tel_rules = NULL; filter_context->flag = 0; elem = psp_config_get_sub_element("mode", filter_name_config, NULL); if (elem==NULL||elem->value==NULL) { } else if (0==strcmp(elem->value, "redirect")) SET_REDIRECT_MODE(filter_context->flag); else if (0==strcmp(elem->value, "statefull")) { } else goto lsci_error1; /* error, bad option */ elem = psp_config_get_sub_element("filter_scope", filter_name_config, NULL); if (elem==NULL||elem->value==NULL) { SET_INTERNAL_FILTERSCOPE(filter_context->flag); SET_EXTERNAL_FILTERSCOPE(filter_context->flag); } else if (0==strcmp(elem->value, "internal")) SET_INTERNAL_FILTERSCOPE(filter_context->flag); else if (0==strcmp(elem->value, "external")) SET_EXTERNAL_FILTERSCOPE(filter_context->flag); else if (0==strcmp(elem->value, "both")) { SET_INTERNAL_FILTERSCOPE(filter_context->flag); SET_EXTERNAL_FILTERSCOPE(filter_context->flag); } else goto lsci_error1; /* error, bad option */ elem = psp_config_get_sub_element("record-route", filter_name_config, NULL); if (elem==NULL||elem->value==NULL) { } else if (0==strcmp(elem->value, "off")) { } else if (0==strcmp(elem->value, "on")) SET_R_ROUTE_MODE(filter_context->flag); else goto lsci_error1; /* error, bad option */ /* load the configuration behavior for INVITE */ i = filter_load_forward_config(); if (i!=0) goto lsci_error2; if (ISSET_R_ROUTE_MODE(filter_context->flag)) { OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL, "filter plugin: configured to do record-routing!\n")); } if (ISSET_REDIRECT_MODE(filter_context->flag)) { OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL, "filter plugin: configured in redirect mode!\n")); } if (ISSET_INTERNAL_FILTERSCOPE(filter_context->flag)) { OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL, "filter plugin: configured to process url for local domain!\n")); } if (ISSET_EXTERNAL_FILTERSCOPE(filter_context->flag)) { OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL, "filter plugin: configured to process url for non local domain!\n")); } return 0; lsci_error2: lsci_error1: osip_free(filter_context); filter_context = NULL; return -1;#endif}voidfilter_ctx_free(){ tel_rule_t *tel_rule; if (filter_context==NULL) return;#if !defined(WIN32) || defined(TRE) for (tel_rule = filter_context->tel_rules; tel_rule!=NULL; tel_rule=filter_context->tel_rules) { REMOVE_ELEMENT(filter_context->tel_rules, tel_rule); regfree(&tel_rule->cprefix); osip_free(tel_rule); } osip_free(filter_context); filter_context = NULL;#endif}#if !defined(WIN32) || defined(TRE)static intfilter_match_rule(tel_rule_t *tel_rule, osip_message_t *request, char *match1, char *match2){ osip_uri_t *req_uri = request->req_uri; char *url; int i; regmatch_t pmatch[3]; if (tel_rule->prefix=='\0') return 0; /* always match */ if (req_uri==NULL) return -1; osip_uri_to_str_canonical(req_uri, &url); if (url==NULL) { OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_ERROR,NULL, "filter plugin: Bad sip url in SIP request.\n", tel_rule->prefix)); return -1; } /* match one sip url */ i = regexec(&tel_rule->cprefix, url, tel_rule->cprefix.re_nsub+1, pmatch, 0); if (i!=0) { if (i!=REG_NOMATCH) { char error_buf[512]; regerror(i, &tel_rule->cprefix, error_buf, 512); OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_ERROR,NULL, "filter plugin: regexec failed(%i) for %s!\n", i, error_buf)); } else { OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO4,NULL, "filter plugin: No match for %s!\n", url)); } osip_free(url); return -1; } #ifdef FILTER_TEST fprintf(stdout, "tel_rule->cprefix.re_nsub+1: %i\n", tel_rule->cprefix.re_nsub+1);#endif for (i=0;pmatch[i].rm_so!=-1 && tel_rule->cprefix.re_nsub+1 != i ;i++) {#ifdef FILTER_TEST fprintf(stdout, "result of regexec: %i %i\n", pmatch[i].rm_so, pmatch[i].rm_eo); fprintf(stdout, "pmatch[i].rm_so: %s\n", url+pmatch[i].rm_so);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -