#include <sys/types.h>
#include <regex.h>
+#include "parse_config.h"
#include "../../mem/shm_mem.h"
#include "../../parser/parse_from.h"
#include "../../ut.h"
/*
- * Add <src_ip, proto, pattern, tag> into hash table, where proto is integer
+ * Add <src_ip, proto, pattern, ruri_pattern, tag, priority> into hash table, where proto is integer
* representation of string argument proto.
*/
int hash_table_insert(struct trusted_list** table, char* src_ip,
- char* proto, char* pattern, char* tag)
+ char* proto, char* pattern, char* ruri_pattern, char* tag, int priority)
{
struct trusted_list *np;
+ struct trusted_list *np0 = NULL;
+ struct trusted_list *np1 = NULL;
unsigned int hash_val;
np = (struct trusted_list *) shm_malloc(sizeof(*np));
np->pattern = 0;
}
+ if (ruri_pattern) {
+ np->ruri_pattern = (char *) shm_malloc(strlen(ruri_pattern)+1);
+ if (np->ruri_pattern == NULL) {
+ LM_CRIT("cannot allocate shm memory for ruri_pattern string\n");
+ shm_free(np->src_ip.s);
+ shm_free(np);
+ return -1;
+ }
+ (void) strcpy(np->ruri_pattern, ruri_pattern);
+ } else {
+ np->ruri_pattern = 0;
+ }
+
if (tag) {
np->tag.len = strlen(tag);
np->tag.s = (char *) shm_malloc((np->tag.len) + 1);
if (np->tag.s == NULL) {
- LM_CRIT("cannot allocate shm memory for pattern string\n");
+ LM_CRIT("cannot allocate shm memory for pattern or ruri_pattern string\n");
shm_free(np->src_ip.s);
shm_free(np->pattern);
+ shm_free(np->ruri_pattern);
shm_free(np);
return -1;
}
np->tag.s = 0;
}
+ np->priority = priority;
+
hash_val = perm_hash(np->src_ip);
- np->next = table[hash_val];
- table[hash_val] = np;
+ if(table[hash_val]==NULL) {
+ np->next = NULL;
+ table[hash_val] = np;
+ } else {
+ np1 = NULL;
+ np0 = table[hash_val];
+ while(np0) {
+ if(np0->priority < np->priority)
+ break;
+ np1 = np0;
+ np0 = np0->next;
+ }
+ if(np1==NULL) {
+ np->next = table[hash_val];
+ table[hash_val] = np;
+ } else {
+ np->next = np1->next;
+ np1->next = np;
+ }
+ }
return 1;
}
int match_hash_table(struct trusted_list** table, struct sip_msg* msg,
char *src_ip_c_str, int proto)
{
- str uri;
+ str uri, ruri;
char uri_string[MAX_URI_SIZE + 1];
+ char ruri_string[MAX_URI_SIZE + 1];
regex_t preg;
struct trusted_list *np;
str src_ip;
}
memcpy(uri_string, uri.s, uri.len);
uri_string[uri.len] = (char)0;
+ ruri = msg->first_line.u.request.uri;
+ if (ruri.len > MAX_URI_SIZE) {
+ LM_ERR("message has Request URI too large\n");
+ return -1;
+ }
+ memcpy(ruri_string, ruri.s, ruri.len);
+ ruri_string[ruri.len] = (char)0;
}
for (np = table[perm_hash(src_ip)]; np != NULL; np = np->next) {
(strncmp(np->src_ip.s, src_ip.s, src_ip.len) == 0) &&
((np->proto == PROTO_NONE) || (proto == PROTO_NONE) ||
(np->proto == proto))) {
- if (np->pattern && IS_SIP(msg)) {
- if (regcomp(&preg, np->pattern, REG_NOSUB)) {
- LM_ERR("invalid regular expression\n");
- continue;
+ if (IS_SIP(msg)) {
+ if (np->pattern) {
+ if (regcomp(&preg, np->pattern, REG_NOSUB)) {
+ LM_ERR("invalid regular expression\n");
+ if (!np->ruri_pattern) {
+ continue;
+ }
+ }
+ if (regexec(&preg, uri_string, 0, (regmatch_t *)0, 0)) {
+ regfree(&preg);
+ continue;
+ }
+ regfree(&preg);
}
- if (regexec(&preg, uri_string, 0, (regmatch_t *)0, 0)) {
+ if (np->ruri_pattern) {
+ if (regcomp(&preg, np->ruri_pattern, REG_NOSUB)) {
+ LM_ERR("invalid regular expression\n");
+ continue;
+ }
+ if (regexec(&preg, ruri_string, 0, (regmatch_t *)0, 0)) {
+ regfree(&preg);
+ continue;
+ }
regfree(&preg);
- continue;
}
- regfree(&preg);
}
/* Found a match */
if (tag_avp.n && np->tag.s) {
np = table[i];
while (np) {
if (addf_mi_node_child(rpl, 0, 0, 0,
- "%4d <%.*s, %d, %s, %s>",
+ "%4d <%.*s, %d, %s, %s, %s, %d>",
i,
np->src_ip.len, ZSW(np->src_ip.s),
np->proto,
np->pattern?np->pattern:"NULL",
- np->tag.len?np->tag.s:"NULL") == 0) {
+ np->ruri_pattern?np->ruri_pattern:"NULL",
+ np->tag.len?np->tag.s:"NULL",
+ np->priority) == 0) {
return -1;
}
np = np->next;
rpc->fault(c, 500, "Internal error creating rpc data (ip)");
return -1;
}
- if(rpc->struct_add(ih, "dss", "proto", np->proto,
+ if(rpc->struct_add(ih, "dsssd", "proto", np->proto,
"pattern", np->pattern ? np->pattern : "NULL",
- "tag", np->tag.len ? np->tag.s : "NULL") < 0)
+ "ruri_pattern", np->ruri_pattern ? np->ruri_pattern : "NULL",
+ "tag", np->tag.len ? np->tag.s : "NULL",
+ "priority", np->priority) < 0)
{
rpc->fault(c, 500, "Internal error creating rpc data");
return -1;
str src_ip; /* Source IP of SIP message */
int proto; /* Protocol -- UDP, TCP, TLS, or SCTP */
char *pattern; /* Pattern matching From header field */
+ char *ruri_pattern; /* Pattern matching Request URI */
str tag; /* Tag to be assigned to AVP */
+ int priority; /* priority */
struct trusted_list *next; /* Next element in the list */
};
/*
- * Add <src_ip, proto, pattern> into hash table, where proto is integer
+ * Add <src_ip, proto, pattern, ruri_pattern, priority> into hash table, where proto is integer
* representation of string argument proto.
*/
int hash_table_insert(struct trusted_list** hash_table, char* src_ip,
- char* proto, char* pattern, char* tag);
+ char* proto, char* pattern, char* ruri_pattern, char* tag, int priority);
/*
* Check if an entry exists in hash table that has given src_ip and protocol
- * value and pattern that matches to From URI.
+ * value and pattern or ruri_pattern that matches to From URI.
*/
int match_hash_table(struct trusted_list** table, struct sip_msg* msg,
char *scr_ip, int proto);
str source_col = str_init("src_ip"); /* Name of source address column */
str proto_col = str_init("proto"); /* Name of protocol column */
str from_col = str_init("from_pattern"); /* Name of from pattern column */
+str ruri_col = str_init("ruri_pattern"); /* Name of RURI pattern column */
str tag_col = str_init("tag"); /* Name of tag column */
+str priority_col = str_init("priority"); /* Name of priority column */
str tag_avp_param = {NULL, 0}; /* Peer tag AVP spec */
int peer_tag_mode = 0; /* Add tags form all mathcing peers to avp */
{"source_col", PARAM_STR, &source_col },
{"proto_col", PARAM_STR, &proto_col },
{"from_col", PARAM_STR, &from_col },
+ {"ruri_col", PARAM_STR, &ruri_col },
{"tag_col", PARAM_STR, &tag_col },
+ {"priority_col", PARAM_STR, &priority_col },
{"peer_tag_avp", PARAM_STR, &tag_avp_param },
{"peer_tag_mode", INT_PARAM, &peer_tag_mode },
{"address_table", PARAM_STR, &address_table },
extern str source_col; /* Name of source address column */
extern str proto_col; /* Name of protocol column */
extern str from_col; /* Name of from pattern column */
+extern str ruri_col; /* Name of RURI pattern column */
extern str tag_col; /* Name of tag column */
+extern str priority_col; /* Name of priority column */
extern str address_table; /* Name of address table */
extern str grp_col; /* Name of address group column */
extern str ip_addr_col; /* Name of ip address column */
#include "../../parser/parse_from.h"
#include "../../usr_avp.h"
-#define TABLE_VERSION 5
+#define TABLE_VERSION 6
struct trusted_list ***hash_table; /* Pointer to current hash table pointer */
struct trusted_list **hash_table_1; /* Pointer to hash table 1 */
*/
int reload_trusted_table(void)
{
- db_key_t cols[4];
+ db_key_t cols[6];
db1_res_t* res = NULL;
db_row_t* row;
db_val_t* val;
struct trusted_list **new_hash_table;
struct trusted_list **old_hash_table;
int i;
+ int priority;
- char *pattern, *tag;
+ char *pattern, *ruri_pattern, *tag;
cols[0] = &source_col;
cols[1] = &proto_col;
cols[2] = &from_col;
- cols[3] = &tag_col;
+ cols[3] = &ruri_col;
+ cols[4] = &tag_col;
+ cols[5] = &priority_col;
if (db_handle == 0) {
LM_ERR("no connection to database\n");
return -1;
}
- if (perm_dbf.query(db_handle, NULL, 0, NULL, cols, 0, 4, 0, &res) < 0) {
+ if (perm_dbf.query(db_handle, NULL, 0, NULL, cols, 0, 6, 0, &res) < 0) {
LM_ERR("failed to query database\n");
return -1;
}
for (i = 0; i < RES_ROW_N(res); i++) {
val = ROW_VALUES(row + i);
- if ((ROW_N(row + i) == 4) &&
+ if ((ROW_N(row + i) == 6) &&
((VAL_TYPE(val) == DB1_STRING) || (VAL_TYPE(val) == DB1_STR) ) &&
!VAL_NULL(val) &&
((VAL_TYPE(val + 1) == DB1_STRING) || (VAL_TYPE(val + 1) == DB1_STR))
(VAL_NULL(val + 2) ||
(((VAL_TYPE(val + 2) == DB1_STRING) || (VAL_TYPE(val + 2) == DB1_STR)) &&
!VAL_NULL(val + 2))) && (VAL_NULL(val + 3) ||
- (((VAL_TYPE(val + 3) == DB1_STRING) || (VAL_TYPE(val + 3) == DB1_STR) )&&
- !VAL_NULL(val + 3)))) {
+ (((VAL_TYPE(val + 3) == DB1_STRING) || (VAL_TYPE(val + 3) == DB1_STR) )&&
+ !VAL_NULL(val + 3))) && (VAL_NULL(val + 4) ||
+ (((VAL_TYPE(val + 4) == DB1_STRING) || (VAL_TYPE(val + 4) == DB1_STR) )&&
+ !VAL_NULL(val + 4)))) {
if (VAL_NULL(val + 2)) {
pattern = 0;
} else {
pattern = (char *)VAL_STRING(val + 2);
}
if (VAL_NULL(val + 3)) {
+ ruri_pattern = 0;
+ } else {
+ ruri_pattern = (char *)VAL_STRING(val + 3);
+ }
+ if (VAL_NULL(val + 4)) {
tag = 0;
} else {
- tag = (char *)VAL_STRING(val + 3);
+ tag = (char *)VAL_STRING(val + 4);
+ }
+ if (VAL_NULL(val + 5)) {
+ priority = 0;
+ } else {
+ priority = (int)VAL_INT(val + 5);
}
if (hash_table_insert(new_hash_table,
(char *)VAL_STRING(val),
(char *)VAL_STRING(val + 1),
- pattern, tag) == -1) {
+ pattern, ruri_pattern, tag, priority) == -1) {
LM_ERR("hash table problem\n");
perm_dbf.free_result(db_handle, res);
empty_hash_table(new_hash_table);
return -1;
}
- LM_DBG("tuple <%s, %s, %s, %s> inserted into trusted hash "
+ LM_DBG("tuple <%s, %s, %s, %s, %s> inserted into trusted hash "
"table\n", VAL_STRING(val), VAL_STRING(val + 1),
- pattern, tag);
+ pattern, ruri_pattern, tag);
} else {
LM_ERR("database problem\n");
perm_dbf.free_result(db_handle, res);
static int match_res(struct sip_msg* msg, int proto, db1_res_t* _r)
{
int i, tag_avp_type;
- str uri;
+ str uri, ruri;
char uri_string[MAX_URI_SIZE+1];
+ char ruri_string[MAX_URI_SIZE+1];
db_row_t* row;
db_val_t* val;
regex_t preg;
}
memcpy(uri_string, uri.s, uri.len);
uri_string[uri.len] = (char)0;
+ ruri = msg->first_line.u.request.uri;
+ if (ruri.len > MAX_URI_SIZE) {
+ LM_ERR("message has Request URI too large\n");
+ return -1;
+ }
+ memcpy(ruri_string, ruri.s, ruri.len);
+ ruri_string[ruri.len] = (char)0;
}
get_tag_avp(&tag_avp, &tag_avp_type);
for(i = 0; i < RES_ROW_N(_r); i++) {
val = ROW_VALUES(row + i);
- if ((ROW_N(row + i) == 3) &&
+ if ((ROW_N(row + i) == 4) &&
(VAL_TYPE(val) == DB1_STRING) && !VAL_NULL(val) &&
match_proto(VAL_STRING(val), proto) &&
(VAL_NULL(val + 1) ||
((VAL_TYPE(val + 1) == DB1_STRING) && !VAL_NULL(val + 1))) &&
(VAL_NULL(val + 2) ||
- ((VAL_TYPE(val + 2) == DB1_STRING) && !VAL_NULL(val + 2))))
+ ((VAL_TYPE(val + 2) == DB1_STRING) && !VAL_NULL(val + 2))) &&
+ (VAL_NULL(val + 3) ||
+ ((VAL_TYPE(val + 3) == DB1_STRING) && !VAL_NULL(val + 3))))
{
- if (!VAL_NULL(val + 1) && IS_SIP(msg)) {
+ if (IS_SIP(msg)) {
+ if (!VAL_NULL(val + 1)) {
if (regcomp(&preg, (char *)VAL_STRING(val + 1), REG_NOSUB)) {
LM_ERR("invalid regular expression\n");
- continue;
+ if (VAL_NULL(val + 2)) {
+ continue;
+ }
}
if (regexec(&preg, uri_string, 0, (regmatch_t *)0, 0)) {
regfree(&preg);
continue;
}
- regfree(&preg);
+ regfree(&preg);
+ }
+ if (!VAL_NULL(val + 2)) {
+ if (regcomp(&preg, (char *)VAL_STRING(val + 2), REG_NOSUB)) {
+ LM_ERR("invalid regular expression\n");
+ continue;
+ }
+ if (regexec(&preg, ruri_string, 0, (regmatch_t *)0, 0)) {
+ regfree(&preg);
+ continue;
+ }
+ regfree(&preg);
+ }
}
/* Found a match */
- if (tag_avp.n && !VAL_NULL(val + 2)) {
- avp_val.s.s = (char *)VAL_STRING(val + 2);
+ if (tag_avp.n && !VAL_NULL(val + 3)) {
+ avp_val.s.s = (char *)VAL_STRING(val + 3);
avp_val.s.len = strlen(avp_val.s.s);
if (add_avp(tag_avp_type|AVP_VAL_STR, tag_avp, avp_val) != 0) {
LM_ERR("failed to set of tag_avp failed\n");
db_key_t keys[1];
db_val_t vals[1];
- db_key_t cols[3];
+ db_key_t cols[4];
if (db_mode == DISABLE_CACHE) {
+ db_key_t order = &priority_col;
if (db_handle == 0) {
LM_ERR("no connection to database\n");
keys[0] = &source_col;
cols[0] = &proto_col;
cols[1] = &from_col;
- cols[2] = &tag_col;
+ cols[2] = &ruri_col;
+ cols[3] = &tag_col;
if (perm_dbf.use_table(db_handle, &trusted_table) < 0) {
LM_ERR("failed to use trusted table\n");
VAL_NULL(vals) = 0;
VAL_STRING(vals) = src_ip;
- if (perm_dbf.query(db_handle, keys, 0, vals, cols, 1, 3, 0,
+ if (perm_dbf.query(db_handle, keys, 0, vals, cols, 1, 4, order,
&res) < 0){
LM_ERR("failed to query database\n");
return -1;