Ejemplo n.º 1
0
/*
 * 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;
}
Ejemplo n.º 2
0
/*
 * 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;
}