コード例 #1
0
ファイル: condition.go プロジェクト: airmao/v2ray-core
func (this *RegexpDomainMatcher) Apply(dest v2net.Destination) bool {
	if !dest.Address().IsDomain() {
		return false
	}
	domain := serial.StringLiteral(dest.Address().Domain())
	return this.pattern.MatchString(domain.ToLower().String())
}
コード例 #2
0
ファイル: dialer.go プロジェクト: wangyou/v2ray-core
func Dial(dest v2net.Destination) (net.Conn, error) {
	if dest.Address().IsDomain() {
		dialer := &net.Dialer{
			Timeout:   time.Second * 60,
			DualStack: true,
		}
		network := "tcp"
		if dest.IsUDP() {
			network = "udp"
		}
		return dialer.Dial(network, dest.NetAddr())
	}

	ip := dest.Address().IP()
	if dest.IsTCP() {
		return net.DialTCP("tcp", nil, &net.TCPAddr{
			IP:   ip,
			Port: int(dest.Port()),
		})
	} else {
		return net.DialUDP("udp", nil, &net.UDPAddr{
			IP:   ip,
			Port: int(dest.Port()),
		})
	}
}
コード例 #3
0
ファイル: command.go プロジェクト: airmao/v2ray-core
func (this *VMessOutboundHandler) handleCommand(dest v2net.Destination, cmdId byte, data []byte) {
	if len(data) < 4 {
		return
	}
	fnv1hash := fnv.New32a()
	fnv1hash.Write(data[4:])
	actualHashValue := fnv1hash.Sum32()
	expectedHashValue := serial.BytesLiteral(data[:4]).Uint32Value()
	if actualHashValue != expectedHashValue {
		return
	}
	data = data[4:]
	cmd, err := command.CreateResponseCommand(cmdId)
	if err != nil {
		log.Warning("VMessOut: Unknown response command (", cmdId, "): ", err)
		return
	}
	if err := cmd.Unmarshal(data); err != nil {
		log.Warning("VMessOut: Failed to parse response command: ", err)
		return
	}
	switch typedCommand := cmd.(type) {
	case *command.SwitchAccount:
		if typedCommand.Host == nil {
			typedCommand.Host = dest.Address()
		}
		this.handleSwitchAccount(typedCommand)
	default:
	}
}
コード例 #4
0
ファイル: vmessout.go プロジェクト: zenwalk/v2ray-core
func startCommunicate(request *protocol.VMessRequest, dest *v2net.Destination, ray core.OutboundRay) error {
	input := ray.OutboundInput()
	output := ray.OutboundOutput()

	conn, err := net.DialTCP(dest.Network(), nil, &net.TCPAddr{dest.Address().IP(), int(dest.Address().Port()), ""})
	if err != nil {
		log.Error("Failed to open tcp (%s): %v", dest.String(), err)
		close(output)
		return err
	}
	log.Info("VMessOut: Tunneling request for %s", request.Address.String())

	defer conn.Close()

	requestFinish := make(chan bool)
	responseFinish := make(chan bool)

	go handleRequest(conn, request, input, requestFinish)
	go handleResponse(conn, request, output, responseFinish)

	<-requestFinish
	conn.CloseWrite()
	<-responseFinish
	return nil
}
コード例 #5
0
ファイル: dialer.go プロジェクト: ChoyesYan/v2ray-core
func Dial(src v2net.Address, dest v2net.Destination, settings *StreamSettings) (Connection, error) {
	var connection Connection
	var err error
	if dest.IsTCP() {
		switch {
		case settings.IsCapableOf(StreamConnectionTypeTCP):
			connection, err = TCPDialer(src, dest)
		case settings.IsCapableOf(StreamConnectionTypeKCP):
			connection, err = KCPDialer(src, dest)
		case settings.IsCapableOf(StreamConnectionTypeRawTCP):
			connection, err = RawTCPDialer(src, dest)
		default:
			return nil, ErrUnsupportedStreamType
		}
		if err != nil {
			return nil, err
		}
		if settings.Security == StreamSecurityTypeNone {
			return connection, nil
		}

		config := settings.TLSSettings.GetTLSConfig()
		if dest.Address().IsDomain() {
			config.ServerName = dest.Address().Domain()
		}
		tlsConn := tls.Client(connection, config)
		return v2tls.NewConnection(tlsConn), nil
	}

	return UDPDialer(src, dest)
}
コード例 #6
0
ファイル: condition.go プロジェクト: ChoyesYan/v2ray-core
func (this *RegexpDomainMatcher) Apply(dest v2net.Destination) bool {
	if !dest.Address().IsDomain() {
		return false
	}
	domain := dest.Address().Domain()
	return this.pattern.MatchString(strings.ToLower(domain))
}
コード例 #7
0
ファイル: condition.go プロジェクト: ChoyesYan/v2ray-core
func (this *PlainDomainMatcher) Apply(dest v2net.Destination) bool {
	if !dest.Address().IsDomain() {
		return false
	}
	domain := dest.Address().Domain()
	return strings.Contains(domain, this.pattern)
}
コード例 #8
0
ファイル: condition.go プロジェクト: airmao/v2ray-core
func (this *PlainDomainMatcher) Apply(dest v2net.Destination) bool {
	if !dest.Address().IsDomain() {
		return false
	}
	domain := serial.StringLiteral(dest.Address().Domain())
	return domain.Contains(this.pattern)
}
コード例 #9
0
ファイル: vmessout.go プロジェクト: xiatiansong/v2ray-core
func startCommunicate(request *protocol.VMessRequest, dest v2net.Destination, ray core.OutboundRay, firstPacket v2net.Packet) error {
	conn, err := net.Dial(dest.Network(), dest.Address().String())
	if err != nil {
		log.Error("Failed to open %s: %v", dest.String(), err)
		if ray != nil {
			close(ray.OutboundOutput())
		}
		return err
	}
	log.Info("VMessOut: Tunneling request to %s via %s", request.Address.String(), dest.String())

	defer conn.Close()

	input := ray.OutboundInput()
	output := ray.OutboundOutput()
	var requestFinish, responseFinish sync.Mutex
	requestFinish.Lock()
	responseFinish.Lock()

	go handleRequest(conn, request, firstPacket, input, &requestFinish)
	go handleResponse(conn, request, output, &responseFinish, dest.IsUDP())

	requestFinish.Lock()
	if tcpConn, ok := conn.(*net.TCPConn); ok {
		tcpConn.CloseWrite()
	}
	responseFinish.Lock()
	return nil
}
コード例 #10
0
ファイル: outbound.go プロジェクト: ChoyesYan/v2ray-core
func (this *VMessOutboundHandler) Dispatch(target v2net.Destination, payload *alloc.Buffer, ray ray.OutboundRay) error {
	defer ray.OutboundInput().Release()
	defer ray.OutboundOutput().Close()

	var rec *protocol.ServerSpec
	var conn internet.Connection

	err := retry.Timed(5, 100).On(func() error {
		rec = this.serverPicker.PickServer()
		rawConn, err := internet.Dial(this.meta.Address, rec.Destination(), this.meta.StreamSettings)
		if err != nil {
			return err
		}
		conn = rawConn

		return nil
	})
	if err != nil {
		log.Error("VMess|Outbound: Failed to find an available destination:", err)
		return err
	}
	log.Info("VMess|Outbound: Tunneling request to ", target, " via ", rec.Destination)

	command := protocol.RequestCommandTCP
	if target.IsUDP() {
		command = protocol.RequestCommandUDP
	}
	request := &protocol.RequestHeader{
		Version: encoding.Version,
		User:    rec.PickUser(),
		Command: command,
		Address: target.Address(),
		Port:    target.Port(),
		Option:  protocol.RequestOptionChunkStream,
	}

	defer conn.Close()

	conn.SetReusable(true)
	if conn.Reusable() { // Conn reuse may be disabled on transportation layer
		request.Option.Set(protocol.RequestOptionConnectionReuse)
	}

	input := ray.OutboundInput()
	output := ray.OutboundOutput()

	var requestFinish, responseFinish sync.Mutex
	requestFinish.Lock()
	responseFinish.Lock()

	session := encoding.NewClientSession(protocol.DefaultIDHash)

	go this.handleRequest(session, conn, request, payload, input, &requestFinish)
	go this.handleResponse(session, conn, request, rec.Destination(), output, &responseFinish)

	requestFinish.Lock()
	responseFinish.Lock()
	return nil
}
コード例 #11
0
ファイル: socks5_helper.go プロジェクト: ChoyesYan/v2ray-core
func socks5UDPRequest(address v2net.Destination, payload []byte) []byte {
	request := make([]byte, 0, 1024)
	request = append(request, 0, 0, 0)
	request = appendAddress(request, address.Address())
	request = address.Port().Bytes(request)
	request = append(request, payload...)
	return request
}
コード例 #12
0
ファイル: command.go プロジェクト: ChoyesYan/v2ray-core
func (this *VMessOutboundHandler) handleCommand(dest v2net.Destination, cmd protocol.ResponseCommand) {
	switch typedCommand := cmd.(type) {
	case *protocol.CommandSwitchAccount:
		if typedCommand.Host == nil {
			typedCommand.Host = dest.Address()
		}
		this.handleSwitchAccount(typedCommand)
	default:
	}
}
コード例 #13
0
ファイル: chinasites.go プロジェクト: adoot/v2ray-core
func (this *ChinaSitesRule) Apply(dest v2net.Destination) bool {
	address := dest.Address()
	if !address.IsDomain() {
		return false
	}
	domain := strings.ToLower(address.Domain())
	for _, matcher := range compiledMatchers {
		if matcher.Match(domain) {
			return true
		}
	}
	return false
}
コード例 #14
0
ファイル: dialer.go プロジェクト: airmao/v2ray-core
func Dial(dest v2net.Destination) (net.Conn, error) {
	var ip net.IP
	if dest.Address().IsIPv4() || dest.Address().IsIPv6() {
		ip = dest.Address().IP()
	} else {
		ips, err := net.LookupIP(dest.Address().Domain())
		if err != nil {
			return nil, err
		}
		if len(ips) == 0 {
			return nil, ErrInvalidHost
		}
		ip = ips[dice.Roll(len(ips))]
	}
	if dest.IsTCP() {
		return net.DialTCP("tcp", nil, &net.TCPAddr{
			IP:   ip,
			Port: int(dest.Port()),
		})
	} else {
		return net.DialUDP("udp", nil, &net.UDPAddr{
			IP:   ip,
			Port: int(dest.Port()),
		})
	}
}
コード例 #15
0
func (this *FieldRule) Apply(dest v2net.Destination) bool {
	address := dest.Address()
	if len(this.Domain) > 0 {
		if !address.IsDomain() {
			return false
		}
		foundMatch := false
		for _, domain := range this.Domain {
			if domain.Match(address.Domain()) {
				foundMatch = true
				break
			}
		}
		if !foundMatch {
			return false
		}
	}

	if this.IP != nil && len(this.IP) > 0 {
		if !(address.IsIPv4() || address.IsIPv6()) {
			return false
		}
		foundMatch := false
		for _, ipnet := range this.IP {
			if ipnet.Contains(address.IP()) {
				foundMatch = true
				break
			}
		}
		if !foundMatch {
			return false
		}
	}

	if this.Port != nil {
		port := dest.Port()
		if port.Value() < this.Port.From().Value() || port.Value() > this.Port.To().Value() {
			return false
		}
	}

	if this.Network != nil {
		if !this.Network.HasNetwork(v2net.Network(dest.Network())) {
			return false
		}
	}

	return true
}
コード例 #16
0
ファイル: router.go プロジェクト: ChoyesYan/v2ray-core
// @Private
func (this *Router) ResolveIP(dest v2net.Destination) []v2net.Destination {
	ips := this.dnsServer.Get(dest.Address().Domain())
	if len(ips) == 0 {
		return nil
	}
	dests := make([]v2net.Destination, len(ips))
	for idx, ip := range ips {
		if dest.IsTCP() {
			dests[idx] = v2net.TCPDestination(v2net.IPAddress(ip), dest.Port())
		} else {
			dests[idx] = v2net.UDPDestination(v2net.IPAddress(ip), dest.Port())
		}
	}
	return dests
}
コード例 #17
0
ファイル: dialer.go プロジェクト: ChoyesYan/v2ray-core
func DialKCP(src v2net.Address, dest v2net.Destination) (internet.Connection, error) {
	udpDest := v2net.UDPDestination(dest.Address(), dest.Port())
	log.Info("Dialling KCP to ", udpDest)
	conn, err := internet.DialToDest(src, udpDest)
	if err != nil {
		return nil, err
	}

	cpip := NewSimpleAuthenticator()
	conv := uint16(atomic.AddUint32(&globalConv, 1))
	session := NewConnection(conv, conn, conn.LocalAddr().(*net.UDPAddr), conn.RemoteAddr().(*net.UDPAddr), cpip)
	session.FetchInputFrom(conn)

	return session, nil
}
コード例 #18
0
ファイル: listener.go プロジェクト: ChoyesYan/v2ray-core
func (this *Listener) OnReceive(payload *alloc.Buffer, src v2net.Destination) {
	defer payload.Release()

	if valid := this.block.Open(payload); !valid {
		log.Info("KCP|Listener: discarding invalid payload from ", src)
		return
	}
	if !this.running {
		return
	}
	this.Lock()
	defer this.Unlock()
	if !this.running {
		return
	}
	if payload.Len() < 4 {
		return
	}
	conv := serial.BytesToUint16(payload.Value)
	cmd := Command(payload.Value[2])
	sourceId := src.NetAddr() + "|" + serial.Uint16ToString(conv)
	conn, found := this.sessions[sourceId]
	if !found {
		if cmd == CommandTerminate {
			return
		}
		log.Debug("KCP|Listener: Creating session with id(", sourceId, ") from ", src)
		writer := &Writer{
			id:       sourceId,
			hub:      this.hub,
			dest:     src,
			listener: this,
		}
		srcAddr := &net.UDPAddr{
			IP:   src.Address().IP(),
			Port: int(src.Port()),
		}
		conn = NewConnection(conv, writer, this.localAddr, srcAddr, this.block)
		select {
		case this.awaitingConns <- conn:
		case <-time.After(time.Second * 5):
			conn.Close()
			return
		}
		this.sessions[sourceId] = conn
	}
	conn.Input(payload.Value)
}
コード例 #19
0
ファイル: freedom.go プロジェクト: ChoyesYan/v2ray-core
// @Private
func (this *FreedomConnection) ResolveIP(destination v2net.Destination) v2net.Destination {
	if !destination.Address().IsDomain() {
		return destination
	}

	ips := this.dns.Get(destination.Address().Domain())
	if len(ips) == 0 {
		log.Info("Freedom: DNS returns nil answer. Keep domain as is.")
		return destination
	}

	ip := ips[dice.Roll(len(ips))]
	var newDest v2net.Destination
	if destination.IsTCP() {
		newDest = v2net.TCPDestination(v2net.IPAddress(ip), destination.Port())
	} else {
		newDest = v2net.UDPDestination(v2net.IPAddress(ip), destination.Port())
	}
	log.Info("Freedom: Changing destination from ", destination, " to ", newDest)
	return newDest
}
コード例 #20
0
ファイル: vmessout.go プロジェクト: starsw001/v2ray-core
func startCommunicate(request *protocol.VMessRequest, dest v2net.Destination, ray core.OutboundRay, firstPacket v2net.Packet) error {
	conn, err := net.DialTCP(dest.Network(), nil, &net.TCPAddr{dest.Address().IP(), int(dest.Address().Port()), ""})
	if err != nil {
		log.Error("Failed to open tcp (%s): %v", dest.String(), err)
		if ray != nil {
			close(ray.OutboundOutput())
		}
		return err
	}
	log.Info("VMessOut: Tunneling request for %s", request.Address.String())

	defer conn.Close()

	if chunk := firstPacket.Chunk(); chunk != nil {
		conn.Write(chunk)
	}

	if !firstPacket.MoreChunks() {
		if ray != nil {
			close(ray.OutboundOutput())
		}
		return nil
	}

	input := ray.OutboundInput()
	output := ray.OutboundOutput()
	var requestFinish, responseFinish sync.Mutex
	requestFinish.Lock()
	responseFinish.Lock()

	go handleRequest(conn, request, input, &requestFinish)
	go handleResponse(conn, request, output, &responseFinish)

	requestFinish.Lock()
	conn.CloseWrite()
	responseFinish.Lock()
	return nil
}
コード例 #21
0
ファイル: router.go プロジェクト: ChoyesYan/v2ray-core
func (this *Router) takeDetourWithoutCache(dest v2net.Destination) (string, error) {
	for _, rule := range this.config.Rules {
		if rule.Apply(dest) {
			return rule.Tag, nil
		}
	}
	if this.config.DomainStrategy == UseIPIfNonMatch && dest.Address().IsDomain() {
		log.Info("Router: Looking up IP for ", dest)
		ipDests := this.ResolveIP(dest)
		if ipDests != nil {
			for _, ipDest := range ipDests {
				log.Info("Router: Trying IP ", ipDest)
				for _, rule := range this.config.Rules {
					if rule.Apply(ipDest) {
						return rule.Tag, nil
					}
				}
			}
		}
	}

	return "", ErrNoRuleApplicable
}
コード例 #22
0
ファイル: outbound.go プロジェクト: caizixian/v2ray-core
func (this *VMessOutboundHandler) startCommunicate(request *proto.RequestHeader, dest v2net.Destination, ray ray.OutboundRay, firstPacket v2net.Packet) error {
	var destIP net.IP
	if dest.Address().IsIPv4() || dest.Address().IsIPv6() {
		destIP = dest.Address().IP()
	} else {
		ips, err := net.LookupIP(dest.Address().Domain())
		if err != nil {
			return err
		}
		destIP = ips[0]
	}
	conn, err := net.DialTCP("tcp", nil, &net.TCPAddr{
		IP:   destIP,
		Port: int(dest.Port()),
	})
	if err != nil {
		log.Error("Failed to open ", dest, ": ", err)
		if ray != nil {
			close(ray.OutboundOutput())
		}
		return err
	}
	log.Info("VMessOut: Tunneling request to ", request.Address, " via ", dest)

	defer conn.Close()

	input := ray.OutboundInput()
	output := ray.OutboundOutput()

	var requestFinish, responseFinish sync.Mutex
	requestFinish.Lock()
	responseFinish.Lock()

	session := raw.NewClientSession(proto.DefaultIDHash)

	go this.handleRequest(session, conn, request, firstPacket, input, &requestFinish)
	go this.handleResponse(session, conn, request, dest, output, &responseFinish)

	requestFinish.Lock()
	conn.CloseWrite()
	responseFinish.Lock()
	return nil
}
コード例 #23
0
ファイル: outbound.go プロジェクト: ibmendoza/v2ray-core
func startCommunicate(request *protocol.VMessRequest, dest v2net.Destination, ray ray.OutboundRay, firstPacket v2net.Packet) error {
	var destIp net.IP
	if dest.Address().IsIPv4() || dest.Address().IsIPv6() {
		destIp = dest.Address().IP()
	} else {
		ips, err := net.LookupIP(dest.Address().Domain())
		if err != nil {
			return err
		}
		destIp = ips[0]
	}
	conn, err := net.DialTCP("tcp", nil, &net.TCPAddr{
		IP:   destIp,
		Port: int(dest.Port()),
	})
	if err != nil {
		log.Error("Failed to open ", dest, ": ", err)
		if ray != nil {
			close(ray.OutboundOutput())
		}
		return err
	}
	log.Info("VMessOut: Tunneling request to ", request.Address, " via ", dest)

	defer conn.Close()

	input := ray.OutboundInput()
	output := ray.OutboundOutput()

	var requestFinish, responseFinish sync.Mutex
	requestFinish.Lock()
	responseFinish.Lock()

	go handleRequest(conn, request, firstPacket, input, &requestFinish)
	go handleResponse(conn, request, output, &responseFinish, (request.Command == protocol.CmdUDP))

	requestFinish.Lock()
	conn.CloseWrite()
	responseFinish.Lock()
	return nil
}
コード例 #24
0
ファイル: socks5_helper.go プロジェクト: ChoyesYan/v2ray-core
func socks5Request(command byte, address v2net.Destination) []byte {
	request := []byte{socks5Version, command, 0}
	request = appendAddress(request, address.Address())
	request = address.Port().Bytes(request)
	return request
}
コード例 #25
0
ファイル: udp.go プロジェクト: ChoyesYan/v2ray-core
func (this *UDPHub) WriteTo(payload []byte, dest v2net.Destination) (int, error) {
	return this.conn.WriteToUDP(payload, &net.UDPAddr{
		IP:   dest.Address().IP(),
		Port: int(dest.Port()),
	})
}
コード例 #26
0
ファイル: condition.go プロジェクト: airmao/v2ray-core
func (this *CIDRMatcher) Apply(dest v2net.Destination) bool {
	if !dest.Address().IsIPv4() && !dest.Address().IsIPv6() {
		return false
	}
	return this.cidr.Contains(dest.Address().IP())
}
コード例 #27
0
ファイル: freedom.go プロジェクト: ChoyesYan/v2ray-core
func (this *FreedomConnection) Dispatch(destination v2net.Destination, payload *alloc.Buffer, ray ray.OutboundRay) error {
	log.Info("Freedom: Opening connection to ", destination)

	defer payload.Release()
	defer ray.OutboundInput().Release()
	defer ray.OutboundOutput().Close()

	var conn internet.Connection
	if this.domainStrategy == DomainStrategyUseIP && destination.Address().IsDomain() {
		destination = this.ResolveIP(destination)
	}
	err := retry.Timed(5, 100).On(func() error {
		rawConn, err := internet.Dial(this.meta.Address, destination, this.meta.StreamSettings)
		if err != nil {
			return err
		}
		conn = rawConn
		return nil
	})
	if err != nil {
		log.Warning("Freedom: Failed to open connection to ", destination, ": ", err)
		return err
	}
	defer conn.Close()

	input := ray.OutboundInput()
	output := ray.OutboundOutput()
	var readMutex, writeMutex sync.Mutex
	readMutex.Lock()
	writeMutex.Lock()

	conn.Write(payload.Value)

	go func() {
		v2writer := v2io.NewAdaptiveWriter(conn)
		defer v2writer.Release()

		v2io.Pipe(input, v2writer)
		writeMutex.Unlock()
	}()

	go func() {
		defer readMutex.Unlock()

		var reader io.Reader = conn

		timeout := this.timeout
		if destination.IsUDP() {
			timeout = 16
		}
		if timeout > 0 {
			reader = v2net.NewTimeOutReader(int(timeout) /* seconds */, conn)
		}

		v2reader := v2io.NewAdaptiveReader(reader)
		defer v2reader.Release()

		v2io.Pipe(v2reader, output)
		ray.OutboundOutput().Close()
	}()

	writeMutex.Lock()
	if tcpConn, ok := conn.(*tcp.RawConnection); ok {
		tcpConn.CloseWrite()
	}
	readMutex.Lock()

	return nil
}
コード例 #28
0
ファイル: condition.go プロジェクト: airmao/v2ray-core
func (this *IPv4Matcher) Apply(dest v2net.Destination) bool {
	if !dest.Address().IsIPv4() {
		return false
	}
	return this.ipv4net.Contains(dest.Address().IP())
}