Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace net.IPNet to netip.Prefix for performances purposes #76

Merged
merged 5 commits into from
Oct 3, 2023

Conversation

tomMoulard
Copy link
Owner

@tomMoulard tomMoulard commented Oct 2, 2023

This PR replaces the usage of net.IPNet to netip.Prefix for performances purposes.

Following the netip doc:

Compared to the net.IP type, Addr type takes less memory, is immutable, and is comparable (supports == and being a map key).

here are a few benchmarks (results may vary)
> go test -bench=. github.com/tomMoulard/fail2ban/ipchecking -test.run=Benchmark
goos: linux
goarch: amd64
pkg: github.com/tomMoulard/fail2ban/ipchecking
cpu: Intel(R) Core(TM) i7-10750H CPU @ 2.60GHz
BenchmarkIPChecking_new-12    	 1000000	      1042 ns/op
BenchmarkIPChecking_old-12    	  512394	      2307 ns/op
PASS
ok  	github.com/tomMoulard/fail2ban/ipchecking	2.618s

func BenchmarkIPChecking_new(b *testing.B) {
	tests := []struct {
		ip1    string
		ip2    string
		expect bool
	}{
		{ip1: "127.0.0.1", ip2: "127.0.0.1", expect: true},
		{ip1: "127.0.0.1", ip2: "127.0.0.2", expect: false},
		{ip1: "127.0.0.1/24", ip2: "127.0.0.2", expect: true},
		{ip1: "127.0.0.1/32", ip2: "127.0.0.2", expect: false},
		{ip1: "10.0.0.1/32", ip2: "127.0.0.2", expect: false},
		{ip1: "10.0.0.1/0", ip2: "127.0.0.2", expect: true},
		{ip1: "0.0.0.0", ip2: "127.0.0.2", expect: false},
	}

	for n := 0; n < b.N; n++ {
		for _, tt := range tests {
			ipv4, _ := ipchecking.ParseNetIP(tt.ip1)
			if ipv4.Contains(tt.ip2) != tt.expect {
				b.Logf("ip1: %s, ip2: %s", tt.ip1, tt.ip2)
				b.Errorf("wanted '%v' got '%v'", tt.expect, ipv4.Contains(tt.ip2))
			}
		}
	}
}

func BenchmarkIPChecking_old(b *testing.B) {
	tests := []struct {
		ip1    string
		ip2    string
		expect bool
	}{
		{ip1: "127.0.0.1", ip2: "127.0.0.1", expect: true},
		{ip1: "127.0.0.1", ip2: "127.0.0.2", expect: false},
		{ip1: "127.0.0.1/24", ip2: "127.0.0.2", expect: true},
		{ip1: "127.0.0.1/32", ip2: "127.0.0.2", expect: false},
		{ip1: "10.0.0.1/32", ip2: "127.0.0.2", expect: false},
		{ip1: "10.0.0.1/0", ip2: "127.0.0.2", expect: true},
		{ip1: "0.0.0.0", ip2: "127.0.0.2", expect: false},
	}

	for n := 0; n < b.N; n++ {
		for _, tt := range tests {
			ipv4, _ := ipchecking.BuildIP(tt.ip1)
			if ipv4.CheckIPInSubnet(tt.ip2) != tt.expect {
				b.Logf("ip1: %s, ip2: %s", tt.ip1, tt.ip2)
				b.Errorf("wanted '%v' got '%v'", tt.expect, ipv4.CheckIPInSubnet(tt.ip2))
			}
		}
	}
}

There is one breaking change in the ipchecking API (except for the functions renaming to be closer to netip function calls) that is StrToIP now breaks when some IPs are faulty instead of ignoring them.

@tomMoulard tomMoulard added the kind/enhancement New feature or request label Oct 2, 2023
@tomMoulard tomMoulard changed the title feat: replace net.IPNet to netip.Prefix for performances purposes Replace net.IPNet to netip.Prefix for performances purposes Oct 2, 2023
@tomMoulard tomMoulard merged commit 68b4f2e into main Oct 3, 2023
6 checks passed
@tomMoulard tomMoulard deleted the feat/netip branch October 3, 2023 10:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

1 participant