ip parse and binary ip bytes use

This commit is contained in:
lion 2025-09-20 17:29:11 +08:00
parent 6712ee9504
commit b01253e6b3
3 changed files with 129 additions and 59 deletions

View File

@ -59,7 +59,7 @@ if string.len(dbFile) < 2 then
return
end
local version = IPv4
local version = xdb.IPv4
-- create the searcher based on the cache-policy
local searcher, v_index, content
@ -116,7 +116,8 @@ while ( true ) do
break
end
version, err = xdb.parse_ip(line)
ip_bytes, err = xdb.parse_ip(line)
-- print(string.format("parse(%s): %s, err: %s", line, xdb.ip_to_string(ip_bytes), err))
if err ~= nil then
print(string.format("invalid ip address `%s`", line))
goto continue
@ -124,7 +125,7 @@ while ( true ) do
-- do the search
s_time = xdb.now()
region, err = searcher:search(line)
region, err = searcher:search(ip_bytes)
c_time = xdb.now() - s_time
if err ~= nil then
print(string.format("{err: %s, io_count: %d}", err, searcher:get_io_count()))

View File

@ -14,27 +14,29 @@ local xdb = require("xdb_searcher")
---- ip checking testing
function test_parse_ip()
local ip_list = {
"1.2.3.4", "192.168.2.3", "120.24.78.129", "255.255.255.0",
"256.7.12.9", "12.56.78.320", "32.12.45.192", "222.221.220.219",
"192.168.1.101 ", "132.96.12.98a", "x23.12.2.12"
"1.2.3.4", "192.168.2.3", "120.24.78.129", "255.255.255.0", "invalid-ipv.4",
"::", "3000::", "240e:3b7:3276:33b0:4844:6f28:f69c:1eee", "2001:4:112::", "invalid-ipv::6"
}
local s_time = xdb.now()
for _, ip_src in ipairs(ip_list) do
ip, err = xdb.parse_ip(ip_src)
ip_bytes, err = xdb.parse_ip(ip_src)
if err ~= nil then
print(string.format("invalid ip address `%s`: %s", ip_src, err))
else
-- io.write(string.format("long(%-15s)=%10d, long2ip(%-10d)=%-15s", ip_src, ip, ip, ip_dst))
-- if ip_src ~= ip_dst then
-- print(" --[Failed]")
-- else
-- print(" --[Ok]")
-- end
print(string.format("parse_ip(%s): %s", ip_src, xdb.ip_to_string(ip_bytes)))
end
end
end
function test_print_const()
print("ipv4: ", xdb.IPv4);
print("ipv6: ", xdb.IPv6);
print("header_buffer: ", xdb.header_buffer);
print("v_index_buffer: ", xdb.v_index_buffer);
print("content_buffer: ", xdb.content_buffer);
end
---- buffer loading test
function test_load_header()
header, err = xdb.load_header("../../data/ip2region_v4.xdb")
@ -50,11 +52,14 @@ function test_load_header()
created_at: %d
start_index_ptr: %d
end_index_ptr: %d
ip_version: %d
runtime_ptr_bytes: %d
}]]
local t = header:to_table()
print(string.format(tpl,
t["version"], t["index_policy"], t["created_at"], t["start_index_ptr"], t["end_index_ptr"])
t["version"], t["index_policy"], t["created_at"],
t["start_index_ptr"], t["end_index_ptr"], t["ip_version"], t["runtime_ptr_bytes"])
)
end
end
@ -86,7 +91,7 @@ end
function test_search()
local ip_str = "1.2.3.4"
searcher, err = xdb.new_with_file_only(IPv4, "../../data/ip2region_v4.xdb")
searcher, err = xdb.new_with_file_only(xdb.IPv4, "../../data/ip2region_v4.xdb")
local t_start = xdb.now()
region, err = searcher:search(ip_str)
local c_time = xdb.now() - t_start
@ -98,7 +103,7 @@ end
local func_name = arg[1]
if func_name == nil then
print("please specified the function to test\n")
print("please specified the function to test")
return
end

View File

