func Dial(src v2net.Address, dest v2net.Destination, options internet.DialerOptions) (internet.Connection, error) { log.Info("WebSocket|Dailer: Creating connection to ", dest) if src == nil { src = v2net.AnyIP } networkSettings, err := options.Stream.GetEffectiveNetworkSettings() if err != nil { return nil, err } wsSettings := networkSettings.(*Config) id := src.String() + "-" + dest.NetAddr() var conn *wsconn if dest.Network == v2net.Network_TCP && wsSettings.ConnectionReuse.IsEnabled() { connt := globalCache.Get(id) if connt != nil { conn = connt.(*wsconn) } } if conn == nil { var err error conn, err = wsDial(src, dest, options) if err != nil { log.Warning("WebSocket|Dialer: Dial failed: ", err) return nil, err } } return NewConnection(id, conn, globalCache, wsSettings), nil }
func (v *IPv4Matcher) Apply(ctx context.Context) bool { ips := make([]net.IP, 0, 4) if resolveIPs, ok := proxy.ResolvedIPsFromContext(ctx); ok { for _, rip := range resolveIPs { if !rip.Family().IsIPv4() { continue } ips = append(ips, rip.IP()) } } var dest v2net.Destination if v.onSource { dest = proxy.SourceFromContext(ctx) } else { dest = proxy.DestinationFromContext(ctx) } if dest.IsValid() && dest.Address.Family().IsIPv4() { ips = append(ips, dest.Address.IP()) } for _, ip := range ips { if v.ipv4net.Contains(ip) { return true } } return false }
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) }
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)) }
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 }
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 }
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 }
func (v *Assert) Destination(value v2net.Destination) *DestinationSubject { return &DestinationSubject{ Subject: Subject{ disp: value.String(), a: v, }, value: value, } }
func (this *Router) TakeDetour(dest v2net.Destination) (string, error) { destStr := dest.String() found, tag, err := this.cache.Get(destStr) if !found { tag, err := this.takeDetourWithoutCache(dest) this.cache.Set(destStr, tag, err) return tag, err } return tag, err }
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: } }
func wsDial(src v2net.Address, dest v2net.Destination, options internet.DialerOptions) (*wsconn, error) { networkSettings, err := options.Stream.GetEffectiveNetworkSettings() if err != nil { return nil, err } wsSettings := networkSettings.(*Config) commonDial := func(network, addr string) (net.Conn, error) { return internet.DialToDest(src, dest) } dialer := websocket.Dialer{ NetDial: commonDial, ReadBufferSize: 65536, WriteBufferSize: 65536, } protocol := "ws" if options.Stream != nil && options.Stream.HasSecuritySettings() { protocol = "wss" securitySettings, err := options.Stream.GetEffectiveSecuritySettings() if err != nil { log.Error("WebSocket: Failed to create security settings: ", err) return nil, err } tlsConfig, ok := securitySettings.(*v2tls.Config) if ok { dialer.TLSClientConfig = tlsConfig.GetTLSConfig() if dest.Address.Family().IsDomain() { dialer.TLSClientConfig.ServerName = dest.Address.Domain() } } } uri := protocol + "://" + dest.NetAddr() + "/" + wsSettings.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, config: wsSettings, } connv2ray.setup() return connv2ray }().(*wsconn), nil }
func (v *Dispatcher) getInboundRay(ctx context.Context, dest v2net.Destination) (ray.InboundRay, bool) { destString := dest.String() v.Lock() defer v.Unlock() if entry, found := v.conns[destString]; found { return entry, true } log.Info("UDP|Server: establishing new connection for ", dest) ctx = proxy.ContextWithDestination(ctx, dest) return v.packetDispatcher.DispatchToOutbound(ctx), false }
func wsDial(ctx context.Context, dest v2net.Destination) (*wsconn, error) { src := internet.DialerSourceFromContext(ctx) wsSettings := internet.TransportSettingsFromContext(ctx).(*Config) commonDial := func(network, addr string) (net.Conn, error) { return internet.DialSystem(src, dest) } dialer := websocket.Dialer{ NetDial: commonDial, ReadBufferSize: 32 * 1024, WriteBufferSize: 32 * 1024, } protocol := "ws" if securitySettings := internet.SecuritySettingsFromContext(ctx); securitySettings != nil { tlsConfig, ok := securitySettings.(*v2tls.Config) if ok { protocol = "wss" dialer.TLSClientConfig = tlsConfig.GetTLSConfig() if dest.Address.Family().IsDomain() { dialer.TLSClientConfig.ServerName = dest.Address.Domain() } } } host := dest.NetAddr() if (protocol == "ws" && dest.Port == 80) || (protocol == "wss" && dest.Port == 443) { host = dest.Address.String() } uri := protocol + "://" + host + "/" + wsSettings.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, config: wsSettings, } connv2ray.setup() return connv2ray }().(*wsconn), nil }
func Dial(src v2net.Address, dest v2net.Destination, options internet.DialerOptions) (internet.Connection, error) { log.Info("Dailing TCP to ", dest) if src == nil { src = v2net.AnyIP } networkSettings, err := options.Stream.GetEffectiveNetworkSettings() if err != nil { return nil, err } tcpSettings := networkSettings.(*Config) id := src.String() + "-" + dest.NetAddr() var conn net.Conn if dest.Network == v2net.Network_TCP && tcpSettings.ConnectionReuse.IsEnabled() { conn = globalCache.Get(id) } if conn == nil { var err error conn, err = internet.DialToDest(src, dest) if err != nil { return nil, err } if options.Stream != nil && options.Stream.HasSecuritySettings() { securitySettings, err := options.Stream.GetEffectiveSecuritySettings() if err != nil { log.Error("TCP: Failed to get security settings: ", err) return nil, err } tlsConfig, ok := securitySettings.(*v2tls.Config) if ok { config := tlsConfig.GetTLSConfig() if dest.Address.Family().IsDomain() { config.ServerName = dest.Address.Domain() } conn = tls.Client(conn, config) } } if tcpSettings.HeaderSettings != nil { headerConfig, err := tcpSettings.HeaderSettings.GetInstance() if err != nil { return nil, errors.New("TCP: Failed to get header settings: " + err.Error()) } auth, err := internet.CreateConnectionAuthenticator(tcpSettings.HeaderSettings.Type, headerConfig) if err != nil { return nil, errors.New("TCP: Failed to create header authenticator: " + err.Error()) } conn = auth.Client(conn) } } return NewConnection(id, conn, globalCache, tcpSettings), nil }
func (v *Dispatcher) Dispatch(ctx context.Context, destination v2net.Destination, payload *buf.Buffer, callback ResponseCallback) { // TODO: Add user to destString destString := destination.String() log.Debug("UDP|Server: Dispatch request: ", destString) inboundRay, existing := v.getInboundRay(ctx, destination) outputStream := inboundRay.InboundInput() if outputStream != nil { if err := outputStream.Write(payload); err != nil { v.RemoveRay(destString) } } if !existing { go func() { handleInput(inboundRay.InboundOutput(), callback) v.RemoveRay(destString) }() } }
func Dial(src v2net.Address, dest v2net.Destination) (internet.Connection, error) { log.Info("Dailing TCP to ", dest) if src == nil { src = v2net.AnyIP } id := src.String() + "-" + dest.NetAddr() var conn net.Conn if dest.IsTCP() && effectiveConfig.ConnectionReuse { conn = globalCache.Get(id) } if conn == nil { var err error conn, err = internet.DialToDest(src, dest) if err != nil { return nil, err } } return NewConnection(id, conn, globalCache), nil }
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 }
func calcPto(dst v2net.Destination) string { if effectiveConfig.Pto != "" { return effectiveConfig.Pto } switch dst.Port().Value() { /* Since the value is not given explicitly, We are guessing it now. HTTP Port: 80 8080 8880 2052 2082 2086 2095 HTTPS Port: 443 2053 2083 2087 2096 8443 if the port you are using is not well-known, specify it to avoid this process. We will return "CRASH"turn "unknown" if we can't guess it, cause Dial to fail. */ case 80, 8080, 8880, 2052, 2082, 2086, 2095: return "ws" case 443, 2053, 2083, 2087, 2096, 8443: return "wss" default: return "unknown" } }
func DialKCP(ctx context.Context, dest v2net.Destination) (internet.Connection, error) { dest.Network = v2net.Network_UDP log.Info("KCP|Dialer: Dialing KCP to ", dest) src := internet.DialerSourceFromContext(ctx) id := internal.NewConnectionID(src, dest) conn := globalPool.Get(id) if conn == nil { rawConn, err := internet.DialSystem(src, dest) if err != nil { log.Error("KCP|Dialer: Failed to dial to dest: ", err) return nil, err } c := &ClientConnection{ Conn: rawConn, id: id, } go c.Run() conn = c } kcpSettings := internet.TransportSettingsFromContext(ctx).(*Config) clientConn := conn.(*ClientConnection) header, err := kcpSettings.GetPackerHeader() if err != nil { return nil, errors.Base(err).Message("KCP|Dialer: Failed to create packet header.") } security, err := kcpSettings.GetSecurity() if err != nil { return nil, errors.Base(err).Message("KCP|Dialer: Failed to create security.") } clientConn.ResetSecurity(header, security) conv := uint16(atomic.AddUint32(&globalConv, 1)) session := NewConnection(conv, clientConn, globalPool, kcpSettings) var iConn internet.Connection iConn = session if securitySettings := internet.SecuritySettingsFromContext(ctx); securitySettings != nil { switch securitySettings := securitySettings.(type) { case *v2tls.Config: config := securitySettings.GetTLSConfig() if dest.Address.Family().IsDomain() { config.ServerName = dest.Address.Domain() } tlsConn := tls.Client(iConn, config) iConn = UnreusableConnection{Conn: tlsConn} } } return iConn, nil }
// 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 }
func (this *DefaultSystemDialer) Dial(src v2net.Address, dest v2net.Destination) (net.Conn, error) { dialer := &net.Dialer{ Timeout: time.Second * 60, DualStack: true, } if src != nil && src != v2net.AnyIP { var addr net.Addr if dest.Network == v2net.Network_TCP { addr = &net.TCPAddr{ IP: src.IP(), Port: 0, } } else { addr = &net.UDPAddr{ IP: src.IP(), Port: 0, } } dialer.LocalAddr = addr } return dialer.Dial(dest.Network.SystemString(), dest.NetAddr()) }
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 }
// 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 }
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 }
func Dial(src v2net.Address, dest v2net.Destination) (internet.Connection, error) { log.Info("WebSocket|Dailer: Creating connection to ", dest) if src == nil { src = v2net.AnyIP } id := src.String() + "-" + dest.NetAddr() var conn *wsconn if dest.IsTCP() && effectiveConfig.ConnectionReuse { connt := globalCache.Get(id) if connt != nil { conn = connt.(*wsconn) } } if conn == nil { var err error conn, err = wsDial(src, dest) if err != nil { log.Warning("WebSocket|Dialer: Dial failed: ", err) return nil, err } } return NewConnection(id, conn, globalCache), nil }
func (w *udpWorker) callback(b *buf.Buffer, source v2net.Destination, originalDest v2net.Destination) { conn, existing := w.getConnection(source) conn.input <- b.Bytes() if !existing { go func() { ctx := w.ctx ctx, cancel := context.WithCancel(ctx) conn.cancel = cancel if originalDest.IsValid() { ctx = proxy.ContextWithOriginalDestination(ctx, originalDest) } if len(w.tag) > 0 { ctx = proxy.ContextWithInboundTag(ctx, w.tag) } ctx = proxy.ContextWithSource(ctx, source) ctx = proxy.ContextWithInboundDestination(ctx, v2net.UDPDestination(w.address, w.port)) w.proxy.Process(ctx, v2net.Network_UDP, conn) w.removeConn(source) cancel() }() } }
func DialKCP(src v2net.Address, dest v2net.Destination, options internet.DialerOptions) (internet.Connection, error) { dest.Network = v2net.Network_UDP log.Info("KCP|Dialer: Dialing KCP to ", dest) conn, err := internet.DialToDest(src, dest) if err != nil { log.Error("KCP|Dialer: Failed to dial to dest: ", err) return nil, err } networkSettings, err := options.Stream.GetEffectiveNetworkSettings() if err != nil { log.Error("KCP|Dialer: Failed to get KCP settings: ", err) return nil, err } kcpSettings := networkSettings.(*Config) cpip, err := kcpSettings.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, kcpSettings) session.FetchInputFrom(conn) var iConn internet.Connection iConn = session if options.Stream != nil && options.Stream.HasSecuritySettings() { securitySettings, err := options.Stream.GetEffectiveSecuritySettings() if err != nil { log.Error("KCP|Dialer: Failed to get security settings: ", err) return nil, err } switch securitySettings := securitySettings.(type) { case *v2tls.Config: config := securitySettings.GetTLSConfig() if dest.Address.Family().IsDomain() { config.ServerName = dest.Address.Domain() } tlsConn := tls.Client(conn, config) iConn = v2tls.NewConnection(tlsConn) } } return iConn, nil }
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) }
func DialKCP(src v2net.Address, dest v2net.Destination, options internet.DialerOptions) (internet.Connection, error) { dest.Network = v2net.Network_UDP log.Info("KCP|Dialer: Dialing KCP to ", dest) id := internal.NewConnectionId(src, dest) conn := globalPool.Get(id) if conn == nil { rawConn, err := internet.DialToDest(src, dest) if err != nil { log.Error("KCP|Dialer: Failed to dial to dest: ", err) return nil, err } c := &ClientConnection{ Conn: rawConn, id: id, } go c.Run() conn = c } networkSettings, err := options.Stream.GetEffectiveNetworkSettings() if err != nil { log.Error("KCP|Dialer: Failed to get KCP settings: ", err) return nil, err } kcpSettings := networkSettings.(*Config) clientConn := conn.(*ClientConnection) header, err := kcpSettings.GetPackerHeader() if err != nil { return nil, errors.Base(err).Message("KCP|Dialer: Failed to create packet header.") } security, err := kcpSettings.GetSecurity() if err != nil { return nil, errors.Base(err).Message("KCP|Dialer: Failed to create security.") } clientConn.ResetSecurity(header, security) conv := uint16(atomic.AddUint32(&globalConv, 1)) session := NewConnection(conv, clientConn, globalPool, kcpSettings) var iConn internet.Connection iConn = session if options.Stream != nil && options.Stream.HasSecuritySettings() { securitySettings, err := options.Stream.GetEffectiveSecuritySettings() if err != nil { log.Error("KCP|Dialer: Failed to get security settings: ", err) return nil, err } switch securitySettings := securitySettings.(type) { case *v2tls.Config: config := securitySettings.GetTLSConfig() if dest.Address.Family().IsDomain() { config.ServerName = dest.Address.Domain() } tlsConn := tls.Client(conn, config) iConn = v2tls.NewConnection(tlsConn) } } return iConn, nil }
func (this *SimpleSystemDialer) Dial(src v2net.Address, dest v2net.Destination) (net.Conn, error) { return this.adapter.Dial(dest.Network().String(), dest.NetAddr()) }