mirror of
https://github.com/XTLS/Xray-core.git
synced 2025-12-18 21:24:37 +03:00
Compare commits
10 Commits
fix-vision
...
optimize-p
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d5f17ab4fc | ||
|
|
a610a4c89a | ||
|
|
b451f8929d | ||
|
|
81f8f398c7 | ||
|
|
aea123842b | ||
|
|
bd7503d506 | ||
|
|
903214a0f0 | ||
|
|
e403abe360 | ||
|
|
c123f163c2 | ||
|
|
93312d29e5 |
@@ -4,7 +4,6 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"math"
|
"math"
|
||||||
"math/big"
|
"math/big"
|
||||||
gonet "net"
|
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -17,7 +16,7 @@ import (
|
|||||||
|
|
||||||
type Holder struct {
|
type Holder struct {
|
||||||
domainToIP cache.Lru
|
domainToIP cache.Lru
|
||||||
ipRange *gonet.IPNet
|
ipRange *net.IPNet
|
||||||
mu *sync.Mutex
|
mu *sync.Mutex
|
||||||
|
|
||||||
config *FakeDnsPool
|
config *FakeDnsPool
|
||||||
@@ -79,10 +78,10 @@ func (fkdns *Holder) initializeFromConfig() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (fkdns *Holder) initialize(ipPoolCidr string, lruSize int) error {
|
func (fkdns *Holder) initialize(ipPoolCidr string, lruSize int) error {
|
||||||
var ipRange *gonet.IPNet
|
var ipRange *net.IPNet
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
if _, ipRange, err = gonet.ParseCIDR(ipPoolCidr); err != nil {
|
if _, ipRange, err = net.ParseCIDR(ipPoolCidr); err != nil {
|
||||||
return errors.New("Unable to parse CIDR for Fake DNS IP assignment").Base(err).AtError()
|
return errors.New("Unable to parse CIDR for Fake DNS IP assignment").Base(err).AtError()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package fakedns
|
package fakedns
|
||||||
|
|
||||||
import (
|
import (
|
||||||
gonet "net"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
@@ -155,7 +154,7 @@ func TestFakeDNSMulti(t *testing.T) {
|
|||||||
assert.True(t, inPool)
|
assert.True(t, inPool)
|
||||||
})
|
})
|
||||||
t.Run("ipv6", func(t *testing.T) {
|
t.Run("ipv6", func(t *testing.T) {
|
||||||
ip, err := gonet.ResolveIPAddr("ip", "fddd:c5b4:ff5f:f4f0::5")
|
ip, err := net.ResolveIPAddr("ip", "fddd:c5b4:ff5f:f4f0::5")
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
inPool := fakeMulti.IsIPInIPPool(net.IPAddress(ip.IP))
|
inPool := fakeMulti.IsIPInIPPool(net.IPAddress(ip.IP))
|
||||||
assert.True(t, inPool)
|
assert.True(t, inPool)
|
||||||
@@ -165,7 +164,7 @@ func TestFakeDNSMulti(t *testing.T) {
|
|||||||
assert.False(t, inPool)
|
assert.False(t, inPool)
|
||||||
})
|
})
|
||||||
t.Run("ipv6_inverse", func(t *testing.T) {
|
t.Run("ipv6_inverse", func(t *testing.T) {
|
||||||
ip, err := gonet.ResolveIPAddr("ip", "fcdd:c5b4:ff5f:f4f0::5")
|
ip, err := net.ResolveIPAddr("ip", "fcdd:c5b4:ff5f:f4f0::5")
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
inPool := fakeMulti.IsIPInIPPool(net.IPAddress(ip.IP))
|
inPool := fakeMulti.IsIPInIPPool(net.IPAddress(ip.IP))
|
||||||
assert.False(t, inPool)
|
assert.False(t, inPool)
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package inbound
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
gonet "net"
|
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
@@ -565,12 +564,12 @@ func (w *dsWorker) Close() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func IsLocal(ip net.IP) bool {
|
func IsLocal(ip net.IP) bool {
|
||||||
addrs, err := gonet.InterfaceAddrs()
|
addrs, err := net.InterfaceAddrs()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
for _, addr := range addrs {
|
for _, addr := range addrs {
|
||||||
if ipnet, ok := addr.(*gonet.IPNet); ok {
|
if ipnet, ok := addr.(*net.IPNet); ok {
|
||||||
if ipnet.IP.Equal(ip) {
|
if ipnet.IP.Equal(ip) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import (
|
|||||||
goerrors "errors"
|
goerrors "errors"
|
||||||
"io"
|
"io"
|
||||||
"math/big"
|
"math/big"
|
||||||
gonet "net"
|
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/xtls/xray-core/common/dice"
|
"github.com/xtls/xray-core/common/dice"
|
||||||
@@ -398,7 +397,7 @@ func (h *Handler) ProxySettings() *serial.TypedMessage {
|
|||||||
|
|
||||||
func ParseRandomIP(addr net.Address, prefix string) net.Address {
|
func ParseRandomIP(addr net.Address, prefix string) net.Address {
|
||||||
|
|
||||||
_, ipnet, _ := gonet.ParseCIDR(addr.IP().String() + "/" + prefix)
|
_, ipnet, _ := net.ParseCIDR(addr.IP().String() + "/" + prefix)
|
||||||
|
|
||||||
ones, bits := ipnet.Mask.Size()
|
ones, bits := ipnet.Mask.Size()
|
||||||
subnetSize := new(big.Int).Lsh(big.NewInt(1), uint(bits-ones))
|
subnetSize := new(big.Int).Lsh(big.NewInt(1), uint(bits-ones))
|
||||||
@@ -412,5 +411,5 @@ func ParseRandomIP(addr net.Address, prefix string) net.Address {
|
|||||||
padded := make([]byte, len(ipnet.IP))
|
padded := make([]byte, len(ipnet.IP))
|
||||||
copy(padded[len(padded)-len(rndBytes):], rndBytes)
|
copy(padded[len(padded)-len(rndBytes):], rndBytes)
|
||||||
|
|
||||||
return net.ParseAddress(gonet.IP(padded).String())
|
return net.ParseAddress(net.IP(padded).String())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ var (
|
|||||||
|
|
||||||
type ListenConfig = net.ListenConfig
|
type ListenConfig = net.ListenConfig
|
||||||
|
|
||||||
|
type KeepAliveConfig = net.KeepAliveConfig
|
||||||
|
|
||||||
var (
|
var (
|
||||||
Listen = net.Listen
|
Listen = net.Listen
|
||||||
ListenTCP = net.ListenTCP
|
ListenTCP = net.ListenTCP
|
||||||
@@ -26,6 +28,12 @@ var FileConn = net.FileConn
|
|||||||
// ParseIP is an alias of net.ParseIP
|
// ParseIP is an alias of net.ParseIP
|
||||||
var ParseIP = net.ParseIP
|
var ParseIP = net.ParseIP
|
||||||
|
|
||||||
|
var ParseCIDR = net.ParseCIDR
|
||||||
|
|
||||||
|
var ResolveIPAddr = net.ResolveIPAddr
|
||||||
|
|
||||||
|
var InterfaceByName = net.InterfaceByName
|
||||||
|
|
||||||
var SplitHostPort = net.SplitHostPort
|
var SplitHostPort = net.SplitHostPort
|
||||||
|
|
||||||
var CIDRMask = net.CIDRMask
|
var CIDRMask = net.CIDRMask
|
||||||
@@ -51,6 +59,8 @@ type (
|
|||||||
UnixConn = net.UnixConn
|
UnixConn = net.UnixConn
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type IPAddr = net.IPAddr
|
||||||
|
|
||||||
// IP is an alias for net.IP.
|
// IP is an alias for net.IP.
|
||||||
type (
|
type (
|
||||||
IP = net.IP
|
IP = net.IP
|
||||||
@@ -82,3 +92,11 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Resolver = net.Resolver
|
type Resolver = net.Resolver
|
||||||
|
|
||||||
|
var DefaultResolver = net.DefaultResolver
|
||||||
|
|
||||||
|
var JoinHostPort = net.JoinHostPort
|
||||||
|
|
||||||
|
var InterfaceAddrs = net.InterfaceAddrs
|
||||||
|
|
||||||
|
var Interfaces = net.Interfaces
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
//go:build !windows
|
|
||||||
// +build !windows
|
|
||||||
|
|
||||||
package ctlcmd
|
|
||||||
|
|
||||||
import "syscall"
|
|
||||||
|
|
||||||
func getSysProcAttr() *syscall.SysProcAttr {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
//go:build windows
|
|
||||||
// +build windows
|
|
||||||
|
|
||||||
package ctlcmd
|
|
||||||
|
|
||||||
import "syscall"
|
|
||||||
|
|
||||||
func getSysProcAttr() *syscall.SysProcAttr {
|
|
||||||
return &syscall.SysProcAttr{
|
|
||||||
HideWindow: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
package ctlcmd
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"io"
|
|
||||||
"os"
|
|
||||||
"os/exec"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/xtls/xray-core/common/buf"
|
|
||||||
"github.com/xtls/xray-core/common/errors"
|
|
||||||
"github.com/xtls/xray-core/common/platform"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Run(args []string, input io.Reader) (buf.MultiBuffer, error) {
|
|
||||||
xctl := platform.GetToolLocation("xctl")
|
|
||||||
if _, err := os.Stat(xctl); err != nil {
|
|
||||||
return nil, errors.New("xctl doesn't exist").Base(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var errBuffer buf.MultiBufferContainer
|
|
||||||
var outBuffer buf.MultiBufferContainer
|
|
||||||
|
|
||||||
cmd := exec.Command(xctl, args...)
|
|
||||||
cmd.Stderr = &errBuffer
|
|
||||||
cmd.Stdout = &outBuffer
|
|
||||||
cmd.SysProcAttr = getSysProcAttr()
|
|
||||||
if input != nil {
|
|
||||||
cmd.Stdin = input
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := cmd.Start(); err != nil {
|
|
||||||
return nil, errors.New("failed to start xctl").Base(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := cmd.Wait(); err != nil {
|
|
||||||
msg := "failed to execute xctl"
|
|
||||||
if errBuffer.Len() > 0 {
|
|
||||||
msg += ": \n" + strings.TrimSpace(errBuffer.MultiBuffer.String())
|
|
||||||
}
|
|
||||||
return nil, errors.New(msg).Base(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// log stderr, info message
|
|
||||||
if !errBuffer.IsEmpty() {
|
|
||||||
errors.LogInfo(context.Background(), "<xctl message> \n", strings.TrimSpace(errBuffer.MultiBuffer.String()))
|
|
||||||
}
|
|
||||||
|
|
||||||
return outBuffer.MultiBuffer, nil
|
|
||||||
}
|
|
||||||
@@ -8,19 +8,10 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
)
|
)
|
||||||
|
|
||||||
func ExpandEnv(s string) string {
|
|
||||||
return os.ExpandEnv(s)
|
|
||||||
}
|
|
||||||
|
|
||||||
func LineSeparator() string {
|
func LineSeparator() string {
|
||||||
return "\n"
|
return "\n"
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetToolLocation(file string) string {
|
|
||||||
toolPath := NewEnvFlag(ToolLocation).GetValue(getExecutableDir)
|
|
||||||
return filepath.Join(toolPath, file)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetAssetLocation searches for `file` in the env dir, the executable dir, and certain locations
|
// GetAssetLocation searches for `file` in the env dir, the executable dir, and certain locations
|
||||||
func GetAssetLocation(file string) string {
|
func GetAssetLocation(file string) string {
|
||||||
assetPath := NewEnvFlag(AssetLocation).GetValue(getExecutableDir)
|
assetPath := NewEnvFlag(AssetLocation).GetValue(getExecutableDir)
|
||||||
|
|||||||
@@ -8,10 +8,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
PluginLocation = "xray.location.plugin"
|
|
||||||
ConfigLocation = "xray.location.config"
|
ConfigLocation = "xray.location.config"
|
||||||
ConfdirLocation = "xray.location.confdir"
|
ConfdirLocation = "xray.location.confdir"
|
||||||
ToolLocation = "xray.location.tool"
|
|
||||||
AssetLocation = "xray.location.asset"
|
AssetLocation = "xray.location.asset"
|
||||||
CertLocation = "xray.location.cert"
|
CertLocation = "xray.location.cert"
|
||||||
|
|
||||||
@@ -79,17 +77,6 @@ func getExecutableDir() string {
|
|||||||
return filepath.Dir(exec)
|
return filepath.Dir(exec)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getExecutableSubDir(dir string) func() string {
|
|
||||||
return func() string {
|
|
||||||
return filepath.Join(getExecutableDir(), dir)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetPluginDirectory() string {
|
|
||||||
pluginDir := NewEnvFlag(PluginLocation).GetValue(getExecutableSubDir("plugins"))
|
|
||||||
return pluginDir
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetConfigurationPath() string {
|
func GetConfigurationPath() string {
|
||||||
configPath := NewEnvFlag(ConfigLocation).GetValue(getExecutableDir)
|
configPath := NewEnvFlag(ConfigLocation).GetValue(getExecutableDir)
|
||||||
return filepath.Join(configPath, "config.json")
|
return filepath.Join(configPath, "config.json")
|
||||||
|
|||||||
@@ -5,20 +5,10 @@ package platform
|
|||||||
|
|
||||||
import "path/filepath"
|
import "path/filepath"
|
||||||
|
|
||||||
func ExpandEnv(s string) string {
|
|
||||||
// TODO
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
|
||||||
func LineSeparator() string {
|
func LineSeparator() string {
|
||||||
return "\r\n"
|
return "\r\n"
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetToolLocation(file string) string {
|
|
||||||
toolPath := NewEnvFlag(ToolLocation).GetValue(getExecutableDir)
|
|
||||||
return filepath.Join(toolPath, file+".exe")
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetAssetLocation searches for `file` in the env dir and the executable dir
|
// GetAssetLocation searches for `file` in the env dir and the executable dir
|
||||||
func GetAssetLocation(file string) string {
|
func GetAssetLocation(file string) string {
|
||||||
assetPath := NewEnvFlag(AssetLocation).GetValue(getExecutableDir)
|
assetPath := NewEnvFlag(AssetLocation).GetValue(getExecutableDir)
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ func GetMergedConfig(args cmdarg.Arg) (string, error) {
|
|||||||
var files []*ConfigSource
|
var files []*ConfigSource
|
||||||
supported := []string{"json", "yaml", "toml"}
|
supported := []string{"json", "yaml", "toml"}
|
||||||
for _, file := range args {
|
for _, file := range args {
|
||||||
format := getFormat(file)
|
format := GetFormat(file)
|
||||||
if slices.Contains(supported, format) {
|
if slices.Contains(supported, format) {
|
||||||
files = append(files, &ConfigSource{
|
files = append(files, &ConfigSource{
|
||||||
Name: file,
|
Name: file,
|
||||||
@@ -98,7 +98,7 @@ func getExtension(filename string) string {
|
|||||||
return filename[idx+1:]
|
return filename[idx+1:]
|
||||||
}
|
}
|
||||||
|
|
||||||
func getFormat(filename string) string {
|
func GetFormat(filename string) string {
|
||||||
return GetFormatByExtension(getExtension(filename))
|
return GetFormatByExtension(getExtension(filename))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -112,7 +112,7 @@ func LoadConfig(formatName string, input interface{}) (*Config, error) {
|
|||||||
|
|
||||||
if formatName == "auto" {
|
if formatName == "auto" {
|
||||||
if file != "stdin:" {
|
if file != "stdin:" {
|
||||||
f = getFormat(file)
|
f = GetFormat(file)
|
||||||
} else {
|
} else {
|
||||||
f = "json"
|
f = "json"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ import (
|
|||||||
var (
|
var (
|
||||||
Version_x byte = 25
|
Version_x byte = 25
|
||||||
Version_y byte = 12
|
Version_y byte = 12
|
||||||
Version_z byte = 1
|
Version_z byte = 8
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|||||||
14
go.mod
14
go.mod
@@ -21,10 +21,10 @@ require (
|
|||||||
github.com/vishvananda/netlink v1.3.1
|
github.com/vishvananda/netlink v1.3.1
|
||||||
github.com/xtls/reality v0.0.0-20251014195629-e4eec4520535
|
github.com/xtls/reality v0.0.0-20251014195629-e4eec4520535
|
||||||
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba
|
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba
|
||||||
golang.org/x/crypto v0.44.0
|
golang.org/x/crypto v0.46.0
|
||||||
golang.org/x/net v0.47.0
|
golang.org/x/net v0.48.0
|
||||||
golang.org/x/sync v0.18.0
|
golang.org/x/sync v0.19.0
|
||||||
golang.org/x/sys v0.38.0
|
golang.org/x/sys v0.39.0
|
||||||
golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173
|
golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173
|
||||||
google.golang.org/grpc v1.77.0
|
google.golang.org/grpc v1.77.0
|
||||||
google.golang.org/protobuf v1.36.10
|
google.golang.org/protobuf v1.36.10
|
||||||
@@ -46,10 +46,10 @@ require (
|
|||||||
github.com/quic-go/qpack v0.6.0 // indirect
|
github.com/quic-go/qpack v0.6.0 // indirect
|
||||||
github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 // indirect
|
github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 // indirect
|
||||||
github.com/vishvananda/netns v0.0.5 // indirect
|
github.com/vishvananda/netns v0.0.5 // indirect
|
||||||
golang.org/x/mod v0.29.0 // indirect
|
golang.org/x/mod v0.30.0 // indirect
|
||||||
golang.org/x/text v0.31.0 // indirect
|
golang.org/x/text v0.32.0 // indirect
|
||||||
golang.org/x/time v0.12.0 // indirect
|
golang.org/x/time v0.12.0 // indirect
|
||||||
golang.org/x/tools v0.38.0 // indirect
|
golang.org/x/tools v0.39.0 // indirect
|
||||||
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect
|
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 // indirect
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 // indirect
|
||||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||||
|
|||||||
28
go.sum
28
go.sum
@@ -95,20 +95,20 @@ go4.org/netipx v0.0.0-20231129151722-fdeea329fbba h1:0b9z3AuHCjxk0x/opv64kcgZLBs
|
|||||||
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba/go.mod h1:PLyyIXexvUFg3Owu6p/WfdlivPbZJsZdgWZlrGope/Y=
|
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba/go.mod h1:PLyyIXexvUFg3Owu6p/WfdlivPbZJsZdgWZlrGope/Y=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.44.0 h1:A97SsFvM3AIwEEmTBiaxPPTYpDC47w720rdiiUvgoAU=
|
golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU=
|
||||||
golang.org/x/crypto v0.44.0/go.mod h1:013i+Nw79BMiQiMsOPcVCB5ZIJbYkerPrGnOa00tvmc=
|
golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0=
|
||||||
golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
|
golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
|
||||||
golang.org/x/mod v0.29.0 h1:HV8lRxZC4l2cr3Zq1LvtOsi/ThTgWnUk/y64QSs8GwA=
|
golang.org/x/mod v0.30.0 h1:fDEXFVZ/fmCKProc/yAXXUijritrDzahmwwefnjoPFk=
|
||||||
golang.org/x/mod v0.29.0/go.mod h1:NyhrlYXJ2H4eJiRy/WDBO6HMqZQ6q9nk4JzS3NuCK+w=
|
golang.org/x/mod v0.30.0/go.mod h1:lAsf5O2EvJeSFMiBxXDki7sCgAxEUcZHXoXMKT4GJKc=
|
||||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=
|
golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU=
|
||||||
golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
|
golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY=
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I=
|
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
|
||||||
golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
@@ -116,21 +116,21 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||||||
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
|
golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk=
|
||||||
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||||
golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=
|
golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU=
|
||||||
golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=
|
golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY=
|
||||||
golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE=
|
golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE=
|
||||||
golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
|
golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.1.8/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=
|
golang.org/x/tools v0.1.8/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=
|
||||||
golang.org/x/tools v0.38.0 h1:Hx2Xv8hISq8Lm16jvBZ2VQf+RLmbd7wVUsALibYI/IQ=
|
golang.org/x/tools v0.39.0 h1:ik4ho21kwuQln40uelmciQPp9SipgNDdrafrYA4TmQQ=
|
||||||
golang.org/x/tools v0.38.0/go.mod h1:yEsQ/d/YK8cjh0L6rZlY8tgtlKiBNTL14pGDJPJpYQs=
|
golang.org/x/tools v0.39.0/go.mod h1:JnefbkDPyD8UU2kI5fuf8ZX4/yUeh9W877ZeBONxUqQ=
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
|||||||
@@ -3,8 +3,6 @@ package conf
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"log"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@@ -47,8 +45,6 @@ var (
|
|||||||
"dns": func() interface{} { return new(DNSOutboundConfig) },
|
"dns": func() interface{} { return new(DNSOutboundConfig) },
|
||||||
"wireguard": func() interface{} { return &WireGuardConfig{IsClient: true} },
|
"wireguard": func() interface{} { return &WireGuardConfig{IsClient: true} },
|
||||||
}, "protocol", "settings")
|
}, "protocol", "settings")
|
||||||
|
|
||||||
ctllog = log.New(os.Stderr, "xctl> ", 0)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type SniffingConfig struct {
|
type SniffingConfig struct {
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package convert
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/xtls/xray-core/common/cmdarg"
|
"github.com/xtls/xray-core/common/cmdarg"
|
||||||
creflect "github.com/xtls/xray-core/common/reflect"
|
creflect "github.com/xtls/xray-core/common/reflect"
|
||||||
@@ -61,7 +60,7 @@ func executeConvertConfigsToProtobuf(cmd *base.Command, args []string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(optFile) > 0 {
|
if len(optFile) > 0 {
|
||||||
switch core.GetFormatByExtension(getFileExtension(optFile)){
|
switch core.GetFormat(optFile){
|
||||||
case "protobuf", "":
|
case "protobuf", "":
|
||||||
fmt.Println("Output ProtoBuf file is ", optFile)
|
fmt.Println("Output ProtoBuf file is ", optFile)
|
||||||
default:
|
default:
|
||||||
@@ -106,11 +105,3 @@ func executeConvertConfigsToProtobuf(cmd *base.Command, args []string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func getFileExtension(filename string) string {
|
|
||||||
idx := strings.LastIndexByte(filename, '.')
|
|
||||||
if idx == -1 {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
return filename[idx+1:]
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -10,12 +10,10 @@ import (
|
|||||||
|
|
||||||
type (
|
type (
|
||||||
configFileLoader func(string) (io.Reader, error)
|
configFileLoader func(string) (io.Reader, error)
|
||||||
extconfigLoader func([]string, io.Reader) (io.Reader, error)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
EffectiveConfigFileLoader configFileLoader
|
EffectiveConfigFileLoader configFileLoader
|
||||||
EffectiveExtConfigLoader extconfigLoader
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// LoadConfig reads from a path/url/stdin
|
// LoadConfig reads from a path/url/stdin
|
||||||
@@ -27,13 +25,3 @@ func LoadConfig(file string) (io.Reader, error) {
|
|||||||
}
|
}
|
||||||
return EffectiveConfigFileLoader(file)
|
return EffectiveConfigFileLoader(file)
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoadExtConfig calls xctl to handle multiple config
|
|
||||||
// the actual work also in external module
|
|
||||||
func LoadExtConfig(files []string, reader io.Reader) (io.Reader, error) {
|
|
||||||
if EffectiveExtConfigLoader == nil {
|
|
||||||
return nil, errors.New("external config module not loaded").AtError()
|
|
||||||
}
|
|
||||||
|
|
||||||
return EffectiveExtConfigLoader(files, reader)
|
|
||||||
}
|
|
||||||
|
|||||||
11
main/confloader/external/external.go
vendored
11
main/confloader/external/external.go
vendored
@@ -13,7 +13,6 @@ import (
|
|||||||
|
|
||||||
"github.com/xtls/xray-core/common/buf"
|
"github.com/xtls/xray-core/common/buf"
|
||||||
"github.com/xtls/xray-core/common/errors"
|
"github.com/xtls/xray-core/common/errors"
|
||||||
"github.com/xtls/xray-core/common/platform/ctlcmd"
|
|
||||||
"github.com/xtls/xray-core/main/confloader"
|
"github.com/xtls/xray-core/main/confloader"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -129,16 +128,6 @@ func FetchUnixSocketHTTPContent(target string) ([]byte, error) {
|
|||||||
return content, nil
|
return content, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func ExtConfigLoader(files []string, reader io.Reader) (io.Reader, error) {
|
|
||||||
buf, err := ctlcmd.Run(append([]string{"convert"}, files...), reader)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return strings.NewReader(buf.String()), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
confloader.EffectiveConfigFileLoader = ConfigLoader
|
confloader.EffectiveConfigFileLoader = ConfigLoader
|
||||||
confloader.EffectiveExtConfigLoader = ExtConfigLoader
|
|
||||||
}
|
}
|
||||||
|
|||||||
129
proxy/proxy.go
129
proxy/proxy.go
@@ -248,7 +248,7 @@ func (w *VisionReader) ReadMultiBuffer() (buf.MultiBuffer, error) {
|
|||||||
*withinPaddingBuffers = false
|
*withinPaddingBuffers = false
|
||||||
*switchToDirectCopy = true
|
*switchToDirectCopy = true
|
||||||
} else {
|
} else {
|
||||||
errors.LogInfo(w.ctx, "XtlsRead unknown command ", *currentCommand, buffer.Len())
|
errors.LogDebug(w.ctx, "XtlsRead unknown command ", *currentCommand, buffer.Len())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if w.trafficState.NumberOfPacketToFilter > 0 {
|
if w.trafficState.NumberOfPacketToFilter > 0 {
|
||||||
@@ -269,9 +269,9 @@ func (w *VisionReader) ReadMultiBuffer() (buf.MultiBuffer, error) {
|
|||||||
w.rawInput = nil
|
w.rawInput = nil
|
||||||
|
|
||||||
if inbound := session.InboundFromContext(w.ctx); inbound != nil && inbound.Conn != nil {
|
if inbound := session.InboundFromContext(w.ctx); inbound != nil && inbound.Conn != nil {
|
||||||
if w.isUplink && inbound.CanSpliceCopy == 2 {
|
// if w.isUplink && inbound.CanSpliceCopy == 2 { // TODO: enable uplink splice
|
||||||
inbound.CanSpliceCopy = 1
|
// inbound.CanSpliceCopy = 1
|
||||||
}
|
// }
|
||||||
if !w.isUplink && w.ob != nil && w.ob.CanSpliceCopy == 2 { // ob need to be passed in due to context can have more than one ob
|
if !w.isUplink && w.ob != nil && w.ob.CanSpliceCopy == 2 { // ob need to be passed in due to context can have more than one ob
|
||||||
w.ob.CanSpliceCopy = 1
|
w.ob.CanSpliceCopy = 1
|
||||||
}
|
}
|
||||||
@@ -334,9 +334,9 @@ func (w *VisionWriter) WriteMultiBuffer(mb buf.MultiBuffer) error {
|
|||||||
if !w.isUplink && inbound.CanSpliceCopy == 2 {
|
if !w.isUplink && inbound.CanSpliceCopy == 2 {
|
||||||
inbound.CanSpliceCopy = 1
|
inbound.CanSpliceCopy = 1
|
||||||
}
|
}
|
||||||
if w.isUplink && w.ob != nil && w.ob.CanSpliceCopy == 2 {
|
// if w.isUplink && w.ob != nil && w.ob.CanSpliceCopy == 2 { // TODO: enable uplink splice
|
||||||
w.ob.CanSpliceCopy = 1
|
// w.ob.CanSpliceCopy = 1
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
rawConn, _, writerCounter := UnwrapRawConn(w.conn)
|
rawConn, _, writerCounter := UnwrapRawConn(w.conn)
|
||||||
w.Writer = buf.NewWriter(rawConn)
|
w.Writer = buf.NewWriter(rawConn)
|
||||||
@@ -395,65 +395,54 @@ func (w *VisionWriter) WriteMultiBuffer(mb buf.MultiBuffer) error {
|
|||||||
|
|
||||||
// IsCompleteRecord Is complete tls data record
|
// IsCompleteRecord Is complete tls data record
|
||||||
func IsCompleteRecord(buffer buf.MultiBuffer) bool {
|
func IsCompleteRecord(buffer buf.MultiBuffer) bool {
|
||||||
mb2 := make(buf.MultiBuffer, 0, len(buffer))
|
b := make([]byte, buffer.Len())
|
||||||
for _, buffer1 := range buffer {
|
if buffer.Copy(b) != int(buffer.Len()) {
|
||||||
buffer2 := buf.New()
|
panic("impossible bytes allocation")
|
||||||
buffer2.Write(buffer1.Bytes())
|
|
||||||
mb2 = append(mb2, buffer2)
|
|
||||||
}
|
}
|
||||||
isComplete := true
|
var headerLen int = 5
|
||||||
var headerLen int32 = 5
|
var recordLen int
|
||||||
var recordLen int32
|
|
||||||
for _, buffer2 := range mb2 {
|
totalLen := len(b)
|
||||||
for buffer2.Len() > 0 {
|
i := 0
|
||||||
if headerLen > 0 {
|
for i < totalLen {
|
||||||
data, _ := buffer2.ReadByte()
|
// record header: 0x17 0x3 0x3 + 2 bytes length
|
||||||
switch headerLen {
|
if headerLen > 0 {
|
||||||
case 5:
|
data := b[i]
|
||||||
if data != 0x17 {
|
i++
|
||||||
isComplete = false
|
switch headerLen {
|
||||||
break
|
case 5:
|
||||||
}
|
if data != 0x17 {
|
||||||
case 4:
|
return false
|
||||||
if data != 0x03 {
|
|
||||||
isComplete = false
|
|
||||||
break
|
|
||||||
}
|
|
||||||
case 3:
|
|
||||||
if data != 0x03 {
|
|
||||||
isComplete = false
|
|
||||||
break
|
|
||||||
}
|
|
||||||
case 2:
|
|
||||||
recordLen = int32(data) << 8
|
|
||||||
case 1:
|
|
||||||
recordLen = recordLen | int32(data)
|
|
||||||
}
|
}
|
||||||
headerLen--
|
case 4:
|
||||||
} else if recordLen > 0 {
|
if data != 0x03 {
|
||||||
var len = recordLen
|
return false
|
||||||
if buffer2.Len() < recordLen{
|
|
||||||
len = buffer2.Len()
|
|
||||||
}
|
}
|
||||||
buffer2.Advance(len)
|
case 3:
|
||||||
recordLen -= len
|
if data != 0x03 {
|
||||||
if recordLen == 0 {
|
return false
|
||||||
headerLen = 5
|
|
||||||
}
|
}
|
||||||
} else {
|
case 2:
|
||||||
isComplete = false
|
recordLen = int(data) << 8
|
||||||
|
case 1:
|
||||||
|
recordLen = recordLen | int(data)
|
||||||
}
|
}
|
||||||
}
|
headerLen--
|
||||||
if !isComplete {
|
} else if recordLen > 0 {
|
||||||
break
|
remaining := totalLen - i
|
||||||
|
if remaining < recordLen {
|
||||||
|
return false
|
||||||
|
} else {
|
||||||
|
i += recordLen
|
||||||
|
recordLen = 0
|
||||||
|
headerLen = 5
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, buffer2 := range mb2 {
|
if headerLen == 5 && recordLen == 0 {
|
||||||
buffer2.Release()
|
return true
|
||||||
buffer2 = nil
|
|
||||||
}
|
|
||||||
if headerLen == 5 && recordLen == 0 && isComplete {
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@@ -489,7 +478,7 @@ func ReshapeMultiBuffer(ctx context.Context, buffer buf.MultiBuffer) buf.MultiBu
|
|||||||
buffer[i] = nil
|
buffer[i] = nil
|
||||||
}
|
}
|
||||||
buffer = buffer[:0]
|
buffer = buffer[:0]
|
||||||
errors.LogInfo(ctx, "ReshapeMultiBuffer ", toPrint)
|
errors.LogDebug(ctx, "ReshapeMultiBuffer ", toPrint)
|
||||||
return mb2
|
return mb2
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -528,7 +517,7 @@ func XtlsPadding(b *buf.Buffer, command byte, userUUID *[]byte, longPadding bool
|
|||||||
b = nil
|
b = nil
|
||||||
}
|
}
|
||||||
newbuffer.Extend(paddingLen)
|
newbuffer.Extend(paddingLen)
|
||||||
errors.LogInfo(ctx, "XtlsPadding ", contentLen, " ", paddingLen, " ", command)
|
errors.LogDebug(ctx, "XtlsPadding ", contentLen, " ", paddingLen, " ", command)
|
||||||
return newbuffer
|
return newbuffer
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -575,7 +564,7 @@ func XtlsUnpadding(b *buf.Buffer, s *TrafficState, isUplink bool, ctx context.Co
|
|||||||
*remainingPadding = int32(data) << 8
|
*remainingPadding = int32(data) << 8
|
||||||
case 1:
|
case 1:
|
||||||
*remainingPadding = *remainingPadding | int32(data)
|
*remainingPadding = *remainingPadding | int32(data)
|
||||||
errors.LogInfo(ctx, "Xtls Unpadding new block, content ", *remainingContent, " padding ", *remainingPadding, " command ", *currentCommand)
|
errors.LogDebug(ctx, "Xtls Unpadding new block, content ", *remainingContent, " padding ", *remainingPadding, " command ", *currentCommand)
|
||||||
}
|
}
|
||||||
*remainingCommand--
|
*remainingCommand--
|
||||||
} else if *remainingContent > 0 {
|
} else if *remainingContent > 0 {
|
||||||
@@ -634,11 +623,11 @@ func XtlsFilterTls(buffer buf.MultiBuffer, trafficState *TrafficState, ctx conte
|
|||||||
cipherSuite := b.BytesRange(43+sessionIdLen+1, 43+sessionIdLen+3)
|
cipherSuite := b.BytesRange(43+sessionIdLen+1, 43+sessionIdLen+3)
|
||||||
trafficState.Cipher = uint16(cipherSuite[0])<<8 | uint16(cipherSuite[1])
|
trafficState.Cipher = uint16(cipherSuite[0])<<8 | uint16(cipherSuite[1])
|
||||||
} else {
|
} else {
|
||||||
errors.LogInfo(ctx, "XtlsFilterTls short server hello, tls 1.2 or older? ", b.Len(), " ", trafficState.RemainingServerHello)
|
errors.LogDebug(ctx, "XtlsFilterTls short server hello, tls 1.2 or older? ", b.Len(), " ", trafficState.RemainingServerHello)
|
||||||
}
|
}
|
||||||
} else if bytes.Equal(TlsClientHandShakeStart, startsBytes[:2]) && startsBytes[5] == TlsHandshakeTypeClientHello {
|
} else if bytes.Equal(TlsClientHandShakeStart, startsBytes[:2]) && startsBytes[5] == TlsHandshakeTypeClientHello {
|
||||||
trafficState.IsTLS = true
|
trafficState.IsTLS = true
|
||||||
errors.LogInfo(ctx, "XtlsFilterTls found tls client hello! ", buffer.Len())
|
errors.LogDebug(ctx, "XtlsFilterTls found tls client hello! ", buffer.Len())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if trafficState.RemainingServerHello > 0 {
|
if trafficState.RemainingServerHello > 0 {
|
||||||
@@ -654,18 +643,18 @@ func XtlsFilterTls(buffer buf.MultiBuffer, trafficState *TrafficState, ctx conte
|
|||||||
} else if v != "TLS_AES_128_CCM_8_SHA256" {
|
} else if v != "TLS_AES_128_CCM_8_SHA256" {
|
||||||
trafficState.EnableXtls = true
|
trafficState.EnableXtls = true
|
||||||
}
|
}
|
||||||
errors.LogInfo(ctx, "XtlsFilterTls found tls 1.3! ", b.Len(), " ", v)
|
errors.LogDebug(ctx, "XtlsFilterTls found tls 1.3! ", b.Len(), " ", v)
|
||||||
trafficState.NumberOfPacketToFilter = 0
|
trafficState.NumberOfPacketToFilter = 0
|
||||||
return
|
return
|
||||||
} else if trafficState.RemainingServerHello <= 0 {
|
} else if trafficState.RemainingServerHello <= 0 {
|
||||||
errors.LogInfo(ctx, "XtlsFilterTls found tls 1.2! ", b.Len())
|
errors.LogDebug(ctx, "XtlsFilterTls found tls 1.2! ", b.Len())
|
||||||
trafficState.NumberOfPacketToFilter = 0
|
trafficState.NumberOfPacketToFilter = 0
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
errors.LogInfo(ctx, "XtlsFilterTls inconclusive server hello ", b.Len(), " ", trafficState.RemainingServerHello)
|
errors.LogDebug(ctx, "XtlsFilterTls inconclusive server hello ", b.Len(), " ", trafficState.RemainingServerHello)
|
||||||
}
|
}
|
||||||
if trafficState.NumberOfPacketToFilter <= 0 {
|
if trafficState.NumberOfPacketToFilter <= 0 {
|
||||||
errors.LogInfo(ctx, "XtlsFilterTls stop filtering", buffer.Len())
|
errors.LogDebug(ctx, "XtlsFilterTls stop filtering", buffer.Len())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -747,7 +736,7 @@ func CopyRawConnIfExist(ctx context.Context, readerConn net.Conn, writerConn net
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if splice {
|
if splice {
|
||||||
errors.LogInfo(ctx, "CopyRawConn splice")
|
errors.LogDebug(ctx, "CopyRawConn splice")
|
||||||
statWriter, _ := writer.(*dispatcher.SizeStatWriter)
|
statWriter, _ := writer.(*dispatcher.SizeStatWriter)
|
||||||
//runtime.Gosched() // necessary
|
//runtime.Gosched() // necessary
|
||||||
time.Sleep(time.Millisecond) // without this, there will be a rare ssl error for freedom splice
|
time.Sleep(time.Millisecond) // without this, there will be a rare ssl error for freedom splice
|
||||||
@@ -790,7 +779,7 @@ func CopyRawConnIfExist(ctx context.Context, readerConn net.Conn, writerConn net
|
|||||||
}
|
}
|
||||||
|
|
||||||
func readV(ctx context.Context, reader buf.Reader, writer buf.Writer, timer signal.ActivityUpdater, readCounter stats.Counter) error {
|
func readV(ctx context.Context, reader buf.Reader, writer buf.Writer, timer signal.ActivityUpdater, readCounter stats.Counter) error {
|
||||||
errors.LogInfo(ctx, "CopyRawConn (maybe) readv")
|
errors.LogDebug(ctx, "CopyRawConn (maybe) readv")
|
||||||
if err := buf.Copy(reader, writer, buf.UpdateActivity(timer), buf.AddToStatCounter(readCounter)); err != nil {
|
if err := buf.Copy(reader, writer, buf.UpdateActivity(timer), buf.AddToStatCounter(readCounter)); err != nil {
|
||||||
return errors.New("failed to process response").Base(err)
|
return errors.New("failed to process response").Base(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,7 +57,12 @@ type Handler struct {
|
|||||||
|
|
||||||
testpre uint32
|
testpre uint32
|
||||||
initpre sync.Once
|
initpre sync.Once
|
||||||
preConns chan stat.Connection
|
preConns chan *ConnExpire
|
||||||
|
}
|
||||||
|
|
||||||
|
type ConnExpire struct {
|
||||||
|
Conn stat.Connection
|
||||||
|
Expire time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
// New creates a new VLess outbound handler.
|
// New creates a new VLess outbound handler.
|
||||||
@@ -141,25 +146,33 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte
|
|||||||
|
|
||||||
if h.testpre > 0 && h.reverse == nil {
|
if h.testpre > 0 && h.reverse == nil {
|
||||||
h.initpre.Do(func() {
|
h.initpre.Do(func() {
|
||||||
h.preConns = make(chan stat.Connection)
|
h.preConns = make(chan *ConnExpire)
|
||||||
for range h.testpre { // TODO: randomize
|
for range h.testpre { // TODO: randomize
|
||||||
go func() {
|
go func() {
|
||||||
defer func() { recover() }()
|
defer func() { recover() }()
|
||||||
ctx := xctx.ContextWithID(context.Background(), session.NewID())
|
ctx := xctx.ContextWithID(context.Background(), session.NewID())
|
||||||
for {
|
for {
|
||||||
time.Sleep(time.Millisecond * 200) // TODO: randomize
|
|
||||||
conn, err := dialer.Dial(ctx, rec.Destination)
|
conn, err := dialer.Dial(ctx, rec.Destination)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errors.LogWarningInner(ctx, err, "pre-connect failed")
|
errors.LogWarningInner(ctx, err, "pre-connect failed")
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
h.preConns <- conn
|
h.preConns <- &ConnExpire{Conn: conn, Expire: time.Now().Add(time.Minute * 2)} // TODO: customize & randomize
|
||||||
|
time.Sleep(time.Millisecond * 200) // TODO: customize & randomize
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
if conn = <-h.preConns; conn == nil {
|
for {
|
||||||
return errors.New("closed handler").AtWarning()
|
connTime := <-h.preConns
|
||||||
|
if connTime == nil {
|
||||||
|
return errors.New("closed handler").AtWarning()
|
||||||
|
}
|
||||||
|
if time.Now().Before(connTime.Expire) {
|
||||||
|
conn = connTime.Conn
|
||||||
|
break
|
||||||
|
}
|
||||||
|
connTime.Conn.Close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,14 +3,13 @@ package wireguard
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"net"
|
|
||||||
"net/netip"
|
"net/netip"
|
||||||
"strconv"
|
"strconv"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"golang.zx2c4.com/wireguard/conn"
|
"golang.zx2c4.com/wireguard/conn"
|
||||||
|
|
||||||
xnet "github.com/xtls/xray-core/common/net"
|
"github.com/xtls/xray-core/common/net"
|
||||||
"github.com/xtls/xray-core/features/dns"
|
"github.com/xtls/xray-core/features/dns"
|
||||||
"github.com/xtls/xray-core/transport/internet"
|
"github.com/xtls/xray-core/transport/internet"
|
||||||
)
|
)
|
||||||
@@ -51,21 +50,21 @@ func (n *netBind) ParseEndpoint(s string) (conn.Endpoint, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
addr := xnet.ParseAddress(ipStr)
|
addr := net.ParseAddress(ipStr)
|
||||||
if addr.Family() == xnet.AddressFamilyDomain {
|
if addr.Family() == net.AddressFamilyDomain {
|
||||||
ips, _, err := n.dns.LookupIP(addr.Domain(), n.dnsOption)
|
ips, _, err := n.dns.LookupIP(addr.Domain(), n.dnsOption)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
} else if len(ips) == 0 {
|
} else if len(ips) == 0 {
|
||||||
return nil, dns.ErrEmptyResponse
|
return nil, dns.ErrEmptyResponse
|
||||||
}
|
}
|
||||||
addr = xnet.IPAddress(ips[0])
|
addr = net.IPAddress(ips[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
dst := xnet.Destination{
|
dst := net.Destination{
|
||||||
Address: addr,
|
Address: addr,
|
||||||
Port: xnet.Port(portNum),
|
Port: net.Port(portNum),
|
||||||
Network: xnet.Network_UDP,
|
Network: net.Network_UDP,
|
||||||
}
|
}
|
||||||
|
|
||||||
return &netEndpoint{
|
return &netEndpoint{
|
||||||
@@ -214,7 +213,7 @@ func (bind *netBindServer) Send(buff [][]byte, endpoint conn.Endpoint) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type netEndpoint struct {
|
type netEndpoint struct {
|
||||||
dst xnet.Destination
|
dst net.Destination
|
||||||
conn net.Conn
|
conn net.Conn
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -247,7 +246,7 @@ func (e netEndpoint) SrcToString() string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func toNetIpAddr(addr xnet.Address) netip.Addr {
|
func toNetIpAddr(addr net.Address) netip.Addr {
|
||||||
if addr.Family().IsIPv4() {
|
if addr.Family().IsIPv4() {
|
||||||
ip := addr.IP()
|
ip := addr.IP()
|
||||||
return netip.AddrFrom4([4]byte{ip[0], ip[1], ip[2], ip[3]})
|
return netip.AddrFrom4([4]byte{ip[0], ip[1], ip[2], ip[3]})
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package wireguard
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
|
||||||
"net/netip"
|
"net/netip"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
@@ -13,7 +12,7 @@ import (
|
|||||||
|
|
||||||
"github.com/xtls/xray-core/common/errors"
|
"github.com/xtls/xray-core/common/errors"
|
||||||
"github.com/xtls/xray-core/common/log"
|
"github.com/xtls/xray-core/common/log"
|
||||||
xnet "github.com/xtls/xray-core/common/net"
|
"github.com/xtls/xray-core/common/net"
|
||||||
"github.com/xtls/xray-core/proxy/wireguard/gvisortun"
|
"github.com/xtls/xray-core/proxy/wireguard/gvisortun"
|
||||||
"gvisor.dev/gvisor/pkg/tcpip"
|
"gvisor.dev/gvisor/pkg/tcpip"
|
||||||
"gvisor.dev/gvisor/pkg/tcpip/adapters/gonet"
|
"gvisor.dev/gvisor/pkg/tcpip/adapters/gonet"
|
||||||
@@ -28,7 +27,7 @@ import (
|
|||||||
|
|
||||||
type tunCreator func(localAddresses []netip.Addr, mtu int, handler promiscuousModeHandler) (Tunnel, error)
|
type tunCreator func(localAddresses []netip.Addr, mtu int, handler promiscuousModeHandler) (Tunnel, error)
|
||||||
|
|
||||||
type promiscuousModeHandler func(dest xnet.Destination, conn net.Conn)
|
type promiscuousModeHandler func(dest net.Destination, conn net.Conn)
|
||||||
|
|
||||||
type Tunnel interface {
|
type Tunnel interface {
|
||||||
BuildDevice(ipc string, bind conn.Bind) error
|
BuildDevice(ipc string, bind conn.Bind) error
|
||||||
@@ -169,7 +168,7 @@ func createGVisorTun(localAddresses []netip.Addr, mtu int, handler promiscuousMo
|
|||||||
ep.SocketOptions().SetKeepAlive(true)
|
ep.SocketOptions().SetKeepAlive(true)
|
||||||
|
|
||||||
// local address is actually destination
|
// local address is actually destination
|
||||||
handler(xnet.TCPDestination(xnet.IPAddress(id.LocalAddress.AsSlice()), xnet.Port(id.LocalPort)), gonet.NewTCPConn(&wq, ep))
|
handler(net.TCPDestination(net.IPAddress(id.LocalAddress.AsSlice()), net.Port(id.LocalPort)), gonet.NewTCPConn(&wq, ep))
|
||||||
}(r)
|
}(r)
|
||||||
})
|
})
|
||||||
stack.SetTransportProtocolHandler(tcp.ProtocolNumber, tcpForwarder.HandlePacket)
|
stack.SetTransportProtocolHandler(tcp.ProtocolNumber, tcpForwarder.HandlePacket)
|
||||||
@@ -194,7 +193,7 @@ func createGVisorTun(localAddresses []netip.Addr, mtu int, handler promiscuousMo
|
|||||||
Timeout: 15 * time.Second,
|
Timeout: 15 * time.Second,
|
||||||
})
|
})
|
||||||
|
|
||||||
handler(xnet.UDPDestination(xnet.IPAddress(id.LocalAddress.AsSlice()), xnet.Port(id.LocalPort)), gonet.NewUDPConn(&wq, ep))
|
handler(net.UDPDestination(net.IPAddress(id.LocalAddress.AsSlice()), net.Port(id.LocalPort)), gonet.NewUDPConn(&wq, ep))
|
||||||
}(r)
|
}(r)
|
||||||
})
|
})
|
||||||
stack.SetTransportProtocolHandler(udp.ProtocolNumber, udpForwarder.HandlePacket)
|
stack.SetTransportProtocolHandler(udp.ProtocolNumber, udpForwarder.HandlePacket)
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package internet
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
gonet "net"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/xtls/xray-core/common"
|
"github.com/xtls/xray-core/common"
|
||||||
@@ -183,7 +182,7 @@ func checkAddressPortStrategy(ctx context.Context, dest net.Destination, sockopt
|
|||||||
if len(parts) != 3 {
|
if len(parts) != 3 {
|
||||||
return nil, errors.New("invalid address format", dest.Address.String())
|
return nil, errors.New("invalid address format", dest.Address.String())
|
||||||
}
|
}
|
||||||
_, srvRecords, err := gonet.DefaultResolver.LookupSRV(context.Background(), parts[0][1:], parts[1][1:], parts[2])
|
_, srvRecords, err := net.DefaultResolver.LookupSRV(context.Background(), parts[0][1:], parts[1][1:], parts[2])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.New("failed to lookup SRV record").Base(err)
|
return nil, errors.New("failed to lookup SRV record").Base(err)
|
||||||
}
|
}
|
||||||
@@ -198,7 +197,7 @@ func checkAddressPortStrategy(ctx context.Context, dest net.Destination, sockopt
|
|||||||
}
|
}
|
||||||
if OverrideBy == "txt" {
|
if OverrideBy == "txt" {
|
||||||
errors.LogDebug(ctx, "query TXT record for "+dest.Address.String())
|
errors.LogDebug(ctx, "query TXT record for "+dest.Address.String())
|
||||||
txtRecords, err := gonet.DefaultResolver.LookupTXT(ctx, dest.Address.String())
|
txtRecords, err := net.DefaultResolver.LookupTXT(ctx, dest.Address.String())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errors.LogError(ctx, "failed to lookup SRV record: "+err.Error())
|
errors.LogError(ctx, "failed to lookup SRV record: "+err.Error())
|
||||||
return nil, errors.New("failed to lookup SRV record").Base(err)
|
return nil, errors.New("failed to lookup SRV record").Base(err)
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package grpc
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
gonet "net"
|
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -99,7 +98,7 @@ func getGrpcClient(ctx context.Context, dest net.Destination, streamSettings *in
|
|||||||
},
|
},
|
||||||
MinConnectTimeout: 5 * time.Second,
|
MinConnectTimeout: 5 * time.Second,
|
||||||
}),
|
}),
|
||||||
grpc.WithContextDialer(func(gctx context.Context, s string) (gonet.Conn, error) {
|
grpc.WithContextDialer(func(gctx context.Context, s string) (net.Conn, error) {
|
||||||
select {
|
select {
|
||||||
case <-gctx.Done():
|
case <-gctx.Done():
|
||||||
return nil, gctx.Err()
|
return nil, gctx.Err()
|
||||||
@@ -180,7 +179,7 @@ func getGrpcClient(ctx context.Context, dest net.Destination, streamSettings *in
|
|||||||
}
|
}
|
||||||
|
|
||||||
conn, err := grpc.Dial(
|
conn, err := grpc.Dial(
|
||||||
gonet.JoinHostPort(grpcDestHost, dest.Port.String()),
|
net.JoinHostPort(grpcDestHost, dest.Port.String()),
|
||||||
dialOptions...,
|
dialOptions...,
|
||||||
)
|
)
|
||||||
globalDialerMap[dialerConf{dest, streamSettings}] = conn
|
globalDialerMap[dialerConf{dest, streamSettings}] = conn
|
||||||
|
|||||||
@@ -3,11 +3,10 @@ package encoding
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
|
||||||
|
|
||||||
"github.com/xtls/xray-core/common/buf"
|
"github.com/xtls/xray-core/common/buf"
|
||||||
"github.com/xtls/xray-core/common/errors"
|
"github.com/xtls/xray-core/common/errors"
|
||||||
xnet "github.com/xtls/xray-core/common/net"
|
"github.com/xtls/xray-core/common/net"
|
||||||
"github.com/xtls/xray-core/common/net/cnc"
|
"github.com/xtls/xray-core/common/net/cnc"
|
||||||
"github.com/xtls/xray-core/common/signal/done"
|
"github.com/xtls/xray-core/common/signal/done"
|
||||||
"google.golang.org/grpc/metadata"
|
"google.golang.org/grpc/metadata"
|
||||||
@@ -55,7 +54,7 @@ func NewHunkConn(hc HunkConn, cancel context.CancelFunc) net.Conn {
|
|||||||
if ok {
|
if ok {
|
||||||
header := md.Get("x-real-ip")
|
header := md.Get("x-real-ip")
|
||||||
if len(header) > 0 {
|
if len(header) > 0 {
|
||||||
realip := xnet.ParseAddress(header[0])
|
realip := net.ParseAddress(header[0])
|
||||||
if realip.Family().IsIP() {
|
if realip.Family().IsIP() {
|
||||||
rAddr = &net.TCPAddr{
|
rAddr = &net.TCPAddr{
|
||||||
IP: realip.IP(),
|
IP: realip.IP(),
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package internet
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
gonet "net"
|
|
||||||
"os"
|
"os"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
@@ -135,7 +134,7 @@ func applyOutboundSocketOptions(network string, address string, fd uintptr, conf
|
|||||||
}
|
}
|
||||||
|
|
||||||
if config.Interface != "" {
|
if config.Interface != "" {
|
||||||
iface, err := gonet.InterfaceByName(config.Interface)
|
iface, err := net.InterfaceByName(config.Interface)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.New("failed to get interface ", config.Interface).Base(err)
|
return errors.New("failed to get interface ", config.Interface).Base(err)
|
||||||
@@ -226,7 +225,7 @@ func applyInboundSocketOptions(network string, fd uintptr, config *SocketConfig)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if config.Interface != "" {
|
if config.Interface != "" {
|
||||||
iface, err := gonet.InterfaceByName(config.Interface)
|
iface, err := net.InterfaceByName(config.Interface)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.New("failed to get interface ", config.Interface).Base(err)
|
return errors.New("failed to get interface ", config.Interface).Base(err)
|
||||||
|
|||||||
@@ -3,9 +3,9 @@ package splithttp
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"io"
|
"io"
|
||||||
gonet "net"
|
|
||||||
|
|
||||||
"github.com/xtls/xray-core/common/errors"
|
"github.com/xtls/xray-core/common/errors"
|
||||||
|
"github.com/xtls/xray-core/common/net"
|
||||||
"github.com/xtls/xray-core/transport/internet/browser_dialer"
|
"github.com/xtls/xray-core/transport/internet/browser_dialer"
|
||||||
"github.com/xtls/xray-core/transport/internet/websocket"
|
"github.com/xtls/xray-core/transport/internet/websocket"
|
||||||
)
|
)
|
||||||
@@ -19,13 +19,13 @@ func (c *BrowserDialerClient) IsClosed() bool {
|
|||||||
panic("not implemented yet")
|
panic("not implemented yet")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *BrowserDialerClient) OpenStream(ctx context.Context, url string, body io.Reader, uploadOnly bool) (io.ReadCloser, gonet.Addr, gonet.Addr, error) {
|
func (c *BrowserDialerClient) OpenStream(ctx context.Context, url string, body io.Reader, uploadOnly bool) (io.ReadCloser, net.Addr, net.Addr, error) {
|
||||||
if body != nil {
|
if body != nil {
|
||||||
return nil, nil, nil, errors.New("bidirectional streaming for browser dialer not implemented yet")
|
return nil, nil, nil, errors.New("bidirectional streaming for browser dialer not implemented yet")
|
||||||
}
|
}
|
||||||
|
|
||||||
conn, err := browser_dialer.DialGet(url, c.transportConfig.GetRequestHeader(url))
|
conn, err := browser_dialer.DialGet(url, c.transportConfig.GetRequestHeader(url))
|
||||||
dummyAddr := &gonet.IPAddr{}
|
dummyAddr := &net.IPAddr{}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, dummyAddr, dummyAddr, err
|
return nil, dummyAddr, dummyAddr, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
gonet "net"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptrace"
|
"net/http/httptrace"
|
||||||
"sync"
|
"sync"
|
||||||
@@ -42,7 +41,7 @@ func (c *DefaultDialerClient) IsClosed() bool {
|
|||||||
return c.closed
|
return c.closed
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *DefaultDialerClient) OpenStream(ctx context.Context, url string, body io.Reader, uploadOnly bool) (wrc io.ReadCloser, remoteAddr, localAddr gonet.Addr, err error) {
|
func (c *DefaultDialerClient) OpenStream(ctx context.Context, url string, body io.Reader, uploadOnly bool) (wrc io.ReadCloser, remoteAddr, localAddr net.Addr, err error) {
|
||||||
// this is done when the TCP/UDP connection to the server was established,
|
// this is done when the TCP/UDP connection to the server was established,
|
||||||
// and we can unblock the Dial function and print correct net addresses in
|
// and we can unblock the Dial function and print correct net addresses in
|
||||||
// logs
|
// logs
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package internet
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
gonet "net"
|
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -89,7 +88,7 @@ func (d *DefaultSystemDialer) Dial(ctx context.Context, src net.Address, dest ne
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
// Chrome defaults
|
// Chrome defaults
|
||||||
keepAliveConfig := gonet.KeepAliveConfig{
|
keepAliveConfig := net.KeepAliveConfig{
|
||||||
Enable: true,
|
Enable: true,
|
||||||
Idle: 45 * time.Second,
|
Idle: 45 * time.Second,
|
||||||
Interval: 45 * time.Second,
|
Interval: 45 * time.Second,
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package internet
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
gonet "net"
|
|
||||||
"os"
|
"os"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
@@ -95,7 +94,7 @@ func (dl *DefaultListener) Listen(ctx context.Context, addr net.Addr, sockopt *S
|
|||||||
if sockopt.TcpKeepAliveIdle*sockopt.TcpKeepAliveInterval < 0 {
|
if sockopt.TcpKeepAliveIdle*sockopt.TcpKeepAliveInterval < 0 {
|
||||||
return nil, errors.New("invalid TcpKeepAliveIdle or TcpKeepAliveInterval value: ", sockopt.TcpKeepAliveIdle, " ", sockopt.TcpKeepAliveInterval)
|
return nil, errors.New("invalid TcpKeepAliveIdle or TcpKeepAliveInterval value: ", sockopt.TcpKeepAliveIdle, " ", sockopt.TcpKeepAliveInterval)
|
||||||
}
|
}
|
||||||
lc.KeepAliveConfig = gonet.KeepAliveConfig{
|
lc.KeepAliveConfig = net.KeepAliveConfig{
|
||||||
Enable: false,
|
Enable: false,
|
||||||
Idle: -1,
|
Idle: -1,
|
||||||
Interval: -1,
|
Interval: -1,
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import (
|
|||||||
_ "embed"
|
_ "embed"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"io"
|
"io"
|
||||||
gonet "net"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/gorilla/websocket"
|
"github.com/gorilla/websocket"
|
||||||
@@ -64,7 +63,7 @@ func dialWebSocket(ctx context.Context, dest net.Destination, streamSettings *in
|
|||||||
tlsConfig := tConfig.GetTLSConfig(tls.WithDestination(dest), tls.WithNextProto("http/1.1"))
|
tlsConfig := tConfig.GetTLSConfig(tls.WithDestination(dest), tls.WithNextProto("http/1.1"))
|
||||||
dialer.TLSClientConfig = tlsConfig
|
dialer.TLSClientConfig = tlsConfig
|
||||||
if fingerprint := tls.GetFingerprint(tConfig.Fingerprint); fingerprint != nil {
|
if fingerprint := tls.GetFingerprint(tConfig.Fingerprint); fingerprint != nil {
|
||||||
dialer.NetDialTLSContext = func(_ context.Context, _, addr string) (gonet.Conn, error) {
|
dialer.NetDialTLSContext = func(_ context.Context, _, addr string) (net.Conn, error) {
|
||||||
// Like the NetDial in the dialer
|
// Like the NetDial in the dialer
|
||||||
pconn, err := internet.DialSystem(ctx, dest, streamSettings.SocketSettings)
|
pconn, err := internet.DialSystem(ctx, dest, streamSettings.SocketSettings)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package pipe
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
"runtime"
|
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -136,11 +135,10 @@ func (p *pipe) writeMultiBufferInternal(mb buf.MultiBuffer) error {
|
|||||||
|
|
||||||
if p.data == nil {
|
if p.data == nil {
|
||||||
p.data = mb
|
p.data = mb
|
||||||
return nil
|
} else {
|
||||||
|
p.data, _ = buf.MergeMulti(p.data, mb)
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
p.data, _ = buf.MergeMulti(p.data, mb)
|
|
||||||
return errSlowDown
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *pipe) WriteMultiBuffer(mb buf.MultiBuffer) error {
|
func (p *pipe) WriteMultiBuffer(mb buf.MultiBuffer) error {
|
||||||
@@ -155,30 +153,23 @@ func (p *pipe) WriteMultiBuffer(mb buf.MultiBuffer) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if err == errSlowDown {
|
if err == errBufferFull {
|
||||||
p.readSignal.Signal()
|
if p.option.discardOverflow {
|
||||||
|
buf.ReleaseMulti(mb)
|
||||||
// Yield current goroutine. Hopefully the reading counterpart can pick up the payload.
|
return nil
|
||||||
runtime.Gosched()
|
}
|
||||||
return nil
|
select {
|
||||||
|
case <-p.writeSignal.Wait():
|
||||||
|
continue
|
||||||
|
case <-p.done.Wait():
|
||||||
|
buf.ReleaseMulti(mb)
|
||||||
|
return io.ErrClosedPipe
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err == errBufferFull && p.option.discardOverflow {
|
buf.ReleaseMulti(mb)
|
||||||
buf.ReleaseMulti(mb)
|
p.readSignal.Signal()
|
||||||
return nil
|
return err
|
||||||
}
|
|
||||||
|
|
||||||
if err != errBufferFull {
|
|
||||||
buf.ReleaseMulti(mb)
|
|
||||||
p.readSignal.Signal()
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
select {
|
|
||||||
case <-p.writeSignal.Wait():
|
|
||||||
case <-p.done.Wait():
|
|
||||||
return io.ErrClosedPipe
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user