@ -18,6 +18,7 @@
#define xdb_header_buffer 1
#define xdb_vector_index_buffer 2
#define xdb_content_buffer 3
#define xdb_ip_buffer 4
// --- xdb buffer interface impl
@ -74,6 +75,12 @@ static int lua_xdb_buffer_to_table(lua_State *L) {
lua_pushinteger(L, header->end_index_ptr);
lua_setfield(L, -2, "end_index_ptr");
lua_pushinteger(L, header->ip_version);
lua_setfield(L, -2, "ip_version");
lua_pushinteger(L, header->runtime_ptr_bytes);
lua_setfield(L, -2, "runtime_ptr_bytes");
} else {
// do nothing for now
}
@ -134,7 +141,7 @@ static const struct luaL_Reg xdb_buffer_methods[] = {
{"close", lua_xdb_buffer_close},
{"__gc", lua_xdb_buffer_close},
{"__tostring", lua_xdb_buffer_tostring},
{NULL, NULL},
{NULL, NULL}
};
// --- End of xdb buffer
@ -142,23 +149,6 @@ static const struct luaL_Reg xdb_buffer_methods[] = {
// --- xdb util function
static int lua_xdb_parse_ip(lua_State *L) {
int err;
unsigned int ip;
const char *ip_str;
luaL_argcheck(L, lua_gettop(L) == 1, 1, "call via '.' and string ip expected, eg: 1.2.3.4");
ip_str = luaL_checkstring(L, 1);
lua_pushstring(L, ip_str);
lua_pushnil(L);
return 2;
}
static int lua_xdb_now(lua_State *L) {
lua_pushinteger(L, xdb_now());
return 1;
}
static int lua_xdb_load_header_from_file(lua_State *L) {
const char *db_path;
xdb_header_t *header;
@ -267,6 +257,67 @@ static int lua_xdb_load_content_from_file(lua_State *L) {
return 2;
}
static int lua_xdb_parse_ip(lua_State *L) {
int err;
const char *ip_str;
bytes_ip_t ip_bytes[18] = {'\0'};
xdb_version_t *version;
luaL_argcheck(L, lua_gettop(L) == 1, 1, "call via '.' and string ip expected, eg: 1.2.3.4 / 3000::");
ip_str = luaL_checkstring(L, 1);
version = xdb_parse_ip(ip_str, ip_bytes, sizeof(ip_bytes));
if (version == NULL) {
lua_pushnil(L);
lua_pushfstring(L, "failed to parse the `%s`", ip_str);
return 2;
}
// append the magic char for later analysis
// printf("ip:%s, version->id: %d\n", ip_str, version->id);
ip_bytes[version->bytes] = '&';
ip_bytes[version->bytes+1] = '\0';
lua_pushstring(L, ip_bytes);
lua_pushnil(L);
return 2;
}
static int lua_xdb_ip_to_string(lua_State *L) {
int err, len;
const bytes_ip_t *ip_bytes;
char ip_string[INET6_ADDRSTRLEN] = {'\0'};
luaL_argcheck(L, lua_gettop(L) == 1, 1, "call via '.' and bytes ip expected");
ip_bytes = luaL_checkstring(L, 1);
len = strlen(ip_bytes);
if (len == 5 && ip_bytes[4] == '&') {
// binary IPv4 bytes
} else if (len == 17 || ip_bytes[16] == '&') { // IPv6
// binary IPv6 bytes
} else {
lua_pushnil(L);
lua_pushstring(L, "invalid binary ip bytes specified");
return 2;
}
err = xdb_ip_to_string(ip_bytes, len-1, ip_string, sizeof(ip_string));
if (err != 0) {
lua_pushnil(L);
lua_pushstring(L, "failed to conver the ip bytes to string");
return 2;
}
lua_pushstring(L, ip_string);
lua_pushnil(L);
return 2;
}
static int lua_xdb_now(lua_State *L) {
lua_pushinteger(L, xdb_now());
return 1;
}
// --- End of xdb util api
@ -428,9 +479,11 @@ static int lua_xdb_close(lua_State *L) {
}
static int lua_xdb_search(lua_State *L) {
int err;
const char *ip_str;
bytes_ip_t ip_bytes[INET6_ADDRSTRLEN] = {'\0'};
int err, len, ip_len;
const char *ip_string;
bytes_ip_t ip_buffer[INET6_ADDRSTRLEN] = {'\0'};
const bytes_ip_t *ip_bytes;
xdb_version_t *version;
xdb_region_buffer_t region;
xdb_searcher_t *searcher;
@ -438,19 +491,30 @@ static int lua_xdb_search(lua_State *L) {
luaL_argcheck(L, lua_gettop(L) == 2, 2, "call via ':' and string ip address expected");
// get the searcher
searcher = (xdb_searcher_t *) luaL_checkudata(L, 1, XDB_METATABLE_NAME);
searcher = (xdb_searcher_t *) luaL_checkudata(L, 1, XDB_METATABLE_NAME);
ip_string = luaL_checkstring(L, 2);
// input ip type checking
if (lua_isstring(L, 2)) {
ip_str = lua_tostring(L, 2);
version = xdb_parse_ip(ip_str, ip_bytes, sizeof(ip_bytes));
// ip string type checking
len = strlen(ip_string);
if (len == 5 && ip_string[4] == '&') {
// binary IPv4
ip_len = 4;
ip_bytes = ip_string;
} else if (len == 17 && ip_string[16] == '&') {
// binary IPv6
ip_len = 16;
ip_bytes = ip_string;
printf("ipv6 binary string\n");
} else {
version = xdb_parse_ip(ip_string, ip_buffer, sizeof(ip_buffer));
if (version == NULL) {
lua_pushnil(L);
lua_pushfstring(L, "failed to parse string ip `%s`", ip_str);
lua_pushfstring(L, "failed to parse string ip `%s`", ip_string);
return 2;
}
} else {
return luaL_error(L, "please specified a string ip address");
ip_len = version->bytes;
ip_bytes = ip_buffer;
}
// init the region buffer
@ -460,7 +524,7 @@ static int lua_xdb_search(lua_State *L) {
}
// do the search
err = xdb_search(searcher, ip_bytes, version->bytes, &region);
err = xdb_search(searcher, ip_bytes, ip_len, &region);
if (err != 0) {
lua_pushinteger(L, err);
lua_pushfstring(L, "err=%d", err);
@ -471,7 +535,6 @@ static int lua_xdb_search(lua_State *L) {
// clean up the region buffer
xdb_region_buffer_free(&region);
return 2;
}
@ -508,6 +571,7 @@ static const struct luaL_Reg xdb_searcher_functions[] = {
{"load_vector_index", lua_xdb_load_vector_index_from_file},
{"load_content", lua_xdb_load_content_from_file},
{"parse_ip", lua_xdb_parse_ip},
{"ip_to_string", lua_xdb_ip_to_string},
{"now", lua_xdb_now},
{NULL, NULL}
};
@ -515,18 +579,6 @@ static const struct luaL_Reg xdb_searcher_functions[] = {
// module register function
int luaopen_xdb_searcher(lua_State *L)
{
// register the constants
lua_pushinteger(L, xdb_ipv4_id);
lua_setglobal(L, "IPv4");
lua_pushinteger(L, xdb_ipv6_id);
lua_setglobal(L, "IPv6");
lua_pushinteger(L, xdb_header_buffer);
lua_setglobal(L, "header_buffer");
lua_pushinteger(L, xdb_vector_index_buffer);
lua_setglobal(L, "v_index_buffer");
lua_pushinteger(L, xdb_content_buffer);
lua_setglobal(L, "content_buffer");
// create a metatable for xdb buffer object
luaL_newmetatable(L, XDB_BUFFER_METATABLE_NAME);
lua_pushvalue(L, -1);
@ -540,5 +592,17 @@ int luaopen_xdb_searcher(lua_State *L)
luaL_setfuncs(L, xdb_searcher_methods, 0);
luaL_setfuncs(L, xdb_searcher_functions, 0);
// register the constants attributes
lua_pushinteger(L, xdb_ipv4_id);
lua_setfield(L, -2, "IPv4");
lua_pushinteger(L, xdb_ipv6_id);
lua_setfield(L, -2, "IPv6");
lua_pushinteger(L, xdb_header_buffer);
lua_setfield(L, -2, "header_buffer");
lua_pushinteger(L, xdb_vector_index_buffer);
lua_setfield(L, -2, "v_index_buffer");
lua_pushinteger(L, xdb_content_buffer);
lua_setfield(L, -2, "content_buffer");
return 1;
}