Subnets
¶ ↑
Subnets
is a C-extension for Ruby with IPv4 and IPv6 address and network classes. The motivating goal is to provide a fast test whether a given set of subnets includes a given IP.
Subnets.include?(subnets, '192.168.1.1')
Rack::Request#ip and ActionDispatch::Request#remote_ip perform such a test. ActionDispatch
, which uses ipaddr
by default, explicitly calls out that the technique is too slow to run on every request. Rack uses a regular expression of IPv4 and IPv6 private address spaces which, while comparably fast, is not easily extended to support arbitrary subnets.
(See also this answer explaining request.ip vs. request.remote_ip)
A benchmark tests if a random IP (75% private IPs) is within any of the private IPv4 ranges. Lower is better. Plotted on logscale. (Ruby 2.5.0p0, 2.5 GHz Intel Core i7).
$ bundle exec rake benchmark TEST=test/private_networks_benchmark ipaddr : 46.25μs/ip ██████████████████████████████████▋ ipaddress : 63.88μs/ip ██████████████████████████████████████▏ netaddr : 31.03μs/ip ██████████████████████████████▎ *subnets : 4.19μs/ip ████████▏ rack (regexp) : 5.25μs/ip ██████████▋ ' ' ' ' ' 2 5 10 20 50
Usage¶ ↑
require 'subnets' subnets = %w(127.0.0.1/32 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16 ::1/128 fc00::/7).map(&Subnets.method(:parse)) Subnets.include?(subnets, '192.168.1.1') #=> true Subnets.include?(subnets, '203.0.113.12') #=> false
Similar Gems¶ ↑
There are several IP gems, all of which are implemented in pure-Ruby and not performance oriented.
-
ipaddr: (Ruby stdlib) A set of methods to manipulate an IP address. Both IPv4 and IPv6 are supported.
-
ipaddress: A Ruby library designed to make the use of IPv4 and IPv6 addresses simple, powerful and enjoyable. It provides a complete set of methods to handle IP addresses for any need, from simple scripting to full network design.
-
netaddr: A Ruby library for performing calculations on IPv4 and IPv6 subnets. There is also limited support for EUI addresses.
Production Ready?¶ ↑
This has not been used in production.
Safe?¶ ↑
The IPv4 and IPv6 parsers are written in C. In addition to the unit test suite, the parsers have had minimal (16+ hours) of fuzzing with American fuzzy lop. There is medium confidence that the parsers will not read out-of-bounds.
Correct?¶ ↑
The unit test suite tests parsing of a variety of valid and invalid IPv4 and IPv6 networks.
Fast?¶ ↑
Yes, for checking if an array of subnets includes a given IP at least.