aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Wild <mwild1@gmail.com>2024-02-23 12:14:51 +0000
committerMatthew Wild <mwild1@gmail.com>2024-02-23 12:14:51 +0000
commitf4d2d7a3a3e563dbd67201cc0cff9caca3a942c3 (patch)
treee4c294ae9427f43a291d0b7008ff4e510412c1bf
parent965d69763c0cc180ad97d403378a9db4626570e0 (diff)
downloadprosody-f4d2d7a3a3e563dbd67201cc0cff9caca3a942c3.tar.gz
prosody-f4d2d7a3a3e563dbd67201cc0cff9caca3a942c3.zip
util.ip: Remove ip.bits and related code, switch to more efficient strbitop
100,000 iterations of match() on my laptop from 3.5s -> 0.5s.
-rw-r--r--util/ip.lua28
1 files changed, 6 insertions, 22 deletions
diff --git a/util/ip.lua b/util/ip.lua
index 268b7d10..d820e72d 100644
--- a/util/ip.lua
+++ b/util/ip.lua
@@ -6,7 +6,7 @@
--
local net = require "prosody.util.net";
-local hex = require "prosody.util.hex";
+local strbit = require "prosody.util.strbitop";
local ip_methods = {};
@@ -28,13 +28,6 @@ ip_mt.__eq = function (ipA, ipB)
return ipA.packed == ipB.packed;
end
-local hex2bits = {
- ["0"] = "0000", ["1"] = "0001", ["2"] = "0010", ["3"] = "0011",
- ["4"] = "0100", ["5"] = "0101", ["6"] = "0110", ["7"] = "0111",
- ["8"] = "1000", ["9"] = "1001", ["A"] = "1010", ["B"] = "1011",
- ["C"] = "1100", ["D"] = "1101", ["E"] = "1110", ["F"] = "1111",
-};
-
local function new_ip(ipStr, proto)
local zone;
if (not proto or proto == "IPv6") and ipStr:find('%', 1, true) then
@@ -66,27 +59,18 @@ function ip_methods:normal()
return net.ntop(self.packed);
end
-function ip_methods.bits(ip)
- return hex.encode(ip.packed):upper():gsub(".", hex2bits);
-end
-
-function ip_methods.bits_full(ip)
+-- Returns the longest packed representation, i.e. IPv4 will be mapped
+function ip_methods.packed_full(ip)
if ip.proto == "IPv4" then
ip = ip.toV4mapped;
end
- return ip.bits;
+ return ip.packed;
end
local match;
local function commonPrefixLength(ipA, ipB)
- ipA, ipB = ipA.bits_full, ipB.bits_full;
- for i = 1, 128 do
- if ipA:sub(i,i) ~= ipB:sub(i,i) then
- return i-1;
- end
- end
- return 128;
+ return strbit.common_prefix_bits(ipA.packed_full, ipB.packed_full);
end
-- Instantiate once
@@ -238,7 +222,7 @@ function match(ipA, ipB, bits)
bits = bits + (128 - 32);
end
end
- return ipA.bits:sub(1, bits) == ipB.bits:sub(1, bits);
+ return strbit.common_prefix_bits(ipA.packed, ipB.packed) >= bits;
end
local function is_ip(obj)