Ejemplo n.º 1
0
func TestDomainRule(t *testing.T) {
	assert := assert.On(t)

	rule := ParseRule([]byte(`{
    "type": "field",
    "domain": [
      "ooxx.com",
      "oxox.com",
      "regexp:\\.cn$"
    ],
    "network": "tcp",
    "outboundTag": "direct"
  }`))
	assert.Pointer(rule).IsNotNil()
	cond, err := rule.BuildCondition()
	assert.Error(err).IsNil()
	assert.Bool(cond.Apply(&proxy.SessionInfo{
		Destination: v2net.TCPDestination(v2net.ParseAddress("www.ooxx.com"), 80),
	})).IsTrue()
	assert.Bool(cond.Apply(&proxy.SessionInfo{
		Destination: v2net.TCPDestination(v2net.ParseAddress("www.aabb.com"), 80),
	})).IsFalse()
	assert.Bool(cond.Apply(&proxy.SessionInfo{
		Destination: v2net.TCPDestination(v2net.IPAddress([]byte{127, 0, 0, 1}), 80),
	})).IsFalse()
	assert.Bool(cond.Apply(&proxy.SessionInfo{
		Destination: v2net.TCPDestination(v2net.ParseAddress("www.12306.cn"), 80),
	})).IsTrue()
	assert.Bool(cond.Apply(&proxy.SessionInfo{
		Destination: v2net.TCPDestination(v2net.ParseAddress("www.acn.com"), 80),
	})).IsFalse()
}
Ejemplo n.º 2
0
func TestChinaSitesJson(t *testing.T) {
	assert := assert.On(t)

	rule := ParseRule([]byte(`{
    "type": "chinasites",
    "outboundTag": "y"
  }`))
	assert.String(rule.Tag).Equals("y")
	cond, err := rule.BuildCondition()
	assert.Error(err).IsNil()
	assert.Bool(cond.Apply(&proxy.SessionInfo{
		Destination: v2net.TCPDestination(v2net.ParseAddress("v.qq.com"), 80),
	})).IsTrue()
	assert.Bool(cond.Apply(&proxy.SessionInfo{
		Destination: v2net.TCPDestination(v2net.ParseAddress("www.163.com"), 80),
	})).IsTrue()
	assert.Bool(cond.Apply(&proxy.SessionInfo{
		Destination: v2net.TCPDestination(v2net.ParseAddress("ngacn.cc"), 80),
	})).IsTrue()
	assert.Bool(cond.Apply(&proxy.SessionInfo{
		Destination: v2net.TCPDestination(v2net.ParseAddress("12306.cn"), 80),
	})).IsTrue()

	assert.Bool(cond.Apply(&proxy.SessionInfo{
		Destination: v2net.TCPDestination(v2net.ParseAddress("v2ray.com"), 80),
	})).IsFalse()
}
Ejemplo n.º 3
0
func TestChinaIPJson(t *testing.T) {
	assert := assert.On(t)

	rule := ParseRule([]byte(`{
    "type": "chinaip",
    "outboundTag": "x"
  }`))
	assert.String(rule.Tag).Equals("x")
	cond, err := rule.BuildCondition()
	assert.Error(err).IsNil()
	assert.Bool(cond.Apply(&proxy.SessionInfo{
		Destination: v2net.TCPDestination(v2net.ParseAddress("121.14.1.189"), 80),
	})).IsTrue() // sina.com.cn
	assert.Bool(cond.Apply(&proxy.SessionInfo{
		Destination: v2net.TCPDestination(v2net.ParseAddress("101.226.103.106"), 80),
	})).IsTrue() // qq.com
	assert.Bool(cond.Apply(&proxy.SessionInfo{
		Destination: v2net.TCPDestination(v2net.ParseAddress("115.239.210.36"), 80),
	})).IsTrue() // image.baidu.com
	assert.Bool(cond.Apply(&proxy.SessionInfo{
		Destination: v2net.TCPDestination(v2net.ParseAddress("120.135.126.1"), 80),
	})).IsTrue()

	assert.Bool(cond.Apply(&proxy.SessionInfo{
		Destination: v2net.TCPDestination(v2net.ParseAddress("8.8.8.8"), 80),
	})).IsFalse()
}
Ejemplo n.º 4
0
func (v *FreedomConfig) Build() (*serial.TypedMessage, error) {
	config := new(freedom.Config)
	config.DomainStrategy = freedom.Config_AS_IS
	domainStrategy := strings.ToLower(v.DomainStrategy)
	if domainStrategy == "useip" || domainStrategy == "use_ip" {
		config.DomainStrategy = freedom.Config_USE_IP
	}
	config.Timeout = 600
	if v.Timeout != nil {
		config.Timeout = *v.Timeout
	}
	if len(v.Redirect) > 0 {
		host, portStr, err := net.SplitHostPort(v.Redirect)
		if err != nil {
			return nil, errors.Base(err).Message("Config: Invalid redirect address: ", v.Redirect, ": ", err)
		}
		port, err := v2net.PortFromString(portStr)
		if err != nil {
			return nil, errors.Base(err).Message("Config: Invalid redirect port: ", v.Redirect, ": ", err)
		}
		if len(host) == 0 {
			host = "127.0.0.1"
		}
		config.DestinationOverride = &freedom.DestinationOverride{
			Server: &protocol.ServerEndpoint{
				Address: v2net.NewIPOrDomain(v2net.ParseAddress(host)),
				Port:    uint32(port),
			},
		}
	}
	return serial.ToTypedMessage(config), nil
}
Ejemplo n.º 5
0
func (this *Address) UnmarshalJSON(data []byte) error {
	var rawStr string
	if err := json.Unmarshal(data, &rawStr); err != nil {
		return err
	}
	this.Address = v2net.ParseAddress(rawStr)

	return nil
}
Ejemplo n.º 6
0
func (request *Socks5Request) Destination() v2net.Destination {
	switch request.AddrType {
	case AddrTypeIPv4:
		return v2net.TCPDestination(v2net.IPAddress(request.IPv4[:]), request.Port)
	case AddrTypeIPv6:
		return v2net.TCPDestination(v2net.IPAddress(request.IPv6[:]), request.Port)
	case AddrTypeDomain:
		return v2net.TCPDestination(v2net.ParseAddress(request.Domain), request.Port)
	default:
		panic("Unknown address type")
	}
}
Ejemplo n.º 7
0
func ReadUDPRequest(packet []byte) (*Socks5UDPRequest, error) {
	if len(packet) < 5 {
		return nil, errors.New("Socks|UDP: Insufficient length of packet.")
	}
	request := new(Socks5UDPRequest)

	// packet[0] and packet[1] are reserved
	request.Fragment = packet[2]

	addrType := packet[3]
	var dataBegin int

	switch addrType {
	case AddrTypeIPv4:
		if len(packet) < 10 {
			return nil, errors.New("Socks|UDP: Insufficient length of packet.")
		}
		ip := packet[4:8]
		request.Port = v2net.PortFromBytes(packet[8:10])
		request.Address = v2net.IPAddress(ip)
		dataBegin = 10
	case AddrTypeIPv6:
		if len(packet) < 22 {
			return nil, errors.New("Socks|UDP: Insufficient length of packet.")
		}
		ip := packet[4:20]
		request.Port = v2net.PortFromBytes(packet[20:22])
		request.Address = v2net.IPAddress(ip)
		dataBegin = 22
	case AddrTypeDomain:
		domainLength := int(packet[4])
		if len(packet) < 5+domainLength+2 {
			return nil, errors.New("Socks|UDP: Insufficient length of packet.")
		}
		domain := string(packet[5 : 5+domainLength])
		request.Port = v2net.PortFromBytes(packet[5+domainLength : 5+domainLength+2])
		request.Address = v2net.ParseAddress(domain)
		dataBegin = 5 + domainLength + 2
	default:
		return nil, errors.Format("Socks|UDP: Unknown address type %d", addrType)
	}

	if len(packet) > dataBegin {
		b := buf.NewSmall()
		b.Append(packet[dataBegin:])
		request.Data = b
	}

	return request, nil
}
Ejemplo n.º 8
0
func parseIP(s string) *router.CIDR {
	var addr, mask string
	i := strings.Index(s, "/")
	if i < 0 {
		addr = s
	} else {
		addr = s[:i]
		mask = s[i+1:]
	}
	ip := v2net.ParseAddress(addr)
	switch ip.Family() {
	case v2net.AddressFamilyIPv4:
		bits := uint32(32)
		if len(mask) > 0 {
			bits64, err := strconv.ParseUint(mask, 10, 32)
			if err != nil {
				return nil
			}
			bits = uint32(bits64)
		}
		if bits > 32 {
			log.Warning("Router: invalid network mask: ", bits)
			return nil
		}
		return &router.CIDR{
			Ip:     []byte(ip.IP()),
			Prefix: bits,
		}
	case v2net.AddressFamilyIPv6:
		bits := uint32(128)
		if len(mask) > 0 {
			bits64, err := strconv.ParseUint(mask, 10, 32)
			if err != nil {
				return nil
			}
			bits = uint32(bits64)
		}
		if bits > 128 {
			log.Warning("Router: invalid network mask: ", bits)
			return nil
		}
		return &router.CIDR{
			Ip:     []byte(ip.IP()),
			Prefix: bits,
		}
	default:
		log.Warning("Router: unsupported address: ", s)
		return nil
	}
}
Ejemplo n.º 9
0
func ReadUDPRequest(packet []byte) (*Socks5UDPRequest, error) {
	if len(packet) < 5 {
		return nil, transport.ErrCorruptedPacket
	}
	request := new(Socks5UDPRequest)

	// packet[0] and packet[1] are reserved
	request.Fragment = packet[2]

	addrType := packet[3]
	var dataBegin int

	switch addrType {
	case AddrTypeIPv4:
		if len(packet) < 10 {
			return nil, transport.ErrCorruptedPacket
		}
		ip := packet[4:8]
		request.Port = v2net.PortFromBytes(packet[8:10])
		request.Address = v2net.IPAddress(ip)
		dataBegin = 10
	case AddrTypeIPv6:
		if len(packet) < 22 {
			return nil, transport.ErrCorruptedPacket
		}
		ip := packet[4:20]
		request.Port = v2net.PortFromBytes(packet[20:22])
		request.Address = v2net.IPAddress(ip)
		dataBegin = 22
	case AddrTypeDomain:
		domainLength := int(packet[4])
		if len(packet) < 5+domainLength+2 {
			return nil, transport.ErrCorruptedPacket
		}
		domain := string(packet[5 : 5+domainLength])
		request.Port = v2net.PortFromBytes(packet[5+domainLength : 5+domainLength+2])
		request.Address = v2net.ParseAddress(domain)
		dataBegin = 5 + domainLength + 2
	default:
		log.Warning("Unknown address type ", addrType)
		return nil, ErrorUnknownAddressType
	}

	if len(packet) > dataBegin {
		request.Data = alloc.NewBuffer().Clear().Append(packet[dataBegin:])
	}

	return request, nil
}
Ejemplo n.º 10
0
func DecodeUDPPacket(packet []byte) (*protocol.RequestHeader, []byte, error) {
	if len(packet) < 5 {
		return nil, nil, errors.New("Socks|UDP: Insufficient length of packet.")
	}
	request := &protocol.RequestHeader{
		Version: socks5Version,
		Command: protocol.RequestCommandUDP,
	}

	// packet[0] and packet[1] are reserved
	if packet[2] != 0 /* fragments */ {
		return nil, nil, errors.New("Socks|UDP: Fragmented payload.")
	}

	addrType := packet[3]
	var dataBegin int

	switch addrType {
	case addrTypeIPv4:
		if len(packet) < 10 {
			return nil, nil, errors.New("Socks|UDP: Insufficient length of packet.")
		}
		ip := packet[4:8]
		request.Port = v2net.PortFromBytes(packet[8:10])
		request.Address = v2net.IPAddress(ip)
		dataBegin = 10
	case addrTypeIPv6:
		if len(packet) < 22 {
			return nil, nil, errors.New("Socks|UDP: Insufficient length of packet.")
		}
		ip := packet[4:20]
		request.Port = v2net.PortFromBytes(packet[20:22])
		request.Address = v2net.IPAddress(ip)
		dataBegin = 22
	case addrTypeDomain:
		domainLength := int(packet[4])
		if len(packet) < 5+domainLength+2 {
			return nil, nil, errors.New("Socks|UDP: Insufficient length of packet.")
		}
		domain := string(packet[5 : 5+domainLength])
		request.Port = v2net.PortFromBytes(packet[5+domainLength : 5+domainLength+2])
		request.Address = v2net.ParseAddress(domain)
		dataBegin = 5 + domainLength + 2
	default:
		return nil, nil, errors.New("Socks|UDP: Unknown address type ", addrType)
	}

	return request, packet[dataBegin:], nil
}
Ejemplo n.º 11
0
func (this *CommandSwitchAccountFactory) Unmarshal(data []byte) (interface{}, error) {
	cmd := new(protocol.CommandSwitchAccount)
	if len(data) == 0 {
		return nil, transport.ErrCorruptedPacket
	}
	lenHost := int(data[0])
	if len(data) < lenHost+1 {
		return nil, transport.ErrCorruptedPacket
	}
	if lenHost > 0 {
		cmd.Host = v2net.ParseAddress(string(data[1 : 1+lenHost]))
	}
	portStart := 1 + lenHost
	if len(data) < portStart+2 {
		return nil, transport.ErrCorruptedPacket
	}
	cmd.Port = v2net.PortFromBytes(data[portStart : portStart+2])
	idStart := portStart + 2
	if len(data) < idStart+16 {
		return nil, transport.ErrCorruptedPacket
	}
	cmd.ID, _ = uuid.ParseBytes(data[idStart : idStart+16])
	alterIdStart := idStart + 16
	if len(data) < alterIdStart+2 {
		return nil, transport.ErrCorruptedPacket
	}
	cmd.AlterIds = serial.BytesToUint16(data[alterIdStart : alterIdStart+2])
	levelStart := alterIdStart + 2
	if len(data) < levelStart+1 {
		return nil, transport.ErrCorruptedPacket
	}
	cmd.Level = protocol.UserLevel(data[levelStart])
	timeStart := levelStart + 1
	if len(data) < timeStart {
		return nil, transport.ErrCorruptedPacket
	}
	cmd.ValidMin = data[timeStart]
	return cmd, nil
}
Ejemplo n.º 12
0
func (v *CommandSwitchAccountFactory) Unmarshal(data []byte) (interface{}, error) {
	cmd := new(protocol.CommandSwitchAccount)
	if len(data) == 0 {
		return nil, errors.New("VMess|SwitchAccountCommand: Insufficient length.")
	}
	lenHost := int(data[0])
	if len(data) < lenHost+1 {
		return nil, errors.New("VMess|SwitchAccountCommand: Insufficient length.")
	}
	if lenHost > 0 {
		cmd.Host = net.ParseAddress(string(data[1 : 1+lenHost]))
	}
	portStart := 1 + lenHost
	if len(data) < portStart+2 {
		return nil, errors.New("VMess|SwitchAccountCommand: Insufficient length.")
	}
	cmd.Port = net.PortFromBytes(data[portStart : portStart+2])
	idStart := portStart + 2
	if len(data) < idStart+16 {
		return nil, errors.New("VMess|SwitchAccountCommand: Insufficient length.")
	}
	cmd.ID, _ = uuid.ParseBytes(data[idStart : idStart+16])
	alterIDStart := idStart + 16
	if len(data) < alterIDStart+2 {
		return nil, errors.New("VMess|SwitchAccountCommand: Insufficient length.")
	}
	cmd.AlterIds = serial.BytesToUint16(data[alterIDStart : alterIDStart+2])
	levelStart := alterIDStart + 2
	if len(data) < levelStart+1 {
		return nil, errors.New("VMess|SwitchAccountCommand: Insufficient length.")
	}
	cmd.Level = uint32(data[levelStart])
	timeStart := levelStart + 1
	if len(data) < timeStart {
		return nil, errors.New("VMess|SwitchAccountCommand: Insufficient length.")
	}
	cmd.ValidMin = data[timeStart]
	return cmd, nil
}