mirror of
https://github.com/XTLS/Xray-core.git
synced 2026-09-15 22:10:26 +00:00
GitHub Action CI: Add Go source file format check (#6090)
https://github.com/XTLS/Xray-core/pull/6057#issuecomment-4364819830 And https://github.com/XTLS/Xray-core/pull/6149#issuecomment-4546876261
This commit is contained in:
@@ -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 }}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
+2
-2
@@ -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
|
||||
}
|
||||
|
||||
@@ -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")),
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
|
||||
|
||||
@@ -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}
|
||||
}
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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{
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
)
|
||||
|
||||
func TestInterface(t *testing.T) {
|
||||
_ = (stats.Manager)(new(Manager))
|
||||
_ = stats.Manager(new(Manager))
|
||||
}
|
||||
|
||||
func TestStatsChannelRunnable(t *testing.T) {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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:]
|
||||
}
|
||||
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
|
||||
@@ -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"),
|
||||
|
||||
@@ -98,7 +98,6 @@ func (l *generalLogger) run() {
|
||||
}
|
||||
|
||||
func (l *generalLogger) Handle(msg Message) {
|
||||
|
||||
select {
|
||||
case l.buffer <- msg:
|
||||
default:
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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,
|
||||
)
|
||||
|
||||
+77
-43
@@ -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.
|
||||
|
||||
@@ -109,4 +109,4 @@ func (m *TypedSyncMap[K, V]) Swap(key K, value V) (previous V, loaded bool) {
|
||||
previous = anyPrevious.(V)
|
||||
}
|
||||
return previous, loaded
|
||||
}
|
||||
}
|
||||
|
||||
+19
-20
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -34,7 +34,6 @@ func (ctx *Context) GetSourceIPs() []net.IP {
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
// GetSourcePort implements routing.Context.
|
||||
|
||||
@@ -48,4 +48,5 @@ var configLoader = NewJSONConfigLoader(
|
||||
"http": func() interface{} { return new(HTTPResponse) },
|
||||
},
|
||||
"type",
|
||||
"")
|
||||
"",
|
||||
)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
+3
-3
@@ -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)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+62
-19
@@ -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.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,7 +59,6 @@ func executeBalancerInfo(cmd *base.Command, args []string) {
|
||||
}
|
||||
|
||||
showBalancerInfo(resp.Balancer)
|
||||
|
||||
}
|
||||
|
||||
func showBalancerInfo(b *routerService.BalancerMsg) {
|
||||
|
||||
@@ -62,7 +62,8 @@ func addInboundUserAction(ctx context.Context, client handlerService.HandlerServ
|
||||
Operation: cserial.ToTypedMessage(
|
||||
&handlerService.AddUserOperation{
|
||||
User: user,
|
||||
}),
|
||||
},
|
||||
),
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -50,7 +50,8 @@ func executeRemoveUsers(cmd *base.Command, args []string) {
|
||||
Operation: cserial.ToTypedMessage(
|
||||
&handlerService.RemoveUserOperation{
|
||||
Email: email,
|
||||
}),
|
||||
},
|
||||
),
|
||||
})
|
||||
if err == nil {
|
||||
success += 1
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -56,5 +56,4 @@ func executeRemoveRules(cmd *base.Command, args []string) {
|
||||
}
|
||||
showJSONResponse(resp)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -136,5 +136,4 @@ func executeSourceIpBlock(cmd *base.Command, args []string) {
|
||||
base.Fatalf("failed to perform AddRule: %s", err)
|
||||
}
|
||||
showJSONResponse(resp)
|
||||
|
||||
}
|
||||
|
||||
@@ -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, "")
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
Vendored
+10
-12
@@ -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
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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)))
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
|
||||
"google.golang.org/protobuf/proto"
|
||||
|
||||
"github.com/xtls/xray-core/common"
|
||||
|
||||
@@ -312,7 +312,6 @@ func (s *Server) handleUDPPayload(ctx context.Context, sessionPolicy policy.Sess
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if err := task.Run(ctx, requestDone); err != nil {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -9,8 +9,7 @@ import (
|
||||
"gvisor.dev/gvisor/pkg/tcpip/stack"
|
||||
)
|
||||
|
||||
type DefaultTun struct {
|
||||
}
|
||||
type DefaultTun struct{}
|
||||
|
||||
// DefaultTun implements Tun
|
||||
var _ Tun = (*DefaultTun)(nil)
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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|"
|
||||
}
|
||||
|
||||
@@ -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().
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package outbound
|
||||
|
||||
import (
|
||||
|
||||
"github.com/xtls/xray-core/common/net"
|
||||
"github.com/xtls/xray-core/common/protocol"
|
||||
)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
)
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user