Beispiel #1
0
func (this *RegexpDomainMatcher) Apply(dest v2net.Destination) bool {
	if !dest.Address().Family().IsDomain() {
		return false
	}
	domain := dest.Address().Domain()
	return this.pattern.MatchString(strings.ToLower(domain))
}
Beispiel #2
0
func wsDial(src v2net.Address, dest v2net.Destination) (*wsconn, error) {
	commonDial := func(network, addr string) (net.Conn, error) {
		return internet.DialToDest(src, dest)
	}

	tlsconf := &tls.Config{ServerName: dest.Address().Domain(), InsecureSkipVerify: effectiveConfig.DeveloperInsecureSkipVerify}

	dialer := websocket.Dialer{NetDial: commonDial, ReadBufferSize: 65536, WriteBufferSize: 65536, TLSClientConfig: tlsconf}

	effpto := calcPto(dest)

	uri := func(dst v2net.Destination, pto string, path string) string {
		return fmt.Sprintf("%v://%v/%v", pto, dst.NetAddr(), path)
	}(dest, effpto, effectiveConfig.Path)

	conn, resp, err := dialer.Dial(uri, nil)
	if err != nil {
		if resp != nil {
			reason, reasonerr := ioutil.ReadAll(resp.Body)
			log.Info(string(reason), reasonerr)
		}
		return nil, err
	}
	return func() internet.Connection {
		connv2ray := &wsconn{wsc: conn, connClosing: false}
		connv2ray.setup()
		return connv2ray
	}().(*wsconn), nil
}
Beispiel #3
0
func (this *PlainDomainMatcher) Apply(dest v2net.Destination) bool {
	if !dest.Address().Family().IsDomain() {
		return false
	}
	domain := dest.Address().Domain()
	return strings.Contains(domain, this.pattern)
}
Beispiel #4
0
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().Family().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()

	if !payload.IsEmpty() {
		conn.Write(payload.Value)
	}

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

		v2io.Pipe(input, v2writer)
		if tcpConn, ok := conn.(*tcp.RawConnection); ok {
			tcpConn.CloseWrite()
		}
	}()

	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)
	v2io.Pipe(v2reader, output)
	v2reader.Release()
	ray.OutboundOutput().Close()

	return nil
}
Beispiel #5
0
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
}
Beispiel #6
0
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
}
Beispiel #7
0
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:
	}
}
Beispiel #8
0
// Private: Visible for testing.
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
}
Beispiel #9
0
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(StreamConnectionTypeWebSocket):
			connection, err = WSDialer(src, dest)

		/*Warning: Hours wasted: the following item must be last one

		internet.StreamConnectionType have a default value of 1,
		so the following attempt will catch all.
		*/

		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().Family().IsDomain() {
			config.ServerName = dest.Address().Domain()
		}
		tlsConn := tls.Client(connection, config)
		return v2tls.NewConnection(tlsConn), nil
	}

	return UDPDialer(src, dest)
}
Beispiel #10
0
func DialKCP(src v2net.Address, dest v2net.Destination) (internet.Connection, error) {
	udpDest := v2net.UDPDestination(dest.Address(), dest.Port())
	log.Info("KCP|Dialer: Dialing KCP to ", udpDest)
	conn, err := internet.DialToDest(src, udpDest)
	if err != nil {
		log.Error("KCP|Dialer: Failed to dial to dest: ", err)
		return nil, err
	}

	cpip, err := effectiveConfig.GetAuthenticator()
	if err != nil {
		log.Error("KCP|Dialer: Failed to create authenticator: ", err)
		return nil, err
	}
	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
}
Beispiel #11
0
// Private: Visible for testing.
func (this *FreedomConnection) ResolveIP(destination v2net.Destination) v2net.Destination {
	if !destination.Address().Family().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
}
Beispiel #12
0
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().Family().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
}
Beispiel #13
0
func (this *IPv4Matcher) Apply(dest v2net.Destination) bool {
	if !dest.Address().Family().Either(v2net.AddressFamilyIPv4) {
		return false
	}
	return this.ipv4net.Contains(dest.Address().IP())
}
Beispiel #14
0
func (this *CIDRMatcher) Apply(dest v2net.Destination) bool {
	if !dest.Address().Family().Either(v2net.AddressFamilyIPv4, v2net.AddressFamilyIPv6) {
		return false
	}
	return this.cidr.Contains(dest.Address().IP())
}
Beispiel #15
0
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()),
	})
}
Beispiel #16
0
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
}