mirror of
https://github.com/XTLS/Xray-core.git
synced 2026-09-15 22:10:26 +00:00
Compare commits
6
Commits
v26.7.11
...
sendthrough
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
23ceba4716 | ||
|
|
6e3322d219 | ||
|
|
1d8eb81d70 | ||
|
|
e78d8ef184 | ||
|
|
6ce924ad56 | ||
|
|
035d438979 |
@@ -92,7 +92,7 @@ jobs:
|
||||
echo "ASSET_NAME=$_NAME" >> $GITHUB_ENV
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v6
|
||||
uses: actions/setup-go@v7
|
||||
with:
|
||||
go-version-file: go.mod
|
||||
check-latest: true
|
||||
|
||||
@@ -193,7 +193,7 @@ jobs:
|
||||
echo "ASSET_NAME=$_NAME" >> $GITHUB_ENV
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v6
|
||||
uses: actions/setup-go@v7
|
||||
with:
|
||||
go-version-file: go.mod
|
||||
check-latest: true
|
||||
|
||||
@@ -61,7 +61,7 @@ jobs:
|
||||
- name: Checkout codebase
|
||||
uses: actions/checkout@v7
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v6
|
||||
uses: actions/setup-go@v7
|
||||
with:
|
||||
go-version-file: go.mod
|
||||
check-latest: true
|
||||
@@ -85,7 +85,7 @@ jobs:
|
||||
- name: Checkout codebase
|
||||
uses: actions/checkout@v7
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v6
|
||||
uses: actions/setup-go@v7
|
||||
with:
|
||||
go-version-file: go.mod
|
||||
check-latest: true
|
||||
|
||||
@@ -347,7 +347,6 @@ func (h *Handler) SetOutboundGateway(ctx context.Context, ob *session.Outbound)
|
||||
// case addr.Family().IsDomain():
|
||||
default:
|
||||
ob.Gateway = addr
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ require (
|
||||
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2
|
||||
golang.zx2c4.com/wireguard v0.0.0-20250521234502-f333402bd9cb
|
||||
golang.zx2c4.com/wireguard/windows v1.0.1
|
||||
google.golang.org/grpc v1.82.0
|
||||
google.golang.org/grpc v1.82.1
|
||||
google.golang.org/protobuf v1.36.11
|
||||
gvisor.dev/gvisor v0.0.0-20260122175437-89a5d21be8f0
|
||||
h12.io/socks v1.0.3
|
||||
|
||||
@@ -149,8 +149,8 @@ gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4=
|
||||
gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 h1:RmoJA1ujG+/lRGNfUnOMfhCy5EipVMyvUE+KNbPbTlw=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
|
||||
google.golang.org/grpc v1.82.0 h1:vguDnZUPjE26w09A63VoxZPnvPjB5Riyc0mkXPFmAIU=
|
||||
google.golang.org/grpc v1.82.0/go.mod h1:yzTZ1TB1Z3SG+LIYaI+WiE8D5+PZ3ArnrSp8zF3+/ZA=
|
||||
google.golang.org/grpc v1.82.1 h1:NnAxzGRA0677vCa4BUkOAnO5+FfQqVl9iUXeD0IqcGE=
|
||||
google.golang.org/grpc v1.82.1/go.mod h1:yzTZ1TB1Z3SG+LIYaI+WiE8D5+PZ3ArnrSp8zF3+/ZA=
|
||||
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
|
||||
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
|
||||
@@ -113,8 +113,10 @@ func (c *REALITYConfig) Build() (proto.Message, error) {
|
||||
config.MinClientVer[i] = byte(u)
|
||||
}
|
||||
}
|
||||
errors.LogWarning(context.Background(), `REALITY: Changing "minClientVer" will increase the likelihood of your server's IP being blocked by the GFW`)
|
||||
} else {
|
||||
config.MinClientVer = []byte{26, 3, 27} // change it at your own risk: https://github.com/XTLS/Xray-core/pull/6181#issuecomment-4567373533
|
||||
config.MinClientVer = []byte{26, 3, 27} // change it at your own risk: https://github.com/XTLS/Xray-core/commit/af7eb68028732a8ee3c0e5d6ab2b8a657bb2e770
|
||||
errors.LogWarning(context.Background(), `REALITY: The default minimal client version is Xray-core v26.3.27, other clients may be refused to connect`)
|
||||
}
|
||||
if c.MaxClientVer != "" {
|
||||
config.MaxClientVer = make([]byte, 3)
|
||||
@@ -159,8 +161,10 @@ func (c *REALITYConfig) Build() (proto.Message, error) {
|
||||
}
|
||||
|
||||
for _, sn := range config.ServerNames {
|
||||
if strings.Contains(sn, "apple") || strings.Contains(sn, "icloud") {
|
||||
errors.LogWarning(context.Background(), `REALITY: Choosing apple, icloud, etc. as the target may get your IP blocked by the GFW`)
|
||||
sn = strings.ToLower(sn)
|
||||
if strings.HasSuffix(sn, ".ru") || strings.HasSuffix(sn, ".ir") || strings.HasSuffix(sn, ".cn") ||
|
||||
strings.Contains(sn, "apple") || strings.Contains(sn, "icloud") || strings.Contains(sn, "microsoft") {
|
||||
errors.LogWarning(context.Background(), `REALITY: Choosing "`, sn, `" as the target will increase the likelihood of your server's IP being blocked by the GFW`)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+70
-1
@@ -1,12 +1,19 @@
|
||||
package conf
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"net"
|
||||
"strconv"
|
||||
|
||||
"github.com/xtls/xray-core/proxy/tun"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
type TunConfig struct {
|
||||
Name string `json:"name"`
|
||||
Desc string `json:"desc"`
|
||||
MTU uint32 `json:"mtu"`
|
||||
Gateway []string `json:"gateway"`
|
||||
DNS []string `json:"dns"`
|
||||
@@ -18,6 +25,7 @@ type TunConfig struct {
|
||||
func (v *TunConfig) Build() (proto.Message, error) {
|
||||
config := &tun.Config{
|
||||
Name: v.Name,
|
||||
Desc: v.Desc,
|
||||
MTU: v.MTU,
|
||||
Gateway: v.Gateway,
|
||||
DNS: v.DNS,
|
||||
@@ -32,10 +40,71 @@ func (v *TunConfig) Build() (proto.Message, error) {
|
||||
}
|
||||
|
||||
if config.Name == "" {
|
||||
config.Name = "xray0"
|
||||
name, err := GetAvailableTunName()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
config.Name = name
|
||||
}
|
||||
if config.Desc == "" {
|
||||
config.Desc = "Wintun"
|
||||
}
|
||||
if config.MTU == 0 {
|
||||
config.MTU = 1500
|
||||
}
|
||||
return config, nil
|
||||
}
|
||||
|
||||
const (
|
||||
tunNamePrefix = "utun"
|
||||
minTunIndex = 10
|
||||
maxTunIndex = 1024
|
||||
)
|
||||
|
||||
func GetAvailableTunName() (string, error) {
|
||||
interfaces, err := net.Interfaces()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("fail to get system interface information: %w", err)
|
||||
}
|
||||
|
||||
usedNames := make(map[string]struct{}, len(interfaces))
|
||||
for _, iface := range interfaces {
|
||||
usedNames[iface.Name] = struct{}{}
|
||||
}
|
||||
|
||||
startIndex, err := randomInt(minTunIndex, maxTunIndex)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("fail to generate valid tun name: %w", err)
|
||||
}
|
||||
|
||||
rangeSize := maxTunIndex - minTunIndex + 1
|
||||
|
||||
for offset := 0; offset < rangeSize; offset++ {
|
||||
index := minTunIndex + (startIndex-minTunIndex+offset)%rangeSize
|
||||
name := tunNamePrefix + strconv.Itoa(index)
|
||||
|
||||
if _, exists := usedNames[name]; !exists {
|
||||
return name, nil
|
||||
}
|
||||
}
|
||||
|
||||
return "", fmt.Errorf(
|
||||
"no available TUN interface name in range %s%d-%s%d",
|
||||
tunNamePrefix,
|
||||
minTunIndex,
|
||||
tunNamePrefix,
|
||||
maxTunIndex,
|
||||
)
|
||||
}
|
||||
|
||||
func randomInt(min, max int) (int, error) {
|
||||
value, err := rand.Int(
|
||||
rand.Reader,
|
||||
big.NewInt(int64(max-min+1)),
|
||||
)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return min + int(value.Int64()), nil
|
||||
}
|
||||
|
||||
+1
-1
@@ -176,7 +176,7 @@ func (c *InboundDetourConfig) Build() (*core.InboundHandlerConfig, error) {
|
||||
receiverSettings.StreamSettings = ss
|
||||
if strings.Contains(ss.SecurityType, "reality") && (receiverSettings.PortList == nil ||
|
||||
len(receiverSettings.PortList.Ports()) != 1 || receiverSettings.PortList.Ports()[0] != 443) {
|
||||
errors.LogWarning(context.Background(), `REALITY: Listening on non-443 ports may get your IP blocked by the GFW`)
|
||||
errors.LogWarning(context.Background(), `REALITY: Listening on non-443 ports will increase the likelihood of your server's IP being blocked by the GFW`)
|
||||
}
|
||||
}
|
||||
if c.SniffingConfig != nil {
|
||||
|
||||
+6
-2
@@ -31,13 +31,17 @@ Here is simple Xray config snippet to enable the inbound:
|
||||
"port": 0,
|
||||
"protocol": "tun",
|
||||
"settings": {
|
||||
"name": "xray0",
|
||||
"MTU": 1492
|
||||
"name": "utun10",
|
||||
"desc": "Wintun",
|
||||
"mtu": 1500
|
||||
}
|
||||
}
|
||||
],
|
||||
```
|
||||
|
||||
`desc` sets the Windows Wintun adapter tunnel type and defaults to `Wintun`.
|
||||
It is ignored on other platforms.
|
||||
|
||||
## SUPPORTED FEATURES
|
||||
|
||||
- IPv4 and IPv6
|
||||
|
||||
+14
-4
@@ -7,11 +7,12 @@
|
||||
package tun
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
unsafe "unsafe"
|
||||
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -30,6 +31,7 @@ type Config struct {
|
||||
UserLevel uint32 `protobuf:"varint,5,opt,name=user_level,json=userLevel,proto3" json:"user_level,omitempty"`
|
||||
AutoSystemRoutingTable []string `protobuf:"bytes,6,rep,name=auto_system_routing_table,json=autoSystemRoutingTable,proto3" json:"auto_system_routing_table,omitempty"`
|
||||
AutoOutboundsInterface string `protobuf:"bytes,7,opt,name=auto_outbounds_interface,json=autoOutboundsInterface,proto3" json:"auto_outbounds_interface,omitempty"`
|
||||
Desc string `protobuf:"bytes,8,opt,name=desc,proto3" json:"desc,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
@@ -113,11 +115,18 @@ func (x *Config) GetAutoOutboundsInterface() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Config) GetDesc() string {
|
||||
if x != nil {
|
||||
return x.Desc
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
var File_proxy_tun_config_proto protoreflect.FileDescriptor
|
||||
|
||||
const file_proxy_tun_config_proto_rawDesc = "" +
|
||||
"\n" +
|
||||
"\x16proxy/tun/config.proto\x12\x0exray.proxy.tun\"\xee\x01\n" +
|
||||
"\x16proxy/tun/config.proto\x12\x0exray.proxy.tun\"\x82\x02\n" +
|
||||
"\x06Config\x12\x12\n" +
|
||||
"\x04name\x18\x01 \x01(\tR\x04name\x12\x10\n" +
|
||||
"\x03MTU\x18\x02 \x01(\rR\x03MTU\x12\x18\n" +
|
||||
@@ -126,7 +135,8 @@ const file_proxy_tun_config_proto_rawDesc = "" +
|
||||
"\n" +
|
||||
"user_level\x18\x05 \x01(\rR\tuserLevel\x129\n" +
|
||||
"\x19auto_system_routing_table\x18\x06 \x03(\tR\x16autoSystemRoutingTable\x128\n" +
|
||||
"\x18auto_outbounds_interface\x18\a \x01(\tR\x16autoOutboundsInterfaceBL\n" +
|
||||
"\x18auto_outbounds_interface\x18\a \x01(\tR\x16autoOutboundsInterface\x12\x12\n" +
|
||||
"\x04desc\x18\b \x01(\tR\x04descBL\n" +
|
||||
"\x12com.xray.proxy.tunP\x01Z#github.com/xtls/xray-core/proxy/tun\xaa\x02\x0eXray.Proxy.Tunb\x06proto3"
|
||||
|
||||
var (
|
||||
|
||||
@@ -14,4 +14,5 @@ message Config {
|
||||
uint32 user_level = 5;
|
||||
repeated string auto_system_routing_table = 6;
|
||||
string auto_outbounds_interface = 7;
|
||||
string desc = 8;
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ var _ GVisorDevice = (*WindowsTun)(nil)
|
||||
// interface with the same name exist, it tried to be reused.
|
||||
func NewTun(options *Config) (Tun, error) {
|
||||
// instantiate wintun adapter
|
||||
adapter, err := open(options.Name)
|
||||
adapter, err := open(options.Name, options.Desc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -73,12 +73,12 @@ func NewTun(options *Config) (Tun, error) {
|
||||
return tun, nil
|
||||
}
|
||||
|
||||
func open(name string) (*wintun.Adapter, error) {
|
||||
func open(name, desc string) (*wintun.Adapter, error) {
|
||||
// generate a deterministic GUID from the adapter name
|
||||
id := md5.Sum([]byte(name))
|
||||
guid := (*windows.GUID)(unsafe.Pointer(&id[0]))
|
||||
// try to create adapter anew
|
||||
adapter, err := wintun.CreateAdapter(name, "Xray", guid)
|
||||
adapter, err := wintun.CreateAdapter(name, desc, guid)
|
||||
if err == nil {
|
||||
return adapter, nil
|
||||
}
|
||||
|
||||
@@ -138,6 +138,7 @@ func (h *Handler) Process(ctx context.Context, link *transport.Link, dialer inte
|
||||
}
|
||||
ob.Name = "wireguard"
|
||||
ob.CanSpliceCopy = 3
|
||||
dialer.SetOutboundGateway(ctx, ob)
|
||||
|
||||
if err := h.init(ctx); err != nil {
|
||||
return err
|
||||
|
||||
Reference in New Issue
Block a user