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

加快内网地址检查,172.16~31.0.0/12 其掩码地址均为 172.16.0.0/12 存在重复 #2

Closed
thinkeridea opened this issue Oct 14, 2019 · 1 comment · Fixed by #3
Labels
optimize Promote or improve code functionality and performance

Comments

@thinkeridea
Copy link
Owner

"10.0.0.0/8",
"169.254.0.0/16",
"172.16.0.0/12",
"172.17.0.0/12",
"172.18.0.0/12",
"172.19.0.0/12",
"172.20.0.0/12",
"172.21.0.0/12",
"172.22.0.0/12",
"172.23.0.0/12",
"172.24.0.0/12",
"172.25.0.0/12",
"172.26.0.0/12",
"172.27.0.0/12",
"172.28.0.0/12",
"172.29.0.0/12",
"172.30.0.0/12",
"172.31.0.0/12",
"192.168.0.0/16",	

172.16~31.0.0/12 其掩码地址均为 172.16.0.0/12 存在重复。

使用直接对比ip段前两段数据检查,不使用 network.Contains 判断,在暂时不支持IPV6 的前提下,这种方法更加高效。

@thinkeridea thinkeridea changed the title 加快内网地址检查,172.16~31.0.0/12 其掩码地址均为 172.16.0.0/12 存在重复 加快内网地址检查,172.16~31.0.0/12 其掩码地址均为 172.16.0.0/12 存在重复 Oct 14, 2019
@thinkeridea
Copy link
Owner Author

package exnet

import (
	"net"
	"testing"
)

// HasLocalIPddr 检测 IP 地址字符串是否是内网地址
func HasLocalIPddr(ip string) bool {
	return HasLocalIP(net.ParseIP(ip))
}

// HasLocalIP 检测 IP 地址是否是内网地址
// 通过直接对比ip段范围效率更高,详见:https://github.com/thinkeridea/go-extend/issues/2
func HasLocalIP(ip net.IP) bool {
	if ip.IsLoopback() {
		return true
	}

	ip4 := ip.To4()
	if ip4 == nil {
		return false
	}

	return ip4[0] == 10 || // 10.0.0.0/8
		(ip4[0] == 172 && ip4[1] >= 16 && ip4[1] <= 31) || // 172.16.0.0/12
		(ip4[0] == 169 && ip4[1] == 254) || // 169.254.0.0/16
		(ip4[0] == 192 && ip4[1] == 168) // 192.168.0.0/16
}

// 收集的内网网络地址 IP 段
var localNetworks []*net.IPNet

func init() {
	localNetworks = make([]*net.IPNet, 4)
	for i, sNetwork := range []string{
		"10.0.0.0/8",
		"169.254.0.0/16",
		"172.16.0.0/12",
		"192.168.0.0/16",
	} {
		_, network, _ := net.ParseCIDR(sNetwork)
		localNetworks[i] = network
	}
}

// HasLocalIPddr 检测 IP 地址字符串是否是内网地址
func HasLocalIPddr_test(ip string) bool {
	return HasLocalIP_test(net.ParseIP(ip))
}

// HasLocalIP 检测 IP 地址是否是内网地址
func HasLocalIP_test(ip net.IP) bool {
	for _, network := range localNetworks {
		if network.Contains(ip) {
			return true
		}
	}

	return ip.IsLoopback()
}

func BenchmarkHasLocalIP(b *testing.B) {
	for i := 0; i < b.N; i++ {
		for _, ip := range []string{
			"192.168.9.18",
			"10.168.9.18",
			"172.16.9.18",
			"172.17.9.18",
			"172.18.9.18",
			"172.19.9.18",
			"172.20.9.18",
			"172.21.9.18",
			"172.22.9.18",
			"172.23.9.18",
			"172.24.9.18",
			"172.25.9.18",
			"172.26.9.18",
			"172.27.9.18",
			"172.28.9.18",
			"172.29.9.18",
			"172.30.9.18",
			"172.31.9.18",
		} {
			if !HasLocalIPddr_test(ip) {
				b.Fatal(ip)
			}
		}
	}
}

func BenchmarkHasLocalIP2(b *testing.B) {
	for i := 0; i < b.N; i++ {
		for _, ip := range []string{
			"192.168.9.18",
			"10.168.9.18",
			"172.16.9.18",
			"172.17.9.18",
			"172.18.9.18",
			"172.19.9.18",
			"172.20.9.18",
			"172.21.9.18",
			"172.22.9.18",
			"172.23.9.18",
			"172.24.9.18",
			"172.25.9.18",
			"172.26.9.18",
			"172.27.9.18",
			"172.28.9.18",
			"172.29.9.18",
			"172.30.9.18",
			"172.31.9.18",
		} {
			if !HasLocalIPddr(ip) {
				b.Fatal(ip)
			}
		}
	}
}

测试结果:

$ go test -benchmem -bench="." ip*.go
goos: darwin
goarch: amd64
BenchmarkHasLocalIP-8             441862              2273 ns/op             288 B/op         18 allocs/op
BenchmarkHasLocalIP2-8            801446              1502 ns/op             288 B/op         18 allocs/op
PASS
ok      command-line-arguments  2.268s

@thinkeridea thinkeridea added enhancement New feature or request optimize Promote or improve code functionality and performance and removed enhancement New feature or request labels Oct 14, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
optimize Promote or improve code functionality and performance
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant