From b01253e6b347cc7ab45eae025ca36227df0e3cf8 Mon Sep 17 00:00:00 2001 From: lion Date: Sat, 20 Sep 2025 17:29:11 +0800 Subject: [PATCH] ip parse and binary ip bytes use --- binding/lua_c/search_test.lua | 7 +- binding/lua_c/util_test.lua | 31 ++++--- binding/lua_c/xdb_searcher.c | 150 ++++++++++++++++++++++++---------- 3 files changed, 129 insertions(+), 59 deletions(-) diff --git a/binding/lua_c/search_test.lua b/binding/lua_c/search_test.lua index 5afa0f5..6f48f1a 100644 --- a/binding/lua_c/search_test.lua +++ b/binding/lua_c/search_test.lua @@ -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())) diff --git a/binding/lua_c/util_test.lua b/binding/lua_c/util_test.lua index d22faa3..20fe708 100644 --- a/binding/lua_c/util_test.lua +++ b/binding/lua_c/util_test.lua @@ -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 diff --git a/binding/lua_c/xdb_searcher.c b/binding/lua_c/xdb_searcher.c index d84b67a..217ddbe 100644 --- a/binding/lua_c/xdb_searcher.c +++ b/binding/lua_c/xdb_searcher.c @@ -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, ®ion); + err = xdb_search(searcher, ip_bytes, ip_len, ®ion); 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(®ion); - 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; } \ No newline at end of file