From 4e0184294362b477e52c996d304e6fe0d6824964 Mon Sep 17 00:00:00 2001 From: Uzlopak Date: Wed, 13 Sep 2023 22:01:36 +0200 Subject: [PATCH] net: improve performance of isIPv4 and isIPv6 PR-URL: https://github.com/nodejs/node/pull/49568 Reviewed-By: Matteo Collina Reviewed-By: Yagiz Nizipli Reviewed-By: Paolo Insogna Reviewed-By: Luigi Pinca --- benchmark/net/net-is-ip-v4.js | 25 +++++++++++++++++++++++++ benchmark/net/net-is-ip-v6.js | 23 +++++++++++++++++++++++ lib/internal/net.js | 20 ++++++++++---------- 3 files changed, 58 insertions(+), 10 deletions(-) create mode 100644 benchmark/net/net-is-ip-v4.js create mode 100644 benchmark/net/net-is-ip-v6.js diff --git a/benchmark/net/net-is-ip-v4.js b/benchmark/net/net-is-ip-v4.js new file mode 100644 index 00000000000000..76fcdfe09a9920 --- /dev/null +++ b/benchmark/net/net-is-ip-v4.js @@ -0,0 +1,25 @@ +'use strict'; + +const common = require('../common.js'); +const { isIPv4 } = require('net'); + +const ips = [ + '0.0.0.0', + '255.255.255.255', + '0.0.0.0.0', + '192.168.0.1', + '10.168.209.250', +]; + +const bench = common.createBenchmark(main, { + n: [1e7], +}); + +function main({ n }) { + bench.start(); + for (let i = 0; i < n; ++i) { + for (let j = 0; j < ips.length; ++j) + isIPv4(ips[j]); + } + bench.end(n); +} diff --git a/benchmark/net/net-is-ip-v6.js b/benchmark/net/net-is-ip-v6.js new file mode 100644 index 00000000000000..dc12e215e42901 --- /dev/null +++ b/benchmark/net/net-is-ip-v6.js @@ -0,0 +1,23 @@ +'use strict'; + +const common = require('../common.js'); +const { isIPv6 } = require('net'); + +const ips = [ + '::1', + 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff', + '0.0.0.0', +]; + +const bench = common.createBenchmark(main, { + n: [1e7], +}); + +function main({ n }) { + bench.start(); + for (let i = 0; i < n; ++i) { + for (let j = 0; j < ips.length; ++j) + isIPv6(ips[j]); + } + bench.end(n); +} diff --git a/lib/internal/net.js b/lib/internal/net.js index bcbaaa94989e28..8b04d5f226eb17 100644 --- a/lib/internal/net.js +++ b/lib/internal/net.js @@ -11,22 +11,22 @@ const { writeBuffer } = internalBinding('fs'); const errors = require('internal/errors'); // IPv4 Segment -const v4Seg = '(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])'; -const v4Str = `(${v4Seg}[.]){3}${v4Seg}`; +const v4Seg = '(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])'; +const v4Str = `(?:${v4Seg}\\.){3}${v4Seg}`; const IPv4Reg = new RegExp(`^${v4Str}$`); // IPv6 Segment const v6Seg = '(?:[0-9a-fA-F]{1,4})'; -const IPv6Reg = new RegExp('^(' + +const IPv6Reg = new RegExp('^(?:' + `(?:${v6Seg}:){7}(?:${v6Seg}|:)|` + `(?:${v6Seg}:){6}(?:${v4Str}|:${v6Seg}|:)|` + - `(?:${v6Seg}:){5}(?::${v4Str}|(:${v6Seg}){1,2}|:)|` + - `(?:${v6Seg}:){4}(?:(:${v6Seg}){0,1}:${v4Str}|(:${v6Seg}){1,3}|:)|` + - `(?:${v6Seg}:){3}(?:(:${v6Seg}){0,2}:${v4Str}|(:${v6Seg}){1,4}|:)|` + - `(?:${v6Seg}:){2}(?:(:${v6Seg}){0,3}:${v4Str}|(:${v6Seg}){1,5}|:)|` + - `(?:${v6Seg}:){1}(?:(:${v6Seg}){0,4}:${v4Str}|(:${v6Seg}){1,6}|:)|` + - `(?::((?::${v6Seg}){0,5}:${v4Str}|(?::${v6Seg}){1,7}|:))` + -')(%[0-9a-zA-Z-.:]{1,})?$'); + `(?:${v6Seg}:){5}(?::${v4Str}|(?::${v6Seg}){1,2}|:)|` + + `(?:${v6Seg}:){4}(?:(?::${v6Seg}){0,1}:${v4Str}|(?::${v6Seg}){1,3}|:)|` + + `(?:${v6Seg}:){3}(?:(?::${v6Seg}){0,2}:${v4Str}|(?::${v6Seg}){1,4}|:)|` + + `(?:${v6Seg}:){2}(?:(?::${v6Seg}){0,3}:${v4Str}|(?::${v6Seg}){1,5}|:)|` + + `(?:${v6Seg}:){1}(?:(?::${v6Seg}){0,4}:${v4Str}|(?::${v6Seg}){1,6}|:)|` + + `(?::(?:(?::${v6Seg}){0,5}:${v4Str}|(?::${v6Seg}){1,7}|:))` + +')(?:%[0-9a-zA-Z-.:]{1,})?$'); function isIPv4(s) { // TODO(aduh95): Replace RegExpPrototypeTest with RegExpPrototypeExec when it