diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index c07983a4..ccc2fab6 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,4 +1,4 @@ -name: Test +name: Tests and Checkings on: push: @@ -8,6 +8,7 @@ on: jobs: check-assets: runs-on: ubuntu-latest + if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name steps: - name: Restore Geodat Cache uses: actions/cache/restore@v5 @@ -36,6 +37,7 @@ jobs: check-proto: runs-on: ubuntu-latest + if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name steps: - name: Checkout codebase uses: actions/checkout@v6 @@ -50,8 +52,28 @@ jobs: fi done + check-format: + runs-on: ubuntu-latest + if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name + permissions: + contents: read + steps: + - name: Checkout codebase + uses: actions/checkout@v6 + - name: Set up Go + uses: actions/setup-go@v6 + with: + go-version-file: go.mod + check-latest: true + cache: false + - name: Check Format + run: | + go install -v mvdan.cc/gofumpt@latest + go run ./infra/vformat/main.go -mode check -pwd ./ + test: needs: check-assets + if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name permissions: contents: read runs-on: ${{ matrix.os }} diff --git a/app/commander/commander.go b/app/commander/commander.go index 3b541f92..ac7bd835 100644 --- a/app/commander/commander.go +++ b/app/commander/commander.go @@ -3,15 +3,15 @@ package commander import ( "context" "net" + "strings" "sync" - "strings" "github.com/xtls/xray-core/common" "github.com/xtls/xray-core/common/errors" "github.com/xtls/xray-core/common/signal/done" core "github.com/xtls/xray-core/core" "github.com/xtls/xray-core/features/outbound" - "github.com/xtls/xray-core/transport/internet" + "github.com/xtls/xray-core/transport/internet" "google.golang.org/grpc" ) @@ -69,16 +69,15 @@ func (c *Commander) Start() error { } c.Unlock() - var listen = func(listener net.Listener) { + listen := func(listener net.Listener) { if err := c.server.Serve(listener); err != nil { errors.LogErrorInner(context.Background(), err, "failed to start grpc server") } } - if len(c.listen) > 0 { var addr net.Addr - + if strings.HasPrefix(c.listen, "/") || strings.HasPrefix(c.listen, "@") { addr = &net.UnixAddr{Name: c.listen, Net: "unix"} } else { @@ -89,7 +88,7 @@ func (c *Commander) Start() error { } addr = tcpAddr } - l, err := internet.ListenSystem(context.Background(), addr, nil) + l, err := internet.ListenSystem(context.Background(), addr, nil) if err != nil { errors.LogErrorInner(context.Background(), err, "API server failed to listen on ", c.listen) return err diff --git a/app/dns/cache_controller.go b/app/dns/cache_controller.go index a303b264..6e2fd6c9 100644 --- a/app/dns/cache_controller.go +++ b/app/dns/cache_controller.go @@ -139,7 +139,8 @@ func (c *CacheController) writeAndShrink(expiredKeys []string) { if lenAfter == 0 { if c.highWatermark >= minSizeForEmptyRebuild { - errors.LogDebug(context.Background(), c.name, + errors.LogDebug( + context.Background(), c.name, " rebuilding empty cache map to reclaim memory.", " size_before_cleanup=", lenBefore, " peak_size_before_rebuild=", c.highWatermark, @@ -153,7 +154,8 @@ func (c *CacheController) writeAndShrink(expiredKeys []string) { if reductionFromPeak := c.highWatermark - lenAfter; reductionFromPeak > shrinkAbsoluteThreshold && float64(reductionFromPeak) > float64(c.highWatermark)*shrinkRatioThreshold { - errors.LogDebug(context.Background(), c.name, + errors.LogDebug( + context.Background(), c.name, " shrinking cache map to reclaim memory.", " new_size=", lenAfter, " peak_size_before_shrink=", c.highWatermark, @@ -165,7 +167,6 @@ func (c *CacheController) writeAndShrink(expiredKeys []string) { c.highWatermark = lenAfter go c.migrate() } - } type migrationEntry struct { diff --git a/app/dns/dns.go b/app/dns/dns.go index abf6894b..b750fce2 100644 --- a/app/dns/dns.go +++ b/app/dns/dns.go @@ -86,7 +86,7 @@ func New(ctx context.Context, config *Config) (*DNS, error) { return nil, errors.New("failed to create hosts").Base(err) } - var defaultTag = config.Tag + defaultTag := config.Tag if len(config.Tag) == 0 { defaultTag = generateRandomTag() } @@ -139,7 +139,7 @@ func New(ctx context.Context, config *Config) (*DNS, error) { serveExpiredTTL = *ns.ServeExpiredTTL } - var tag = defaultTag + tag := defaultTag if len(ns.Tag) > 0 { tag = ns.Tag } diff --git a/app/dns/dnscommon_test.go b/app/dns/dnscommon_test.go index fc73d20d..64e98760 100644 --- a/app/dns/dnscommon_test.go +++ b/app/dns/dnscommon_test.go @@ -25,7 +25,8 @@ func Test_parseResponse(t *testing.T) { ans = new(dns.Msg) ans.Id = 1 - ans.Answer = append(ans.Answer, + ans.Answer = append( + ans.Answer, common.Must2(dns.NewRR("google.com. IN CNAME m.test.google.com")), common.Must2(dns.NewRR("google.com. IN CNAME fake.google.com")), common.Must2(dns.NewRR("google.com. IN A 8.8.8.8")), @@ -35,7 +36,8 @@ func Test_parseResponse(t *testing.T) { ans = new(dns.Msg) ans.Id = 2 - ans.Answer = append(ans.Answer, + ans.Answer = append( + ans.Answer, common.Must2(dns.NewRR("google.com. IN CNAME m.test.google.com")), common.Must2(dns.NewRR("google.com. IN CNAME fake.google.com")), common.Must2(dns.NewRR("google.com. IN CNAME m.test.google.com")), diff --git a/app/dns/fakedns/fakedns_test.go b/app/dns/fakedns/fakedns_test.go index f9a8449c..0cea3919 100644 --- a/app/dns/fakedns/fakedns_test.go +++ b/app/dns/fakedns/fakedns_test.go @@ -129,15 +129,16 @@ func TestFakeDnsHolderCreateMappingAndRollOver(t *testing.T) { } func TestFakeDNSMulti(t *testing.T) { - fakeMulti, err := NewFakeDNSHolderMulti(&FakeDnsPoolMulti{ - Pools: []*FakeDnsPool{{ - IpPool: "240.0.0.0/12", - LruSize: 256, - }, { - IpPool: "fddd:c5b4:ff5f:f4f0::/64", - LruSize: 256, - }}, - }, + fakeMulti, err := NewFakeDNSHolderMulti( + &FakeDnsPoolMulti{ + Pools: []*FakeDnsPool{{ + IpPool: "240.0.0.0/12", + LruSize: 256, + }, { + IpPool: "fddd:c5b4:ff5f:f4f0::/64", + LruSize: 256, + }}, + }, ) common.Must(err) diff --git a/app/dns/nameserver.go b/app/dns/nameserver.go index 91862453..06882611 100644 --- a/app/dns/nameserver.go +++ b/app/dns/nameserver.go @@ -135,7 +135,7 @@ func NewClient( } } - var timeoutMs = 4000 * time.Millisecond + timeoutMs := 4000 * time.Millisecond if ns.TimeoutMs > 0 { timeoutMs = time.Duration(ns.TimeoutMs) * time.Millisecond } diff --git a/app/dns/nameserver_local.go b/app/dns/nameserver_local.go index 576c259b..4369f89e 100644 --- a/app/dns/nameserver_local.go +++ b/app/dns/nameserver_local.go @@ -18,7 +18,6 @@ type LocalNameServer struct { // QueryIP implements Server. func (s *LocalNameServer) QueryIP(ctx context.Context, domain string, option dns.IPOption) (ips []net.IP, ttl uint32, err error) { - start := time.Now() ips, ttl, err = s.client.LookupIP(domain, option) diff --git a/app/metrics/metrics.go b/app/metrics/metrics.go index a3737384..a2ae2f30 100644 --- a/app/metrics/metrics.go +++ b/app/metrics/metrics.go @@ -85,7 +85,6 @@ func (p *MetricsHandler) Type() interface{} { } func (p *MetricsHandler) Start() error { - // direct listen a port if listen is set if p.listen != "" { TCPlistener, err := net.Listen("tcp", p.listen) diff --git a/app/observatory/burst/burstobserver.go b/app/observatory/burst/burstobserver.go index 9af96a1d..fbcbfdcc 100644 --- a/app/observatory/burst/burstobserver.go +++ b/app/observatory/burst/burstobserver.go @@ -2,7 +2,6 @@ package burst import ( "context" - "sync" "github.com/xtls/xray-core/app/observatory" @@ -72,7 +71,6 @@ func (o *Observer) Start() error { o.hp.StartScheduler(func() ([]string, error) { hs, ok := o.ohm.(outbound.HandlerSelector) if !ok { - return nil, errors.New("outbound.Manager is not a HandlerSelector") } diff --git a/app/observatory/observer.go b/app/observatory/observer.go index 02dbaf13..80d81e22 100644 --- a/app/observatory/observer.go +++ b/app/observatory/observer.go @@ -186,7 +186,7 @@ func (o *Observer) probe(outbound string) ProbeResult { return nil }) if err != nil { - var errorMessage = "the outbound " + outbound + " is dead: GET request failed:" + err.Error() + "with outbound handler report underlying connection failed" + errorMessage := "the outbound " + outbound + " is dead: GET request failed:" + err.Error() + "with outbound handler report underlying connection failed" errors.LogInfoInner(o.ctx, errorCollectorForRequest.UnderlyingError(), errorMessage) return ProbeResult{Alive: false, LastErrorReason: errorMessage} } diff --git a/app/proxyman/command/command.go b/app/proxyman/command/command.go index a86f0921..217b2b4f 100644 --- a/app/proxyman/command/command.go +++ b/app/proxyman/command/command.go @@ -138,7 +138,7 @@ func (s *handlerServer) GetInboundUsers(ctx context.Context, request *GetInbound if len(request.Email) > 0 { return &GetInboundUserResponse{Users: []*protocol.User{protocol.ToProtoUser(um.GetUser(ctx, request.Email))}}, nil } - var result = make([]*protocol.User, 0, 100) + result := make([]*protocol.User, 0, 100) users := um.GetUsers(ctx) for _, u := range users { result = append(result, protocol.ToProtoUser(u)) diff --git a/app/proxyman/inbound/inbound.go b/app/proxyman/inbound/inbound.go index 374a0428..cec93dd4 100644 --- a/app/proxyman/inbound/inbound.go +++ b/app/proxyman/inbound/inbound.go @@ -16,10 +16,10 @@ import ( // Manager manages all inbound handlers. type Manager struct { - access sync.RWMutex + access sync.RWMutex untaggedHandlers []inbound.Handler - taggedHandlers map[string]inbound.Handler - running bool + taggedHandlers map[string]inbound.Handler + running bool } // New returns a new Manager for inbound handlers. diff --git a/app/proxyman/outbound/handler.go b/app/proxyman/outbound/handler.go index 62902c60..7284a848 100644 --- a/app/proxyman/outbound/handler.go +++ b/app/proxyman/outbound/handler.go @@ -348,7 +348,7 @@ func (h *Handler) SetOutboundGateway(ctx context.Context, ob *session.Outbound) errors.LogDebug(ctx, "use inbound source ip as sendthrough: ", inbound.Source.Address.String()) } } - //case addr.Family().IsDomain(): + // case addr.Family().IsDomain(): default: ob.Gateway = addr @@ -396,7 +396,6 @@ func (h *Handler) ProxySettings() *serial.TypedMessage { } func ParseRandomIP(addr net.Address, prefix string) net.Address { - _, ipnet, _ := net.ParseCIDR(addr.IP().String() + "/" + prefix) ones, bits := ipnet.Mask.Size() diff --git a/app/proxyman/outbound/handler_test.go b/app/proxyman/outbound/handler_test.go index b90224f8..70294429 100644 --- a/app/proxyman/outbound/handler_test.go +++ b/app/proxyman/outbound/handler_test.go @@ -22,8 +22,8 @@ import ( ) func TestInterfaces(t *testing.T) { - _ = (outbound.Handler)(new(Handler)) - _ = (outbound.Manager)(new(Manager)) + _ = outbound.Handler(new(Handler)) + _ = outbound.Manager(new(Manager)) } const xrayKey core.XrayKey = 1 @@ -43,7 +43,7 @@ func TestOutboundWithoutStatCounter(t *testing.T) { } v, _ := core.New(config) - v.AddFeature((outbound.Manager)(new(Manager))) + v.AddFeature(outbound.Manager(new(Manager))) ctx := context.WithValue(context.Background(), xrayKey, v) ctx = session.ContextWithOutbounds(ctx, []*session.Outbound{{}}) h, _ := NewHandler(ctx, &core.OutboundHandlerConfig{ @@ -73,7 +73,7 @@ func TestOutboundWithStatCounter(t *testing.T) { } v, _ := core.New(config) - v.AddFeature((outbound.Manager)(new(Manager))) + v.AddFeature(outbound.Manager(new(Manager))) ctx := context.WithValue(context.Background(), xrayKey, v) ctx = session.ContextWithOutbounds(ctx, []*session.Outbound{{}}) h, _ := NewHandler(ctx, &core.OutboundHandlerConfig{ @@ -88,7 +88,6 @@ func TestOutboundWithStatCounter(t *testing.T) { } func TestTagsCache(t *testing.T) { - test_duration := 10 * time.Second threads_num := 50 delay := 10 * time.Millisecond diff --git a/app/proxyman/outbound/outbound.go b/app/proxyman/outbound/outbound.go index 244fcffe..d8654288 100644 --- a/app/proxyman/outbound/outbound.go +++ b/app/proxyman/outbound/outbound.go @@ -162,7 +162,6 @@ func (m *Manager) ListHandlers(ctx context.Context) []outbound.Handler { // Select implements outbound.HandlerSelector. func (m *Manager) Select(selectors []string) []string { - key := strings.Join(selectors, ",") if cache, ok := m.tagsCache.Load(key); ok { return cache.([]string) diff --git a/app/router/command/command.go b/app/router/command/command.go index c0974553..8274d3b4 100644 --- a/app/router/command/command.go +++ b/app/router/command/command.go @@ -58,7 +58,6 @@ func (s *routingServer) AddRule(ctx context.Context, request *AddRuleRequest) (* return &AddRuleResponse{}, bo.AddRule(request.Config, request.ShouldAppend) } return nil, errors.New("unsupported router implementation") - } func (s *routingServer) RemoveRule(ctx context.Context, request *RemoveRuleRequest) (*RemoveRuleResponse, error) { diff --git a/app/router/router.go b/app/router/router.go index df770a3a..97a1d0d5 100644 --- a/app/router/router.go +++ b/app/router/router.go @@ -110,7 +110,6 @@ func (r *Router) PickRoute(ctx routing.Context) (routing.Route, error) { // AddRule implements routing.Router. func (r *Router) AddRule(config *serial.TypedMessage, shouldAppend bool) error { - inst, err := config.GetInstance() if err != nil { return err @@ -227,7 +226,6 @@ func (r *Router) RemoveRule(tag string) error { return nil } return errors.New("empty tag name!") - } // ListRule implements routing.Router diff --git a/app/router/strategy_leastload_test.go b/app/router/strategy_leastload_test.go index 832e0a87..5f7fab41 100644 --- a/app/router/strategy_leastload_test.go +++ b/app/router/strategy_leastload_test.go @@ -85,6 +85,7 @@ func TestSelectLeastExpected(t *testing.T) { t.Errorf("expected: %v, actual: %v", expected, len(ns)) } } + func TestSelectLeastExpected2(t *testing.T) { strategy := &LeastLoadStrategy{ settings: &StrategyLeastLoadConfig{ @@ -102,6 +103,7 @@ func TestSelectLeastExpected2(t *testing.T) { t.Errorf("expected: %v, actual: %v", expected, len(ns)) } } + func TestSelectLeastExpectedAndBaselines(t *testing.T) { strategy := &LeastLoadStrategy{ settings: &StrategyLeastLoadConfig{ @@ -122,6 +124,7 @@ func TestSelectLeastExpectedAndBaselines(t *testing.T) { t.Errorf("expected: %v, actual: %v", expected, len(ns)) } } + func TestSelectLeastExpectedAndBaselines2(t *testing.T) { strategy := &LeastLoadStrategy{ settings: &StrategyLeastLoadConfig{ @@ -142,6 +145,7 @@ func TestSelectLeastExpectedAndBaselines2(t *testing.T) { t.Errorf("expected: %v, actual: %v", expected, len(ns)) } } + func TestSelectLeastLoadBaselines(t *testing.T) { strategy := &LeastLoadStrategy{ settings: &StrategyLeastLoadConfig{ @@ -160,6 +164,7 @@ func TestSelectLeastLoadBaselines(t *testing.T) { t.Errorf("expected: %v, actual: %v", expected, len(ns)) } } + func TestSelectLeastLoadBaselinesNoQualified(t *testing.T) { strategy := &LeastLoadStrategy{ settings: &StrategyLeastLoadConfig{ diff --git a/app/router/webhook.go b/app/router/webhook.go index 535ed294..0c7a3e4d 100644 --- a/app/router/webhook.go +++ b/app/router/webhook.go @@ -16,8 +16,6 @@ import ( routing_session "github.com/xtls/xray-core/features/routing/session" ) - - func ptr[T any](v T) *T { return &v } type event struct { diff --git a/app/stats/stats_test.go b/app/stats/stats_test.go index cdbd404e..a38f554d 100644 --- a/app/stats/stats_test.go +++ b/app/stats/stats_test.go @@ -11,7 +11,7 @@ import ( ) func TestInterface(t *testing.T) { - _ = (stats.Manager)(new(Manager)) + _ = stats.Manager(new(Manager)) } func TestStatsChannelRunnable(t *testing.T) { diff --git a/app/version/version.go b/app/version/version.go index 25d7e6ff..03856051 100644 --- a/app/version/version.go +++ b/app/version/version.go @@ -2,10 +2,11 @@ package version import ( "context" - "github.com/xtls/xray-core/common" - "github.com/xtls/xray-core/common/errors" "strconv" "strings" + + "github.com/xtls/xray-core/common" + "github.com/xtls/xray-core/common/errors" ) type Version struct { diff --git a/common/buf/multi_buffer.go b/common/buf/multi_buffer.go index fcac84d7..a5cc38bc 100644 --- a/common/buf/multi_buffer.go +++ b/common/buf/multi_buffer.go @@ -38,8 +38,8 @@ func MergeMulti(dest MultiBuffer, src MultiBuffer) (MultiBuffer, MultiBuffer) { // MergeBytes merges the given bytes into MultiBuffer and return the new address of the merged MultiBuffer. func MergeBytes(dest MultiBuffer, src []byte) MultiBuffer { n := len(dest) - if n > 0 && !(dest)[n-1].IsFull() { - nBytes, _ := (dest)[n-1].Write(src) + if n > 0 && !dest[n-1].IsFull() { + nBytes, _ := dest[n-1].Write(src) src = src[nBytes:] } diff --git a/common/buf/reader_test.go b/common/buf/reader_test.go index d2e95169..58b6c72f 100644 --- a/common/buf/reader_test.go +++ b/common/buf/reader_test.go @@ -121,11 +121,11 @@ func TestPacketReader_ReadMultiBuffer(t *testing.T) { } func TestReaderInterface(t *testing.T) { - _ = (io.Reader)(new(ReadVReader)) - _ = (Reader)(new(ReadVReader)) + _ = io.Reader(new(ReadVReader)) + _ = Reader(new(ReadVReader)) - _ = (Reader)(new(BufferedReader)) - _ = (io.Reader)(new(BufferedReader)) - _ = (io.ByteReader)(new(BufferedReader)) - _ = (io.WriterTo)(new(BufferedReader)) + _ = Reader(new(BufferedReader)) + _ = io.Reader(new(BufferedReader)) + _ = io.ByteReader(new(BufferedReader)) + _ = io.WriterTo(new(BufferedReader)) } diff --git a/common/buf/readv_posix.go b/common/buf/readv_posix.go index e8b3bd7f..860030ed 100644 --- a/common/buf/readv_posix.go +++ b/common/buf/readv_posix.go @@ -19,7 +19,7 @@ func (r *posixReader) Init(bs []*Buffer) { } for idx, b := range bs { iovecs = append(iovecs, syscall.Iovec{ - Base: &(b.v[0]), + Base: &b.v[0], }) iovecs[idx].SetLen(int(Size)) } diff --git a/common/geodata/ip_matcher_test.go b/common/geodata/ip_matcher_test.go index 829c455d..fc6a016d 100644 --- a/common/geodata/ip_matcher_test.go +++ b/common/geodata/ip_matcher_test.go @@ -315,7 +315,7 @@ func TestIPMatcherAnyMatchAndMatches(t *testing.T) { } if !matcher.AnyMatch([]net.IP{ - net.IP{}, + {}, ip("1.1.1.1"), ip("8.8.8.8"), }) { @@ -345,7 +345,7 @@ func TestIPMatcherAnyMatchAndMatches(t *testing.T) { if matcher.Matches([]net.IP{ ip("8.8.8.8"), - net.IP{}, + {}, }) { t.Fatal("expect Matches to be false when any IP is invalid") } @@ -362,7 +362,7 @@ func TestIPMatcherFilterIPs(t *testing.T) { } matched, unmatched := matcher.FilterIPs([]net.IP{ - net.IP{}, + {}, ip("8.8.8.8"), ip("91.108.255.254"), ip("1.1.1.1"), diff --git a/common/log/logger.go b/common/log/logger.go index 538eda2d..1b4eda86 100644 --- a/common/log/logger.go +++ b/common/log/logger.go @@ -98,7 +98,6 @@ func (l *generalLogger) run() { } func (l *generalLogger) Handle(msg Message) { - select { case l.buffer <- msg: default: diff --git a/common/platform/platform_test.go b/common/platform/platform_test.go index ae823217..854c397f 100644 --- a/common/platform/platform_test.go +++ b/common/platform/platform_test.go @@ -36,9 +36,10 @@ func TestNormalizeEnvName(t *testing.T) { } func TestEnvFlag(t *testing.T) { - if v := (EnvFlag{ + v := EnvFlag{ Name: "xxxxx.y", - }.GetValueAsInt(10)); v != 10 { + }.GetValueAsInt(10) + if v != 10 { t.Error("env value: ", v) } } diff --git a/common/protocol/id.go b/common/protocol/id.go index 211fc578..5dd7a2f0 100644 --- a/common/protocol/id.go +++ b/common/protocol/id.go @@ -19,7 +19,7 @@ type ID struct { // Equals returns true if this ID equals to the other one. func (id *ID) Equals(another *ID) bool { - return id.uuid.Equals(&(another.uuid)) + return id.uuid.Equals(&another.uuid) } func (id *ID) Bytes() []byte { diff --git a/common/protocol/quic/sniff_test.go b/common/protocol/quic/sniff_test.go index 8a85ea87..8c6fbef4 100644 --- a/common/protocol/quic/sniff_test.go +++ b/common/protocol/quic/sniff_test.go @@ -229,7 +229,7 @@ func TestSniffQUICComplex(t *testing.T) { t.Errorf("SniffQUIC() error = %v, wantErr %v", err, tt.wantErr) return } - if (errors.Is(err, protocol.ErrProtoNeedMoreData)) != tt.needsMoreData { + if errors.Is(err, protocol.ErrProtoNeedMoreData) != tt.needsMoreData { t.Errorf("SniffQUIC() error = %v, expectsNoClue %v", err, tt.needsMoreData) return } diff --git a/common/protocol/server_spec.go b/common/protocol/server_spec.go index d3ab0089..5c1b99f4 100644 --- a/common/protocol/server_spec.go +++ b/common/protocol/server_spec.go @@ -5,8 +5,8 @@ import ( ) type ServerSpec struct { - Destination net.Destination - User *MemoryUser + Destination net.Destination + User *MemoryUser } func NewServerSpec(dest net.Destination, user *MemoryUser) *ServerSpec { diff --git a/common/reflect/marshal.go b/common/reflect/marshal.go index 127dc8e0..a2888010 100644 --- a/common/reflect/marshal.go +++ b/common/reflect/marshal.go @@ -228,7 +228,6 @@ func isValueKind(kind reflect.Kind) bool { } func marshalInterface(v interface{}, ignoreNullValue bool, insertTypeInfo bool) interface{} { - if r, ok := marshalKnownType(v, ignoreNullValue, insertTypeInfo); ok { return r } diff --git a/common/reflect/marshal_test.go b/common/reflect/marshal_test.go index 1a897ef7..d560f1b4 100644 --- a/common/reflect/marshal_test.go +++ b/common/reflect/marshal_test.go @@ -27,7 +27,6 @@ func TestMashalAccount(t *testing.T) { j, ok := MarshalToJson(user, false) if !ok || strings.Contains(j, "_TypedMessage_") { - t.Error("marshal account failed") } @@ -79,13 +78,12 @@ func TestMashalStruct(t *testing.T) { v := (*f2.Arr)[0]["foo"]["hello"] - if f1.N != f2.N || *(f1.Np) != *(f2.Np) || f1.S != f2.S || v != "world" { + if f1.N != f2.N || *f1.Np != *f2.Np || f1.S != f2.S || v != "world" { t.Error("f1 not equal to f2") } } func TestMarshalConfigJson(t *testing.T) { - buf := bytes.NewBufferString(getConfig()) config, err := iserial.DecodeJSONConfig(buf) if err != nil { diff --git a/common/units/bytesize_test.go b/common/units/bytesize_test.go index 3b8b9c88..4631231f 100644 --- a/common/units/bytesize_test.go +++ b/common/units/bytesize_test.go @@ -10,37 +10,44 @@ func TestByteSizes(t *testing.T) { size := units.ByteSize(0) assertSizeString(t, size, "0") size++ - assertSizeValue(t, + assertSizeValue( + t, assertSizeString(t, size, "1.00B"), size, ) size <<= 10 - assertSizeValue(t, + assertSizeValue( + t, assertSizeString(t, size, "1.00KB"), size, ) size <<= 10 - assertSizeValue(t, + assertSizeValue( + t, assertSizeString(t, size, "1.00MB"), size, ) size <<= 10 - assertSizeValue(t, + assertSizeValue( + t, assertSizeString(t, size, "1.00GB"), size, ) size <<= 10 - assertSizeValue(t, + assertSizeValue( + t, assertSizeString(t, size, "1.00TB"), size, ) size <<= 10 - assertSizeValue(t, + assertSizeValue( + t, assertSizeString(t, size, "1.00PB"), size, ) size <<= 10 - assertSizeValue(t, + assertSizeValue( + t, assertSizeString(t, size, "1.00EB"), size, ) diff --git a/common/utils/browser.go b/common/utils/browser.go index 957f49b7..12640564 100644 --- a/common/utils/browser.go +++ b/common/utils/browser.go @@ -4,10 +4,10 @@ import ( "hash/fnv" "math" "math/rand" - "strconv" - "time" "net/http" + "strconv" "strings" + "time" "github.com/klauspost/cpuid/v2" ) @@ -18,6 +18,7 @@ func GetRandomizer() *rand.Rand { fnvHash.Write([]byte(strconv.Itoa(cpuid.CPU.Family) + strconv.Itoa(cpuid.CPU.Model) + strconv.Itoa(cpuid.CPU.PhysicalCores) + strconv.Itoa(cpuid.CPU.LogicalCores) + strconv.Itoa(cpuid.CPU.CacheLine) + strconv.Itoa(cpuid.CPU.ThreadsPerCore))) return rand.New(rand.NewSource(int64(fnvHash.Sum64()))) } + var globalRng *rand.Rand = GetRandomizer() // The Chrome version generator will suffer from deviation of a normal distribution. @@ -26,83 +27,114 @@ func ChromeVersion() int { var startVersion int = 144 var timeStart int64 = time.Date(2026, 1, 13, 0, 0, 0, 0, time.UTC).Unix() / 86400 var timeCurrent int64 = time.Now().Unix() / 86400 - var timeDiff int = int((timeCurrent - timeStart - 35)) - int(math.Floor(math.Pow(globalRng.Float64(), 2) * 105)) + var timeDiff int = int((timeCurrent - timeStart - 35)) - int(math.Floor(math.Pow(globalRng.Float64(), 2)*105)) return startVersion + (timeDiff / 35) // It's 31.15 currently. } -var safariMinorMap [25]int = [25]int{0, 0, 0, 1, 1, +var safariMinorMap [25]int = [25]int{ + 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, - 4, 5, 5, 5, 5, 5, 6, 6, 6, 6} + 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, +} // The following version generators use deterministic generators, but with the distribution scaled by a curve. func CurlVersion() string { // curl 8.0.0 was released on 20/03/2023. var timeCurrent int64 = time.Now().Unix() / 86400 var timeStart int64 = time.Date(2023, 3, 20, 0, 0, 0, 0, time.UTC).Unix() / 86400 - var timeDiff int = int((timeCurrent - timeStart - 60)) - int(math.Floor(math.Pow(globalRng.Float64(), 2) * 165)) + var timeDiff int = int((timeCurrent - timeStart - 60)) - int(math.Floor(math.Pow(globalRng.Float64(), 2)*165)) var minorValue int = int(timeDiff / 57) // The release cadence is actually 56.67 days. return "8." + strconv.Itoa(minorValue) + ".0" } + func FirefoxVersion() int { // Firefox 128 ESR was released on 09/07/2023. var timeCurrent int64 = time.Now().Unix() / 86400 var timeStart int64 = time.Date(2024, 7, 29, 0, 0, 0, 0, time.UTC).Unix() / 86400 - var timeDiff = timeCurrent - timeStart - 25 - int64(math.Floor(math.Pow(globalRng.Float64(), 2) * 50)) - return int(timeDiff / 30) + 128 + timeDiff := timeCurrent - timeStart - 25 - int64(math.Floor(math.Pow(globalRng.Float64(), 2)*50)) + return int(timeDiff/30) + 128 } + func SafariVersion() string { var anchoredTime time.Time = time.Now() var releaseYear int = anchoredTime.Year() var splitPoint time.Time = time.Date(releaseYear, 9, 23, 0, 0, 0, 0, time.UTC) - var delayedDays = int(math.Floor(math.Pow(globalRng.Float64(), 3) * 75)) + delayedDays := int(math.Floor(math.Pow(globalRng.Float64(), 3) * 75)) splitPoint = splitPoint.AddDate(0, 0, delayedDays) - if (anchoredTime.Compare(splitPoint) < 0) { - releaseYear -- + if anchoredTime.Compare(splitPoint) < 0 { + releaseYear-- splitPoint = time.Date(releaseYear, 9, 23, 0, 0, 0, 0, time.UTC) splitPoint = splitPoint.AddDate(0, 0, delayedDays) } - var minorVersion = safariMinorMap[(anchoredTime.Unix() - splitPoint.Unix()) / 1296000] - return strconv.Itoa(releaseYear - 1999) + "." + strconv.Itoa(minorVersion) + minorVersion := safariMinorMap[(anchoredTime.Unix()-splitPoint.Unix())/1296000] + return strconv.Itoa(releaseYear-1999) + "." + strconv.Itoa(minorVersion) } // The full Chromium brand GREASE implementation -var clientHintGreaseNA = []string{" ", "(", ":", "-", ".", "/", ")", ";", "=", "?", "_"} -var clientHintVersionNA = []string{"8", "99", "24"} -var clientHintShuffle3 = [][3]int{{0, 1, 2}, {0, 2, 1}, {1, 0, 2}, {1, 2, 0}, {2, 0, 1}, {2, 1, 0}} -var clientHintShuffle4 = [][4]int{ - {0, 1, 2, 3}, {0, 1, 3, 2}, {0, 2, 1, 3}, {0, 2, 3, 1}, {0, 3, 1, 2}, {0, 3, 2, 1}, - {1, 0, 2, 3}, {1, 0, 3, 2}, {1, 2, 0, 3}, {1, 2, 3, 0}, {1, 3, 0, 2}, {1, 3, 2, 0}, - {2, 0, 1, 3}, {2, 0, 3, 1}, {2, 1, 0, 3}, {2, 1, 3, 0}, {2, 3, 0, 1}, {2, 3, 1, 0}, - {3, 0, 1, 2}, {3, 0, 2, 1}, {3, 1, 0, 2}, {3, 1, 2, 0}, {3, 2, 0, 1}, {3, 2, 1, 0}} +var ( + clientHintGreaseNA = []string{" ", "(", ":", "-", ".", "/", ")", ";", "=", "?", "_"} + clientHintVersionNA = []string{"8", "99", "24"} + clientHintShuffle3 = [][3]int{{0, 1, 2}, {0, 2, 1}, {1, 0, 2}, {1, 2, 0}, {2, 0, 1}, {2, 1, 0}} + clientHintShuffle4 = [][4]int{ + {0, 1, 2, 3}, + {0, 1, 3, 2}, + {0, 2, 1, 3}, + {0, 2, 3, 1}, + {0, 3, 1, 2}, + {0, 3, 2, 1}, + {1, 0, 2, 3}, + {1, 0, 3, 2}, + {1, 2, 0, 3}, + {1, 2, 3, 0}, + {1, 3, 0, 2}, + {1, 3, 2, 0}, + {2, 0, 1, 3}, + {2, 0, 3, 1}, + {2, 1, 0, 3}, + {2, 1, 3, 0}, + {2, 3, 0, 1}, + {2, 3, 1, 0}, + {3, 0, 1, 2}, + {3, 0, 2, 1}, + {3, 1, 0, 2}, + {3, 1, 2, 0}, + {3, 2, 0, 1}, + {3, 2, 1, 0}, + } +) + func getGreasedChInvalidBrand(seed int) string { - return "\"Not" + clientHintGreaseNA[seed % len(clientHintGreaseNA)] + "A" + clientHintGreaseNA[(seed + 1) % len(clientHintGreaseNA)] + "Brand\";v=\"" + clientHintVersionNA[seed % len(clientHintVersionNA)] + "\""; + return "\"Not" + clientHintGreaseNA[seed%len(clientHintGreaseNA)] + "A" + clientHintGreaseNA[(seed+1)%len(clientHintGreaseNA)] + "Brand\";v=\"" + clientHintVersionNA[seed%len(clientHintVersionNA)] + "\"" } + func getGreasedChOrder(brandLength int, seed int) []int { switch brandLength { - case 1: - return []int{0} - case 2: - return []int{seed % brandLength, (seed + 1) % brandLength} - case 3: - return clientHintShuffle3[seed % len(clientHintShuffle3)][:] - default: - return clientHintShuffle4[seed % len(clientHintShuffle4)][:] + case 1: + return []int{0} + case 2: + return []int{seed % brandLength, (seed + 1) % brandLength} + case 3: + return clientHintShuffle3[seed%len(clientHintShuffle3)][:] + default: + return clientHintShuffle4[seed%len(clientHintShuffle4)][:] } //return []int{} } + func getUngreasedChUa(majorVersion int, forkName string) []string { // Set the capacity to 4, the maximum allowed brand size, so Go will never allocate memory twice baseChUa := make([]string, 0, 4) baseChUa = append(baseChUa, getGreasedChInvalidBrand(majorVersion), - "\"Chromium\";v=\"" + strconv.Itoa(majorVersion) + "\"") + "\"Chromium\";v=\""+strconv.Itoa(majorVersion)+"\"") switch forkName { case "chrome": - baseChUa = append(baseChUa, "\"Google Chrome\";v=\"" + strconv.Itoa(majorVersion) + "\"") + baseChUa = append(baseChUa, "\"Google Chrome\";v=\""+strconv.Itoa(majorVersion)+"\"") case "edge": - baseChUa = append(baseChUa, "\"Microsoft Edge\";v=\"" + strconv.Itoa(majorVersion) + "\"") + baseChUa = append(baseChUa, "\"Microsoft Edge\";v=\""+strconv.Itoa(majorVersion)+"\"") } return baseChUa } + func getGreasedChUa(majorVersion int, forkName string) string { ungreasedCh := getUngreasedChUa(majorVersion, forkName) shuffleMap := getGreasedChOrder(len(ungreasedCh), majorVersion) @@ -114,16 +146,18 @@ func getGreasedChUa(majorVersion int, forkName string) string { } // The code below provides a coherent default browser user agent string based on a CPU-seeded PRNG. -var CurlUA = "curl/" + CurlVersion() -var AnchoredFirefoxVersion = strconv.Itoa(FirefoxVersion()) -var FirefoxUA = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:" + AnchoredFirefoxVersion + ".0) Gecko/20100101 Firefox/" + AnchoredFirefoxVersion + ".0" -var SafariUA = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/" + SafariVersion() + " Safari/605.1.15" -// Chromium browsers. -var AnchoredChromeVersion = ChromeVersion() -var ChromeUA = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/" + strconv.Itoa(AnchoredChromeVersion) + ".0.0.0 Safari/537.36" -var ChromeUACH = getGreasedChUa(AnchoredChromeVersion, "chrome") -var MSEdgeUA = ChromeUA + "Edg/" + strconv.Itoa(AnchoredChromeVersion) + ".0.0.0" -var MSEdgeUACH = getGreasedChUa(AnchoredChromeVersion, "edge") +var ( + CurlUA = "curl/" + CurlVersion() + AnchoredFirefoxVersion = strconv.Itoa(FirefoxVersion()) + FirefoxUA = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:" + AnchoredFirefoxVersion + ".0) Gecko/20100101 Firefox/" + AnchoredFirefoxVersion + ".0" + SafariUA = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/" + SafariVersion() + " Safari/605.1.15" + // Chromium browsers. + AnchoredChromeVersion = ChromeVersion() + ChromeUA = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/" + strconv.Itoa(AnchoredChromeVersion) + ".0.0.0 Safari/537.36" + ChromeUACH = getGreasedChUa(AnchoredChromeVersion, "chrome") + MSEdgeUA = ChromeUA + "Edg/" + strconv.Itoa(AnchoredChromeVersion) + ".0.0.0" + MSEdgeUACH = getGreasedChUa(AnchoredChromeVersion, "edge") +) func applyMasqueradedHeaders(header http.Header, browser string, variant string) { // Browser-specific. diff --git a/common/utils/typed_sync_map.go b/common/utils/typed_sync_map.go index 39524a6f..72d425f7 100644 --- a/common/utils/typed_sync_map.go +++ b/common/utils/typed_sync_map.go @@ -109,4 +109,4 @@ func (m *TypedSyncMap[K, V]) Swap(key K, value V) (previous V, loaded bool) { previous = anyPrevious.(V) } return previous, loaded -} \ No newline at end of file +} diff --git a/common/utils/unixsocket.go b/common/utils/unixsocket.go index 52d36256..8bb156c6 100644 --- a/common/utils/unixsocket.go +++ b/common/utils/unixsocket.go @@ -19,18 +19,18 @@ import ( // Filesystem paths and abstract sockets on other platforms are returned // unchanged. func ResolveSocketPath(path string) string { - if len(path) == 0 || path[0] != '@' { - return path - } - if runtime.GOOS != "linux" && runtime.GOOS != "android" { - return path - } - if len(path) > 1 && path[1] == '@' { - fullAddr := make([]byte, len(syscall.RawSockaddrUnix{}.Path)) - copy(fullAddr, path[1:]) - return string(fullAddr) - } - return path + if len(path) == 0 || path[0] != '@' { + return path + } + if runtime.GOOS != "linux" && runtime.GOOS != "android" { + return path + } + if len(path) > 1 && path[1] == '@' { + fullAddr := make([]byte, len(syscall.RawSockaddrUnix{}.Path)) + copy(fullAddr, path[1:]) + return string(fullAddr) + } + return path } // SplitHTTPUnixURL splits a target into an HTTP URL and an optional Unix @@ -44,12 +44,11 @@ func ResolveSocketPath(path string) string { // The :/ separator delimits the socket path from the HTTP request path. // If omitted, "/" is used. func SplitHTTPUnixURL(raw string) (httpURL, socketPath string) { - if len(raw) == 0 || (!filepath.IsAbs(raw) && raw[0] != '@') { - return raw, "" - } - if idx := strings.Index(raw, ":/"); idx >= 0 { - return "http://localhost" + raw[idx+1:], raw[:idx] - } - return "http://localhost/", raw + if len(raw) == 0 || (!filepath.IsAbs(raw) && raw[0] != '@') { + return raw, "" + } + if idx := strings.Index(raw, ":/"); idx >= 0 { + return "http://localhost" + raw[idx+1:], raw[:idx] + } + return "http://localhost/", raw } - diff --git a/features/routing/session/context.go b/features/routing/session/context.go index 45fa8d8f..e331c434 100644 --- a/features/routing/session/context.go +++ b/features/routing/session/context.go @@ -34,7 +34,6 @@ func (ctx *Context) GetSourceIPs() []net.IP { } return nil - } // GetSourcePort implements routing.Context. diff --git a/infra/conf/blackhole.go b/infra/conf/blackhole.go index 7b78742f..19ee1a6e 100644 --- a/infra/conf/blackhole.go +++ b/infra/conf/blackhole.go @@ -48,4 +48,5 @@ var configLoader = NewJSONConfigLoader( "http": func() interface{} { return new(HTTPResponse) }, }, "type", - "") + "", +) diff --git a/infra/conf/router_strategy.go b/infra/conf/router_strategy.go index 464cbcfb..6c426c51 100644 --- a/infra/conf/router_strategy.go +++ b/infra/conf/router_strategy.go @@ -1,9 +1,10 @@ package conf import ( - "google.golang.org/protobuf/proto" "strings" + "google.golang.org/protobuf/proto" + "github.com/xtls/xray-core/app/observatory/burst" "github.com/xtls/xray-core/app/router" "github.com/xtls/xray-core/infra/conf/cfgcommon/duration" @@ -16,17 +17,14 @@ const ( strategyLeastLoad string = "leastload" ) -var ( - strategyConfigLoader = NewJSONConfigLoader(ConfigCreatorCache{ - strategyRandom: func() interface{} { return new(strategyEmptyConfig) }, - strategyLeastPing: func() interface{} { return new(strategyEmptyConfig) }, - strategyRoundRobin: func() interface{} { return new(strategyEmptyConfig) }, - strategyLeastLoad: func() interface{} { return new(strategyLeastLoadConfig) }, - }, "type", "settings") -) +var strategyConfigLoader = NewJSONConfigLoader(ConfigCreatorCache{ + strategyRandom: func() interface{} { return new(strategyEmptyConfig) }, + strategyLeastPing: func() interface{} { return new(strategyEmptyConfig) }, + strategyRoundRobin: func() interface{} { return new(strategyEmptyConfig) }, + strategyLeastLoad: func() interface{} { return new(strategyLeastLoadConfig) }, +}, "type", "settings") -type strategyEmptyConfig struct { -} +type strategyEmptyConfig struct{} func (v *strategyEmptyConfig) Build() (proto.Message, error) { return nil, nil diff --git a/infra/conf/serial/loader.go b/infra/conf/serial/loader.go index 912f105c..d7d0d465 100644 --- a/infra/conf/serial/loader.go +++ b/infra/conf/serial/loader.go @@ -78,18 +78,17 @@ func DecodeJSONConfig(reader io.Reader) (*conf.Config, error) { // byte-by-byte comment stripper and TeeReader, which are significant overhead on // large configs. func DecodeJSONConfigStrict(reader io.Reader) (*conf.Config, error) { - data, err := io.ReadAll(reader) - if err != nil { - return nil, errors.New("failed to read config file").Base(err) - } - jsonConfig := &conf.Config{} - if err := json.Unmarshal(data, jsonConfig); err != nil { - return nil, errors.New("failed to parse remote JSON config").Base(err) - } - return jsonConfig, nil + data, err := io.ReadAll(reader) + if err != nil { + return nil, errors.New("failed to read config file").Base(err) + } + jsonConfig := &conf.Config{} + if err := json.Unmarshal(data, jsonConfig); err != nil { + return nil, errors.New("failed to parse remote JSON config").Base(err) + } + return jsonConfig, nil } - func LoadJSONConfig(reader io.Reader) (*core.Config, error) { jsonConfig, err := DecodeJSONConfig(reader) if err != nil { diff --git a/infra/conf/transport_authenticators.go b/infra/conf/transport_authenticators.go index a9590af9..9afdd4f0 100644 --- a/infra/conf/transport_authenticators.go +++ b/infra/conf/transport_authenticators.go @@ -45,31 +45,31 @@ func (v *AuthenticatorRequest) Build() (*http.RequestConfig, error) { Value: []string{utils.ChromeUA}, }, { - Name: "Sec-CH-UA", + Name: "Sec-CH-UA", Value: []string{utils.ChromeUACH}, }, { - Name: "Sec-CH-UA-Mobile", + Name: "Sec-CH-UA-Mobile", Value: []string{"?0"}, }, { - Name: "Sec-CH-UA-Platform", + Name: "Sec-CH-UA-Platform", Value: []string{"Windows"}, }, { - Name: "Sec-Fetch-Mode", + Name: "Sec-Fetch-Mode", Value: []string{"no-cors", "cors", "same-origin"}, }, { - Name: "Sec-Fetch-Dest", + Name: "Sec-Fetch-Dest", Value: []string{"empty"}, }, { - Name: "Sec-Fetch-Site", + Name: "Sec-Fetch-Site", Value: []string{"none"}, }, { - Name: "Sec-Fetch-User", + Name: "Sec-Fetch-User", Value: []string{"?1"}, }, { @@ -96,7 +96,7 @@ func (v *AuthenticatorRequest) Build() (*http.RequestConfig, error) { } if len(v.Path) > 0 { - config.Uri = append([]string(nil), (v.Path)...) + config.Uri = append([]string(nil), v.Path...) } if len(v.Headers) > 0 { diff --git a/infra/conf/transport_internet.go b/infra/conf/transport_internet.go index 25fe978a..7a86a08b 100644 --- a/infra/conf/transport_internet.go +++ b/infra/conf/transport_internet.go @@ -45,12 +45,10 @@ import ( "google.golang.org/protobuf/proto" ) -var ( - tcpHeaderLoader = NewJSONConfigLoader(ConfigCreatorCache{ - "none": func() interface{} { return new(NoOpConnectionAuthenticator) }, - "http": func() interface{} { return new(Authenticator) }, - }, "type", "") -) +var tcpHeaderLoader = NewJSONConfigLoader(ConfigCreatorCache{ + "none": func() interface{} { return new(NoOpConnectionAuthenticator) }, + "http": func() interface{} { return new(Authenticator) }, +}, "type", "") type KCPConfig struct { Mtu *uint32 `json:"mtu"` @@ -1034,7 +1032,7 @@ type HappyEyeballsConfig struct { } func (h *HappyEyeballsConfig) UnmarshalJSON(data []byte) error { - var innerHappyEyeballsConfig = struct { + innerHappyEyeballsConfig := struct { PrioritizeIPv6 bool `json:"prioritizeIPv6"` TryDelayMs uint64 `json:"tryDelayMs"` Interleave uint32 `json:"interleave"` @@ -1162,7 +1160,7 @@ func (c *SocketConfig) Build() (*internet.SocketConfig, error) { return nil, errors.New("unsupported address and port strategy: ", c.AddressPortStrategy) } - var happyEyeballs = &internet.HappyEyeballsConfig{Interleave: 1, PrioritizeIpv6: false, TryDelayMs: 0, MaxConcurrentTry: 4} + happyEyeballs := &internet.HappyEyeballsConfig{Interleave: 1, PrioritizeIpv6: false, TryDelayMs: 0, MaxConcurrentTry: 4} if c.HappyEyeballsSettings != nil { happyEyeballs.PrioritizeIpv6 = c.HappyEyeballsSettings.PrioritizeIPv6 happyEyeballs.Interleave = c.HappyEyeballsSettings.Interleave diff --git a/infra/conf/version.go b/infra/conf/version.go index 5fedeb08..3cbe9215 100644 --- a/infra/conf/version.go +++ b/infra/conf/version.go @@ -1,9 +1,10 @@ package conf import ( + "strconv" + "github.com/xtls/xray-core/app/version" "github.com/xtls/xray-core/core" - "strconv" ) type VersionConfig struct { diff --git a/infra/conf/xray.go b/infra/conf/xray.go index a077af5e..3e6e4371 100644 --- a/infra/conf/xray.go +++ b/infra/conf/xray.go @@ -177,7 +177,8 @@ func (c *InboundDetourConfig) Build() (*core.InboundHandlerConfig, error) { protocol := ss.GetEffectiveProtocol() if (protocol == "websocket" || protocol == "httpupgrade" || protocol == "splithttp") && (c.StreamSetting.SocketSettings == nil || len(c.StreamSetting.SocketSettings.TrustedXForwardedFor) == 0) { - errors.LogWarning(context.Background(), + errors.LogWarning( + context.Background(), `====== SECURITY WARNING ======`, "\n", `inbound "`, c.Tag, `" using `, protocol, ` has not configured "sockopt.trustedXForwardedFor".`, @@ -285,7 +286,7 @@ func (c *OutboundDetourConfig) Build() (*core.OutboundHandlerConfig, error) { if c.SendThrough != nil { address := ParseSendThough(c.SendThrough) - //Check if CIDR exists + // Check if CIDR exists if strings.Contains(*c.SendThrough, "/") { senderSettings.ViaCidr = strings.Split(*c.SendThrough, "/")[1] } else { @@ -469,7 +470,6 @@ func (c *Config) Override(o *Config, fn string) { c.InboundConfigs = append(c.InboundConfigs, o.InboundConfigs[i]) errors.LogInfo(context.Background(), "[", fn, "] appended inbound with tag: ", o.InboundConfigs[i].Tag) } - } } diff --git a/infra/vformat/main.go b/infra/vformat/main.go index 84c63a42..533a5a14 100644 --- a/infra/vformat/main.go +++ b/infra/vformat/main.go @@ -12,7 +12,16 @@ import ( "strings" ) -var directory = flag.String("pwd", "", "Working directory of Xray vformat.") +var ( + directory = flag.String("pwd", "", "Working directory of Xray vformat.") + action = flag.String("mode", "format", "Execution mode. Default is 'format'.\n'format' formatting source files and save changes to files.\n'check' list all paths of improper formatted file.\n'dryrun' formatting source files and shows all diffs, but will not make any changes to files.") +) + +var ( + isCheck bool + isDryrun bool + isFormat bool +) // envFile returns the name of the Go environment configuration file. // Copy from https://github.com/golang/go/blob/c4f2a9788a7be04daf931ac54382fbe2cb754938/src/cmd/go/internal/cfg/cfg.go#L150-L166 @@ -90,9 +99,10 @@ func Run(binary string, args []string) ([]byte, error) { return output, nil } -func RunMany(binary string, args, files []string) { - fmt.Println("Processing...") +func RunMany(binary string, args, files []string) bool { + fmt.Println("Processing with", binary, args, "...") + formatRequired := false maxTasks := make(chan struct{}, runtime.NumCPU()) for _, file := range files { maxTasks <- struct{}{} @@ -102,10 +112,12 @@ func RunMany(binary string, args, files []string) { fmt.Println(err) } else if len(output) > 0 { fmt.Println(string(output)) + formatRequired = true } <-maxTasks }(file) } + return formatRequired } func main() { @@ -124,6 +136,19 @@ func main() { *directory = filepath.Join(pwd, *directory) } + switch *action { + case "format": + isFormat = true + case "check": + isCheck = true + case "dryrun": + isCheck = true + isDryrun = true + default: + fmt.Println("Unrecognized 'mode'. Will format all source files and save changes.") + isFormat = true + } + pwd := *directory GOBIN := GetGOBIN() binPath := os.Getenv("PATH") @@ -136,7 +161,6 @@ func main() { suffix = ".exe" } gofmt := "gofumpt" + suffix - goimports := "gci" + suffix if gofmtPath, err := exec.LookPath(gofmt); err != nil { fmt.Println("Can not find", gofmt, "in system path or current working directory.") @@ -145,13 +169,6 @@ func main() { gofmt = gofmtPath } - if goimportsPath, err := exec.LookPath(goimports); err != nil { - fmt.Println("Can not find", goimports, "in system path or current working directory.") - os.Exit(1) - } else { - goimports = goimportsPath - } - rawFilesSlice := make([]string, 0, 1000) walkErr := filepath.Walk(pwd, func(path string, info os.FileInfo, err error) error { if err != nil { @@ -179,15 +196,41 @@ func main() { os.Exit(1) } - gofmtArgs := []string{ - "-s", "-l", "-e", "-w", + if isFormat { + gofmtArgs := []string{ + "-l", "-e", "-w", + } + + fmt.Println("Formatting Go source files...") + RunMany(gofmt, gofmtArgs, rawFilesSlice) + fmt.Println("Do NOT forget to commit file changes.") } - goimportsArgs := []string{ - "write", - } + if isCheck { + gofmtListArgs := []string{ + "-l", "-e", + } - RunMany(gofmt, gofmtArgs, rawFilesSlice) - RunMany(goimports, goimportsArgs, rawFilesSlice) - fmt.Println("Do NOT forget to commit file changes.") + fmt.Println("Checking files thar are not properly formatted...") + formatRequired := RunMany(gofmt, gofmtListArgs, rawFilesSlice) + if formatRequired { + fmt.Println("Format problem(s) found.") + } + + if isDryrun { + if formatRequired { + gofmtShowArgs := []string{ + "-d", "-e", + } + RunMany(gofmt, gofmtShowArgs, rawFilesSlice) + } + } + + if formatRequired { + fmt.Println("Please run 'go install -v mvdan.cc/gofumpt@latest', then run 'go run ./infra/vformat/main.go' to format the Go source files.") + os.Exit(1) + } else { + fmt.Println("All Go source file format check has been passed.") + } + } } diff --git a/main/commands/all/api/balancer_info.go b/main/commands/all/api/balancer_info.go index f5b6804c..cabc66d9 100644 --- a/main/commands/all/api/balancer_info.go +++ b/main/commands/all/api/balancer_info.go @@ -59,7 +59,6 @@ func executeBalancerInfo(cmd *base.Command, args []string) { } showBalancerInfo(resp.Balancer) - } func showBalancerInfo(b *routerService.BalancerMsg) { diff --git a/main/commands/all/api/inbound_user_add.go b/main/commands/all/api/inbound_user_add.go index 759bf596..81afc0d2 100644 --- a/main/commands/all/api/inbound_user_add.go +++ b/main/commands/all/api/inbound_user_add.go @@ -62,7 +62,8 @@ func addInboundUserAction(ctx context.Context, client handlerService.HandlerServ Operation: cserial.ToTypedMessage( &handlerService.AddUserOperation{ User: user, - }), + }, + ), }) return err } diff --git a/main/commands/all/api/inbound_user_remove.go b/main/commands/all/api/inbound_user_remove.go index d1261700..d6e8a4b3 100644 --- a/main/commands/all/api/inbound_user_remove.go +++ b/main/commands/all/api/inbound_user_remove.go @@ -50,7 +50,8 @@ func executeRemoveUsers(cmd *base.Command, args []string) { Operation: cserial.ToTypedMessage( &handlerService.RemoveUserOperation{ Email: email, - }), + }, + ), }) if err == nil { success += 1 diff --git a/main/commands/all/api/rules_add.go b/main/commands/all/api/rules_add.go index 4ff3d0b8..fc0fda6c 100644 --- a/main/commands/all/api/rules_add.go +++ b/main/commands/all/api/rules_add.go @@ -38,9 +38,7 @@ Example: } func executeAddRules(cmd *base.Command, args []string) { - var ( - shouldAppend bool - ) + var shouldAppend bool setSharedFlags(cmd) cmd.Flag.BoolVar(&shouldAppend, "append", false, "") cmd.Flag.Parse(args) @@ -96,5 +94,4 @@ func executeAddRules(cmd *base.Command, args []string) { } showJSONResponse(resp) } - } diff --git a/main/commands/all/api/rules_remove.go b/main/commands/all/api/rules_remove.go index ac9a8d09..7be62f71 100644 --- a/main/commands/all/api/rules_remove.go +++ b/main/commands/all/api/rules_remove.go @@ -56,5 +56,4 @@ func executeRemoveRules(cmd *base.Command, args []string) { } showJSONResponse(resp) } - } diff --git a/main/commands/all/api/source_ip_block.go b/main/commands/all/api/source_ip_block.go index 9479ef35..caff15a4 100644 --- a/main/commands/all/api/source_ip_block.go +++ b/main/commands/all/api/source_ip_block.go @@ -136,5 +136,4 @@ func executeSourceIpBlock(cmd *base.Command, args []string) { base.Fatalf("failed to perform AddRule: %s", err) } showJSONResponse(resp) - } diff --git a/main/commands/all/convert/json.go b/main/commands/all/convert/json.go index 58066795..9da7527b 100644 --- a/main/commands/all/convert/json.go +++ b/main/commands/all/convert/json.go @@ -38,7 +38,6 @@ Examples: } func executeTypedMessageToJson(cmd *base.Command, args []string) { - var injectTypeInfo bool cmd.Flag.BoolVar(&injectTypeInfo, "t", false, "") cmd.Flag.BoolVar(&injectTypeInfo, "type", false, "") diff --git a/main/commands/all/convert/protobuf.go b/main/commands/all/convert/protobuf.go index 2f4296e1..d56acc2d 100644 --- a/main/commands/all/convert/protobuf.go +++ b/main/commands/all/convert/protobuf.go @@ -41,7 +41,6 @@ Examples: } func executeConvertConfigsToProtobuf(cmd *base.Command, args []string) { - var optFile string var optDump bool var optType bool @@ -60,7 +59,7 @@ func executeConvertConfigsToProtobuf(cmd *base.Command, args []string) { } if len(optFile) > 0 { - switch core.GetFormat(optFile){ + switch core.GetFormat(optFile) { case "protobuf", "": fmt.Println("Output ProtoBuf file is ", optFile) default: diff --git a/main/commands/all/tls/ech.go b/main/commands/all/tls/ech.go index b2b532ff..c31ddcc6 100644 --- a/main/commands/all/tls/ech.go +++ b/main/commands/all/tls/ech.go @@ -34,8 +34,10 @@ func init() { var input_echServerKeys = cmdECH.Flag.String("i", "", "ECHServerKeys (base64.StdEncoding)") // var input_pqSignatureSchemesEnabled = cmdECH.Flag.Bool("pqSignatureSchemesEnabled", false, "") -var input_serverName = cmdECH.Flag.String("serverName", "cloudflare-ech.com", "") -var input_pem = cmdECH.Flag.Bool("pem", false, "True == turn on pem output") +var ( + input_serverName = cmdECH.Flag.String("serverName", "cloudflare-ech.com", "") + input_pem = cmdECH.Flag.Bool("pem", false, "True == turn on pem output") +) func executeECH(cmd *base.Command, args []string) { var kem uint16 diff --git a/main/commands/all/x25519.go b/main/commands/all/x25519.go index 784a1790..c9a823ac 100644 --- a/main/commands/all/x25519.go +++ b/main/commands/all/x25519.go @@ -21,8 +21,10 @@ func init() { cmdX25519.Run = executeX25519 // break init loop } -var input_stdEncoding = cmdX25519.Flag.Bool("std-encoding", false, "") -var input_x25519 = cmdX25519.Flag.String("i", "", "") +var ( + input_stdEncoding = cmdX25519.Flag.Bool("std-encoding", false, "") + input_x25519 = cmdX25519.Flag.String("i", "", "") +) func executeX25519(cmd *base.Command, args []string) { Curve25519Genkey(false, *input_x25519) diff --git a/main/confloader/confloader.go b/main/confloader/confloader.go index b9652a67..a4b42513 100644 --- a/main/confloader/confloader.go +++ b/main/confloader/confloader.go @@ -12,9 +12,7 @@ type ( configFileLoader func(string) (io.Reader, error) ) -var ( - EffectiveConfigFileLoader configFileLoader -) +var EffectiveConfigFileLoader configFileLoader // LoadConfig reads from a path/url/stdin // actual work is in external module diff --git a/main/confloader/external/external.go b/main/confloader/external/external.go index f9ea874c..02066109 100644 --- a/main/confloader/external/external.go +++ b/main/confloader/external/external.go @@ -52,7 +52,7 @@ func ConfigLoader(arg string) (out io.Reader, err error) { // When the ":/" separator is omitted on a socket target, the request is // made to "/". func FetchHTTPContent(target string) ([]byte, error) { - httpURL, socketPath := utils.SplitHTTPUnixURL(target) + httpURL, socketPath := utils.SplitHTTPUnixURL(target) parsedTarget, err := url.Parse(httpURL) if err != nil { @@ -63,15 +63,15 @@ func FetchHTTPContent(target string) ([]byte, error) { Timeout: 30 * time.Second, } - if socketPath != "" { - dialAddr := utils.ResolveSocketPath(socketPath) - client.Transport = &http.Transport{ - DialContext: func(ctx context.Context, _, _ string) (net.Conn, error) { - var d net.Dialer - return d.DialContext(ctx, "unix", dialAddr) - }, - } - } + if socketPath != "" { + dialAddr := utils.ResolveSocketPath(socketPath) + client.Transport = &http.Transport{ + DialContext: func(ctx context.Context, _, _ string) (net.Conn, error) { + var d net.Dialer + return d.DialContext(ctx, "unix", dialAddr) + }, + } + } resp, err := client.Do(&http.Request{ Method: "GET", @@ -95,7 +95,6 @@ func FetchHTTPContent(target string) ([]byte, error) { return content, nil } - // isRemoteSource reports whether arg should be fetched via HTTP (regular // network or Unix socket) rather than read from the local filesystem. // Recognized forms: @@ -124,7 +123,6 @@ func isRemoteSource(arg string) bool { return err == nil && info.Mode()&os.ModeSocket != 0 } - // httpUnixToCanonical converts the deprecated http+unix:///path/to/socket.sock/api // URL into the canonical /path/to/socket.sock:/api form by inserting ":" // between the ".sock" extension and the HTTP path. Inputs without a path diff --git a/proxy/dokodemo/dokodemo.go b/proxy/dokodemo/dokodemo.go index 5d51c22e..39c790c7 100644 --- a/proxy/dokodemo/dokodemo.go +++ b/proxy/dokodemo/dokodemo.go @@ -190,9 +190,11 @@ func (d *DokodemoDoor) Process(ctx context.Context, network net.Network, conn st } } - if err := dispatcher.DispatchLink(ctx, dest, &transport.Link{ - Reader: reader, - Writer: writer}, + if err := dispatcher.DispatchLink( + ctx, dest, &transport.Link{ + Reader: reader, + Writer: writer, + }, ); err != nil { return errors.New("failed to dispatch request").Base(err) } diff --git a/proxy/freedom/freedom.go b/proxy/freedom/freedom.go index f8181a34..9cdce38a 100644 --- a/proxy/freedom/freedom.go +++ b/proxy/freedom/freedom.go @@ -30,10 +30,12 @@ import ( "github.com/xtls/xray-core/transport/internet/stat" ) -var useSplice bool -var allNetworks [8]bool -var defaultBlockPrivateRule *FinalRule -var defaultBlockAllRule *FinalRule +var ( + useSplice bool + allNetworks [8]bool + defaultBlockPrivateRule *FinalRule + defaultBlockAllRule *FinalRule +) func init() { common.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, config interface{}) (interface{}, error) { @@ -677,7 +679,7 @@ type NoisePacketWriter struct { func (w *NoisePacketWriter) WriteMultiBuffer(mb buf.MultiBuffer) error { if w.firstWrite { w.firstWrite = false - //Do not send Noise for dns requests(just to be safe) + // Do not send Noise for dns requests(just to be safe) if w.UDPOverride.Port == 53 { return w.Writer.WriteMultiBuffer(mb) } @@ -700,11 +702,11 @@ func (w *NoisePacketWriter) WriteMultiBuffer(mb buf.MultiBuffer) error { default: panic("unreachable, applyTo is ip/ipv4/ipv6") } - //User input string or base64 encoded string or hex string + // User input string or base64 encoded string or hex string if n.Packet != nil { noise = n.Packet } else { - //Random noise + // Random noise noise, err = GenerateRandomBytes(crypto.RandBetween(int64(n.LengthMin), int64(n.LengthMax))) } diff --git a/proxy/http/server.go b/proxy/http/server.go index 90a07b38..054e40bf 100644 --- a/proxy/http/server.go +++ b/proxy/http/server.go @@ -192,9 +192,11 @@ func (s *Server) handleConnect(ctx context.Context, _ *http.Request, buffer *buf if inbound.CanSpliceCopy == 2 { inbound.CanSpliceCopy = 1 } - if err := dispatcher.DispatchLink(ctx, dest, &transport.Link{ - Reader: reader, - Writer: buf.NewWriter(conn)}, + if err := dispatcher.DispatchLink( + ctx, dest, &transport.Link{ + Reader: reader, + Writer: buf.NewWriter(conn), + }, ); err != nil { return errors.New("failed to dispatch request").Base(err) } diff --git a/proxy/hysteria/account/config.go b/proxy/hysteria/account/config.go index 0e50dcc9..63ecaf65 100644 --- a/proxy/hysteria/account/config.go +++ b/proxy/hysteria/account/config.go @@ -113,7 +113,7 @@ func (v *Validator) GetAll() []*protocol.MemoryUser { v.mutex.Lock() defer v.mutex.Unlock() - var users = make([]*protocol.MemoryUser, 0, len(v.users)) + users := make([]*protocol.MemoryUser, 0, len(v.users)) for _, user := range v.users { users = append(users, user) } diff --git a/proxy/proxy.go b/proxy/proxy.go index dbd81d6b..ab7d7abc 100644 --- a/proxy/proxy.go +++ b/proxy/proxy.go @@ -743,7 +743,7 @@ func CopyRawConnIfExist(ctx context.Context, readerConn net.Conn, writerConn net for { inbound := session.InboundFromContext(ctx) outbounds := session.OutboundsFromContext(ctx) - var splice = inbound.CanSpliceCopy == 1 + splice := inbound.CanSpliceCopy == 1 for _, ob := range outbounds { if ob.CanSpliceCopy != 1 { splice = false diff --git a/proxy/socks/server.go b/proxy/socks/server.go index fab66476..53049dfe 100644 --- a/proxy/socks/server.go +++ b/proxy/socks/server.go @@ -153,9 +153,11 @@ func (s *Server) processTCP(ctx context.Context, conn stat.Connection, dispatche if inbound.CanSpliceCopy == 2 { inbound.CanSpliceCopy = 1 } - if err := dispatcher.DispatchLink(ctx, dest, &transport.Link{ - Reader: reader, - Writer: buf.NewWriter(conn)}, + if err := dispatcher.DispatchLink( + ctx, dest, &transport.Link{ + Reader: reader, + Writer: buf.NewWriter(conn), + }, ); err != nil { return errors.New("failed to dispatch request").Base(err) } diff --git a/proxy/trojan/config.go b/proxy/trojan/config.go index b7591996..00d94bc9 100644 --- a/proxy/trojan/config.go +++ b/proxy/trojan/config.go @@ -4,6 +4,7 @@ import ( "crypto/sha256" "encoding/hex" "fmt" + "google.golang.org/protobuf/proto" "github.com/xtls/xray-core/common" diff --git a/proxy/trojan/server.go b/proxy/trojan/server.go index d66219c4..d5979e52 100644 --- a/proxy/trojan/server.go +++ b/proxy/trojan/server.go @@ -312,7 +312,6 @@ func (s *Server) handleUDPPayload(ctx context.Context, sessionPolicy policy.Sess } } } - } if err := task.Run(ctx, requestDone); err != nil { diff --git a/proxy/trojan/validator.go b/proxy/trojan/validator.go index 7841a249..026649f6 100644 --- a/proxy/trojan/validator.go +++ b/proxy/trojan/validator.go @@ -63,7 +63,7 @@ func (v *Validator) GetByEmail(email string) *protocol.MemoryUser { // Get all users func (v *Validator) GetAll() []*protocol.MemoryUser { - var u = make([]*protocol.MemoryUser, 0, 100) + u := make([]*protocol.MemoryUser, 0, 100) v.email.Range(func(key, value interface{}) bool { u = append(u, value.(*protocol.MemoryUser)) return true diff --git a/proxy/tun/stack_gvisor.go b/proxy/tun/stack_gvisor.go index 73f65f19..8584616e 100644 --- a/proxy/tun/stack_gvisor.go +++ b/proxy/tun/stack_gvisor.go @@ -69,7 +69,7 @@ func (t *stackGVisor) Start() error { tcpForwarder := tcp.NewForwarder(ipStack, 0, 65535, func(r *tcp.ForwarderRequest) { go func(r *tcp.ForwarderRequest) { var wq waiter.Queue - var id = r.ID() + id := r.ID() // Perform a TCP three-way handshake. ep, err := r.CreateEndpoint(&wq) diff --git a/proxy/tun/stack_gvisor_endpoint.go b/proxy/tun/stack_gvisor_endpoint.go index 31def35e..26d8ecab 100644 --- a/proxy/tun/stack_gvisor_endpoint.go +++ b/proxy/tun/stack_gvisor_endpoint.go @@ -68,7 +68,6 @@ func (e *LinkEndpoint) IsAttached() bool { } func (e *LinkEndpoint) Wait() { - } func (e *LinkEndpoint) ARPHardwareType() header.ARPHardwareType { @@ -91,7 +90,6 @@ func (e *LinkEndpoint) Close() { } func (e *LinkEndpoint) SetOnCloseAction(_ func()) { - } func (e *LinkEndpoint) WritePackets(packetBufferList stack.PacketBufferList) (int, tcpip.Error) { diff --git a/proxy/tun/tun_darwin.go b/proxy/tun/tun_darwin.go index 955f3614..81eaece0 100644 --- a/proxy/tun/tun_darwin.go +++ b/proxy/tun/tun_darwin.go @@ -44,8 +44,10 @@ type DarwinTun struct { ownsFd bool // true for macOS (we created the fd), false for iOS (fd from system) } -var _ Tun = (*DarwinTun)(nil) -var _ GVisorDevice = (*DarwinTun)(nil) +var ( + _ Tun = (*DarwinTun)(nil) + _ GVisorDevice = (*DarwinTun)(nil) +) func NewTun(options *Config) (Tun, error) { // Check if fd is provided via environment (iOS mode) diff --git a/proxy/tun/tun_default.go b/proxy/tun/tun_default.go index 24e6d08b..3ab6c961 100644 --- a/proxy/tun/tun_default.go +++ b/proxy/tun/tun_default.go @@ -9,8 +9,7 @@ import ( "gvisor.dev/gvisor/pkg/tcpip/stack" ) -type DefaultTun struct { -} +type DefaultTun struct{} // DefaultTun implements Tun var _ Tun = (*DefaultTun)(nil) diff --git a/proxy/tun/tun_freebsd.go b/proxy/tun/tun_freebsd.go index 8833a753..07469ca2 100644 --- a/proxy/tun/tun_freebsd.go +++ b/proxy/tun/tun_freebsd.go @@ -27,8 +27,10 @@ type FreeBSDTun struct { mtu uint32 } -var _ Tun = (*FreeBSDTun)(nil) -var _ GVisorDevice = (*FreeBSDTun)(nil) +var ( + _ Tun = (*FreeBSDTun)(nil) + _ GVisorDevice = (*FreeBSDTun)(nil) +) // NewTun builds new tun interface handler func NewTun(options *Config) (Tun, error) { diff --git a/proxy/vless/encoding/encoding_test.go b/proxy/vless/encoding/encoding_test.go index ae558865..48a64797 100644 --- a/proxy/vless/encoding/encoding_test.go +++ b/proxy/vless/encoding/encoding_test.go @@ -53,7 +53,7 @@ func TestRequestSerialization(t *testing.T) { } addonsComparer := func(x, y *Addons) bool { - return (x.Flow == y.Flow) && (cmp.Equal(x.Seed, y.Seed)) + return (x.Flow == y.Flow) && cmp.Equal(x.Seed, y.Seed) } if r := cmp.Diff(actualAddons, expectedAddons, cmp.Comparer(addonsComparer)); r != "" { t.Error(r) @@ -125,7 +125,7 @@ func TestMuxRequest(t *testing.T) { } addonsComparer := func(x, y *Addons) bool { - return (x.Flow == y.Flow) && (cmp.Equal(x.Seed, y.Seed)) + return (x.Flow == y.Flow) && cmp.Equal(x.Seed, y.Seed) } if r := cmp.Diff(actualAddons, expectedAddons, cmp.Comparer(addonsComparer)); r != "" { t.Error(r) diff --git a/proxy/vless/encryption/client.go b/proxy/vless/encryption/client.go index 54959d0e..2eb43409 100644 --- a/proxy/vless/encryption/client.go +++ b/proxy/vless/encryption/client.go @@ -79,7 +79,7 @@ func (i *ClientInstance) Handshake(conn net.Conn) (*CommonConn, error) { var nfsKey []byte var lastCTR cipher.Stream for j, k := range i.NfsPKeys { - var index = 32 + index := 32 if k, ok := k.(*ecdh.PublicKey); ok { privateKey, _ := ecdh.X25519().GenerateKey(rand.Reader) copy(relays, privateKey.PublicKey().Bytes()) diff --git a/proxy/vless/encryption/server.go b/proxy/vless/encryption/server.go index e1d73716..41c969c7 100644 --- a/proxy/vless/encryption/server.go +++ b/proxy/vless/encryption/server.go @@ -135,7 +135,7 @@ func (i *ServerInstance) Handshake(conn net.Conn, fallback *[]byte) (*CommonConn if lastCTR != nil { lastCTR.XORKeyStream(relays, relays[:32]) // recover this relay } - var index = 32 + index := 32 if _, ok := k.(*mlkem.DecapsulationKey768); ok { index = 1088 } diff --git a/proxy/vless/inbound/inbound.go b/proxy/vless/inbound/inbound.go index 0301fb78..2d10a006 100644 --- a/proxy/vless/inbound/inbound.go +++ b/proxy/vless/inbound/inbound.go @@ -630,9 +630,11 @@ func (h *Handler) Process(ctx context.Context, network net.Network, connection s return r.NewMux(ctx, dispatcher.WrapLink(ctx, h.policyManager, h.stats, &transport.Link{Reader: clientReader, Writer: clientWriter}), h.observer) } - if err := dispatch.DispatchLink(ctx, request.Destination(), &transport.Link{ - Reader: clientReader, - Writer: clientWriter}, + if err := dispatch.DispatchLink( + ctx, request.Destination(), &transport.Link{ + Reader: clientReader, + Writer: clientWriter, + }, ); err != nil { return errors.New("failed to dispatch request").Base(err) } diff --git a/proxy/vless/validator.go b/proxy/vless/validator.go index 35a4469a..fc5dc95e 100644 --- a/proxy/vless/validator.go +++ b/proxy/vless/validator.go @@ -79,7 +79,7 @@ func (v *MemoryValidator) GetByEmail(email string) *protocol.MemoryUser { // Get all users func (v *MemoryValidator) GetAll() []*protocol.MemoryUser { - var u = make([]*protocol.MemoryUser, 0, 100) + u := make([]*protocol.MemoryUser, 0, 100) v.email.Range(func(key, value interface{}) bool { u = append(u, value.(*protocol.MemoryUser)) return true diff --git a/proxy/vmess/account.go b/proxy/vmess/account.go index df8ba52b..a7a1b78e 100644 --- a/proxy/vmess/account.go +++ b/proxy/vmess/account.go @@ -1,9 +1,10 @@ package vmess import ( - "google.golang.org/protobuf/proto" "strings" + "google.golang.org/protobuf/proto" + "github.com/xtls/xray-core/common/errors" "github.com/xtls/xray-core/common/protocol" "github.com/xtls/xray-core/common/uuid" @@ -30,7 +31,7 @@ func (a *MemoryAccount) Equals(account protocol.Account) bool { } func (a *MemoryAccount) ToProto() proto.Message { - var test = "" + test := "" if a.AuthenticatedLengthExperiment { test = "AuthenticatedLength|" } diff --git a/proxy/vmess/inbound/inbound.go b/proxy/vmess/inbound/inbound.go index 6a8591ad..e084a881 100644 --- a/proxy/vmess/inbound/inbound.go +++ b/proxy/vmess/inbound/inbound.go @@ -138,7 +138,8 @@ func New(ctx context.Context, config *Config) (*Handler, error) { func (h *Handler) Close() error { return errors.Combine( h.sessionHistory.Close(), - common.Close(h.usersByEmail)) + common.Close(h.usersByEmail), + ) } // Network implements proxy.Inbound.Network(). diff --git a/proxy/vmess/outbound/command.go b/proxy/vmess/outbound/command.go index c284bfb6..5e07b0f3 100644 --- a/proxy/vmess/outbound/command.go +++ b/proxy/vmess/outbound/command.go @@ -1,7 +1,6 @@ package outbound import ( - "github.com/xtls/xray-core/common/net" "github.com/xtls/xray-core/common/protocol" ) diff --git a/proxy/vmess/outbound/outbound.go b/proxy/vmess/outbound/outbound.go index 4850e728..903e73ce 100644 --- a/proxy/vmess/outbound/outbound.go +++ b/proxy/vmess/outbound/outbound.go @@ -224,9 +224,7 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte return nil } -var ( - enablePadding = false -) +var enablePadding = false func shouldEnablePadding(s protocol.SecurityType) bool { return enablePadding || s == protocol.SecurityType_AES128_GCM || s == protocol.SecurityType_CHACHA20_POLY1305 || s == protocol.SecurityType_AUTO diff --git a/proxy/wireguard/bind.go b/proxy/wireguard/bind.go index ddbc2178..c5c0f8c8 100644 --- a/proxy/wireguard/bind.go +++ b/proxy/wireguard/bind.go @@ -134,7 +134,6 @@ func (bind *netBindClient) connectTo(endpoint *netEndpoint) error { for { buff := buf.NewWithSize(device.MaxMessageSize) n, err := buff.ReadFrom(c) - if err != nil { buff.Release() endpoint.conn = nil diff --git a/proxy/wireguard/server.go b/proxy/wireguard/server.go index 1f358a38..876d749f 100644 --- a/proxy/wireguard/server.go +++ b/proxy/wireguard/server.go @@ -162,7 +162,6 @@ func (s *Server) forwardConnection(dest net.Destination, conn net.Conn) { Reader: buf.NewReader(conn), Writer: buf.NewWriter(conn), }) - if err != nil { errors.LogInfoInner(ctx, err, "connection ends") } diff --git a/proxy/wireguard/server_test.go b/proxy/wireguard/server_test.go index 057b508e..1cb4697c 100644 --- a/proxy/wireguard/server_test.go +++ b/proxy/wireguard/server_test.go @@ -2,10 +2,11 @@ package wireguard_test import ( "context" - "github.com/stretchr/testify/assert" "runtime/debug" "testing" + "github.com/stretchr/testify/assert" + "github.com/xtls/xray-core/core" "github.com/xtls/xray-core/proxy/wireguard" ) diff --git a/proxy/wireguard/tun.go b/proxy/wireguard/tun.go index 4168e175..2f9c1ab1 100644 --- a/proxy/wireguard/tun.go +++ b/proxy/wireguard/tun.go @@ -156,7 +156,7 @@ func createGVisorTun(localAddresses []netip.Addr, mtu int, handler promiscuousMo tcpForwarder := tcp.NewForwarder(gstack, 0, 65535, func(r *tcp.ForwarderRequest) { go func(r *tcp.ForwarderRequest) { var wq waiter.Queue - var id = r.ID() + id := r.ID() ep, err := r.CreateEndpoint(&wq) if err != nil { diff --git a/testing/scenarios/command_test.go b/testing/scenarios/command_test.go index 37686e2e..8f82bb2b 100644 --- a/testing/scenarios/command_test.go +++ b/testing/scenarios/command_test.go @@ -292,7 +292,8 @@ func TestCommanderListHandlers(t *testing.T) { protocmp.Transform(), cmpopts.SortSlices(func(a, b *core.InboundHandlerConfig) bool { return a.Tag < b.Tag - })); diff != "" { + }), + ); diff != "" { t.Fatalf("inbound response doesn't match config (-want +got):\n%s", diff) } @@ -308,7 +309,8 @@ func TestCommanderListHandlers(t *testing.T) { protocmp.Transform(), cmpopts.SortSlices(func(a, b *core.InboundHandlerConfig) bool { return a.Tag < b.Tag - })); diff != "" { + }), + ); diff != "" { t.Fatalf("outbound response doesn't match config (-want +got):\n%s", diff) } } @@ -467,7 +469,8 @@ func TestCommanderAddRemoveUser(t *testing.T) { Id: u2.String(), }), }, - }), + }, + ), }) common.Must(err) if resp == nil { diff --git a/transport/internet/browser_dialer/dialer.go b/transport/internet/browser_dialer/dialer.go index 3be712d7..5705f950 100644 --- a/transport/internet/browser_dialer/dialer.go +++ b/transport/internet/browser_dialer/dialer.go @@ -26,9 +26,11 @@ type task struct { StreamResponse bool `json:"streamResponse"` } -var conns chan *websocket.Conn -var server *http.Server -var mu sync.Mutex +var ( + conns chan *websocket.Conn + server *http.Server + mu sync.Mutex +) var upgrader = &websocket.Upgrader{ ReadBufferSize: 0, diff --git a/transport/internet/config.go b/transport/internet/config.go index 0b6f9324..460cdc4f 100644 --- a/transport/internet/config.go +++ b/transport/internet/config.go @@ -8,9 +8,7 @@ import ( type ConfigCreator func() interface{} -var ( - globalTransportConfigCreatorCache = make(map[string]ConfigCreator) -) +var globalTransportConfigCreatorCache = make(map[string]ConfigCreator) var strategy = [][]byte{ // name strategy, prefer, fallback diff --git a/transport/internet/dialer.go b/transport/internet/dialer.go index 9342f26f..475d0ff9 100644 --- a/transport/internet/dialer.go +++ b/transport/internet/dialer.go @@ -133,7 +133,6 @@ func redirect(ctx context.Context, dst net.Destination, obt string, h outbound.H cnc.ConnectionOnClose(common.ChainedClosable{uw, dw}), ) return nc - } func checkAddressPortStrategy(ctx context.Context, dest net.Destination, sockopt *SocketConfig) (*net.Destination, error) { diff --git a/transport/internet/finalmask/realm/client.go b/transport/internet/finalmask/realm/client.go index ab7ba6bb..f2c0fb7c 100644 --- a/transport/internet/finalmask/realm/client.go +++ b/transport/internet/finalmask/realm/client.go @@ -91,15 +91,15 @@ func (c *realmConnClient) getpeer() (net.PacketConn, error) { } func (c *realmConnClient) discover(servers []*net.UDPAddr) []netip.AddrPort { - var transactionIDs = make(map[[stun.TransactionIDSize]byte]struct{}, len(servers)) + transactionIDs := make(map[[stun.TransactionIDSize]byte]struct{}, len(servers)) for _, server := range servers { msg := common.Must2(stun.Build(stun.TransactionID, stun.BindingRequest)) transactionIDs[msg.TransactionID] = struct{}{} _, _ = c.PacketConn.WriteTo(msg.Raw, server) } - var buf = make([]byte, 1500) - var results = make([]netip.AddrPort, 0, len(servers)) + buf := make([]byte, 1500) + results := make([]netip.AddrPort, 0, len(servers)) c.PacketConn.SetReadDeadline(time.Now().Add(defaultSTUNTimeout)) for len(transactionIDs) > 0 { n, _, err := c.PacketConn.ReadFrom(buf) diff --git a/transport/internet/finalmask/realm/server.go b/transport/internet/finalmask/realm/server.go index 544bf49d..aacd4d0f 100644 --- a/transport/internet/finalmask/realm/server.go +++ b/transport/internet/finalmask/realm/server.go @@ -16,9 +16,11 @@ import ( "github.com/xtls/xray-core/common/errors" ) -const defaultEventBuffer = 16 -const defaultStunCacheTTL = time.Second * 10 -const defaultHeartbeatInterval = time.Second * 15 +const ( + defaultEventBuffer = 16 + defaultStunCacheTTL = time.Second * 10 + defaultHeartbeatInterval = time.Second * 15 +) type PunchPacketEvent struct { Addr netip.AddrPort @@ -124,15 +126,15 @@ func (c *realmConnServer) waitctx(ctx context.Context, t time.Duration) bool { } func (c *realmConnServer) discover(servers []*net.UDPAddr) []netip.AddrPort { - var transactionIDs = make(map[[stun.TransactionIDSize]byte]struct{}, len(servers)) + transactionIDs := make(map[[stun.TransactionIDSize]byte]struct{}, len(servers)) for _, server := range servers { msg := common.Must2(stun.Build(stun.TransactionID, stun.BindingRequest)) transactionIDs[msg.TransactionID] = struct{}{} _, _ = c.PacketConn.WriteTo(msg.Raw, server) } - var deadline = time.NewTimer(c.stunTimeout) - var results = make([]netip.AddrPort, 0, len(servers)) + deadline := time.NewTimer(c.stunTimeout) + results := make([]netip.AddrPort, 0, len(servers)) for len(transactionIDs) > 0 { select { case <-deadline.C: diff --git a/transport/internet/finalmask/realm/stun.go b/transport/internet/finalmask/realm/stun.go index 5ff59bb3..07b07dc4 100644 --- a/transport/internet/finalmask/realm/stun.go +++ b/transport/internet/finalmask/realm/stun.go @@ -35,8 +35,8 @@ func resolveSTUNServers(local net.IP, servers []string) []*net.UDPAddr { } } - var seen = make(map[string]struct{}) - var addrs = make([]*net.UDPAddr, 0, len(servers)) + seen := make(map[string]struct{}) + addrs := make([]*net.UDPAddr, 0, len(servers)) for _, server := range servers { h, p, err := net.SplitHostPort(server) if err != nil { @@ -116,8 +116,8 @@ func candidatePunchAddrs(locals, peers []netip.AddrPort) ([]netip.AddrPort, map[ break } } - var seen = make(map[netip.AddrPort]struct{}, len(peers)) - var candidates = make([]netip.AddrPort, 0, len(peers)) + seen := make(map[netip.AddrPort]struct{}, len(peers)) + candidates := make([]netip.AddrPort, 0, len(peers)) for _, peer := range peers { if _, ok := seen[peer]; ok { continue diff --git a/transport/internet/finalmask/sudoku/sudoku_test.go b/transport/internet/finalmask/sudoku/sudoku_test.go index f0780e2b..1a01de92 100644 --- a/transport/internet/finalmask/sudoku/sudoku_test.go +++ b/transport/internet/finalmask/sudoku/sudoku_test.go @@ -934,7 +934,8 @@ func cloneConfig(cfg *Config) *Config { } func defaultApps(cfg *core.Config) *core.Config { - cfg.App = append(cfg.App, + cfg.App = append( + cfg.App, serial.ToTypedMessage(&log.Config{ ErrorLogLevel: clog.Severity_Warning, ErrorLogType: log.LogType_Console, diff --git a/transport/internet/finalmask/tcp_test.go b/transport/internet/finalmask/tcp_test.go index 4c07d983..2ae888d0 100644 --- a/transport/internet/finalmask/tcp_test.go +++ b/transport/internet/finalmask/tcp_test.go @@ -49,7 +49,7 @@ type layerMaskTcp struct { type failingWrapMask struct{} -func (failingWrapMask) TCP() {} +func (failingWrapMask) TCP() {} func (f failingWrapMask) WrapConnClient(raw net.Conn) (net.Conn, error) { return raw, nil } func (f failingWrapMask) WrapConnServer(raw net.Conn) (net.Conn, error) { return nil, io.ErrClosedPipe diff --git a/transport/internet/finalmask/udp_test.go b/transport/internet/finalmask/udp_test.go index c829d1ad..8a507d2e 100644 --- a/transport/internet/finalmask/udp_test.go +++ b/transport/internet/finalmask/udp_test.go @@ -123,10 +123,12 @@ func (c *scriptedPacketConn) SetDeadline(t time.Time) error { c.deadline.Store(t.UnixNano()) return nil } + func (c *scriptedPacketConn) SetReadDeadline(t time.Time) error { c.deadline.Store(t.UnixNano()) return nil } + func (c *scriptedPacketConn) SetWriteDeadline(t time.Time) error { c.deadline.Store(t.UnixNano()) return nil diff --git a/transport/internet/finalmask/xdns/client.go b/transport/internet/finalmask/xdns/client.go index 7513a0a9..557347f2 100644 --- a/transport/internet/finalmask/xdns/client.go +++ b/transport/internet/finalmask/xdns/client.go @@ -73,7 +73,7 @@ func NewConnClient(c *Config, raw net.PacketConn) (net.PacketConn, error) { } var resolverAddrs []*net.UDPAddr - var resolverSend = make(map[string]*atomic.Uint32) + resolverSend := make(map[string]*atomic.Uint32) for _, rs := range servers { h, p, err := net.SplitHostPort(rs) if err != nil { diff --git a/transport/internet/finalmask/xdns/dns_test.go b/transport/internet/finalmask/xdns/dns_test.go index 45da317d..7eac084e 100644 --- a/transport/internet/finalmask/xdns/dns_test.go +++ b/transport/internet/finalmask/xdns/dns_test.go @@ -35,19 +35,25 @@ func TestName(t *testing.T) { {[][]byte{[]byte("a"), {}, []byte("c")}, ErrZeroLengthLabel, ""}, // 63 octets. - {[][]byte{[]byte("0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABCDE")}, nil, - "0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABCDE"}, + { + [][]byte{[]byte("0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABCDE")}, + nil, + "0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABCDE", + }, // 64 octets. {[][]byte{[]byte("0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABCDEF")}, ErrLabelTooLong, ""}, // 64+64+64+62 octets. - {[][]byte{ - []byte("0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABCDE"), - []byte("0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABCDE"), - []byte("0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABCDE"), - []byte("0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABC"), - }, nil, - "0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABCDE.0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABCDE.0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABCDE.0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABC"}, + { + [][]byte{ + []byte("0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABCDE"), + []byte("0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABCDE"), + []byte("0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABCDE"), + []byte("0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABC"), + }, + nil, + "0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABCDE.0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABCDE.0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABCDE.0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABC", + }, // 64+64+64+63 octets. {[][]byte{ []byte("0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABCDE"), @@ -56,27 +62,269 @@ func TestName(t *testing.T) { []byte("0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABCD"), }, ErrNameTooLong, ""}, // 127 one-octet labels. - {[][]byte{ - {'0'}, {'1'}, {'2'}, {'3'}, {'4'}, {'5'}, {'6'}, {'7'}, {'8'}, {'9'}, {'a'}, {'b'}, {'c'}, {'d'}, {'e'}, {'f'}, - {'0'}, {'1'}, {'2'}, {'3'}, {'4'}, {'5'}, {'6'}, {'7'}, {'8'}, {'9'}, {'A'}, {'B'}, {'C'}, {'D'}, {'E'}, {'F'}, - {'0'}, {'1'}, {'2'}, {'3'}, {'4'}, {'5'}, {'6'}, {'7'}, {'8'}, {'9'}, {'a'}, {'b'}, {'c'}, {'d'}, {'e'}, {'f'}, - {'0'}, {'1'}, {'2'}, {'3'}, {'4'}, {'5'}, {'6'}, {'7'}, {'8'}, {'9'}, {'A'}, {'B'}, {'C'}, {'D'}, {'E'}, {'F'}, - {'0'}, {'1'}, {'2'}, {'3'}, {'4'}, {'5'}, {'6'}, {'7'}, {'8'}, {'9'}, {'a'}, {'b'}, {'c'}, {'d'}, {'e'}, {'f'}, - {'0'}, {'1'}, {'2'}, {'3'}, {'4'}, {'5'}, {'6'}, {'7'}, {'8'}, {'9'}, {'A'}, {'B'}, {'C'}, {'D'}, {'E'}, {'F'}, - {'0'}, {'1'}, {'2'}, {'3'}, {'4'}, {'5'}, {'6'}, {'7'}, {'8'}, {'9'}, {'a'}, {'b'}, {'c'}, {'d'}, {'e'}, {'f'}, - {'0'}, {'1'}, {'2'}, {'3'}, {'4'}, {'5'}, {'6'}, {'7'}, {'8'}, {'9'}, {'A'}, {'B'}, {'C'}, {'D'}, {'E'}, - }, nil, - "0.1.2.3.4.5.6.7.8.9.a.b.c.d.e.f.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.0.1.2.3.4.5.6.7.8.9.a.b.c.d.e.f.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.0.1.2.3.4.5.6.7.8.9.a.b.c.d.e.f.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.0.1.2.3.4.5.6.7.8.9.a.b.c.d.e.f.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E"}, + { + [][]byte{ + {'0'}, + {'1'}, + {'2'}, + {'3'}, + {'4'}, + {'5'}, + {'6'}, + {'7'}, + {'8'}, + {'9'}, + {'a'}, + {'b'}, + {'c'}, + {'d'}, + {'e'}, + {'f'}, + {'0'}, + {'1'}, + {'2'}, + {'3'}, + {'4'}, + {'5'}, + {'6'}, + {'7'}, + {'8'}, + {'9'}, + {'A'}, + {'B'}, + {'C'}, + {'D'}, + {'E'}, + {'F'}, + {'0'}, + {'1'}, + {'2'}, + {'3'}, + {'4'}, + {'5'}, + {'6'}, + {'7'}, + {'8'}, + {'9'}, + {'a'}, + {'b'}, + {'c'}, + {'d'}, + {'e'}, + {'f'}, + {'0'}, + {'1'}, + {'2'}, + {'3'}, + {'4'}, + {'5'}, + {'6'}, + {'7'}, + {'8'}, + {'9'}, + {'A'}, + {'B'}, + {'C'}, + {'D'}, + {'E'}, + {'F'}, + {'0'}, + {'1'}, + {'2'}, + {'3'}, + {'4'}, + {'5'}, + {'6'}, + {'7'}, + {'8'}, + {'9'}, + {'a'}, + {'b'}, + {'c'}, + {'d'}, + {'e'}, + {'f'}, + {'0'}, + {'1'}, + {'2'}, + {'3'}, + {'4'}, + {'5'}, + {'6'}, + {'7'}, + {'8'}, + {'9'}, + {'A'}, + {'B'}, + {'C'}, + {'D'}, + {'E'}, + {'F'}, + {'0'}, + {'1'}, + {'2'}, + {'3'}, + {'4'}, + {'5'}, + {'6'}, + {'7'}, + {'8'}, + {'9'}, + {'a'}, + {'b'}, + {'c'}, + {'d'}, + {'e'}, + {'f'}, + {'0'}, + {'1'}, + {'2'}, + {'3'}, + {'4'}, + {'5'}, + {'6'}, + {'7'}, + {'8'}, + {'9'}, + {'A'}, + {'B'}, + {'C'}, + {'D'}, + {'E'}, + }, + nil, + "0.1.2.3.4.5.6.7.8.9.a.b.c.d.e.f.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.0.1.2.3.4.5.6.7.8.9.a.b.c.d.e.f.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.0.1.2.3.4.5.6.7.8.9.a.b.c.d.e.f.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F.0.1.2.3.4.5.6.7.8.9.a.b.c.d.e.f.0.1.2.3.4.5.6.7.8.9.A.B.C.D.E", + }, // 128 one-octet labels. {[][]byte{ - {'0'}, {'1'}, {'2'}, {'3'}, {'4'}, {'5'}, {'6'}, {'7'}, {'8'}, {'9'}, {'a'}, {'b'}, {'c'}, {'d'}, {'e'}, {'f'}, - {'0'}, {'1'}, {'2'}, {'3'}, {'4'}, {'5'}, {'6'}, {'7'}, {'8'}, {'9'}, {'A'}, {'B'}, {'C'}, {'D'}, {'E'}, {'F'}, - {'0'}, {'1'}, {'2'}, {'3'}, {'4'}, {'5'}, {'6'}, {'7'}, {'8'}, {'9'}, {'a'}, {'b'}, {'c'}, {'d'}, {'e'}, {'f'}, - {'0'}, {'1'}, {'2'}, {'3'}, {'4'}, {'5'}, {'6'}, {'7'}, {'8'}, {'9'}, {'A'}, {'B'}, {'C'}, {'D'}, {'E'}, {'F'}, - {'0'}, {'1'}, {'2'}, {'3'}, {'4'}, {'5'}, {'6'}, {'7'}, {'8'}, {'9'}, {'a'}, {'b'}, {'c'}, {'d'}, {'e'}, {'f'}, - {'0'}, {'1'}, {'2'}, {'3'}, {'4'}, {'5'}, {'6'}, {'7'}, {'8'}, {'9'}, {'A'}, {'B'}, {'C'}, {'D'}, {'E'}, {'F'}, - {'0'}, {'1'}, {'2'}, {'3'}, {'4'}, {'5'}, {'6'}, {'7'}, {'8'}, {'9'}, {'a'}, {'b'}, {'c'}, {'d'}, {'e'}, {'f'}, - {'0'}, {'1'}, {'2'}, {'3'}, {'4'}, {'5'}, {'6'}, {'7'}, {'8'}, {'9'}, {'A'}, {'B'}, {'C'}, {'D'}, {'E'}, {'F'}, + {'0'}, + {'1'}, + {'2'}, + {'3'}, + {'4'}, + {'5'}, + {'6'}, + {'7'}, + {'8'}, + {'9'}, + {'a'}, + {'b'}, + {'c'}, + {'d'}, + {'e'}, + {'f'}, + {'0'}, + {'1'}, + {'2'}, + {'3'}, + {'4'}, + {'5'}, + {'6'}, + {'7'}, + {'8'}, + {'9'}, + {'A'}, + {'B'}, + {'C'}, + {'D'}, + {'E'}, + {'F'}, + {'0'}, + {'1'}, + {'2'}, + {'3'}, + {'4'}, + {'5'}, + {'6'}, + {'7'}, + {'8'}, + {'9'}, + {'a'}, + {'b'}, + {'c'}, + {'d'}, + {'e'}, + {'f'}, + {'0'}, + {'1'}, + {'2'}, + {'3'}, + {'4'}, + {'5'}, + {'6'}, + {'7'}, + {'8'}, + {'9'}, + {'A'}, + {'B'}, + {'C'}, + {'D'}, + {'E'}, + {'F'}, + {'0'}, + {'1'}, + {'2'}, + {'3'}, + {'4'}, + {'5'}, + {'6'}, + {'7'}, + {'8'}, + {'9'}, + {'a'}, + {'b'}, + {'c'}, + {'d'}, + {'e'}, + {'f'}, + {'0'}, + {'1'}, + {'2'}, + {'3'}, + {'4'}, + {'5'}, + {'6'}, + {'7'}, + {'8'}, + {'9'}, + {'A'}, + {'B'}, + {'C'}, + {'D'}, + {'E'}, + {'F'}, + {'0'}, + {'1'}, + {'2'}, + {'3'}, + {'4'}, + {'5'}, + {'6'}, + {'7'}, + {'8'}, + {'9'}, + {'a'}, + {'b'}, + {'c'}, + {'d'}, + {'e'}, + {'f'}, + {'0'}, + {'1'}, + {'2'}, + {'3'}, + {'4'}, + {'5'}, + {'6'}, + {'7'}, + {'8'}, + {'9'}, + {'A'}, + {'B'}, + {'C'}, + {'D'}, + {'E'}, + {'F'}, }, ErrNameTooLong, ""}, } { // Test that NewName returns proper error codes, and otherwise diff --git a/transport/internet/grpc/dial.go b/transport/internet/grpc/dial.go index c8b8423c..9ffbbfd1 100644 --- a/transport/internet/grpc/dial.go +++ b/transport/internet/grpc/dial.go @@ -10,8 +10,8 @@ import ( c "github.com/xtls/xray-core/common/ctx" "github.com/xtls/xray-core/common/errors" "github.com/xtls/xray-core/common/net" - "github.com/xtls/xray-core/common/utils" "github.com/xtls/xray-core/common/session" + "github.com/xtls/xray-core/common/utils" "github.com/xtls/xray-core/transport/internet" "github.com/xtls/xray-core/transport/internet/grpc/encoding" "github.com/xtls/xray-core/transport/internet/reality" diff --git a/transport/internet/happy_eyeballs.go b/transport/internet/happy_eyeballs.go index d7f30227..08a8a0e3 100644 --- a/transport/internet/happy_eyeballs.go +++ b/transport/internet/happy_eyeballs.go @@ -2,9 +2,10 @@ package internet import ( "context" + "time" + "github.com/xtls/xray-core/common/errors" "github.com/xtls/xray-core/common/net" - "time" ) type result struct { @@ -26,7 +27,7 @@ func TcpRaceDial(ctx context.Context, src net.Address, ips []net.IP, port net.Po ips = sortIPs(ips, prioritizeIPv6, interleave) newCtx, cancel := context.WithCancel(ctx) defer cancel() - var resultCh = make(chan *result, len(ips)) + resultCh := make(chan *result, len(ips)) nextTryIndex := 0 activeNum := uint32(0) timer := time.NewTimer(0) @@ -101,8 +102,8 @@ func sortIPs(ips []net.IP, prioritizeIPv6 bool, interleave uint32) []net.IP { if len(ips) == 0 { return ips } - var ip4 = make([]net.IP, 0, len(ips)) - var ip6 = make([]net.IP, 0, len(ips)) + ip4 := make([]net.IP, 0, len(ips)) + ip6 := make([]net.IP, 0, len(ips)) for _, ip := range ips { parsedIp := net.IPAddress(ip).IP() if len(parsedIp) == net.IPv4len { @@ -116,7 +117,7 @@ func sortIPs(ips []net.IP, prioritizeIPv6 bool, interleave uint32) []net.IP { return ips } - var newIPs = make([]net.IP, 0, len(ips)) + newIPs := make([]net.IP, 0, len(ips)) consumeIP4 := 0 consumeIP6 := 0 consumeTurn := uint32(0) diff --git a/transport/internet/hysteria/dialer.go b/transport/internet/hysteria/dialer.go index dfaac92f..3cca9356 100644 --- a/transport/internet/hysteria/dialer.go +++ b/transport/internet/hysteria/dialer.go @@ -317,8 +317,10 @@ func (m *clientManager) clean() { } } -var manager *clientManager -var initmanager sync.Once +var ( + manager *clientManager + initmanager sync.Once +) func Dial(ctx context.Context, dest net.Destination, streamSettings *internet.MemoryStreamConfig) (stat.Connection, error) { tlsConfig := tls.ConfigFromStreamSettings(streamSettings) diff --git a/transport/internet/kcp/connection.go b/transport/internet/kcp/connection.go index f31e54f0..72e3229a 100644 --- a/transport/internet/kcp/connection.go +++ b/transport/internet/kcp/connection.go @@ -237,12 +237,14 @@ func NewConnection(meta ConnMetadata, writer io.Writer, closer io.Closer, config return !isTerminating() && (conn.sendingWorker.UpdateNecessary() || conn.receivingWorker.UpdateNecessary()) }, isTerminating, - conn.updateTask) + conn.updateTask, + ) conn.pingUpdater = NewUpdater( 5000, // 5 seconds func() bool { return !isTerminated() }, isTerminated, - conn.updateTask) + conn.updateTask, + ) conn.pingUpdater.WakeUp() return conn diff --git a/transport/internet/kcp/connection_test.go b/transport/internet/kcp/connection_test.go index cf1a529d..702d273a 100644 --- a/transport/internet/kcp/connection_test.go +++ b/transport/internet/kcp/connection_test.go @@ -36,8 +36,8 @@ func TestConnectionReadTimeout(t *testing.T) { } func TestConnectionInterface(t *testing.T) { - _ = (io.Writer)(new(Connection)) - _ = (io.Reader)(new(Connection)) - _ = (buf.Reader)(new(Connection)) - _ = (buf.Writer)(new(Connection)) + _ = io.Writer(new(Connection)) + _ = io.Reader(new(Connection)) + _ = buf.Reader(new(Connection)) + _ = buf.Writer(new(Connection)) } diff --git a/transport/internet/reality/config.go b/transport/internet/reality/config.go index 9bc6ee15..0b26621d 100644 --- a/transport/internet/reality/config.go +++ b/transport/internet/reality/config.go @@ -63,7 +63,7 @@ func KeyLogWriterFromConfig(c *Config) io.Writer { return nil } - writer, err := os.OpenFile(c.MasterKeyLog, os.O_CREATE|os.O_RDWR|os.O_APPEND, 0644) + writer, err := os.OpenFile(c.MasterKeyLog, os.O_CREATE|os.O_RDWR|os.O_APPEND, 0o644) if err != nil { errors.LogErrorInner(context.Background(), err, "failed to open ", c.MasterKeyLog, " as master key log") } diff --git a/transport/internet/sockopt_darwin.go b/transport/internet/sockopt_darwin.go index 46995711..73a85d8f 100644 --- a/transport/internet/sockopt_darwin.go +++ b/transport/internet/sockopt_darwin.go @@ -135,7 +135,6 @@ func applyOutboundSocketOptions(network string, address string, fd uintptr, conf if config.Interface != "" { iface, err := net.InterfaceByName(config.Interface) - if err != nil { return errors.New("failed to get interface ", config.Interface).Base(err) } @@ -163,7 +162,7 @@ func applyOutboundSocketOptions(network string, address string, fd uintptr, conf if !strings.HasPrefix(network, custom.Network) { continue } - var level = 0x6 // default TCP + level := 0x6 // default TCP var opt int if len(custom.Opt) == 0 { return errors.New("No opt!") @@ -226,7 +225,6 @@ func applyInboundSocketOptions(network string, fd uintptr, config *SocketConfig) if config.Interface != "" { iface, err := net.InterfaceByName(config.Interface) - if err != nil { return errors.New("failed to get interface ", config.Interface).Base(err) } @@ -260,7 +258,7 @@ func applyInboundSocketOptions(network string, fd uintptr, config *SocketConfig) if !strings.HasPrefix(network, custom.Network) { continue } - var level = 0x6 // default TCP + level := 0x6 // default TCP var opt int if len(custom.Opt) == 0 { return errors.New("No opt!") diff --git a/transport/internet/sockopt_linux.go b/transport/internet/sockopt_linux.go index f1fb3f81..bf100350 100644 --- a/transport/internet/sockopt_linux.go +++ b/transport/internet/sockopt_linux.go @@ -76,7 +76,7 @@ func applyOutboundSocketOptions(network string, address string, fd uintptr, conf if !strings.HasPrefix(network, custom.Network) { continue } - var level = 0x6 // default TCP + level := 0x6 // default TCP var opt int if len(custom.Opt) == 0 { return errors.New("No opt!") @@ -182,7 +182,7 @@ func applyInboundSocketOptions(network string, fd uintptr, config *SocketConfig) if !strings.HasPrefix(network, custom.Network) { continue } - var level = 0x6 // default TCP + level := 0x6 // default TCP var opt int if len(custom.Opt) == 0 { return errors.New("No opt!") diff --git a/transport/internet/sockopt_windows.go b/transport/internet/sockopt_windows.go index 3555b399..dd1df0bd 100644 --- a/transport/internet/sockopt_windows.go +++ b/transport/internet/sockopt_windows.go @@ -94,7 +94,7 @@ func applyOutboundSocketOptions(network string, address string, fd uintptr, conf if !strings.HasPrefix(network, custom.Network) { continue } - var level = 0x6 // default TCP + level := 0x6 // default TCP var opt int if len(custom.Opt) == 0 { return errors.New("No opt!") @@ -155,7 +155,7 @@ func applyInboundSocketOptions(network string, fd uintptr, config *SocketConfig) if !strings.HasPrefix(network, custom.Network) { continue } - var level = 0x6 // default TCP + level := 0x6 // default TCP var opt int if len(custom.Opt) == 0 { return errors.New("No opt!") diff --git a/transport/internet/splithttp/hub.go b/transport/internet/splithttp/hub.go index 9744a985..535549bf 100644 --- a/transport/internet/splithttp/hub.go +++ b/transport/internet/splithttp/hub.go @@ -344,7 +344,6 @@ func (h *requestHandler) ServeHTTP(writer http.ResponseWriter, request *http.Req Payload: payload, Seq: seq, }) - if err != nil { errors.LogInfoInner(context.Background(), err, "failed to upload (PushPayload)") writer.WriteHeader(http.StatusInternalServerError) @@ -604,6 +603,7 @@ func (ln *Listener) Close() error { } return errors.New("listener does not have an HTTP/3 server or a net.listener") } + func getTLSConfig(streamSettings *internet.MemoryStreamConfig) *gotls.Config { config := tls.ConfigFromStreamSettings(streamSettings) if config == nil { @@ -611,6 +611,7 @@ func getTLSConfig(streamSettings *internet.MemoryStreamConfig) *gotls.Config { } return config.GetTLSConfig() } + func init() { common.Must(internet.RegisterTransportListener(protocolName, ListenXH)) } diff --git a/transport/internet/system_dialer.go b/transport/internet/system_dialer.go index 35dc55fa..05adc778 100644 --- a/transport/internet/system_dialer.go +++ b/transport/internet/system_dialer.go @@ -12,9 +12,11 @@ import ( "github.com/xtls/xray-core/features/outbound" ) -var Controllers []func(network, address string, c syscall.RawConn) error -var ControllersLock sync.Mutex -var effectiveSystemDialer SystemDialer = &DefaultSystemDialer{} +var ( + Controllers []func(network, address string, c syscall.RawConn) error + ControllersLock sync.Mutex + effectiveSystemDialer SystemDialer = &DefaultSystemDialer{} +) type SystemDialer interface { Dial(ctx context.Context, source net.Address, destination net.Destination, sockopt *SocketConfig) (net.Conn, error) diff --git a/transport/internet/tls/config.go b/transport/internet/tls/config.go index cfb360c0..0c887804 100644 --- a/transport/internet/tls/config.go +++ b/transport/internet/tls/config.go @@ -459,7 +459,7 @@ func (c *Config) GetTLSConfig(opts ...Option) *tls.Config { } if len(c.MasterKeyLog) > 0 && c.MasterKeyLog != "none" { - writer, err := os.OpenFile(c.MasterKeyLog, os.O_CREATE|os.O_RDWR|os.O_APPEND, 0644) + writer, err := os.OpenFile(c.MasterKeyLog, os.O_CREATE|os.O_RDWR|os.O_APPEND, 0o644) if err != nil { errors.LogErrorInner(context.Background(), err, "failed to open ", c.MasterKeyLog, " as master key log") } else { diff --git a/transport/internet/tls/ech.go b/transport/internet/tls/ech.go index 1a691f97..9de124c1 100644 --- a/transport/internet/tls/ech.go +++ b/transport/internet/tls/ech.go @@ -326,9 +326,7 @@ func ConvertToGoECHKeys(data []byte) ([]tls.EncryptedClientHelloKey, error) { return keys, ErrInvalidLen } child := cryptobyte.String(s[:2+keyLength+2+configLength]) - var ( - sk, config cryptobyte.String - ) + var sk, config cryptobyte.String if !child.ReadUint16LengthPrefixed(&sk) || !child.ReadUint16LengthPrefixed(&config) || !child.Empty() { return keys, ErrInvalidLen } diff --git a/transport/internet/tls/ech_test.go b/transport/internet/tls/ech_test.go index 69db965b..ed67cede 100644 --- a/transport/internet/tls/ech_test.go +++ b/transport/internet/tls/ech_test.go @@ -44,7 +44,6 @@ func TestECHDial(t *testing.T) { echConfigCache, ok := GlobalECHConfigCache.Load(ECHCacheKey("udp://1.1.1.1", "encryptedsni.com", nil)) if !ok { t.Error("ECH config cache not found") - } ok = echConfigCache.UpdateLock.TryLock() if !ok { diff --git a/transport/internet/tls/tls.go b/transport/internet/tls/tls.go index 7fa3c25b..f9d368d8 100644 --- a/transport/internet/tls/tls.go +++ b/transport/internet/tls/tls.go @@ -22,8 +22,10 @@ type Interface interface { NegotiatedProtocol() string } -var _ buf.Writer = (*Conn)(nil) -var _ Interface = (*Conn)(nil) +var ( + _ buf.Writer = (*Conn)(nil) + _ Interface = (*Conn)(nil) +) type Conn struct { *tls.Conn diff --git a/transport/pipe/pipe.go b/transport/pipe/pipe.go index f4b78303..6343adb7 100644 --- a/transport/pipe/pipe.go +++ b/transport/pipe/pipe.go @@ -59,7 +59,7 @@ func New(opts ...Option) (*Reader, *Writer) { } for _, opt := range opts { - opt(&(p.option)) + opt(&p.option) } return &Reader{ diff --git a/transport/pipe/pipe_test.go b/transport/pipe/pipe_test.go index a5cb25c5..79e369aa 100644 --- a/transport/pipe/pipe_test.go +++ b/transport/pipe/pipe_test.go @@ -129,12 +129,12 @@ func TestPipeWriteMultiThread(t *testing.T) { } func TestInterfaces(t *testing.T) { - _ = (buf.Reader)(new(Reader)) - _ = (buf.TimeoutReader)(new(Reader)) + _ = buf.Reader(new(Reader)) + _ = buf.TimeoutReader(new(Reader)) - _ = (common.Interruptible)(new(Reader)) - _ = (common.Interruptible)(new(Writer)) - _ = (common.Closable)(new(Writer)) + _ = common.Interruptible(new(Reader)) + _ = common.Interruptible(new(Writer)) + _ = common.Closable(new(Writer)) } func BenchmarkPipeReadWrite(b *testing.B) {