/* * Reload addr table to new hash table and when done, make new hash table * current one. */ int reload_address_table(void) { db_key_t cols[5]; db1_res_t* res = NULL; db_row_t* row; db_val_t* val; struct addr_list **new_hash_table; struct subnet *new_subnet_table; struct domain_name_list **new_domain_name_table; int i; unsigned int gid; unsigned int port; unsigned int mask; str ips; ip_addr_t *ipa; char *tagv; cols[0] = &grp_col; cols[1] = &ip_addr_col; cols[2] = &mask_col; cols[3] = &port_col; cols[4] = &tag_col; if (perm_dbf.use_table(db_handle, &address_table) < 0) { LM_ERR("failed to use table\n"); return -1; } if (perm_dbf.query(db_handle, NULL, 0, NULL, cols, 0, 5, 0, &res) < 0) { LM_ERR("failed to query database\n"); return -1; } /* Choose new hash table and free its old contents */ if (*addr_hash_table == addr_hash_table_1) { empty_addr_hash_table(addr_hash_table_2); new_hash_table = addr_hash_table_2; } else { empty_addr_hash_table(addr_hash_table_1); new_hash_table = addr_hash_table_1; } /* Choose new subnet table */ if (*subnet_table == subnet_table_1) { empty_subnet_table(subnet_table_2); new_subnet_table = subnet_table_2; } else { empty_subnet_table(subnet_table_1); new_subnet_table = subnet_table_1; } /* Choose new domain name table */ if (*domain_list_table == domain_list_table_1) { empty_domain_name_table(domain_list_table_2); new_domain_name_table = domain_list_table_2; } else { empty_domain_name_table(domain_list_table_1); new_domain_name_table = domain_list_table_1; } row = RES_ROWS(res); LM_DBG("Number of rows in address table: %d\n", RES_ROW_N(res)); for (i = 0; i < RES_ROW_N(res); i++) { val = ROW_VALUES(row + i); /* basic checks to db values */ if (ROW_N(row + i) != 5) { LM_DBG("failure during checks of db address table: Colums %d - expected 5\n", ROW_N(row + i)); goto dberror; } if ((VAL_TYPE(val) != DB1_INT) || VAL_NULL(val) || (VAL_INT(val) <= 0)) { LM_DBG("failure during checks of database value 1 (group) in address table\n"); goto dberror; } if ((VAL_TYPE(val + 1) != DB1_STRING) && (VAL_TYPE(val + 1) != DB1_STR)) { LM_DBG("failure during checks of database value 2 (IP address) in address table - not a string value\n"); goto dberror; } if (VAL_NULL(val + 1)) { LM_DBG("failure during checks of database value 2 (IP address) in address table - NULL value not permitted\n"); goto dberror; } if ((VAL_TYPE(val + 2) != DB1_INT) || VAL_NULL(val + 2)) { LM_DBG("failure during checks of database value 3 (subnet size/CIDR) in address table\n"); goto dberror; } if ((VAL_TYPE(val + 3) != DB1_INT) || VAL_NULL(val + 3)) { LM_DBG("failure during checks of database value 4 (port) in address table\n"); goto dberror; } gid = VAL_UINT(val); ips.s = (char *)VAL_STRING(val + 1); ips.len = strlen(ips.s); mask = VAL_UINT(val + 2); port = VAL_UINT(val + 3); tagv = VAL_NULL(val + 4)?NULL:(char *)VAL_STRING(val + 4); ipa = strtoipX(&ips); if ( ipa==NULL ) { LM_DBG("Domain name: %.*s\n", ips.len, ips.s); // goto dberror; } else { if(ipa->af == AF_INET6) { if((int)mask<0 || mask>128) { LM_DBG("failure during IP mask check for v6\n"); goto dberror; } } else { if((int)mask<0 || mask>32) { LM_DBG("failure during IP mask check for v4\n"); goto dberror; } } } if ( ipa ) { if ( (ipa->af==AF_INET6 && mask==128) || (ipa->af==AF_INET && mask==32) ) { if (addr_hash_table_insert(new_hash_table, gid, ipa, port, tagv) == -1) { LM_ERR("hash table problem\n"); perm_dbf.free_result(db_handle, res); return -1; } LM_DBG("Tuple <%u, %s, %u> inserted into address hash table\n", gid, ips.s, port); } else { if (subnet_table_insert(new_subnet_table, gid, ipa, mask, port, tagv) == -1) { LM_ERR("subnet table problem\n"); perm_dbf.free_result(db_handle, res); return -1; } LM_DBG("Tuple <%u, %s, %u, %u> inserted into subnet table\n", gid, ips.s, port, mask); } } else { if (domain_name_table_insert(new_domain_name_table, gid, &ips, port, tagv) == -1) { LM_ERR("domain name table problem\n"); perm_dbf.free_result(db_handle, res); return -1; } LM_DBG("Tuple <%u, %s, %u> inserted into domain name table\n", gid, ips.s, port); } } perm_dbf.free_result(db_handle, res); *addr_hash_table = new_hash_table; *subnet_table = new_subnet_table; *domain_list_table = new_domain_name_table; LM_DBG("address table reloaded successfully.\n"); return 1; dberror: LM_ERR("database problem - invalid record\n"); perm_dbf.free_result(db_handle, res); return -1; }
/* * Reload address table to new hash table and when done, make new hash table * current one. */ int reload_address_table(struct pm_part_struct *part_struct) { db_key_t cols[8]; db_res_t* res = NULL; db_row_t* row; db_val_t* val; struct address_list **new_hash_table; struct subnet *new_subnet_table; int i, mask, proto, group, port, id; struct ip_addr *ip_addr; struct net *subnet; str str_pattern = {NULL,0}, str_info={NULL,0}; str str_src_ip, str_proto; UNUSED(id); cols[0] = &ip_col; cols[1] = &grp_col; cols[2] = &mask_col; cols[3] = &port_col; cols[4] = &proto_col; cols[5] = &pattern_col; cols[6] = &info_col; cols[7] = &id_col; if (part_struct->perm_dbf.use_table(part_struct->db_handle, &part_struct->table) < 0) { LM_ERR("failed to use address table\n"); return -1; } if (part_struct->perm_dbf.query(part_struct->db_handle, NULL, 0, NULL, cols, 0, 8, 0, &res) < 0) { LM_ERR("failed to query database\n"); return -1; } /* Choose new hash table and free its old contents */ if (*part_struct->hash_table == part_struct->hash_table_1) { empty_hash(part_struct->hash_table_2); new_hash_table = part_struct->hash_table_2; } else { empty_hash(part_struct->hash_table_1); new_hash_table = part_struct->hash_table_1; } /* Choose new subnet table */ if (*part_struct->subnet_table == part_struct->subnet_table_1) { empty_subnet_table(part_struct->subnet_table_2); new_subnet_table = part_struct->subnet_table_2; } else { empty_subnet_table(part_struct->subnet_table_1); new_subnet_table = part_struct->subnet_table_1; } row = RES_ROWS(res); LM_DBG("number of rows in address table: %d\n", RES_ROW_N(res)); if (RES_COL_N(res) != 8) { LM_ERR("too many columns\n"); goto error; } for (i = 0; i < RES_ROW_N(res); i++) { val = ROW_VALUES(row + i); if ((VAL_TYPE(val)!=DB_STRING && VAL_TYPE(val)!=DB_STR) || VAL_NULL(val)) { LM_ERR("invalid IP column type on row %d, skipping..\n", i); continue; } if (VAL_TYPE(val + 1) != DB_INT || VAL_NULL(val + 1) || VAL_INT(val + 1) < 0) { LM_ERR("invalid group column type on row %d, skipping..\n", i); continue; } if (VAL_TYPE(val + 2) != DB_INT || VAL_NULL(val + 2) || VAL_INT(val + 2) < 0 || VAL_INT(val + 2) > 32) { LM_ERR("invalid mask column type on row %d, skipping..\n", i); continue; } if (VAL_TYPE(val + 3) != DB_INT || VAL_NULL(val + 3)) { LM_ERR("invalid port column type on row %d, skipping..\n", i); continue; } if ((VAL_TYPE(val + 4) != DB_STRING && VAL_TYPE(val + 4) != DB_STR) || VAL_NULL(val + 4)) { LM_ERR("invalid protocol column type on row %d, skipping..\n", i); continue; } if (VAL_TYPE(val + 5) != DB_STRING && VAL_TYPE(val + 5) != DB_STR) { LM_ERR("invalid pattern column type on row %d, skipping..\n", i); continue; } if (VAL_TYPE(val + 6) != DB_STRING && VAL_TYPE(val + 6) != DB_STR) { LM_ERR("invalid info column type on row %d, skipping..\n", i); goto error; } id = (unsigned int) VAL_INT(val + 7); /* IP string */ if (VAL_TYPE(val)==DB_STRING) { str_src_ip.s = (char*)VAL_STRING(val); str_src_ip.len = strlen(str_src_ip.s); } else { str_src_ip = VAL_STR(val); } if (str_src_ip.len==0) { LM_DBG("empty ip field in address table, ignoring entry" " number %d\n", i); continue; } ip_addr = str2ip(&str_src_ip); if (!ip_addr) { LM_DBG("invalid ip field in address table, ignoring entry " "with id %d\n", id); continue; } /* proto string */ if (VAL_TYPE(val+4)==DB_STRING) { str_proto.s = (char*)VAL_STRING(val+4); str_proto.len = strlen(str_proto.s); } else { str_proto = VAL_STR(val+4); } if (str_proto.len==4 && !strncasecmp(str_proto.s, "none",4)) { LM_DBG("protocol field is \"none\" in address table, ignoring" " entry with id %d\n", id); continue; } proto = proto_char2int(&str_proto); if (proto == -1) { LM_DBG("unknown protocol field in address table, ignoring" " entry with id %d\n", id); continue; } /* pattern string */ if (!VAL_NULL(val + 5)) { if (VAL_TYPE(val+5)==DB_STRING) { str_pattern.s = (char*)VAL_STRING(val+5); str_pattern.len = strlen(str_pattern.s); } else { str_pattern = VAL_STR(val+5); } } else { str_pattern.len = 0; str_pattern.s = 0; } /* info string */ if (!VAL_NULL(val + 6)) { if (VAL_TYPE(val+6)==DB_STRING) { str_info.s = (char*)VAL_STRING(val+6); str_info.len = strlen(str_info.s); } else { str_info = VAL_STR(val+6); } } else { str_info.len = 0; str_info.s = 0; } group = (unsigned int) VAL_INT(val + 1); port = (unsigned int) VAL_INT(val + 3); mask = (unsigned int) VAL_INT(val + 2); if (mask == 32) { if (hash_insert(new_hash_table, ip_addr, group, port, proto, &str_pattern, &str_info) == -1) { LM_ERR("hash table insert error\n"); goto error; } LM_DBG("Tuple <%.*s, %u, %u, %u, %.*s, %.*s> inserted into " "address hash table\n", str_src_ip.len, str_src_ip.s, group, port, proto, str_pattern.len, str_pattern.s, str_info.len,str_info.s); } else { subnet = mk_net_bitlen(ip_addr, mask); if (subnet_table_insert(new_subnet_table, group, subnet, port, proto, &str_pattern, &str_info) == -1) { LM_ERR("subnet table problem\n"); if (subnet) { pkg_free(subnet); } goto error; } LM_DBG("Tuple <%.*s, %u, %u, %u> inserted into subnet table\n", str_src_ip.len, str_src_ip.s, group, mask, port); /* subnet in pkg; needs to be freed since was copied to shm */ if (subnet) { pkg_free(subnet); } } } part_struct->perm_dbf.free_result(part_struct->db_handle, res); *part_struct->hash_table = new_hash_table; *part_struct->subnet_table = new_subnet_table; LM_DBG("address table reloaded successfully.\n"); return 1; error: part_struct->perm_dbf.free_result(part_struct->db_handle, res); return -1; }