diff --git a/common/proxyproto/dialer.go b/common/proxyproto/dialer.go new file mode 100644 index 00000000..f3fba6f4 --- /dev/null +++ b/common/proxyproto/dialer.go @@ -0,0 +1,50 @@ +package proxyproto + +import ( + "context" + "net" + "net/netip" + + "github.com/sagernet/sing-box/adapter" + E "github.com/sagernet/sing/common/exceptions" + M "github.com/sagernet/sing/common/metadata" + N "github.com/sagernet/sing/common/network" + + "github.com/pires/go-proxyproto" +) + +var _ N.Dialer = (*Dialer)(nil) + +type Dialer struct { + N.Dialer +} + +func (d *Dialer) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) { + switch N.NetworkName(network) { + case N.NetworkTCP: + conn, err := d.Dialer.DialContext(ctx, network, destination) + if err != nil { + return nil, err + } + var source M.Socksaddr + metadata := adapter.ContextFrom(ctx) + if metadata != nil { + source = metadata.Source + } + if !source.IsValid() { + source = M.SocksaddrFromNet(conn.LocalAddr()) + } + if destination.Addr.Is6() { + source = M.SocksaddrFrom(netip.AddrFrom16(source.Addr.As16()), source.Port) + } + h := proxyproto.HeaderProxyFromAddrs(1, source.TCPAddr(), destination.TCPAddr()) + _, err = h.WriteTo(conn) + if err != nil { + conn.Close() + return nil, E.Cause(err, "write proxy protocol header") + } + return conn, nil + default: + return d.Dialer.DialContext(ctx, network, destination) + } +} diff --git a/common/proxyproto/listener.go b/common/proxyproto/listener.go new file mode 100644 index 00000000..e70e097e --- /dev/null +++ b/common/proxyproto/listener.go @@ -0,0 +1,40 @@ +package proxyproto + +import ( + std_bufio "bufio" + "net" + + "github.com/sagernet/sing/common/buf" + "github.com/sagernet/sing/common/bufio" + M "github.com/sagernet/sing/common/metadata" + + "github.com/pires/go-proxyproto" +) + +type Listener struct { + net.Listener +} + +func (l *Listener) Accept() (net.Conn, error) { + conn, err := l.Listener.Accept() + if err != nil { + return nil, err + } + bufReader := std_bufio.NewReader(conn) + header, err := proxyproto.Read(bufReader) + if err != nil { + return nil, err + } + if bufReader.Buffered() > 0 { + cache := buf.NewSize(bufReader.Buffered()) + _, err = cache.ReadFullFrom(bufReader, cache.FreeLen()) + if err != nil { + return nil, err + } + conn = bufio.NewCachedConn(conn, cache) + } + return &bufio.AddrConn{Conn: conn, Metadata: M.Metadata{ + Source: M.SocksaddrFromNet(header.SourceAddr), + Destination: M.SocksaddrFromNet(header.DestinationAddr), + }}, nil +} diff --git a/go.mod b/go.mod index dc7d8923..73602fc5 100644 --- a/go.mod +++ b/go.mod @@ -16,6 +16,7 @@ require ( github.com/hashicorp/yamux v0.1.1 github.com/logrusorgru/aurora v2.0.3+incompatible github.com/oschwald/maxminddb-golang v1.10.0 + github.com/pires/go-proxyproto v0.6.2 github.com/sagernet/certmagic v0.0.0-20220819042630-4a57f8b6853a github.com/sagernet/netlink v0.0.0-20220820041223-3cd8365d17ac github.com/sagernet/quic-go v0.0.0-20220818150011-de611ab3e2bb diff --git a/go.sum b/go.sum index 8fab3c52..087ee15b 100644 --- a/go.sum +++ b/go.sum @@ -121,6 +121,8 @@ github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1y github.com/onsi/gomega v1.13.0 h1:7lLHu94wT9Ij0o6EWWclhu0aOh32VxhkwEJvzuWPeak= github.com/oschwald/maxminddb-golang v1.10.0 h1:Xp1u0ZhqkSuopaKmk1WwHtjF0H9Hd9181uj2MQ5Vndg= github.com/oschwald/maxminddb-golang v1.10.0/go.mod h1:Y2ELenReaLAZ0b400URyGwvYxHV1dLIxBuyOsyYjHK0= +github.com/pires/go-proxyproto v0.6.2 h1:KAZ7UteSOt6urjme6ZldyFm4wDe/z0ZUP0Yv0Dos0d8= +github.com/pires/go-proxyproto v0.6.2/go.mod h1:Odh9VFOZJCf9G8cLW5o435Xf1J95Jw9Gw5rnCjcwzAY= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= diff --git a/inbound/default.go b/inbound/default.go index 5471f382..1f03fbc8 100644 --- a/inbound/default.go +++ b/inbound/default.go @@ -9,6 +9,7 @@ import ( "time" "github.com/sagernet/sing-box/adapter" + "github.com/sagernet/sing-box/common/proxyproto" "github.com/sagernet/sing-box/common/settings" C "github.com/sagernet/sing-box/constant" "github.com/sagernet/sing-box/log" @@ -45,7 +46,7 @@ type myInboundAdapter struct { // internal - tcpListener *net.TCPListener + tcpListener net.Listener udpConn *net.UDPConn udpAddr M.Socksaddr packetAccess sync.RWMutex @@ -101,10 +102,10 @@ func (a *myInboundAdapter) Start() error { return nil } -func (a *myInboundAdapter) ListenTCP() (*net.TCPListener, error) { +func (a *myInboundAdapter) ListenTCP() (net.Listener, error) { var err error bindAddr := M.SocksaddrFrom(netip.Addr(a.listenOptions.Listen), a.listenOptions.ListenPort) - var tcpListener *net.TCPListener + var tcpListener net.Listener if !a.listenOptions.TCPFastOpen { tcpListener, err = net.ListenTCP(M.NetworkFromNetAddr(N.NetworkTCP, bindAddr.Addr), bindAddr.TCPAddr()) } else { @@ -113,11 +114,15 @@ func (a *myInboundAdapter) ListenTCP() (*net.TCPListener, error) { if err == nil { a.logger.Info("tcp server started at ", tcpListener.Addr()) } + if a.listenOptions.ProxyProtocol { + a.logger.Debug("proxy protocol enabled") + tcpListener = &proxyproto.Listener{Listener: tcpListener} + } a.tcpListener = tcpListener return tcpListener, err } -func (a *myInboundAdapter) ListenUDP() (*net.UDPConn, error) { +func (a *myInboundAdapter) ListenUDP() (net.PacketConn, error) { bindAddr := M.SocksaddrFrom(netip.Addr(a.listenOptions.Listen), a.listenOptions.ListenPort) udpConn, err := net.ListenUDP(M.NetworkFromNetAddr(N.NetworkUDP, bindAddr.Addr), bindAddr.UDPAddr()) if err != nil { @@ -135,7 +140,7 @@ func (a *myInboundAdapter) Close() error { err = a.clearSystemProxy() } return E.Errors(err, common.Close( - common.PtrOrNil(a.tcpListener), + a.tcpListener, common.PtrOrNil(a.udpConn), )) } @@ -168,7 +173,7 @@ func (a *myInboundAdapter) newPacketConnection(ctx context.Context, conn N.Packe func (a *myInboundAdapter) loopTCPIn() { tcpListener := a.tcpListener for { - conn, err := tcpListener.AcceptTCP() + conn, err := tcpListener.Accept() if err != nil { return } @@ -183,8 +188,15 @@ func (a *myInboundAdapter) createMetadata(conn net.Conn, metadata adapter.Inboun metadata.SniffOverrideDestination = a.listenOptions.SniffOverrideDestination metadata.DomainStrategy = dns.DomainStrategy(a.listenOptions.DomainStrategy) metadata.Network = N.NetworkTCP - metadata.Source = M.SocksaddrFromNet(conn.RemoteAddr()) - metadata.OriginDestination = M.SocksaddrFromNet(conn.LocalAddr()) + if !metadata.Source.IsValid() { + metadata.Source = M.SocksaddrFromNet(conn.RemoteAddr()) + } + if !metadata.Destination.IsValid() { + metadata.Destination = M.SocksaddrFromNet(conn.LocalAddr()) + } + if tcpConn, isTCP := common.Cast[*net.TCPConn](conn); isTCP { + metadata.OriginDestination = M.SocksaddrFromNet(tcpConn.LocalAddr()) + } return metadata } diff --git a/inbound/hysteria.go b/inbound/hysteria.go index 47e4d352..d7732e20 100644 --- a/inbound/hysteria.go +++ b/inbound/hysteria.go @@ -5,8 +5,6 @@ package inbound import ( "bytes" "context" - "net" - "net/netip" "sync" "github.com/sagernet/quic-go" @@ -26,23 +24,18 @@ import ( var _ adapter.Inbound = (*Hysteria)(nil) type Hysteria struct { - ctx context.Context - router adapter.Router - logger log.ContextLogger - tag string - listenOptions option.ListenOptions - quicConfig *quic.Config - tlsConfig *TLSConfig - authKey []byte - xplusKey []byte - sendBPS uint64 - recvBPS uint64 - udpListener net.PacketConn - listener quic.Listener - udpAccess sync.RWMutex - udpSessionId uint32 - udpSessions map[uint32]chan *hysteria.UDPMessage - udpDefragger hysteria.Defragger + myInboundAdapter + quicConfig *quic.Config + tlsConfig *TLSConfig + authKey []byte + xplusKey []byte + sendBPS uint64 + recvBPS uint64 + listener quic.Listener + udpAccess sync.RWMutex + udpSessionId uint32 + udpSessions map[uint32]chan *hysteria.UDPMessage + udpDefragger hysteria.Defragger } func NewHysteria(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.HysteriaInboundOptions) (*Hysteria, error) { @@ -101,17 +94,21 @@ func NewHysteria(ctx context.Context, router adapter.Router, logger log.ContextL return nil, E.New("invalid down speed") } inbound := &Hysteria{ - ctx: ctx, - router: router, - logger: logger, - tag: tag, - quicConfig: quicConfig, - listenOptions: options.ListenOptions, - authKey: auth, - xplusKey: xplus, - sendBPS: up, - recvBPS: down, - udpSessions: make(map[uint32]chan *hysteria.UDPMessage), + myInboundAdapter: myInboundAdapter{ + protocol: C.TypeHysteria, + network: []string{N.NetworkUDP}, + ctx: ctx, + router: router, + logger: logger, + tag: tag, + listenOptions: options.ListenOptions, + }, + quicConfig: quicConfig, + authKey: auth, + xplusKey: xplus, + sendBPS: up, + recvBPS: down, + udpSessions: make(map[uint32]chan *hysteria.UDPMessage), } if options.TLS == nil || !options.TLS.Enabled { return nil, C.ErrTLSRequired @@ -127,19 +124,8 @@ func NewHysteria(ctx context.Context, router adapter.Router, logger log.ContextL return inbound, nil } -func (h *Hysteria) Type() string { - return C.TypeHysteria -} - -func (h *Hysteria) Tag() string { - return h.tag -} - func (h *Hysteria) Start() error { - listenAddr := M.SocksaddrFrom(netip.Addr(h.listenOptions.Listen), h.listenOptions.ListenPort) - var packetConn net.PacketConn - var err error - packetConn, err = net.ListenUDP(M.NetworkFromNetAddr("udp", listenAddr.Addr), listenAddr.UDPAddr()) + packetConn, err := h.myInboundAdapter.ListenUDP() if err != nil { return err } @@ -147,7 +133,6 @@ func (h *Hysteria) Start() error { packetConn = hysteria.NewXPlusPacketConn(packetConn, h.xplusKey) packetConn = &hysteria.PacketConnWrapper{PacketConn: packetConn} } - h.udpListener = packetConn err = h.tlsConfig.Start() if err != nil { return err @@ -316,7 +301,7 @@ func (h *Hysteria) Close() error { h.udpSessions = make(map[uint32]chan *hysteria.UDPMessage) h.udpAccess.Unlock() return common.Close( - h.udpListener, + &h.myInboundAdapter, h.listener, common.PtrOrNil(h.tlsConfig), ) diff --git a/option/direct.go b/option/direct.go index a953bed8..77cd0a06 100644 --- a/option/direct.go +++ b/option/direct.go @@ -11,4 +11,5 @@ type DirectOutboundOptions struct { OutboundDialerOptions OverrideAddress string `json:"override_address,omitempty"` OverridePort uint16 `json:"override_port,omitempty"` + ProxyProtocol uint8 `json:"proxy_protocol,omitempty"` } diff --git a/option/inbound.go b/option/inbound.go index 2ac440c5..5a5ae9e1 100644 --- a/option/inbound.go +++ b/option/inbound.go @@ -106,9 +106,10 @@ type InboundOptions struct { } type ListenOptions struct { - Listen ListenAddress `json:"listen"` - ListenPort uint16 `json:"listen_port,omitempty"` - TCPFastOpen bool `json:"tcp_fast_open,omitempty"` - UDPTimeout int64 `json:"udp_timeout,omitempty"` + Listen ListenAddress `json:"listen"` + ListenPort uint16 `json:"listen_port,omitempty"` + TCPFastOpen bool `json:"tcp_fast_open,omitempty"` + UDPTimeout int64 `json:"udp_timeout,omitempty"` + ProxyProtocol bool `json:"proxy_protocol,omitempty"` InboundOptions } diff --git a/option/simple.go b/option/simple.go index e262c3b3..fc2c0bb4 100644 --- a/option/simple.go +++ b/option/simple.go @@ -27,7 +27,7 @@ type SocksOutboundOptions struct { type HTTPOutboundOptions struct { OutboundDialerOptions ServerOptions - Username string `json:"username,omitempty"` - Password string `json:"password,omitempty"` - TLSOptions *OutboundTLSOptions `json:"tls,omitempty"` + Username string `json:"username,omitempty"` + Password string `json:"password,omitempty"` + TLS *OutboundTLSOptions `json:"tls,omitempty"` } diff --git a/outbound/builder.go b/outbound/builder.go index 5644a00a..fff9eb42 100644 --- a/outbound/builder.go +++ b/outbound/builder.go @@ -16,7 +16,7 @@ func New(ctx context.Context, router adapter.Router, logger log.ContextLogger, o } switch options.Type { case C.TypeDirect: - return NewDirect(router, logger, options.Tag, options.DirectOptions), nil + return NewDirect(router, logger, options.Tag, options.DirectOptions) case C.TypeBlock: return NewBlock(logger, options.Tag), nil case C.TypeDNS: diff --git a/outbound/direct.go b/outbound/direct.go index c95de9d7..e01613ab 100644 --- a/outbound/direct.go +++ b/outbound/direct.go @@ -3,14 +3,18 @@ package outbound import ( "context" "net" + "net/netip" "github.com/sagernet/sing-box/adapter" "github.com/sagernet/sing-box/common/dialer" C "github.com/sagernet/sing-box/constant" "github.com/sagernet/sing-box/log" "github.com/sagernet/sing-box/option" + E "github.com/sagernet/sing/common/exceptions" M "github.com/sagernet/sing/common/metadata" N "github.com/sagernet/sing/common/network" + + "github.com/pires/go-proxyproto" ) var _ adapter.Outbound = (*Direct)(nil) @@ -20,9 +24,10 @@ type Direct struct { dialer N.Dialer overrideOption int overrideDestination M.Socksaddr + proxyProto uint8 } -func NewDirect(router adapter.Router, logger log.ContextLogger, tag string, options option.DirectOutboundOptions) *Direct { +func NewDirect(router adapter.Router, logger log.ContextLogger, tag string, options option.DirectOutboundOptions) (*Direct, error) { outbound := &Direct{ myOutboundAdapter: myOutboundAdapter{ protocol: C.TypeDirect, @@ -31,7 +36,11 @@ func NewDirect(router adapter.Router, logger log.ContextLogger, tag string, opti logger: logger, tag: tag, }, - dialer: dialer.NewOutbound(router, options.OutboundDialerOptions), + dialer: dialer.NewOutbound(router, options.OutboundDialerOptions), + proxyProto: options.ProxyProtocol, + } + if options.ProxyProtocol > 2 { + return nil, E.New("invalid proxy protocol option: ", options.ProxyProtocol) } if options.OverrideAddress != "" && options.OverridePort != 0 { outbound.overrideOption = 1 @@ -43,11 +52,12 @@ func NewDirect(router adapter.Router, logger log.ContextLogger, tag string, opti outbound.overrideOption = 3 outbound.overrideDestination = M.Socksaddr{Port: options.OverridePort} } - return outbound + return outbound, nil } func (h *Direct) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) { ctx, metadata := adapter.AppendContext(ctx) + originDestination := metadata.Destination metadata.Outbound = h.tag metadata.Destination = destination switch h.overrideOption { @@ -60,13 +70,33 @@ func (h *Direct) DialContext(ctx context.Context, network string, destination M. case 3: destination.Port = h.overrideDestination.Port } + network = N.NetworkName(network) switch network { case N.NetworkTCP: h.logger.InfoContext(ctx, "outbound connection to ", destination) case N.NetworkUDP: h.logger.InfoContext(ctx, "outbound packet connection to ", destination) } - return h.dialer.DialContext(ctx, network, destination) + conn, err := h.dialer.DialContext(ctx, network, destination) + if err != nil { + return nil, err + } + if h.proxyProto > 0 { + source := metadata.Source + if !source.IsValid() { + source = M.SocksaddrFromNet(conn.LocalAddr()) + } + if originDestination.Addr.Is6() { + source = M.SocksaddrFrom(netip.AddrFrom16(source.Addr.As16()), source.Port) + } + header := proxyproto.HeaderProxyFromAddrs(h.proxyProto, source.TCPAddr(), originDestination.TCPAddr()) + _, err = header.WriteTo(conn) + if err != nil { + conn.Close() + return nil, E.Cause(err, "write proxy protocol header") + } + } + return conn, nil } func (h *Direct) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) { diff --git a/outbound/http.go b/outbound/http.go index a570fdc2..95e19430 100644 --- a/outbound/http.go +++ b/outbound/http.go @@ -24,7 +24,7 @@ type HTTP struct { } func NewHTTP(router adapter.Router, logger log.ContextLogger, tag string, options option.HTTPOutboundOptions) (*HTTP, error) { - detour, err := dialer.NewTLS(dialer.NewOutbound(router, options.OutboundDialerOptions), options.Server, common.PtrValueOrDefault(options.TLSOptions)) + detour, err := dialer.NewTLS(dialer.NewOutbound(router, options.OutboundDialerOptions), options.Server, common.PtrValueOrDefault(options.TLS)) if err != nil { return nil, err } diff --git a/test/direct_test.go b/test/direct_test.go new file mode 100644 index 00000000..c03b39fe --- /dev/null +++ b/test/direct_test.go @@ -0,0 +1,64 @@ +package main + +import ( + "net/netip" + "testing" + + C "github.com/sagernet/sing-box/constant" + "github.com/sagernet/sing-box/option" +) + +func TestProxyProtocol(t *testing.T) { + startInstance(t, option.Options{ + Log: &option.LogOptions{ + Level: "error", + }, + Inbounds: []option.Inbound{ + { + Type: C.TypeMixed, + Tag: "mixed-in", + MixedOptions: option.HTTPMixedInboundOptions{ + ListenOptions: option.ListenOptions{ + Listen: option.ListenAddress(netip.IPv4Unspecified()), + ListenPort: clientPort, + }, + }, + }, + { + Type: C.TypeDirect, + DirectOptions: option.DirectInboundOptions{ + ListenOptions: option.ListenOptions{ + Listen: option.ListenAddress(netip.IPv4Unspecified()), + ListenPort: serverPort, + ProxyProtocol: true, + }, + }, + }, + }, + Outbounds: []option.Outbound{ + { + Type: C.TypeDirect, + }, + { + Type: C.TypeDirect, + Tag: "trojan-out", + DirectOptions: option.DirectOutboundOptions{ + OverrideAddress: "127.0.0.1", + OverridePort: serverPort, + ProxyProtocol: 2, + }, + }, + }, + Route: &option.RouteOptions{ + Rules: []option.Rule{ + { + DefaultOptions: option.DefaultRule{ + Inbound: []string{"mixed-in"}, + Outbound: "trojan-out", + }, + }, + }, + }, + }) + testSuit(t, clientPort, testPort) +} diff --git a/test/go.mod b/test/go.mod index bb060133..5728caa6 100644 --- a/test/go.mod +++ b/test/go.mod @@ -10,11 +10,11 @@ require ( github.com/docker/docker v20.10.17+incompatible github.com/docker/go-connections v0.4.0 github.com/gofrs/uuid v4.2.0+incompatible - github.com/sagernet/sing v0.0.0-20220822075357-8b9965b73533 + github.com/sagernet/sing v0.0.0-20220823075935-c333192241ec github.com/sagernet/sing-shadowsocks v0.0.0-20220819002358-7461bb09a8f6 github.com/spyzhov/ajson v0.7.1 github.com/stretchr/testify v1.8.0 - golang.org/x/net v0.0.0-20220812174116-3211cb980234 + golang.org/x/net v0.0.0-20220822230855-b0a4917ee28c ) require ( @@ -51,6 +51,7 @@ require ( github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.0.2 // indirect github.com/oschwald/maxminddb-golang v1.10.0 // indirect + github.com/pires/go-proxyproto v0.6.2 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/sagernet/abx-go v0.0.0-20220819185957-dba1257d738e // indirect diff --git a/test/go.sum b/test/go.sum index 0de900ab..6162c6ad 100644 --- a/test/go.sum +++ b/test/go.sum @@ -141,6 +141,8 @@ github.com/opencontainers/image-spec v1.0.2 h1:9yCKha/T5XdGtO0q9Q9a6T5NUCsTn/DrB github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= github.com/oschwald/maxminddb-golang v1.10.0 h1:Xp1u0ZhqkSuopaKmk1WwHtjF0H9Hd9181uj2MQ5Vndg= github.com/oschwald/maxminddb-golang v1.10.0/go.mod h1:Y2ELenReaLAZ0b400URyGwvYxHV1dLIxBuyOsyYjHK0= +github.com/pires/go-proxyproto v0.6.2 h1:KAZ7UteSOt6urjme6ZldyFm4wDe/z0ZUP0Yv0Dos0d8= +github.com/pires/go-proxyproto v0.6.2/go.mod h1:Odh9VFOZJCf9G8cLW5o435Xf1J95Jw9Gw5rnCjcwzAY= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -160,8 +162,8 @@ github.com/sagernet/quic-go v0.0.0-20220818150011-de611ab3e2bb h1:wc0yQ+SBn4TaTY github.com/sagernet/quic-go v0.0.0-20220818150011-de611ab3e2bb/go.mod h1:MIccjRKnPTjWwAOpl+AUGWOkzyTd9tERytudxu+1ra4= github.com/sagernet/sing v0.0.0-20220812082120-05f9836bff8f/go.mod h1:QVsS5L/ZA2Q5UhQwLrn0Trw+msNd/NPGEhBKR/ioWiY= github.com/sagernet/sing v0.0.0-20220817130738-ce854cda8522/go.mod h1:QVsS5L/ZA2Q5UhQwLrn0Trw+msNd/NPGEhBKR/ioWiY= -github.com/sagernet/sing v0.0.0-20220822075357-8b9965b73533 h1:oOOlmOE6QAGtkYeNyboTm/RzPO8g9mCybg0xveWxvnI= -github.com/sagernet/sing v0.0.0-20220822075357-8b9965b73533/go.mod h1:kZvzh1VDa/Dg/Bt5WaYKU0jl5ept8KKDpl3Ay4gRtRQ= +github.com/sagernet/sing v0.0.0-20220823075935-c333192241ec h1:71B48luR/x6uGug+8VN1oUwGuBNgpb7lgb0q9FjgsVw= +github.com/sagernet/sing v0.0.0-20220823075935-c333192241ec/go.mod h1:kZvzh1VDa/Dg/Bt5WaYKU0jl5ept8KKDpl3Ay4gRtRQ= github.com/sagernet/sing-dns v0.0.0-20220822023312-3e086b06d666 h1:XUTocA/Ek0dFxUX+xJCWMPPFZCn2GC/uLrBjTSr1vHY= github.com/sagernet/sing-dns v0.0.0-20220822023312-3e086b06d666/go.mod h1:eDyH7AJmqBGjZQdQmpZIzlbTREudZuWDExMuGKgjRVM= github.com/sagernet/sing-shadowsocks v0.0.0-20220819002358-7461bb09a8f6 h1:JJfDeYYhWunvtxsU/mOVNTmFQmnzGx9dY034qG6G3g4= @@ -241,8 +243,8 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220630215102-69896b714898/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.0.0-20220812174116-3211cb980234 h1:RDqmgfe7SvlMWoqC3xwQ2blLO3fcWcxMa3eBLRdRW7E= -golang.org/x/net v0.0.0-20220812174116-3211cb980234/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.0.0-20220822230855-b0a4917ee28c h1:JVAXQ10yGGVbSyoer5VILysz6YKjdNT2bsvlayjqhes= +golang.org/x/net v0.0.0-20220822230855-b0a4917ee28c/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=