?? hash.c
字號:
/* * Hash functions for cached trusted table * * Copyright (C) 2003 Juha Heinanen * * This file is part of ser, a free SIP server. * * ser 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 * * For a license to use the ser software under conditions * other than those described here, or to purchase support for this * software, please contact iptel.org by e-mail at the following addresses: * info@iptel.org * * ser 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 this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */#include <sys/types.h>#include <regex.h>#include "../../mem/shm_mem.h"#include "../../parser/parse_from.h"#include "../../ut.h"#include "hash.h"/* * Create and initialize a hash table */struct trusted_list** new_hash_table(void){ struct trusted_list** ptr; /* Initializing hash tables and hash table variable */ ptr = (struct trusted_list **)shm_malloc(sizeof(struct trusted_list*) * HASH_SIZE); if (!ptr) { LOG(L_ERR, "new_hash_table(): No memory for hash table\n"); return 0; } memset(ptr, 0, sizeof(struct trusted_list*) * HASH_SIZE); return ptr;}/* * Release all memory allocated for a hash table */void free_hash_table(struct trusted_list** table){ if (table) { empty_hash_table(table); } shm_free(table);}/* * String hash function */static unsigned int hash(str* src_ip){ char *p; unsigned int h = 0; unsigned int len; unsigned int i; p = src_ip->s; len = src_ip->len; for (i = 0; i < len; i++) { h = ( h << 5 ) - h + *(p + i); } return h % HASH_SIZE;}/* * Add <src_ip, proto, pattern> 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){ struct trusted_list *np; unsigned int hash_val; np = (struct trusted_list *) shm_malloc(sizeof(*np)); if (np == NULL) { LOG(L_CRIT, "hash_table_insert(): Cannot allocate memory for table entry\n"); return -1; } np->src_ip.len = strlen(src_ip); np->src_ip.s = (char *) shm_malloc(np->src_ip.len); if (np->src_ip.s == NULL) { LOG(L_CRIT, "hash_table_insert(): Cannot allocate memory for src_ip string\n"); return -1; } (void) strncpy(np->src_ip.s, src_ip, np->src_ip.len); if (strcmp(proto, "any") == 0) { np->proto = PROTO_NONE; } else if (strcmp(proto, "udp") == 0) { np->proto = PROTO_UDP; } else if (strcmp(proto, "tcp") == 0) { np->proto = PROTO_TCP; } else if (strcmp(proto, "tls") == 0) { np->proto = PROTO_TLS; } else if (strcmp(proto, "sctp") == 0) { np->proto = PROTO_SCTP; } else { LOG(L_CRIT, "hash_table_insert(): Unknown protocol\n"); return -1; } np->pattern = (char *) shm_malloc(strlen(pattern)+1); if (np->pattern == NULL) { LOG(L_CRIT, "hash_table_insert(): Cannot allocate memory for pattern string\n"); return -1; } (void) strcpy(np->pattern, pattern); hash_val = hash(&(np->src_ip)); np->next = hash_table[hash_val]; hash_table[hash_val] = np; return 1;}/* * Check if an entry exists in hash table that has given src_ip and protocol * value and pattern that matches to From URI. */int match_hash_table(struct trusted_list** table, struct sip_msg* msg){ str uri; char uri_string[MAX_URI_SIZE + 1]; regex_t preg; struct trusted_list *np; str src_ip; src_ip.s = ip_addr2a(&msg->rcv.src_ip); src_ip.len = strlen(src_ip.s); if (parse_from_header(msg) < 0) return -1; uri = get_from(msg)->uri; if (uri.len > MAX_URI_SIZE) { LOG(L_ERR, "match_hash_table(): From URI too large\n"); return -1; } memcpy(uri_string, uri.s, uri.len); uri_string[uri.len] = (char)0; for (np = table[hash(&src_ip)]; np != NULL; np = np->next) { if ((np->src_ip.len == src_ip.len) && (strncasecmp(np->src_ip.s, src_ip.s, src_ip.len) == 0) && ((np->proto == PROTO_NONE) || (np->proto == msg->rcv.proto))) { if (regcomp(&preg, np->pattern, REG_NOSUB)) { LOG(L_ERR, "match_hash_table(): Error in regular expression\n"); return -1; } if (regexec(&preg, uri_string, 0, (regmatch_t *)0, 0)) { regfree(&preg); } else { regfree(&preg); return 1; } } } return -1;}/* * Print domains stored in hash table */void hash_table_print(struct trusted_list** hash_table, FILE* reply_file){ int i; struct trusted_list *np; for (i = 0; i < HASH_SIZE; i++) { np = hash_table[i]; while (np) { fprintf(reply_file, "%4d <%.*s, %d, %s>\n", i, np->src_ip.len, ZSW(np->src_ip.s), np->proto, np->pattern); np = np->next; } }}/* * Free contents of hash table, it doesn't destroy the * hash table itself */void empty_hash_table(struct trusted_list **hash_table){ int i; struct trusted_list *np, *next; for (i = 0; i < HASH_SIZE; i++) { np = hash_table[i]; while (np) { shm_free(np->src_ip.s); shm_free(np->pattern); next = np->next; shm_free(np); np = next; } hash_table[i] = 0; }}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -