1
0
mirror of https://github.com/v2fly/v2ray-core.git synced 2024-09-26 13:56:12 -04:00
This commit is contained in:
Darien Raymond 2015-12-08 16:31:31 +00:00
parent 0ccce0ff7e
commit c19341ffab
9 changed files with 12894 additions and 6343 deletions

File diff suppressed because it is too large Load Diff

View File

@ -28,6 +28,14 @@ func parseRule(msg json.RawMessage) rules.Rule {
}
return fieldrule
}
if rule.Type == "chinaip" {
chinaiprule := new(ChinaIPRule)
if err := json.Unmarshal(msg, chinaiprule); err != nil {
log.Error("Invalid chinaip rule: %v", err)
return nil
}
return chinaiprule
}
log.Error("Unknown router rule type: %s", rule.Type)
return nil
}

97
common/net/ipnet.go Normal file
View File

@ -0,0 +1,97 @@
package net
import (
"net"
)
var (
onesCount = make(map[byte]byte)
)
type IPNet struct {
cache map[uint32]byte
}
func NewIPNet() *IPNet {
return NewIPNetInitialValue(make(map[uint32]byte, 1024))
}
func NewIPNetInitialValue(data map[uint32]byte) *IPNet {
return &IPNet{
cache: data,
}
}
func ipToUint32(ip net.IP) uint32 {
value := uint32(0)
for _, b := range []byte(ip) {
value <<= 8
value += uint32(b)
}
return value
}
func ipMaskToByte(mask net.IPMask) byte {
value := byte(0)
for _, b := range []byte(mask) {
value += onesCount[b]
}
return value
}
func (this *IPNet) Add(ipNet *net.IPNet) {
ipv4 := ipNet.IP.To4()
if ipv4 == nil {
// For now, we don't support IPv6
return
}
value := ipToUint32(ipv4)
mask := ipMaskToByte(ipNet.Mask)
existing, found := this.cache[value]
if !found || existing > mask {
this.cache[value] = mask
}
}
func (this *IPNet) Contains(ip net.IP) bool {
ipv4 := ip.To4()
if ipv4 == nil {
return false
}
originalValue := ipToUint32(ipv4)
if entry, found := this.cache[originalValue]; found {
if entry == 0 {
return true
}
}
mask := uint32(0)
for maskbit := byte(1); maskbit <= 32; maskbit++ {
mask += 1 << uint32(32-maskbit)
maskedValue := originalValue & mask
if entry, found := this.cache[maskedValue]; found {
if entry == maskbit {
return true
}
}
}
return false
}
func (this *IPNet) Serialize() []uint32 {
content := make([]uint32, 0, 2*len(this.cache))
for key, value := range this.cache {
content = append(content, uint32(key), uint32(value))
}
return content
}
func init() {
value := byte(0)
for mask := byte(1); mask <= 8; mask++ {
value += 1 << byte(8-mask)
onesCount[value] = mask
}
}

42
common/net/ipnet_test.go Normal file
View File

@ -0,0 +1,42 @@
package net_test
import (
"net"
"testing"
. "github.com/v2ray/v2ray-core/common/net"
v2testing "github.com/v2ray/v2ray-core/testing"
"github.com/v2ray/v2ray-core/testing/assert"
)
func parseCIDR(str string) *net.IPNet {
_, ipNet, err := net.ParseCIDR(str)
assert.Error(err).IsNil()
return ipNet
}
func TestIPNet(t *testing.T) {
v2testing.Current(t)
ipNet := NewIPNet()
ipNet.Add(parseCIDR(("0.0.0.0/8")))
ipNet.Add(parseCIDR(("10.0.0.0/8")))
ipNet.Add(parseCIDR(("100.64.0.0/10")))
ipNet.Add(parseCIDR(("127.0.0.0/8")))
ipNet.Add(parseCIDR(("169.254.0.0/16")))
ipNet.Add(parseCIDR(("172.16.0.0/12")))
ipNet.Add(parseCIDR(("192.0.0.0/24")))
ipNet.Add(parseCIDR(("192.0.2.0/24")))
ipNet.Add(parseCIDR(("192.168.0.0/16")))
ipNet.Add(parseCIDR(("198.18.0.0/15")))
ipNet.Add(parseCIDR(("198.51.100.0/24")))
ipNet.Add(parseCIDR(("203.0.113.0/24")))
ipNet.Add(parseCIDR(("8.8.8.8/32")))
assert.Bool(ipNet.Contains(net.ParseIP("192.168.1.1"))).IsTrue()
assert.Bool(ipNet.Contains(net.ParseIP("192.0.0.0"))).IsTrue()
assert.Bool(ipNet.Contains(net.ParseIP("192.0.1.0"))).IsFalse()
assert.Bool(ipNet.Contains(net.ParseIP("0.1.0.0"))).IsTrue()
assert.Bool(ipNet.Contains(net.ParseIP("1.0.0.1"))).IsFalse()
assert.Bool(ipNet.Contains(net.ParseIP("8.8.8.7"))).IsFalse()
assert.Bool(ipNet.Contains(net.ParseIP("8.8.8.8"))).IsTrue()
}

File diff suppressed because it is too large Load Diff

4
tools/chinaip/ip_gen.sh Executable file
View File

@ -0,0 +1,4 @@
#!/bin/bash
APNIC_FILE="http://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest"
curl "${APNIC_FILE}" | grep ipv4 | grep CN | awk -F\| '{ printf("%s/%d\n", $4, 32-log($5)/log(2)) }' > ipv4.txt

6324
tools/chinaip/ipv4.txt Normal file

File diff suppressed because it is too large Load Diff

42
tools/chinaip/main.go Normal file
View File

@ -0,0 +1,42 @@
package main
import (
"bufio"
"fmt"
"net"
"os"
"path/filepath"
"strings"
v2net "github.com/v2ray/v2ray-core/common/net"
)
func main() {
GOPATH := os.Getenv("GOPATH")
src := filepath.Join(GOPATH, "src", "github.com", "v2ray", "v2ray-core", "tools", "chinaip", "ipv4.txt")
reader, err := os.Open(src)
if err != nil {
panic(err)
}
ipNet := v2net.NewIPNet()
scanner := bufio.NewScanner(reader)
for scanner.Scan() {
line := scanner.Text()
line = strings.TrimSpace(line)
if len(line) == 0 {
break
}
_, t, err := net.ParseCIDR(line)
if err != nil {
panic(err)
}
ipNet.Add(t)
}
dump := ipNet.Serialize()
fmt.Println("map[uint32]byte {")
for i := 0; i < len(dump); i += 2 {
fmt.Println(dump[i], ": ", dump[i+1], ",")
}
fmt.Println("}")
}