diff options
Diffstat (limited to 'net/kamailio/patches/022-lcr-pcre2-migration.patch')
| -rw-r--r-- | net/kamailio/patches/022-lcr-pcre2-migration.patch | 508 |
1 files changed, 508 insertions, 0 deletions
diff --git a/net/kamailio/patches/022-lcr-pcre2-migration.patch b/net/kamailio/patches/022-lcr-pcre2-migration.patch new file mode 100644 index 0000000..c894e3a --- /dev/null +++ b/net/kamailio/patches/022-lcr-pcre2-migration.patch @@ -0,0 +1,508 @@ +From e3e2c41e8c46a13bad18dd40fd9e3540020dd5eb Mon Sep 17 00:00:00 2001 +From: Victor Seva <linuxmaniac@torreviejawireless.org> +Date: Mon, 21 Aug 2023 13:30:36 +0200 +Subject: [PATCH] lcr: pcre2 migration + +--- + src/modules/lcr/Makefile | 12 +-- + src/modules/lcr/hash.c | 24 ++--- + src/modules/lcr/hash.h | 10 +- + src/modules/lcr/lcr_mod.c | 187 +++++++++++++++++++++++++------------- + src/modules/lcr/lcr_mod.h | 8 +- + 5 files changed, 150 insertions(+), 91 deletions(-) + +--- a/src/modules/lcr/Makefile ++++ b/src/modules/lcr/Makefile +@@ -9,20 +9,15 @@ auto_gen= + NAME=lcr.so + + ifeq ($(CROSS_COMPILE),) +-PCRE_BUILDER = $(shell \ +- if pkg-config --exists libcre; then \ +- echo 'pkg-config libpcre'; \ +- else \ +- which pcre-config; \ +- fi) ++PCRE_BUILDER = $(shell command -v pcre2-config) + endif + + ifeq ($(PCRE_BUILDER),) + PCREDEFS=-I$(LOCALBASE)/include +- PCRELIBS=-L$(LOCALBASE)/lib -lpcre ++ PCRELIBS=-L$(LOCALBASE)/lib -lpcre2-8 + else + PCREDEFS = $(shell $(PCRE_BUILDER) --cflags) +- PCRELIBS = $(shell $(PCRE_BUILDER) --libs) ++ PCRELIBS = $(shell $(PCRE_BUILDER) --libs8) + endif + + DEFS+=$(PCREDEFS) +@@ -31,4 +26,3 @@ LIBS+=$(PCRELIBS) + SERLIBPATH=../../lib + SER_LIBS+=$(SERLIBPATH)/srdb1/srdb1 + include ../../Makefile.modules +- +--- a/src/modules/lcr/hash.c ++++ b/src/modules/lcr/hash.c +@@ -15,8 +15,8 @@ + * 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 this program; if not, write to the Free Software ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +@@ -36,10 +36,10 @@ + /* Add lcr entry into hash table */ + int rule_hash_table_insert(struct rule_info **hash_table, unsigned int lcr_id, + unsigned int rule_id, unsigned short prefix_len, char *prefix, +- unsigned short from_uri_len, char *from_uri, pcre *from_uri_re, ++ unsigned short from_uri_len, char *from_uri, pcre2_code *from_uri_re, + unsigned short mt_tvalue_len, char *mt_tvalue, +- unsigned short request_uri_len, char *request_uri, pcre *request_uri_re, +- unsigned short stopper) ++ unsigned short request_uri_len, char *request_uri, ++ pcre2_code *request_uri_re, unsigned short stopper) + { + struct rule_info *rule; + str prefix_str; +@@ -50,9 +50,9 @@ int rule_hash_table_insert(struct rule_i + if(rule == NULL) { + SHM_MEM_ERROR_FMT("for rule hash table entry\n"); + if(from_uri_re) +- shm_free(from_uri_re); ++ pcre2_code_free(from_uri_re); + if(request_uri_re) +- shm_free(request_uri_re); ++ pcre2_code_free(request_uri_re); + return 0; + } + memset(rule, 0, sizeof(struct rule_info)); +@@ -99,9 +99,9 @@ int rule_hash_table_insert(struct rule_i + if(rid == NULL) { + PKG_MEM_ERROR_FMT("for rule_id hash table entry\n"); + if(from_uri_re) +- shm_free(from_uri_re); ++ pcre2_code_free(from_uri_re); + if(request_uri_re) +- shm_free(request_uri_re); ++ pcre2_code_free(request_uri_re); + shm_free(rule); + return 0; + } +@@ -180,7 +180,7 @@ int rule_hash_table_insert_target(struct + } + + +-/* ++/* + * Return pointer to lcr hash table entry to which given prefix hashes to. + */ + struct rule_info *rule_hash_table_lookup( +@@ -209,10 +209,10 @@ void rule_hash_table_contents_free(struc + r = hash_table[i]; + while(r) { + if(r->from_uri_re) { +- shm_free(r->from_uri_re); ++ pcre2_code_free(r->from_uri_re); + } + if(r->request_uri_re) +- shm_free(r->request_uri_re); ++ pcre2_code_free(r->request_uri_re); + t = r->targets; + while(t) { + next_t = t->next; +--- a/src/modules/lcr/hash.h ++++ b/src/modules/lcr/hash.h +@@ -15,8 +15,8 @@ + * 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 this program; if not, write to the Free Software ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +@@ -34,10 +34,10 @@ + + int rule_hash_table_insert(struct rule_info **hash_table, unsigned int lcr_id, + unsigned int rule_id, unsigned short prefix_len, char *prefix, +- unsigned short from_uri_len, char *from_uri, pcre *from_uri_re, ++ unsigned short from_uri_len, char *from_uri, pcre2_code *from_uri_re, + unsigned short mt_tvalue_len, char *mt_tvalue, +- unsigned short request_uri_len, char *request_uri, pcre *request_uri_re, +- unsigned short stopper); ++ unsigned short request_uri_len, char *request_uri, ++ pcre2_code *request_uri_re, unsigned short stopper); + + int rule_hash_table_insert_target(struct rule_info **hash_table, + struct gw_info *gws, unsigned int rule_id, unsigned int gw_id, +--- a/src/modules/lcr/lcr_mod.c ++++ b/src/modules/lcr/lcr_mod.c +@@ -16,8 +16,8 @@ + * 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 this program; if not, write to the Free Software ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +@@ -43,7 +43,8 @@ + #include <stdlib.h> + #include <string.h> + #include <arpa/inet.h> +-#include <pcre.h> ++#define PCRE2_CODE_UNIT_WIDTH 8 ++#include <pcre2.h> + #include "../../core/locking.h" + #include "../../core/sr_module.h" + #include "../../core/dprint.h" +@@ -204,6 +205,9 @@ static unsigned int priority_ordering_pa + /* mtree tree name */ + str mtree_param = {"lcr", 3}; + ++static pcre2_general_context *lcr_gctx = NULL; ++static pcre2_compile_context *lcr_ctx = NULL; ++ + /* + * Other module types and variables + */ +@@ -364,7 +368,7 @@ static param_export_t params[] = { + * Module interface + */ + struct module_exports exports = { +- "lcr", ++ "lcr", + DEFAULT_DLFLAGS, /* dlopen flags */ + cmds, /* Exported functions */ + params, /* Exported parameters */ +@@ -422,6 +426,16 @@ static void lcr_db_close(void) + } + } + ++static void *pcre2_malloc(size_t size, void *ext) ++{ ++ return shm_malloc(size); ++} ++ ++static void pcre2_free(void *ptr, void *ext) ++{ ++ shm_free(ptr); ++ ptr = NULL; ++} + + /* + * Module initialization function that is called before the main process forks +@@ -703,7 +717,15 @@ static int mod_init(void) + lcr_db_close(); + + /* rule shared memory */ +- ++ if((lcr_gctx = pcre2_general_context_create(pcre2_malloc, pcre2_free, NULL)) ++ == NULL) { ++ LM_ERR("pcre2 general context creation failed\n"); ++ goto err; ++ } ++ if((lcr_ctx = pcre2_compile_context_create(lcr_gctx)) == NULL) { ++ LM_ERR("pcre2 compile context creation failed\n"); ++ goto err; ++ } + /* rule hash table pointer table */ + /* pointer at index 0 points to temp rule hash table */ + rule_pt = (struct rule_info ***)shm_malloc( +@@ -779,6 +801,12 @@ dberror: + lcr_db_close(); + + err: ++ if(lcr_ctx) { ++ pcre2_compile_context_free(lcr_ctx); ++ } ++ if(lcr_gctx) { ++ pcre2_general_context_free(lcr_gctx); ++ } + free_shared_memory(); + return -1; + } +@@ -794,7 +822,12 @@ static int child_init(int rank) + static void destroy(void) + { + lcr_db_close(); +- ++ if(lcr_ctx) { ++ pcre2_compile_context_free(lcr_ctx); ++ } ++ if(lcr_gctx) { ++ pcre2_general_context_free(lcr_gctx); ++ } + free_shared_memory(); + } + +@@ -875,33 +908,32 @@ static int comp_matched(const void *m1, + + + /* Compile pattern into shared memory and return pointer to it. */ +-static pcre *reg_ex_comp(const char *pattern) ++static pcre2_code *reg_ex_comp(const char *pattern) + { +- pcre *re, *result; +- const char *error; +- int rc, err_offset; +- size_t size; +- +- re = pcre_compile(pattern, 0, &error, &err_offset, NULL); +- if(re == NULL) { +- LM_ERR("pcre compilation of '%s' failed at offset %d: %s\n", pattern, +- err_offset, error); +- return (pcre *)0; +- } +- rc = pcre_fullinfo(re, NULL, PCRE_INFO_SIZE, &size); +- if(rc != 0) { +- LM_ERR("pcre_fullinfo on compiled pattern '%s' yielded error: %d\n", +- pattern, rc); +- return (pcre *)0; +- } +- result = (pcre *)shm_malloc(size); ++ pcre2_code *result; ++ int pcre_error_num = 0; ++ char pcre_error[128]; ++ size_t pcre_erroffset; ++ ++ result = pcre2_compile((PCRE2_SPTR)pattern, PCRE2_ZERO_TERMINATED, 0, ++ &pcre_error_num, &pcre_erroffset, lcr_ctx); + if(result == NULL) { +- pcre_free(re); +- SHM_MEM_ERROR_FMT("for compiled PCRE pattern\n"); +- return (pcre *)0; ++ switch(pcre2_get_error_message( ++ pcre_error_num, (PCRE2_UCHAR *)pcre_error, 128)) { ++ case PCRE2_ERROR_NOMEMORY: ++ snprintf(pcre_error, 128, ++ "unknown error[%d]: pcre2 error buffer too small", ++ pcre_error_num); ++ break; ++ case PCRE2_ERROR_BADDATA: ++ snprintf(pcre_error, 128, "unknown pcre2 error[%d]", ++ pcre_error_num); ++ break; ++ } ++ LM_ERR("pcre compilation of '%s' failed at offset %zu: %s\n", pattern, ++ pcre_erroffset, pcre_error); ++ return NULL; + } +- memcpy(result, re, size); +- pcre_free(re); + return result; + } + +@@ -950,7 +982,7 @@ static struct gw_info *find_gateway_by_i + return NULL; + } + +-/* ++/* + * Insert gw info into index i or gws table + */ + static int insert_gw(struct gw_info *gws, unsigned int i, unsigned int gw_id, +@@ -1024,7 +1056,7 @@ static int insert_gw(struct gw_info *gws + + + /* +- * Insert prefix_len into list pointed by last rule hash table entry ++ * Insert prefix_len into list pointed by last rule hash table entry + * if not there already. Keep list in decending prefix_len order. + */ + static int prefix_len_insert( +@@ -1414,7 +1446,7 @@ int reload_tables() + db_key_t gw_cols[13]; + db_key_t rule_cols[7]; + db_key_t target_cols[4]; +- pcre *from_uri_re, *request_uri_re; ++ pcre2_code *from_uri_re, *request_uri_re; + struct gw_info *gws, *gw_pt_tmp; + struct rule_info **rules, **rule_pt_tmp; + +@@ -2129,11 +2161,12 @@ void add_gws_into_avps(struct gw_info *g + int load_gws_dummy(int lcr_id, str *ruri_user, str *from_uri, str *request_uri, + unsigned int *gw_indexes) + { +- int i, j; ++ int i, j, rc; + unsigned int gw_index, now, dex; + struct rule_info **rules, *rule, *pl; + struct gw_info *gws; + struct target *t; ++ pcre2_match_data *pcre_md = NULL; + struct matched_gw_info matched_gws[MAX_NO_OF_GWS + 1]; + struct sip_uri furi; + struct usr_avp *avp; +@@ -2178,12 +2211,18 @@ int load_gws_dummy(int lcr_id, str *ruri + || strncmp(rule->prefix, ruri_user->s, pl->prefix_len)) + goto next; + +- if((rule->from_uri_len != 0) +- && (pcre_exec(rule->from_uri_re, NULL, from_uri->s, +- from_uri->len, 0, 0, NULL, 0) +- < 0)) +- goto next; +- ++ if(rule->from_uri_len != 0) { ++ pcre_md = pcre2_match_data_create_from_pattern( ++ rule->from_uri_re, NULL); ++ rc = pcre2_match(rule->from_uri_re, (PCRE2_SPTR)from_uri->s, ++ (PCRE2_SIZE)from_uri->len, 0, 0, pcre_md, NULL); ++ if(pcre_md) { ++ pcre2_match_data_free(pcre_md); ++ pcre_md = NULL; ++ } ++ if(rc < 0) ++ goto next; ++ } + if((from_uri->len > 0) && (rule->mt_tvalue_len > 0)) { + if(mtree_api.mt_match(&msg, &mtree_param, &(furi.user), 2) + == -1) { +@@ -2216,9 +2255,16 @@ int load_gws_dummy(int lcr_id, str *ruri + "param has not been given.\n"); + return -1; + } +- if(pcre_exec(rule->request_uri_re, NULL, request_uri->s, +- request_uri->len, 0, 0, NULL, 0) +- < 0) ++ pcre_md = pcre2_match_data_create_from_pattern( ++ rule->request_uri_re, NULL); ++ rc = pcre2_match(rule->request_uri_re, ++ (PCRE2_SPTR)request_uri->s, ++ (PCRE2_SIZE)request_uri->len, 0, 0, pcre_md, NULL); ++ if(pcre_md) { ++ pcre2_match_data_free(pcre_md); ++ pcre_md = NULL; ++ } ++ if(rc < 0) + goto next; + } + +@@ -2282,9 +2328,10 @@ static int ki_load_gws_furi( + sip_msg_t *_m, int lcr_id, str *ruri_user, str *from_uri) + { + str *request_uri; +- int i, j; ++ int i, j, rc; + unsigned int gw_index, now, dex; + int_str val; ++ pcre2_match_data *pcre_md = NULL; + struct matched_gw_info matched_gws[MAX_NO_OF_GWS + 1]; + struct rule_info **rules, *rule, *pl; + struct gw_info *gws; +@@ -2343,14 +2390,22 @@ static int ki_load_gws_furi( + goto next; + + /* Match from uri */ +- if((rule->from_uri_len != 0) +- && (pcre_exec(rule->from_uri_re, NULL, from_uri->s, +- from_uri->len, 0, 0, NULL, 0) +- < 0)) { +- LM_DBG("from uri <%.*s> did not match to from regex <%.*s>\n", +- from_uri->len, from_uri->s, rule->from_uri_len, +- rule->from_uri); +- goto next; ++ if(rule->from_uri_len != 0) { ++ pcre_md = pcre2_match_data_create_from_pattern( ++ rule->from_uri_re, NULL); ++ rc = pcre2_match(rule->from_uri_re, (PCRE2_SPTR)from_uri->s, ++ (PCRE2_SIZE)from_uri->len, 0, 0, pcre_md, NULL); ++ if(pcre_md) { ++ pcre2_match_data_free(pcre_md); ++ pcre_md = NULL; ++ } ++ if(rc < 0) { ++ LM_DBG("from uri <%.*s> did not match to from regex " ++ "<%.*s>\n", ++ from_uri->len, from_uri->s, rule->from_uri_len, ++ rule->from_uri); ++ goto next; ++ } + } + + /* Match from uri user */ +@@ -2379,15 +2434,23 @@ static int ki_load_gws_furi( + } + + /* Match request uri */ +- if((rule->request_uri_len != 0) +- && (pcre_exec(rule->request_uri_re, NULL, request_uri->s, +- request_uri->len, 0, 0, NULL, 0) +- < 0)) { +- LM_DBG("request uri <%.*s> did not match to request regex " +- "<%.*s>\n", +- request_uri->len, request_uri->s, rule->request_uri_len, +- rule->request_uri); +- goto next; ++ if(rule->request_uri_len != 0) { ++ pcre_md = pcre2_match_data_create_from_pattern( ++ rule->request_uri_re, NULL); ++ rc = pcre2_match(rule->request_uri_re, ++ (PCRE2_SPTR)request_uri->s, ++ (PCRE2_SIZE)request_uri->len, 0, 0, pcre_md, NULL); ++ if(pcre_md) { ++ pcre2_match_data_free(pcre_md); ++ pcre_md = NULL; ++ } ++ if(rc < 0) { ++ LM_DBG("request uri <%.*s> did not match to request regex " ++ "<%.*s>\n", ++ request_uri->len, request_uri->s, ++ rule->request_uri_len, rule->request_uri); ++ goto next; ++ } + } + + /* Load gws associated with this rule */ +@@ -3015,7 +3078,7 @@ static int ki_next_gw(sip_msg_t *_m) + } + + /** +- * ++ * + */ + static int next_gw(struct sip_msg *_m, char *_s1, char *_s2) + { +--- a/src/modules/lcr/lcr_mod.h ++++ b/src/modules/lcr/lcr_mod.h +@@ -2,6 +2,7 @@ + * Various lcr related constant, types, and external variables + * + * Copyright (C) 2005-2014 Juha Heinanen ++ * Copyright (C) 2023 Victor Seva + * + * This file is part of Kamailio, a free SIP server. + * +@@ -33,7 +34,8 @@ + #define LCR_MOD_H + + #include <stdio.h> +-#include <pcre.h> ++#define PCRE2_CODE_UNIT_WIDTH 8 ++#include <pcre2.h> + #include "../../core/locking.h" + #include "../../core/parser/parse_uri.h" + #include "../../core/ip_addr.h" +@@ -60,10 +62,10 @@ struct rule_info + unsigned short from_uri_len; + char mt_tvalue[MAX_MT_TVALUE_LEN + 1]; + unsigned short mt_tvalue_len; +- pcre *from_uri_re; ++ pcre2_code *from_uri_re; + char request_uri[MAX_URI_LEN + 1]; + unsigned short request_uri_len; +- pcre *request_uri_re; ++ pcre2_code *request_uri_re; + unsigned short stopper; + unsigned int enabled; + struct target *targets; |
