mirror of
https://github.com/XTLS/Xray-core.git
synced 2025-08-23 01:56:48 +08:00
Compare commits
3 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
f6c15a09b3 | ||
![]() |
0a099d972b | ||
![]() |
837d7d885f |
4
.github/workflows/release.yml
vendored
4
.github/workflows/release.yml
vendored
@@ -186,12 +186,12 @@ jobs:
|
||||
- name: Build Xray
|
||||
run: |
|
||||
mkdir -p build_assets
|
||||
go build -v -o build_assets/xray -trimpath -ldflags "-s -w -buildid=" -tags with_gvisor ./main
|
||||
go build -v -o build_assets/xray -trimpath -ldflags "-s -w -buildid=" ./main
|
||||
|
||||
- name: Build background Xray on Windows
|
||||
if: matrix.goos == 'windows'
|
||||
run: |
|
||||
go build -v -o build_assets/wxray.exe -trimpath -ldflags "-s -w -H windowsgui -buildid=" -tags with_gvisor ./main
|
||||
go build -v -o build_assets/wxray.exe -trimpath -ldflags "-s -w -H windowsgui -buildid=" ./main
|
||||
|
||||
- name: Build Mips softfloat Xray
|
||||
if: matrix.goarch == 'mips' || matrix.goarch == 'mipsle'
|
||||
|
@@ -30,10 +30,15 @@ var errSniffingTimeout = newError("timeout on sniffing")
|
||||
|
||||
type cachedReader struct {
|
||||
sync.Mutex
|
||||
reader *pipe.Reader
|
||||
reader timeoutReader
|
||||
cache buf.MultiBuffer
|
||||
}
|
||||
|
||||
type timeoutReader interface {
|
||||
buf.Reader
|
||||
buf.TimeoutReader
|
||||
}
|
||||
|
||||
func (r *cachedReader) Cache(b *buf.Buffer) {
|
||||
mb, _ := r.reader.ReadMultiBufferTimeout(time.Millisecond * 100)
|
||||
r.Lock()
|
||||
@@ -84,7 +89,7 @@ func (r *cachedReader) Interrupt() {
|
||||
r.cache = buf.ReleaseMulti(r.cache)
|
||||
}
|
||||
r.Unlock()
|
||||
r.reader.Interrupt()
|
||||
common.Interrupt(r.reader)
|
||||
}
|
||||
|
||||
// DefaultDispatcher is a default implementation of Dispatcher.
|
||||
@@ -345,7 +350,7 @@ func (d *DefaultDispatcher) DispatchLink(ctx context.Context, destination net.De
|
||||
d.routedDispatch(ctx, outbound, destination)
|
||||
} else {
|
||||
cReader := &cachedReader{
|
||||
reader: outbound.Reader.(*pipe.Reader),
|
||||
reader: outbound.Reader.(timeoutReader),
|
||||
}
|
||||
outbound.Reader = cReader
|
||||
result, err := sniffer(ctx, cReader, sniffingRequest.MetadataOnly, destination.Network)
|
||||
|
@@ -524,6 +524,7 @@ type SenderConfig struct {
|
||||
StreamSettings *internet.StreamConfig `protobuf:"bytes,2,opt,name=stream_settings,json=streamSettings,proto3" json:"stream_settings,omitempty"`
|
||||
ProxySettings *internet.ProxyConfig `protobuf:"bytes,3,opt,name=proxy_settings,json=proxySettings,proto3" json:"proxy_settings,omitempty"`
|
||||
MultiplexSettings *MultiplexingConfig `protobuf:"bytes,4,opt,name=multiplex_settings,json=multiplexSettings,proto3" json:"multiplex_settings,omitempty"`
|
||||
SmuxSettings *SingMultiplexConfig `protobuf:"bytes,5,opt,name=smux_settings,json=smuxSettings,proto3" json:"smux_settings,omitempty"`
|
||||
}
|
||||
|
||||
func (x *SenderConfig) Reset() {
|
||||
@@ -586,6 +587,13 @@ func (x *SenderConfig) GetMultiplexSettings() *MultiplexingConfig {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *SenderConfig) GetSmuxSettings() *SingMultiplexConfig {
|
||||
if x != nil {
|
||||
return x.SmuxSettings
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type MultiplexingConfig struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
@@ -661,6 +669,93 @@ func (x *MultiplexingConfig) GetXudpProxyUDP443() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
type SingMultiplexConfig struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Enabled bool `protobuf:"varint,1,opt,name=enabled,proto3" json:"enabled,omitempty"`
|
||||
Protocol string `protobuf:"bytes,2,opt,name=protocol,proto3" json:"protocol,omitempty"`
|
||||
MaxConnections int32 `protobuf:"varint,3,opt,name=max_connections,json=maxConnections,proto3" json:"max_connections,omitempty"`
|
||||
MinStreams int32 `protobuf:"varint,4,opt,name=min_streams,json=minStreams,proto3" json:"min_streams,omitempty"`
|
||||
MaxStreams int32 `protobuf:"varint,5,opt,name=max_streams,json=maxStreams,proto3" json:"max_streams,omitempty"`
|
||||
Padding bool `protobuf:"varint,6,opt,name=padding,proto3" json:"padding,omitempty"`
|
||||
}
|
||||
|
||||
func (x *SingMultiplexConfig) Reset() {
|
||||
*x = SingMultiplexConfig{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_app_proxyman_config_proto_msgTypes[8]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *SingMultiplexConfig) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*SingMultiplexConfig) ProtoMessage() {}
|
||||
|
||||
func (x *SingMultiplexConfig) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_app_proxyman_config_proto_msgTypes[8]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use SingMultiplexConfig.ProtoReflect.Descriptor instead.
|
||||
func (*SingMultiplexConfig) Descriptor() ([]byte, []int) {
|
||||
return file_app_proxyman_config_proto_rawDescGZIP(), []int{8}
|
||||
}
|
||||
|
||||
func (x *SingMultiplexConfig) GetEnabled() bool {
|
||||
if x != nil {
|
||||
return x.Enabled
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *SingMultiplexConfig) GetProtocol() string {
|
||||
if x != nil {
|
||||
return x.Protocol
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *SingMultiplexConfig) GetMaxConnections() int32 {
|
||||
if x != nil {
|
||||
return x.MaxConnections
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *SingMultiplexConfig) GetMinStreams() int32 {
|
||||
if x != nil {
|
||||
return x.MinStreams
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *SingMultiplexConfig) GetMaxStreams() int32 {
|
||||
if x != nil {
|
||||
return x.MaxStreams
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *SingMultiplexConfig) GetPadding() bool {
|
||||
if x != nil {
|
||||
return x.Padding
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type AllocationStrategy_AllocationStrategyConcurrency struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
@@ -672,7 +767,7 @@ type AllocationStrategy_AllocationStrategyConcurrency struct {
|
||||
func (x *AllocationStrategy_AllocationStrategyConcurrency) Reset() {
|
||||
*x = AllocationStrategy_AllocationStrategyConcurrency{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_app_proxyman_config_proto_msgTypes[8]
|
||||
mi := &file_app_proxyman_config_proto_msgTypes[9]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -685,7 +780,7 @@ func (x *AllocationStrategy_AllocationStrategyConcurrency) String() string {
|
||||
func (*AllocationStrategy_AllocationStrategyConcurrency) ProtoMessage() {}
|
||||
|
||||
func (x *AllocationStrategy_AllocationStrategyConcurrency) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_app_proxyman_config_proto_msgTypes[8]
|
||||
mi := &file_app_proxyman_config_proto_msgTypes[9]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -719,7 +814,7 @@ type AllocationStrategy_AllocationStrategyRefresh struct {
|
||||
func (x *AllocationStrategy_AllocationStrategyRefresh) Reset() {
|
||||
*x = AllocationStrategy_AllocationStrategyRefresh{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_app_proxyman_config_proto_msgTypes[9]
|
||||
mi := &file_app_proxyman_config_proto_msgTypes[10]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -732,7 +827,7 @@ func (x *AllocationStrategy_AllocationStrategyRefresh) String() string {
|
||||
func (*AllocationStrategy_AllocationStrategyRefresh) ProtoMessage() {}
|
||||
|
||||
func (x *AllocationStrategy_AllocationStrategyRefresh) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_app_proxyman_config_proto_msgTypes[9]
|
||||
mi := &file_app_proxyman_config_proto_msgTypes[10]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -855,7 +950,7 @@ var file_app_proxyman_config_proto_rawDesc = []byte{
|
||||
0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x2e, 0x54, 0x79, 0x70, 0x65,
|
||||
0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x0d, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x53,
|
||||
0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x22, 0x10, 0x0a, 0x0e, 0x4f, 0x75, 0x74, 0x62, 0x6f,
|
||||
0x75, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0xb0, 0x02, 0x0a, 0x0c, 0x53, 0x65,
|
||||
0x75, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0xfd, 0x02, 0x0a, 0x0c, 0x53, 0x65,
|
||||
0x6e, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x2d, 0x0a, 0x03, 0x76, 0x69,
|
||||
0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x63,
|
||||
0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2e, 0x49, 0x50, 0x4f, 0x72, 0x44, 0x6f,
|
||||
@@ -874,18 +969,36 @@ var file_app_proxyman_config_proto_rawDesc = []byte{
|
||||
0x28, 0x0b, 0x32, 0x25, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x70, 0x72,
|
||||
0x6f, 0x78, 0x79, 0x6d, 0x61, 0x6e, 0x2e, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x78,
|
||||
0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x11, 0x6d, 0x75, 0x6c, 0x74, 0x69,
|
||||
0x70, 0x6c, 0x65, 0x78, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x22, 0xa4, 0x01, 0x0a,
|
||||
0x12, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x78, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e,
|
||||
0x66, 0x69, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01,
|
||||
0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x20, 0x0a,
|
||||
0x0b, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x02, 0x20, 0x01,
|
||||
0x28, 0x05, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x12,
|
||||
0x28, 0x0a, 0x0f, 0x78, 0x75, 0x64, 0x70, 0x43, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e,
|
||||
0x63, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0f, 0x78, 0x75, 0x64, 0x70, 0x43, 0x6f,
|
||||
0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x28, 0x0a, 0x0f, 0x78, 0x75, 0x64,
|
||||
0x70, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x55, 0x44, 0x50, 0x34, 0x34, 0x33, 0x18, 0x04, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x0f, 0x78, 0x75, 0x64, 0x70, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x55, 0x44, 0x50,
|
||||
0x34, 0x34, 0x33, 0x2a, 0x23, 0x0a, 0x0e, 0x4b, 0x6e, 0x6f, 0x77, 0x6e, 0x50, 0x72, 0x6f, 0x74,
|
||||
0x70, 0x6c, 0x65, 0x78, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x4b, 0x0a, 0x0d,
|
||||
0x73, 0x6d, 0x75, 0x78, 0x5f, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x05, 0x20,
|
||||
0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x70,
|
||||
0x72, 0x6f, 0x78, 0x79, 0x6d, 0x61, 0x6e, 0x2e, 0x53, 0x69, 0x6e, 0x67, 0x4d, 0x75, 0x6c, 0x74,
|
||||
0x69, 0x70, 0x6c, 0x65, 0x78, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0c, 0x73, 0x6d, 0x75,
|
||||
0x78, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x22, 0xa4, 0x01, 0x0a, 0x12, 0x4d, 0x75,
|
||||
0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x78, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
|
||||
0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
|
||||
0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x6f,
|
||||
0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52,
|
||||
0x0b, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x28, 0x0a, 0x0f,
|
||||
0x78, 0x75, 0x64, 0x70, 0x43, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x18,
|
||||
0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0f, 0x78, 0x75, 0x64, 0x70, 0x43, 0x6f, 0x6e, 0x63, 0x75,
|
||||
0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x28, 0x0a, 0x0f, 0x78, 0x75, 0x64, 0x70, 0x50, 0x72,
|
||||
0x6f, 0x78, 0x79, 0x55, 0x44, 0x50, 0x34, 0x34, 0x33, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x0f, 0x78, 0x75, 0x64, 0x70, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x55, 0x44, 0x50, 0x34, 0x34, 0x33,
|
||||
0x22, 0xd0, 0x01, 0x0a, 0x13, 0x53, 0x69, 0x6e, 0x67, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c,
|
||||
0x65, 0x78, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62,
|
||||
0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c,
|
||||
0x65, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x02,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x27,
|
||||
0x0a, 0x0f, 0x6d, 0x61, 0x78, 0x5f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e,
|
||||
0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0e, 0x6d, 0x61, 0x78, 0x43, 0x6f, 0x6e, 0x6e,
|
||||
0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x69, 0x6e, 0x5f, 0x73,
|
||||
0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x6d, 0x69,
|
||||
0x6e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x61, 0x78, 0x5f,
|
||||
0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x6d,
|
||||
0x61, 0x78, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x64,
|
||||
0x64, 0x69, 0x6e, 0x67, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x70, 0x61, 0x64, 0x64,
|
||||
0x69, 0x6e, 0x67, 0x2a, 0x23, 0x0a, 0x0e, 0x4b, 0x6e, 0x6f, 0x77, 0x6e, 0x50, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x12, 0x08, 0x0a, 0x04, 0x48, 0x54, 0x54, 0x50, 0x10, 0x00, 0x12,
|
||||
0x07, 0x0a, 0x03, 0x54, 0x4c, 0x53, 0x10, 0x01, 0x42, 0x55, 0x0a, 0x15, 0x63, 0x6f, 0x6d, 0x2e,
|
||||
0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x6d, 0x61,
|
||||
@@ -909,7 +1022,7 @@ func file_app_proxyman_config_proto_rawDescGZIP() []byte {
|
||||
}
|
||||
|
||||
var file_app_proxyman_config_proto_enumTypes = make([]protoimpl.EnumInfo, 2)
|
||||
var file_app_proxyman_config_proto_msgTypes = make([]protoimpl.MessageInfo, 10)
|
||||
var file_app_proxyman_config_proto_msgTypes = make([]protoimpl.MessageInfo, 11)
|
||||
var file_app_proxyman_config_proto_goTypes = []interface{}{
|
||||
(KnownProtocols)(0), // 0: xray.app.proxyman.KnownProtocols
|
||||
(AllocationStrategy_Type)(0), // 1: xray.app.proxyman.AllocationStrategy.Type
|
||||
@@ -921,35 +1034,37 @@ var file_app_proxyman_config_proto_goTypes = []interface{}{
|
||||
(*OutboundConfig)(nil), // 7: xray.app.proxyman.OutboundConfig
|
||||
(*SenderConfig)(nil), // 8: xray.app.proxyman.SenderConfig
|
||||
(*MultiplexingConfig)(nil), // 9: xray.app.proxyman.MultiplexingConfig
|
||||
(*AllocationStrategy_AllocationStrategyConcurrency)(nil), // 10: xray.app.proxyman.AllocationStrategy.AllocationStrategyConcurrency
|
||||
(*AllocationStrategy_AllocationStrategyRefresh)(nil), // 11: xray.app.proxyman.AllocationStrategy.AllocationStrategyRefresh
|
||||
(*net.PortList)(nil), // 12: xray.common.net.PortList
|
||||
(*net.IPOrDomain)(nil), // 13: xray.common.net.IPOrDomain
|
||||
(*internet.StreamConfig)(nil), // 14: xray.transport.internet.StreamConfig
|
||||
(*serial.TypedMessage)(nil), // 15: xray.common.serial.TypedMessage
|
||||
(*internet.ProxyConfig)(nil), // 16: xray.transport.internet.ProxyConfig
|
||||
(*SingMultiplexConfig)(nil), // 10: xray.app.proxyman.SingMultiplexConfig
|
||||
(*AllocationStrategy_AllocationStrategyConcurrency)(nil), // 11: xray.app.proxyman.AllocationStrategy.AllocationStrategyConcurrency
|
||||
(*AllocationStrategy_AllocationStrategyRefresh)(nil), // 12: xray.app.proxyman.AllocationStrategy.AllocationStrategyRefresh
|
||||
(*net.PortList)(nil), // 13: xray.common.net.PortList
|
||||
(*net.IPOrDomain)(nil), // 14: xray.common.net.IPOrDomain
|
||||
(*internet.StreamConfig)(nil), // 15: xray.transport.internet.StreamConfig
|
||||
(*serial.TypedMessage)(nil), // 16: xray.common.serial.TypedMessage
|
||||
(*internet.ProxyConfig)(nil), // 17: xray.transport.internet.ProxyConfig
|
||||
}
|
||||
var file_app_proxyman_config_proto_depIdxs = []int32{
|
||||
1, // 0: xray.app.proxyman.AllocationStrategy.type:type_name -> xray.app.proxyman.AllocationStrategy.Type
|
||||
10, // 1: xray.app.proxyman.AllocationStrategy.concurrency:type_name -> xray.app.proxyman.AllocationStrategy.AllocationStrategyConcurrency
|
||||
11, // 2: xray.app.proxyman.AllocationStrategy.refresh:type_name -> xray.app.proxyman.AllocationStrategy.AllocationStrategyRefresh
|
||||
12, // 3: xray.app.proxyman.ReceiverConfig.port_list:type_name -> xray.common.net.PortList
|
||||
13, // 4: xray.app.proxyman.ReceiverConfig.listen:type_name -> xray.common.net.IPOrDomain
|
||||
11, // 1: xray.app.proxyman.AllocationStrategy.concurrency:type_name -> xray.app.proxyman.AllocationStrategy.AllocationStrategyConcurrency
|
||||
12, // 2: xray.app.proxyman.AllocationStrategy.refresh:type_name -> xray.app.proxyman.AllocationStrategy.AllocationStrategyRefresh
|
||||
13, // 3: xray.app.proxyman.ReceiverConfig.port_list:type_name -> xray.common.net.PortList
|
||||
14, // 4: xray.app.proxyman.ReceiverConfig.listen:type_name -> xray.common.net.IPOrDomain
|
||||
3, // 5: xray.app.proxyman.ReceiverConfig.allocation_strategy:type_name -> xray.app.proxyman.AllocationStrategy
|
||||
14, // 6: xray.app.proxyman.ReceiverConfig.stream_settings:type_name -> xray.transport.internet.StreamConfig
|
||||
15, // 6: xray.app.proxyman.ReceiverConfig.stream_settings:type_name -> xray.transport.internet.StreamConfig
|
||||
0, // 7: xray.app.proxyman.ReceiverConfig.domain_override:type_name -> xray.app.proxyman.KnownProtocols
|
||||
4, // 8: xray.app.proxyman.ReceiverConfig.sniffing_settings:type_name -> xray.app.proxyman.SniffingConfig
|
||||
15, // 9: xray.app.proxyman.InboundHandlerConfig.receiver_settings:type_name -> xray.common.serial.TypedMessage
|
||||
15, // 10: xray.app.proxyman.InboundHandlerConfig.proxy_settings:type_name -> xray.common.serial.TypedMessage
|
||||
13, // 11: xray.app.proxyman.SenderConfig.via:type_name -> xray.common.net.IPOrDomain
|
||||
14, // 12: xray.app.proxyman.SenderConfig.stream_settings:type_name -> xray.transport.internet.StreamConfig
|
||||
16, // 13: xray.app.proxyman.SenderConfig.proxy_settings:type_name -> xray.transport.internet.ProxyConfig
|
||||
16, // 9: xray.app.proxyman.InboundHandlerConfig.receiver_settings:type_name -> xray.common.serial.TypedMessage
|
||||
16, // 10: xray.app.proxyman.InboundHandlerConfig.proxy_settings:type_name -> xray.common.serial.TypedMessage
|
||||
14, // 11: xray.app.proxyman.SenderConfig.via:type_name -> xray.common.net.IPOrDomain
|
||||
15, // 12: xray.app.proxyman.SenderConfig.stream_settings:type_name -> xray.transport.internet.StreamConfig
|
||||
17, // 13: xray.app.proxyman.SenderConfig.proxy_settings:type_name -> xray.transport.internet.ProxyConfig
|
||||
9, // 14: xray.app.proxyman.SenderConfig.multiplex_settings:type_name -> xray.app.proxyman.MultiplexingConfig
|
||||
15, // [15:15] is the sub-list for method output_type
|
||||
15, // [15:15] is the sub-list for method input_type
|
||||
15, // [15:15] is the sub-list for extension type_name
|
||||
15, // [15:15] is the sub-list for extension extendee
|
||||
0, // [0:15] is the sub-list for field type_name
|
||||
10, // 15: xray.app.proxyman.SenderConfig.smux_settings:type_name -> xray.app.proxyman.SingMultiplexConfig
|
||||
16, // [16:16] is the sub-list for method output_type
|
||||
16, // [16:16] is the sub-list for method input_type
|
||||
16, // [16:16] is the sub-list for extension type_name
|
||||
16, // [16:16] is the sub-list for extension extendee
|
||||
0, // [0:16] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_app_proxyman_config_proto_init() }
|
||||
@@ -1055,7 +1170,7 @@ func file_app_proxyman_config_proto_init() {
|
||||
}
|
||||
}
|
||||
file_app_proxyman_config_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*AllocationStrategy_AllocationStrategyConcurrency); i {
|
||||
switch v := v.(*SingMultiplexConfig); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
@@ -1067,6 +1182,18 @@ func file_app_proxyman_config_proto_init() {
|
||||
}
|
||||
}
|
||||
file_app_proxyman_config_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*AllocationStrategy_AllocationStrategyConcurrency); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_app_proxyman_config_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*AllocationStrategy_AllocationStrategyRefresh); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -1085,7 +1212,7 @@ func file_app_proxyman_config_proto_init() {
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_app_proxyman_config_proto_rawDesc,
|
||||
NumEnums: 2,
|
||||
NumMessages: 10,
|
||||
NumMessages: 11,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
|
@@ -27,13 +27,13 @@ message AllocationStrategy {
|
||||
|
||||
Type type = 1;
|
||||
|
||||
message AllocationStrategyConcurrency { uint32 value = 1; }
|
||||
message AllocationStrategyConcurrency {uint32 value = 1;}
|
||||
|
||||
// Number of handlers (ports) running in parallel.
|
||||
// Default value is 3 if unset.
|
||||
AllocationStrategyConcurrency concurrency = 2;
|
||||
|
||||
message AllocationStrategyRefresh { uint32 value = 1; }
|
||||
message AllocationStrategyRefresh {uint32 value = 1;}
|
||||
|
||||
// Number of minutes before a handler is regenerated.
|
||||
// Default value is 5 if unset.
|
||||
@@ -73,7 +73,7 @@ message ReceiverConfig {
|
||||
reserved 6;
|
||||
// Override domains for the given protocol.
|
||||
// Deprecated. Use sniffing_settings.
|
||||
repeated KnownProtocols domain_override = 7 [ deprecated = true ];
|
||||
repeated KnownProtocols domain_override = 7 [deprecated = true];
|
||||
SniffingConfig sniffing_settings = 8;
|
||||
}
|
||||
|
||||
@@ -91,6 +91,7 @@ message SenderConfig {
|
||||
xray.transport.internet.StreamConfig stream_settings = 2;
|
||||
xray.transport.internet.ProxyConfig proxy_settings = 3;
|
||||
MultiplexingConfig multiplex_settings = 4;
|
||||
SingMultiplexConfig smux_settings = 5;
|
||||
}
|
||||
|
||||
message MultiplexingConfig {
|
||||
@@ -103,3 +104,12 @@ message MultiplexingConfig {
|
||||
// "reject" (default), "allow" or "skip".
|
||||
string xudpProxyUDP443 = 4;
|
||||
}
|
||||
|
||||
message SingMultiplexConfig {
|
||||
bool enabled = 1;
|
||||
string protocol = 2;
|
||||
int32 max_connections = 3;
|
||||
int32 min_streams = 4;
|
||||
int32 max_streams = 5;
|
||||
bool padding = 6;
|
||||
}
|
||||
|
@@ -6,12 +6,15 @@ import (
|
||||
"io"
|
||||
"os"
|
||||
|
||||
sing_mux "github.com/sagernet/sing-mux"
|
||||
sing_net "github.com/sagernet/sing/common/network"
|
||||
"github.com/xtls/xray-core/app/proxyman"
|
||||
"github.com/xtls/xray-core/common"
|
||||
"github.com/xtls/xray-core/common/mux"
|
||||
"github.com/xtls/xray-core/common/net"
|
||||
"github.com/xtls/xray-core/common/net/cnc"
|
||||
"github.com/xtls/xray-core/common/session"
|
||||
"github.com/xtls/xray-core/common/singbridge"
|
||||
"github.com/xtls/xray-core/core"
|
||||
"github.com/xtls/xray-core/features/outbound"
|
||||
"github.com/xtls/xray-core/features/policy"
|
||||
@@ -58,6 +61,8 @@ type Handler struct {
|
||||
outboundManager outbound.Manager
|
||||
mux *mux.ClientManager
|
||||
xudp *mux.ClientManager
|
||||
smux *sing_mux.Client
|
||||
|
||||
udp443 string
|
||||
uplinkCounter stats.Counter
|
||||
downlinkCounter stats.Counter
|
||||
@@ -154,6 +159,21 @@ func NewHandler(ctx context.Context, config *core.OutboundHandlerConfig) (outbou
|
||||
h.udp443 = config.XudpProxyUDP443
|
||||
}
|
||||
}
|
||||
if h.senderSettings != nil && h.senderSettings.SmuxSettings != nil {
|
||||
if config := h.senderSettings.SmuxSettings; config.Enabled {
|
||||
h.smux, err = sing_mux.NewClient(sing_mux.Options{
|
||||
Dialer: singbridge.NewOutboundDialer(proxyHandler, h),
|
||||
Protocol: config.Protocol,
|
||||
MaxConnections: int(config.MaxConnections),
|
||||
MinStreams: int(config.MinStreams),
|
||||
MaxStreams: int(config.MaxStreams),
|
||||
Padding: config.Padding,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, newError("failed to create sing mux client").Base(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
h.proxy = proxyHandler
|
||||
return h, nil
|
||||
@@ -197,6 +217,34 @@ func (h *Handler) Dispatch(ctx context.Context, link *transport.Link) {
|
||||
return
|
||||
}
|
||||
}
|
||||
if h.smux != nil {
|
||||
test := func(err error) {
|
||||
if err != nil {
|
||||
err := newError("failed to process mux outbound traffic").Base(err)
|
||||
session.SubmitOutboundErrorToOriginator(ctx, err)
|
||||
err.WriteToLog(session.ExportIDToError(ctx))
|
||||
common.Interrupt(link.Writer)
|
||||
}
|
||||
}
|
||||
inbound := session.InboundFromContext(ctx)
|
||||
outbound := session.OutboundFromContext(ctx)
|
||||
if outbound.Target.Network == net.Network_TCP {
|
||||
conn, err := h.smux.DialContext(ctx, sing_net.NetworkTCP, singbridge.ToSocksaddr(outbound.Target))
|
||||
if err != nil {
|
||||
test(err)
|
||||
return
|
||||
}
|
||||
test(singbridge.CopyConn(ctx, inbound.Conn, link, conn))
|
||||
} else {
|
||||
packetConn, err := h.smux.ListenPacket(ctx, singbridge.ToSocksaddr(outbound.Target))
|
||||
if err != nil {
|
||||
test(err)
|
||||
return
|
||||
}
|
||||
test(singbridge.CopyPacketConn(ctx, inbound.Conn, link, outbound.Target, packetConn))
|
||||
}
|
||||
return
|
||||
}
|
||||
out:
|
||||
err := h.proxy.Process(ctx, link, h)
|
||||
if err != nil {
|
||||
|
@@ -1,347 +0,0 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.28.1
|
||||
// protoc v3.21.12
|
||||
// source: app/tun/config.proto
|
||||
|
||||
package tun
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
InterfaceName string `protobuf:"bytes,1,opt,name=interface_name,json=interfaceName,proto3" json:"interface_name,omitempty"`
|
||||
Inet4Address []string `protobuf:"bytes,2,rep,name=inet4_address,json=inet4Address,proto3" json:"inet4_address,omitempty"`
|
||||
Inet6Address []string `protobuf:"bytes,3,rep,name=inet6_address,json=inet6Address,proto3" json:"inet6_address,omitempty"`
|
||||
Mtu uint32 `protobuf:"varint,4,opt,name=mtu,proto3" json:"mtu,omitempty"`
|
||||
AutoRoute bool `protobuf:"varint,5,opt,name=auto_route,json=autoRoute,proto3" json:"auto_route,omitempty"`
|
||||
StrictRoute bool `protobuf:"varint,6,opt,name=strict_route,json=strictRoute,proto3" json:"strict_route,omitempty"`
|
||||
Inet4RouteAddress []string `protobuf:"bytes,7,rep,name=inet4_route_address,json=inet4RouteAddress,proto3" json:"inet4_route_address,omitempty"`
|
||||
Inet6RouteAddress []string `protobuf:"bytes,8,rep,name=inet6_route_address,json=inet6RouteAddress,proto3" json:"inet6_route_address,omitempty"`
|
||||
EndpointIndependentNat bool `protobuf:"varint,9,opt,name=endpoint_independent_nat,json=endpointIndependentNat,proto3" json:"endpoint_independent_nat,omitempty"`
|
||||
UdpTimeout int64 `protobuf:"varint,10,opt,name=udp_timeout,json=udpTimeout,proto3" json:"udp_timeout,omitempty"`
|
||||
Stack string `protobuf:"bytes,11,opt,name=stack,proto3" json:"stack,omitempty"`
|
||||
IncludeUid []uint32 `protobuf:"varint,12,rep,packed,name=include_uid,json=includeUid,proto3" json:"include_uid,omitempty"`
|
||||
IncludeUidRange []string `protobuf:"bytes,13,rep,name=include_uid_range,json=includeUidRange,proto3" json:"include_uid_range,omitempty"`
|
||||
ExcludeUid []uint32 `protobuf:"varint,14,rep,packed,name=exclude_uid,json=excludeUid,proto3" json:"exclude_uid,omitempty"`
|
||||
ExcludeUidRange []string `protobuf:"bytes,15,rep,name=exclude_uid_range,json=excludeUidRange,proto3" json:"exclude_uid_range,omitempty"`
|
||||
IncludeAndroidUser []int32 `protobuf:"varint,16,rep,packed,name=include_android_user,json=includeAndroidUser,proto3" json:"include_android_user,omitempty"`
|
||||
IncludePackage []string `protobuf:"bytes,17,rep,name=include_package,json=includePackage,proto3" json:"include_package,omitempty"`
|
||||
ExcludePackage []string `protobuf:"bytes,18,rep,name=exclude_package,json=excludePackage,proto3" json:"exclude_package,omitempty"`
|
||||
// for xray
|
||||
AutoDetectInterface bool `protobuf:"varint,100,opt,name=auto_detect_interface,json=autoDetectInterface,proto3" json:"auto_detect_interface,omitempty"`
|
||||
OverrideAndroidVpn bool `protobuf:"varint,101,opt,name=override_android_vpn,json=overrideAndroidVpn,proto3" json:"override_android_vpn,omitempty"`
|
||||
}
|
||||
|
||||
func (x *Config) Reset() {
|
||||
*x = Config{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_app_tun_config_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *Config) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*Config) ProtoMessage() {}
|
||||
|
||||
func (x *Config) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_app_tun_config_proto_msgTypes[0]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use Config.ProtoReflect.Descriptor instead.
|
||||
func (*Config) Descriptor() ([]byte, []int) {
|
||||
return file_app_tun_config_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *Config) GetInterfaceName() string {
|
||||
if x != nil {
|
||||
return x.InterfaceName
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Config) GetInet4Address() []string {
|
||||
if x != nil {
|
||||
return x.Inet4Address
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Config) GetInet6Address() []string {
|
||||
if x != nil {
|
||||
return x.Inet6Address
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Config) GetMtu() uint32 {
|
||||
if x != nil {
|
||||
return x.Mtu
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *Config) GetAutoRoute() bool {
|
||||
if x != nil {
|
||||
return x.AutoRoute
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *Config) GetStrictRoute() bool {
|
||||
if x != nil {
|
||||
return x.StrictRoute
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *Config) GetInet4RouteAddress() []string {
|
||||
if x != nil {
|
||||
return x.Inet4RouteAddress
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Config) GetInet6RouteAddress() []string {
|
||||
if x != nil {
|
||||
return x.Inet6RouteAddress
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Config) GetEndpointIndependentNat() bool {
|
||||
if x != nil {
|
||||
return x.EndpointIndependentNat
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *Config) GetUdpTimeout() int64 {
|
||||
if x != nil {
|
||||
return x.UdpTimeout
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *Config) GetStack() string {
|
||||
if x != nil {
|
||||
return x.Stack
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Config) GetIncludeUid() []uint32 {
|
||||
if x != nil {
|
||||
return x.IncludeUid
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Config) GetIncludeUidRange() []string {
|
||||
if x != nil {
|
||||
return x.IncludeUidRange
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Config) GetExcludeUid() []uint32 {
|
||||
if x != nil {
|
||||
return x.ExcludeUid
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Config) GetExcludeUidRange() []string {
|
||||
if x != nil {
|
||||
return x.ExcludeUidRange
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Config) GetIncludeAndroidUser() []int32 {
|
||||
if x != nil {
|
||||
return x.IncludeAndroidUser
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Config) GetIncludePackage() []string {
|
||||
if x != nil {
|
||||
return x.IncludePackage
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Config) GetExcludePackage() []string {
|
||||
if x != nil {
|
||||
return x.ExcludePackage
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Config) GetAutoDetectInterface() bool {
|
||||
if x != nil {
|
||||
return x.AutoDetectInterface
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *Config) GetOverrideAndroidVpn() bool {
|
||||
if x != nil {
|
||||
return x.OverrideAndroidVpn
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
var File_app_tun_config_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_app_tun_config_proto_rawDesc = []byte{
|
||||
0x0a, 0x14, 0x61, 0x70, 0x70, 0x2f, 0x74, 0x75, 0x6e, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
|
||||
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0c, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70,
|
||||
0x2e, 0x74, 0x75, 0x6e, 0x22, 0xa2, 0x06, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12,
|
||||
0x25, 0x0a, 0x0e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d,
|
||||
0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61,
|
||||
0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x69, 0x6e, 0x65, 0x74, 0x34, 0x5f,
|
||||
0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x69,
|
||||
0x6e, 0x65, 0x74, 0x34, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x69,
|
||||
0x6e, 0x65, 0x74, 0x36, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x03,
|
||||
0x28, 0x09, 0x52, 0x0c, 0x69, 0x6e, 0x65, 0x74, 0x36, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73,
|
||||
0x12, 0x10, 0x0a, 0x03, 0x6d, 0x74, 0x75, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x6d,
|
||||
0x74, 0x75, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x75, 0x74, 0x6f, 0x5f, 0x72, 0x6f, 0x75, 0x74, 0x65,
|
||||
0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x61, 0x75, 0x74, 0x6f, 0x52, 0x6f, 0x75, 0x74,
|
||||
0x65, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x5f, 0x72, 0x6f, 0x75, 0x74,
|
||||
0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x52,
|
||||
0x6f, 0x75, 0x74, 0x65, 0x12, 0x2e, 0x0a, 0x13, 0x69, 0x6e, 0x65, 0x74, 0x34, 0x5f, 0x72, 0x6f,
|
||||
0x75, 0x74, 0x65, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28,
|
||||
0x09, 0x52, 0x11, 0x69, 0x6e, 0x65, 0x74, 0x34, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x41, 0x64, 0x64,
|
||||
0x72, 0x65, 0x73, 0x73, 0x12, 0x2e, 0x0a, 0x13, 0x69, 0x6e, 0x65, 0x74, 0x36, 0x5f, 0x72, 0x6f,
|
||||
0x75, 0x74, 0x65, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28,
|
||||
0x09, 0x52, 0x11, 0x69, 0x6e, 0x65, 0x74, 0x36, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x41, 0x64, 0x64,
|
||||
0x72, 0x65, 0x73, 0x73, 0x12, 0x38, 0x0a, 0x18, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74,
|
||||
0x5f, 0x69, 0x6e, 0x64, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x74, 0x5f, 0x6e, 0x61, 0x74,
|
||||
0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x16, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74,
|
||||
0x49, 0x6e, 0x64, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x74, 0x4e, 0x61, 0x74, 0x12, 0x1f,
|
||||
0x0a, 0x0b, 0x75, 0x64, 0x70, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x0a, 0x20,
|
||||
0x01, 0x28, 0x03, 0x52, 0x0a, 0x75, 0x64, 0x70, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12,
|
||||
0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05,
|
||||
0x73, 0x74, 0x61, 0x63, 0x6b, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65,
|
||||
0x5f, 0x75, 0x69, 0x64, 0x18, 0x0c, 0x20, 0x03, 0x28, 0x0d, 0x52, 0x0a, 0x69, 0x6e, 0x63, 0x6c,
|
||||
0x75, 0x64, 0x65, 0x55, 0x69, 0x64, 0x12, 0x2a, 0x0a, 0x11, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64,
|
||||
0x65, 0x5f, 0x75, 0x69, 0x64, 0x5f, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x0d, 0x20, 0x03, 0x28,
|
||||
0x09, 0x52, 0x0f, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x55, 0x69, 0x64, 0x52, 0x61, 0x6e,
|
||||
0x67, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x75, 0x69,
|
||||
0x64, 0x18, 0x0e, 0x20, 0x03, 0x28, 0x0d, 0x52, 0x0a, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65,
|
||||
0x55, 0x69, 0x64, 0x12, 0x2a, 0x0a, 0x11, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x75,
|
||||
0x69, 0x64, 0x5f, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x0f, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0f,
|
||||
0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x55, 0x69, 0x64, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x12,
|
||||
0x30, 0x0a, 0x14, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x61, 0x6e, 0x64, 0x72, 0x6f,
|
||||
0x69, 0x64, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x18, 0x10, 0x20, 0x03, 0x28, 0x05, 0x52, 0x12, 0x69,
|
||||
0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x55, 0x73, 0x65,
|
||||
0x72, 0x12, 0x27, 0x0a, 0x0f, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x70, 0x61, 0x63,
|
||||
0x6b, 0x61, 0x67, 0x65, 0x18, 0x11, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, 0x69, 0x6e, 0x63, 0x6c,
|
||||
0x75, 0x64, 0x65, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x65, 0x78,
|
||||
0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x18, 0x12, 0x20,
|
||||
0x03, 0x28, 0x09, 0x52, 0x0e, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x50, 0x61, 0x63, 0x6b,
|
||||
0x61, 0x67, 0x65, 0x12, 0x32, 0x0a, 0x15, 0x61, 0x75, 0x74, 0x6f, 0x5f, 0x64, 0x65, 0x74, 0x65,
|
||||
0x63, 0x74, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x18, 0x64, 0x20, 0x01,
|
||||
0x28, 0x08, 0x52, 0x13, 0x61, 0x75, 0x74, 0x6f, 0x44, 0x65, 0x74, 0x65, 0x63, 0x74, 0x49, 0x6e,
|
||||
0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x12, 0x30, 0x0a, 0x14, 0x6f, 0x76, 0x65, 0x72, 0x72,
|
||||
0x69, 0x64, 0x65, 0x5f, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x5f, 0x76, 0x70, 0x6e, 0x18,
|
||||
0x65, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x41,
|
||||
0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x56, 0x70, 0x6e, 0x42, 0x46, 0x0a, 0x10, 0x63, 0x6f, 0x6d,
|
||||
0x2e, 0x78, 0x72, 0x61, 0x79, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x74, 0x75, 0x6e, 0x50, 0x01, 0x5a,
|
||||
0x21, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x74, 0x6c, 0x73,
|
||||
0x2f, 0x78, 0x72, 0x61, 0x79, 0x2d, 0x63, 0x6f, 0x72, 0x65, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x74,
|
||||
0x75, 0x6e, 0xaa, 0x02, 0x0c, 0x58, 0x72, 0x61, 0x79, 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x54, 0x75,
|
||||
0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
file_app_tun_config_proto_rawDescOnce sync.Once
|
||||
file_app_tun_config_proto_rawDescData = file_app_tun_config_proto_rawDesc
|
||||
)
|
||||
|
||||
func file_app_tun_config_proto_rawDescGZIP() []byte {
|
||||
file_app_tun_config_proto_rawDescOnce.Do(func() {
|
||||
file_app_tun_config_proto_rawDescData = protoimpl.X.CompressGZIP(file_app_tun_config_proto_rawDescData)
|
||||
})
|
||||
return file_app_tun_config_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_app_tun_config_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
|
||||
var file_app_tun_config_proto_goTypes = []interface{}{
|
||||
(*Config)(nil), // 0: xray.app.tun.Config
|
||||
}
|
||||
var file_app_tun_config_proto_depIdxs = []int32{
|
||||
0, // [0:0] is the sub-list for method output_type
|
||||
0, // [0:0] is the sub-list for method input_type
|
||||
0, // [0:0] is the sub-list for extension type_name
|
||||
0, // [0:0] is the sub-list for extension extendee
|
||||
0, // [0:0] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_app_tun_config_proto_init() }
|
||||
func file_app_tun_config_proto_init() {
|
||||
if File_app_tun_config_proto != nil {
|
||||
return
|
||||
}
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_app_tun_config_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Config); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_app_tun_config_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 1,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
GoTypes: file_app_tun_config_proto_goTypes,
|
||||
DependencyIndexes: file_app_tun_config_proto_depIdxs,
|
||||
MessageInfos: file_app_tun_config_proto_msgTypes,
|
||||
}.Build()
|
||||
File_app_tun_config_proto = out.File
|
||||
file_app_tun_config_proto_rawDesc = nil
|
||||
file_app_tun_config_proto_goTypes = nil
|
||||
file_app_tun_config_proto_depIdxs = nil
|
||||
}
|
@@ -1,32 +0,0 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package xray.app.tun;
|
||||
option csharp_namespace = "Xray.App.Tun";
|
||||
option go_package = "github.com/xtls/xray-core/app/tun";
|
||||
option java_package = "com.xray.app.tun";
|
||||
option java_multiple_files = true;
|
||||
|
||||
message Config {
|
||||
string interface_name = 1;
|
||||
repeated string inet4_address = 2;
|
||||
repeated string inet6_address = 3;
|
||||
uint32 mtu = 4;
|
||||
bool auto_route = 5;
|
||||
bool strict_route = 6;
|
||||
repeated string inet4_route_address = 7;
|
||||
repeated string inet6_route_address = 8;
|
||||
bool endpoint_independent_nat = 9;
|
||||
int64 udp_timeout = 10;
|
||||
string stack = 11;
|
||||
repeated uint32 include_uid = 12;
|
||||
repeated string include_uid_range = 13;
|
||||
repeated uint32 exclude_uid = 14;
|
||||
repeated string exclude_uid_range = 15;
|
||||
repeated int32 include_android_user = 16;
|
||||
repeated string include_package = 17;
|
||||
repeated string exclude_package = 18;
|
||||
|
||||
// for xray
|
||||
bool auto_detect_interface = 100;
|
||||
bool override_android_vpn = 101;
|
||||
}
|
@@ -1,9 +0,0 @@
|
||||
package tun
|
||||
|
||||
import "github.com/xtls/xray-core/common/errors"
|
||||
|
||||
type errPathObjHolder struct{}
|
||||
|
||||
func newError(values ...interface{}) *errors.Error {
|
||||
return errors.New(values...).WithPathObj(errPathObjHolder{})
|
||||
}
|
@@ -1,50 +0,0 @@
|
||||
package tun
|
||||
|
||||
import (
|
||||
"net"
|
||||
|
||||
"github.com/sagernet/sing/common/control"
|
||||
)
|
||||
|
||||
var _ control.InterfaceFinder = (*myInterfaceFinder)(nil)
|
||||
|
||||
type myInterfaceFinder struct {
|
||||
ifs []net.Interface
|
||||
}
|
||||
|
||||
func (f *myInterfaceFinder) update() error {
|
||||
ifs, err := net.Interfaces()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
f.ifs = ifs
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *myInterfaceFinder) InterfaceIndexByName(name string) (interfaceIndex int, err error) {
|
||||
for _, netInterface := range f.ifs {
|
||||
if netInterface.Name == name {
|
||||
return netInterface.Index, nil
|
||||
}
|
||||
}
|
||||
netInterface, err := net.InterfaceByName(name)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
f.update()
|
||||
return netInterface.Index, nil
|
||||
}
|
||||
|
||||
func (f *myInterfaceFinder) InterfaceNameByIndex(index int) (interfaceName string, err error) {
|
||||
for _, netInterface := range f.ifs {
|
||||
if netInterface.Index == index {
|
||||
return netInterface.Name, nil
|
||||
}
|
||||
}
|
||||
netInterface, err := net.InterfaceByIndex(index)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
f.update()
|
||||
return netInterface.Name, nil
|
||||
}
|
@@ -1,42 +0,0 @@
|
||||
package tun
|
||||
|
||||
import (
|
||||
sing_common "github.com/sagernet/sing/common"
|
||||
sing_buf "github.com/sagernet/sing/common/buf"
|
||||
N "github.com/sagernet/sing/common/network"
|
||||
"github.com/xtls/xray-core/common/buf"
|
||||
"github.com/xtls/xray-core/common/net"
|
||||
"github.com/xtls/xray-core/common/singbridge"
|
||||
)
|
||||
|
||||
type PacketConn struct {
|
||||
N.PacketConn
|
||||
}
|
||||
|
||||
func (p *PacketConn) ReadMultiBuffer() (buf.MultiBuffer, error) {
|
||||
packet := buf.New()
|
||||
packet.Extend(buf.Size)
|
||||
sPacket := sing_buf.With(packet.Bytes())
|
||||
destination, err := p.ReadPacket(sPacket)
|
||||
if err != nil {
|
||||
packet.Release()
|
||||
return nil, err
|
||||
}
|
||||
packet.Clear()
|
||||
packet.Resize(int32(sPacket.Start()), int32(sPacket.Start()+sPacket.Len()))
|
||||
destinationX := singbridge.ToDestination(destination, net.Network_UDP)
|
||||
packet.UDP = &destinationX
|
||||
return buf.MultiBuffer{packet}, nil
|
||||
}
|
||||
|
||||
func (p *PacketConn) WriteMultiBuffer(mb buf.MultiBuffer) error {
|
||||
defer buf.ReleaseMulti(mb)
|
||||
for _, buffer := range mb {
|
||||
destination := sing_common.PtrValueOrDefault(buffer.UDP)
|
||||
err := p.PacketConn.WritePacket(sing_buf.As(buffer.Bytes()), singbridge.ToSocksaddr(destination))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
296
app/tun/tun.go
296
app/tun/tun.go
@@ -1,296 +0,0 @@
|
||||
package tun
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/netip"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/sagernet/sing-tun"
|
||||
sing_common "github.com/sagernet/sing/common"
|
||||
"github.com/sagernet/sing/common/control"
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
"github.com/sagernet/sing/common/logger"
|
||||
M "github.com/sagernet/sing/common/metadata"
|
||||
N "github.com/sagernet/sing/common/network"
|
||||
"github.com/sagernet/sing/common/ranges"
|
||||
"github.com/xtls/xray-core/common"
|
||||
"github.com/xtls/xray-core/common/net"
|
||||
"github.com/xtls/xray-core/common/session"
|
||||
"github.com/xtls/xray-core/common/singbridge"
|
||||
"github.com/xtls/xray-core/core"
|
||||
"github.com/xtls/xray-core/features/routing"
|
||||
features_tun "github.com/xtls/xray-core/features/tun"
|
||||
"github.com/xtls/xray-core/transport"
|
||||
"github.com/xtls/xray-core/transport/internet"
|
||||
)
|
||||
|
||||
//go:generate go run github.com/xtls/xray-core/common/errors/errorgen
|
||||
|
||||
func init() {
|
||||
common.Must(common.RegisterConfig((*Config)(nil), func(ctx context.Context, cfg interface{}) (interface{}, error) {
|
||||
return New(ctx, cfg.(*Config))
|
||||
}))
|
||||
}
|
||||
|
||||
var TunInitializer features_tun.Interface = (*Tun)(nil)
|
||||
|
||||
type Tun struct {
|
||||
ctx context.Context
|
||||
dispatcher routing.Dispatcher
|
||||
logger logger.ContextLogger
|
||||
tunOptions tun.Options
|
||||
stack string
|
||||
endpointIndependentNat bool
|
||||
udpTimeout int64
|
||||
tunIf tun.Tun
|
||||
tunStack tun.Stack
|
||||
networkMonitor tun.NetworkUpdateMonitor
|
||||
interfaceMonitor tun.DefaultInterfaceMonitor
|
||||
packageManager tun.PackageManager
|
||||
interfaceFinder *myInterfaceFinder
|
||||
}
|
||||
|
||||
func New(ctx context.Context, config *Config) (*Tun, error) {
|
||||
instance := core.MustFromContext(ctx)
|
||||
tunInterface := &Tun{
|
||||
ctx: ctx,
|
||||
dispatcher: instance.GetFeature(routing.DispatcherType()).(routing.Dispatcher),
|
||||
logger: singbridge.NewLogger(newError),
|
||||
stack: config.Stack,
|
||||
endpointIndependentNat: config.EndpointIndependentNat,
|
||||
udpTimeout: int64(5 * time.Minute.Seconds()),
|
||||
interfaceFinder: new(myInterfaceFinder),
|
||||
}
|
||||
networkUpdateMonitor, err := tun.NewNetworkUpdateMonitor(tunInterface)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defaultInterfaceMonitor, err := tun.NewDefaultInterfaceMonitor(networkUpdateMonitor, tun.DefaultInterfaceMonitorOptions{
|
||||
OverrideAndroidVPN: config.OverrideAndroidVpn,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defaultInterfaceMonitor.RegisterCallback(tunInterface.notifyNetworkUpdate)
|
||||
if config.AutoDetectInterface {
|
||||
networkUpdateMonitor.RegisterCallback(tunInterface.interfaceFinder.update)
|
||||
const useInterfaceName = runtime.GOOS == "linux" || runtime.GOOS == "android"
|
||||
bindFunc := control.BindToInterfaceFunc(tunInterface.interfaceFinder, func(network string, address string) (interfaceName string, interfaceIndex int) {
|
||||
remoteAddr := M.ParseSocksaddr(address).Addr
|
||||
if useInterfaceName {
|
||||
return defaultInterfaceMonitor.DefaultInterfaceName(remoteAddr), -1
|
||||
} else {
|
||||
return "", defaultInterfaceMonitor.DefaultInterfaceIndex(remoteAddr)
|
||||
}
|
||||
})
|
||||
internet.UseAlternativeSystemDialer(nil)
|
||||
internet.RegisterDialerController(bindFunc)
|
||||
internet.RegisterListenerController(bindFunc)
|
||||
}
|
||||
if runtime.GOOS == "android" {
|
||||
packageManage, err := tun.NewPackageManager(tunInterface)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tunInterface.packageManager = packageManage
|
||||
}
|
||||
tunInterface.networkMonitor = networkUpdateMonitor
|
||||
tunInterface.interfaceMonitor = defaultInterfaceMonitor
|
||||
tunName := config.InterfaceName
|
||||
if tunName == "" {
|
||||
tunName = tun.CalculateInterfaceName("")
|
||||
}
|
||||
tunMTU := config.Mtu
|
||||
if tunMTU == 0 {
|
||||
tunMTU = 9000
|
||||
}
|
||||
includeUID := uidToRange(config.IncludeUid)
|
||||
if len(config.IncludeUidRange) > 0 {
|
||||
var err error
|
||||
includeUID, err = parseRange(includeUID, config.IncludeUidRange)
|
||||
if err != nil {
|
||||
return nil, E.Cause(err, "parse include_uid_range")
|
||||
}
|
||||
}
|
||||
excludeUID := uidToRange(config.ExcludeUid)
|
||||
if len(config.ExcludeUidRange) > 0 {
|
||||
var err error
|
||||
excludeUID, err = parseRange(excludeUID, config.ExcludeUidRange)
|
||||
if err != nil {
|
||||
return nil, E.Cause(err, "parse exclude_uid_range")
|
||||
}
|
||||
}
|
||||
if config.UdpTimeout != 0 {
|
||||
tunInterface.udpTimeout = config.UdpTimeout
|
||||
}
|
||||
tunInterface.tunOptions = tun.Options{
|
||||
Name: tunName,
|
||||
Inet4Address: sing_common.Map(config.Inet4Address, netip.MustParsePrefix),
|
||||
Inet6Address: sing_common.Map(config.Inet6Address, netip.MustParsePrefix),
|
||||
MTU: tunMTU,
|
||||
AutoRoute: config.AutoRoute,
|
||||
StrictRoute: config.StrictRoute,
|
||||
Inet4RouteAddress: sing_common.Map(config.Inet4RouteAddress, netip.MustParsePrefix),
|
||||
Inet6RouteAddress: sing_common.Map(config.Inet6RouteAddress, netip.MustParsePrefix),
|
||||
IncludeUID: includeUID,
|
||||
ExcludeUID: excludeUID,
|
||||
IncludeAndroidUser: sing_common.Map(config.IncludeAndroidUser, func(it int32) int {
|
||||
return int(it)
|
||||
}),
|
||||
IncludePackage: config.IncludePackage,
|
||||
ExcludePackage: config.ExcludePackage,
|
||||
InterfaceMonitor: defaultInterfaceMonitor,
|
||||
TableIndex: 2022,
|
||||
}
|
||||
return tunInterface, nil
|
||||
}
|
||||
|
||||
func (t *Tun) Type() interface{} {
|
||||
return features_tun.InterfaceType()
|
||||
}
|
||||
|
||||
func (t *Tun) Start() error {
|
||||
err := t.interfaceMonitor.Start()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = t.networkMonitor.Start()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if runtime.GOOS == "android" {
|
||||
err = t.packageManager.Start()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
t.tunOptions.BuildAndroidRules(t.packageManager, t)
|
||||
}
|
||||
tunIf, err := tun.New(t.tunOptions)
|
||||
if err != nil {
|
||||
return E.Cause(err, "configure tun interface")
|
||||
}
|
||||
t.tunIf = tunIf
|
||||
t.tunStack, err = tun.NewStack(t.stack, tun.StackOptions{
|
||||
Context: t.ctx,
|
||||
Tun: tunIf,
|
||||
MTU: t.tunOptions.MTU,
|
||||
Name: t.tunOptions.Name,
|
||||
Inet4Address: t.tunOptions.Inet4Address,
|
||||
Inet6Address: t.tunOptions.Inet6Address,
|
||||
EndpointIndependentNat: t.endpointIndependentNat,
|
||||
UDPTimeout: t.udpTimeout,
|
||||
Handler: t,
|
||||
Logger: t.logger,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = t.tunStack.Start()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
t.logger.Info("tun started at ", t.tunOptions.Name)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *Tun) NewConnection(ctx context.Context, conn net.Conn, metadata M.Metadata) error {
|
||||
sid := session.NewID()
|
||||
ctx = session.ContextWithID(ctx, sid)
|
||||
t.logger.InfoContext(ctx, "inbound connection from ", metadata.Source)
|
||||
t.logger.InfoContext(ctx, "inbound connection to ", metadata.Destination)
|
||||
ctx = session.ContextWithInbound(ctx, &session.Inbound{
|
||||
Source: net.DestinationFromAddr(metadata.Source.TCPAddr()),
|
||||
Conn: conn,
|
||||
})
|
||||
wConn := singbridge.NewConn(conn)
|
||||
_ = t.dispatcher.DispatchLink(ctx, singbridge.ToDestination(metadata.Destination, net.Network_TCP), &transport.Link{
|
||||
Reader: wConn,
|
||||
Writer: wConn,
|
||||
})
|
||||
conn.Close()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *Tun) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata M.Metadata) error {
|
||||
sid := session.NewID()
|
||||
ctx = session.ContextWithID(ctx, sid)
|
||||
t.logger.InfoContext(ctx, "inbound packet connection from ", metadata.Source)
|
||||
t.logger.InfoContext(ctx, "inbound packet connection to ", metadata.Destination)
|
||||
ctx = session.ContextWithInbound(ctx, &session.Inbound{
|
||||
Source: net.DestinationFromAddr(metadata.Source.UDPAddr()),
|
||||
})
|
||||
pc := &PacketConn{conn}
|
||||
_ = t.dispatcher.DispatchLink(ctx, singbridge.ToDestination(metadata.Destination, net.Network_UDP), &transport.Link{
|
||||
Reader: pc,
|
||||
Writer: pc,
|
||||
})
|
||||
conn.Close()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *Tun) Close() error {
|
||||
return sing_common.Close(
|
||||
t.packageManager,
|
||||
t.interfaceMonitor,
|
||||
t.networkMonitor,
|
||||
t.tunStack,
|
||||
t.tunIf,
|
||||
)
|
||||
}
|
||||
|
||||
func (t *Tun) OnPackagesUpdated(packages int, sharedUsers int) {
|
||||
t.logger.Info("updated packages list: ", packages, " packages, ", sharedUsers, " shared users")
|
||||
}
|
||||
|
||||
func (t *Tun) NewError(ctx context.Context, err error) {
|
||||
}
|
||||
|
||||
func (t *Tun) notifyNetworkUpdate(int) error {
|
||||
if runtime.GOOS == "android" {
|
||||
var vpnStatus string
|
||||
if t.interfaceMonitor.AndroidVPNEnabled() {
|
||||
vpnStatus = "enabled"
|
||||
} else {
|
||||
vpnStatus = "disabled"
|
||||
}
|
||||
t.logger.Info("updated default interface ", t.interfaceMonitor.DefaultInterfaceName(netip.IPv4Unspecified()), ", index ", t.interfaceMonitor.DefaultInterfaceIndex(netip.IPv4Unspecified()), ", vpn ", vpnStatus)
|
||||
} else {
|
||||
t.logger.Info("updated default interface ", t.interfaceMonitor.DefaultInterfaceName(netip.IPv4Unspecified()), ", index ", t.interfaceMonitor.DefaultInterfaceIndex(netip.IPv4Unspecified()))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func uidToRange(uidList []uint32) []ranges.Range[uint32] {
|
||||
return sing_common.Map(uidList, func(uid uint32) ranges.Range[uint32] {
|
||||
return ranges.NewSingle(uint32(uid))
|
||||
})
|
||||
}
|
||||
|
||||
func parseRange(uidRanges []ranges.Range[uint32], rangeList []string) ([]ranges.Range[uint32], error) {
|
||||
for _, uidRange := range rangeList {
|
||||
if !strings.Contains(uidRange, ":") {
|
||||
return nil, E.New("missing ':' in range: ", uidRange)
|
||||
}
|
||||
subIndex := strings.Index(uidRange, ":")
|
||||
if subIndex == 0 {
|
||||
return nil, E.New("missing range start: ", uidRange)
|
||||
} else if subIndex == len(uidRange)-1 {
|
||||
return nil, E.New("missing range end: ", uidRange)
|
||||
}
|
||||
var start, end uint64
|
||||
var err error
|
||||
start, err = strconv.ParseUint(uidRange[:subIndex], 10, 32)
|
||||
if err != nil {
|
||||
return nil, E.Cause(err, "parse range start")
|
||||
}
|
||||
end, err = strconv.ParseUint(uidRange[subIndex+1:], 10, 32)
|
||||
if err != nil {
|
||||
return nil, E.Cause(err, "parse range end")
|
||||
}
|
||||
uidRanges = append(uidRanges, ranges.New(uint32(start), uint32(end)))
|
||||
}
|
||||
return uidRanges, nil
|
||||
}
|
@@ -7,7 +7,7 @@ import (
|
||||
"github.com/xtls/xray-core/common/errors"
|
||||
)
|
||||
|
||||
func readOneUDP(r io.Reader) (*Buffer, error) {
|
||||
func ReadOneUDP(r io.Reader) (*Buffer, error) {
|
||||
b := New()
|
||||
for i := 0; i < 64; i++ {
|
||||
_, err := b.ReadFrom(r)
|
||||
@@ -166,7 +166,7 @@ type PacketReader struct {
|
||||
|
||||
// ReadMultiBuffer implements Reader.
|
||||
func (r *PacketReader) ReadMultiBuffer() (MultiBuffer, error) {
|
||||
b, err := readOneUDP(r.Reader)
|
||||
b, err := ReadOneUDP(r.Reader)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@@ -4,13 +4,17 @@ import (
|
||||
"context"
|
||||
"io"
|
||||
|
||||
sing_mux "github.com/sagernet/sing-mux"
|
||||
"github.com/sagernet/sing/common/metadata"
|
||||
"github.com/xtls/xray-core/common"
|
||||
"github.com/xtls/xray-core/common/buf"
|
||||
"github.com/xtls/xray-core/common/errors"
|
||||
"github.com/xtls/xray-core/common/log"
|
||||
"github.com/xtls/xray-core/common/net"
|
||||
"github.com/xtls/xray-core/common/net/cnc"
|
||||
"github.com/xtls/xray-core/common/protocol"
|
||||
"github.com/xtls/xray-core/common/session"
|
||||
"github.com/xtls/xray-core/common/singbridge"
|
||||
"github.com/xtls/xray-core/core"
|
||||
"github.com/xtls/xray-core/features/routing"
|
||||
"github.com/xtls/xray-core/transport"
|
||||
@@ -38,6 +42,14 @@ func (s *Server) Type() interface{} {
|
||||
// Dispatch implements routing.Dispatcher
|
||||
func (s *Server) Dispatch(ctx context.Context, dest net.Destination) (*transport.Link, error) {
|
||||
if dest.Address != muxCoolAddress {
|
||||
if dest.Address.Family() == net.AddressFamilyDomain && dest.Address.Domain() == sing_mux.Destination.Fqdn {
|
||||
opts := pipe.OptionsFromContext(ctx)
|
||||
uplinkReader, uplinkWriter := pipe.New(opts...)
|
||||
downlinkReader, downlinkWriter := pipe.New(opts...)
|
||||
conn := cnc.NewConnection(cnc.ConnectionInputMulti(downlinkWriter), cnc.ConnectionOutputMulti(uplinkReader))
|
||||
go sing_mux.HandleConnection(ctx, singbridge.NewDispatcher(s.dispatcher, newError), singbridge.NewLogger(newError), conn, metadata.Metadata{Destination: singbridge.ToSocksaddr(dest)})
|
||||
return &transport.Link{Reader: downlinkReader, Writer: uplinkWriter}, nil
|
||||
}
|
||||
return s.dispatcher.Dispatch(ctx, dest)
|
||||
}
|
||||
|
||||
@@ -59,6 +71,10 @@ func (s *Server) Dispatch(ctx context.Context, dest net.Destination) (*transport
|
||||
// DispatchLink implements routing.Dispatcher
|
||||
func (s *Server) DispatchLink(ctx context.Context, dest net.Destination, link *transport.Link) error {
|
||||
if dest.Address != muxCoolAddress {
|
||||
if dest.Address.Family() == net.AddressFamilyDomain && dest.Address.Domain() == sing_mux.Destination.Fqdn {
|
||||
conn := cnc.NewConnection(cnc.ConnectionInputMulti(link.Writer), cnc.ConnectionOutputMulti(link.Reader))
|
||||
return sing_mux.HandleConnection(ctx, singbridge.NewDispatcher(s.dispatcher, newError), singbridge.NewLogger(newError), conn, metadata.Metadata{Destination: singbridge.ToSocksaddr(dest)})
|
||||
}
|
||||
return s.dispatcher.DispatchLink(ctx, dest, link)
|
||||
}
|
||||
_, err := NewServerWorker(ctx, s.dispatcher, link)
|
||||
|
@@ -2,11 +2,10 @@ package singbridge
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
|
||||
"github.com/sagernet/sing/common/bufio"
|
||||
M "github.com/sagernet/sing/common/metadata"
|
||||
N "github.com/sagernet/sing/common/network"
|
||||
"github.com/xtls/xray-core/common/buf"
|
||||
"github.com/xtls/xray-core/common/errors"
|
||||
"github.com/xtls/xray-core/common/net"
|
||||
"github.com/xtls/xray-core/common/session"
|
||||
@@ -40,9 +39,10 @@ func (d *Dispatcher) NewConnection(ctx context.Context, conn net.Conn, metadata
|
||||
}
|
||||
|
||||
func (d *Dispatcher) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata M.Metadata) error {
|
||||
packetConn := &PacketConn{bufio.NewBindPacketConn(conn.(net.PacketConn), metadata.Destination), ToDestination(metadata.Destination, net.Network_UDP)}
|
||||
return d.upstream.DispatchLink(ctx, ToDestination(metadata.Destination, net.Network_UDP), &transport.Link{
|
||||
Reader: buf.NewPacketReader(conn.(io.Reader)),
|
||||
Writer: buf.NewWriter(conn.(io.Writer)),
|
||||
Reader: packetConn,
|
||||
Writer: packetConn,
|
||||
})
|
||||
}
|
||||
|
||||
|
@@ -14,6 +14,9 @@ var (
|
||||
_ buf.Reader = (*Conn)(nil)
|
||||
_ buf.TimeoutReader = (*Conn)(nil)
|
||||
_ buf.Writer = (*Conn)(nil)
|
||||
_ buf.Reader = (*PacketConn)(nil)
|
||||
_ buf.TimeoutReader = (*PacketConn)(nil)
|
||||
_ buf.Writer = (*PacketConn)(nil)
|
||||
)
|
||||
|
||||
type Conn struct {
|
||||
@@ -64,3 +67,32 @@ func (c *Conn) WriteMultiBuffer(bufferList buf.MultiBuffer) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type PacketConn struct {
|
||||
net.Conn
|
||||
destination net.Destination
|
||||
}
|
||||
|
||||
func (c *PacketConn) ReadMultiBuffer() (buf.MultiBuffer, error) {
|
||||
buffer, err := buf.ReadBuffer(c.Conn)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
buffer.UDP = &c.destination
|
||||
return buf.MultiBuffer{buffer}, nil
|
||||
}
|
||||
|
||||
func (c *PacketConn) ReadMultiBufferTimeout(duration time.Duration) (buf.MultiBuffer, error) {
|
||||
err := c.SetReadDeadline(time.Now().Add(duration))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer c.SetReadDeadline(time.Time{})
|
||||
return c.ReadMultiBuffer()
|
||||
}
|
||||
|
||||
func (c *PacketConn) WriteMultiBuffer(mb buf.MultiBuffer) error {
|
||||
mb, err := buf.WriteMultiBuffer(c.Conn, mb)
|
||||
buf.ReleaseMulti(mb)
|
||||
return err
|
||||
}
|
||||
|
@@ -1,11 +0,0 @@
|
||||
package tun
|
||||
|
||||
import "github.com/xtls/xray-core/features"
|
||||
|
||||
type Interface interface {
|
||||
features.Feature
|
||||
}
|
||||
|
||||
func InterfaceType() interface{} {
|
||||
return (*Interface)(nil)
|
||||
}
|
10
go.mod
10
go.mod
@@ -13,7 +13,8 @@ require (
|
||||
github.com/pires/go-proxyproto v0.7.0
|
||||
github.com/quic-go/quic-go v0.34.0
|
||||
github.com/refraction-networking/utls v1.3.2
|
||||
github.com/sagernet/sing v0.2.4
|
||||
github.com/sagernet/sing v0.2.5-0.20230423085534-0902e6216207
|
||||
github.com/sagernet/sing-mux v0.0.0-20230425101127-4e8851eb1a2c
|
||||
github.com/sagernet/sing-shadowsocks v0.2.1
|
||||
github.com/sagernet/wireguard-go v0.0.0-20221116151939-c99467f53f2c
|
||||
github.com/seiflotfy/cuckoofilter v0.0.0-20220411075957-e3b120b3f5fb
|
||||
@@ -37,11 +38,11 @@ require (
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/dgryski/go-metro v0.0.0-20211217172704-adc40b04c140 // indirect
|
||||
github.com/francoispqt/gojay v1.2.13 // indirect
|
||||
github.com/fsnotify/fsnotify v1.6.0 // indirect
|
||||
github.com/gaukas/godicttls v0.0.3 // indirect
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
|
||||
github.com/google/btree v1.1.2 // indirect
|
||||
github.com/google/pprof v0.0.0-20230406165453-00490a63f317 // indirect
|
||||
github.com/hashicorp/yamux v0.1.1 // indirect
|
||||
github.com/klauspost/compress v1.16.5 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.4 // indirect
|
||||
github.com/onsi/ginkgo/v2 v2.9.2 // indirect
|
||||
@@ -49,10 +50,7 @@ require (
|
||||
github.com/quic-go/qtls-go1-19 v0.3.2 // indirect
|
||||
github.com/quic-go/qtls-go1-20 v0.2.2 // indirect
|
||||
github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 // indirect
|
||||
github.com/sagernet/go-tun2socks v1.16.12-0.20220818015926-16cb67876a61 // indirect
|
||||
github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97 // indirect
|
||||
github.com/sagernet/sing-tun v0.1.4 // indirect
|
||||
github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 // indirect
|
||||
github.com/sagernet/smux v0.0.0-20230312102458-337ec2a5af37 // indirect
|
||||
go.uber.org/atomic v1.10.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20230321023759-10a507213a29 // indirect
|
||||
golang.org/x/mod v0.10.0 // indirect
|
||||
|
28
go.sum
28
go.sum
@@ -33,8 +33,6 @@ github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI
|
||||
github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk=
|
||||
github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
|
||||
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
|
||||
github.com/gaukas/godicttls v0.0.3 h1:YNDIf0d9adcxOijiLrEzpfZGAkNwLRzPaG6OjU7EITk=
|
||||
github.com/gaukas/godicttls v0.0.3/go.mod h1:l6EenT4TLWgTdwslVb4sEMOCf7Bv0JAK67deKr9/NCI=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
@@ -91,6 +89,8 @@ github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:Fecb
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw=
|
||||
github.com/h12w/go-socks5 v0.0.0-20200522160539-76189e178364 h1:5XxdakFhqd9dnXoAZy1Mb2R/DZ6D1e+0bGC/JhucGYI=
|
||||
github.com/h12w/go-socks5 v0.0.0-20200522160539-76189e178364/go.mod h1:eDJQioIyy4Yn3MVivT7rv/39gAJTrA7lgmYr8EW950c=
|
||||
github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE=
|
||||
github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ=
|
||||
github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU=
|
||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
@@ -145,19 +145,15 @@ github.com/refraction-networking/utls v1.3.2/go.mod h1:fmoaOww2bxzzEpIKOebIsnBvj
|
||||
github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 h1:f/FNXud6gA3MNr8meMVVGxhp+QBTqY91tM8HjEuMjGg=
|
||||
github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3/go.mod h1:HgjTstvQsPGkxUsCd2KWxErBblirPizecHcpD3ffK+s=
|
||||
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||
github.com/sagernet/go-tun2socks v1.16.12-0.20220818015926-16cb67876a61 h1:5+m7c6AkmAylhauulqN/c5dnh8/KssrE9c93TQrXldA=
|
||||
github.com/sagernet/go-tun2socks v1.16.12-0.20220818015926-16cb67876a61/go.mod h1:QUQ4RRHD6hGGHdFMEtR8T2P6GS6R3D/CXKdaYHKKXms=
|
||||
github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97 h1:iL5gZI3uFp0X6EslacyapiRz7LLSJyr4RajF/BhMVyE=
|
||||
github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97/go.mod h1:xLnfdiJbSp8rNqYEdIW/6eDO4mVoogml14Bh2hSiFpM=
|
||||
github.com/sagernet/sing v0.0.0-20220817130738-ce854cda8522/go.mod h1:QVsS5L/ZA2Q5UhQwLrn0Trw+msNd/NPGEhBKR/ioWiY=
|
||||
github.com/sagernet/sing v0.2.3 h1:V50MvZ4c3Iij2lYFWPlzL1PyipwSzjGeN9x+Ox89vpk=
|
||||
github.com/sagernet/sing v0.2.3/go.mod h1:Ta8nHnDLAwqySzKhGoKk4ZIB+vJ3GTKj7UPrWYvM+4w=
|
||||
github.com/sagernet/sing v0.2.4 h1:gC8BR5sglbJZX23RtMyFa8EETP9YEUADhfbEzU1yVbo=
|
||||
github.com/sagernet/sing v0.2.4/go.mod h1:Ta8nHnDLAwqySzKhGoKk4ZIB+vJ3GTKj7UPrWYvM+4w=
|
||||
github.com/sagernet/sing v0.1.8/go.mod h1:jt1w2u7lJQFFSGLiRrRIs5YWmx4kAPfWuOejuDW9qMk=
|
||||
github.com/sagernet/sing v0.2.5-0.20230423085534-0902e6216207 h1:+dDVjW20IT+e8maKryaDeRY2+RFmTFdrQeIzqE2WOss=
|
||||
github.com/sagernet/sing v0.2.5-0.20230423085534-0902e6216207/go.mod h1:Ta8nHnDLAwqySzKhGoKk4ZIB+vJ3GTKj7UPrWYvM+4w=
|
||||
github.com/sagernet/sing-mux v0.0.0-20230425101127-4e8851eb1a2c h1:56vRmAIFvQZi9V2kNBNM/tOinmLtR9hx1xAWeDbTZb4=
|
||||
github.com/sagernet/sing-mux v0.0.0-20230425101127-4e8851eb1a2c/go.mod h1:pF+RnLvCAOhECrvauy6LYOpBakJ/vuaF1Wm4lPsWryI=
|
||||
github.com/sagernet/sing-shadowsocks v0.2.1 h1:FvdLQOqpvxHBJUcUe4fvgiYP2XLLwH5i1DtXQviVEPw=
|
||||
github.com/sagernet/sing-shadowsocks v0.2.1/go.mod h1:T/OgurSjsAe+Ug3+6PprXjmgHFmJidjOvQcjXGTKb3I=
|
||||
github.com/sagernet/sing-tun v0.1.4 h1:Fa6kgvuM2fPbPu3R97S8L8NgaD5lJq3wQorNuTb5oqo=
|
||||
github.com/sagernet/sing-tun v0.1.4/go.mod h1:7BrtP7NMp9FK5oVsZWg92b7yFrD+sM2+udapFurReyw=
|
||||
github.com/sagernet/smux v0.0.0-20230312102458-337ec2a5af37 h1:HuE6xSwco/Xed8ajZ+coeYLmioq0Qp1/Z2zczFaV8as=
|
||||
github.com/sagernet/smux v0.0.0-20230312102458-337ec2a5af37/go.mod h1:3skNSftZDJWTGVtVaM2jfbce8qHnmH/AGDRe62iNOg0=
|
||||
github.com/sagernet/wireguard-go v0.0.0-20221116151939-c99467f53f2c h1:vK2wyt9aWYHHvNLWniwijBu/n4pySypiKRhN32u/JGo=
|
||||
github.com/sagernet/wireguard-go v0.0.0-20221116151939-c99467f53f2c/go.mod h1:euOmN6O5kk9dQmgSS8Df4psAl3TCjxOz0NW60EWkSaI=
|
||||
github.com/seiflotfy/cuckoofilter v0.0.0-20220411075957-e3b120b3f5fb h1:XfLJSPIOUX+osiMraVgIrMR27uMXnRJWGm1+GL8/63U=
|
||||
@@ -201,8 +197,6 @@ github.com/v2fly/ss-bloomring v0.0.0-20210312155135-28617310f63e h1:5QefA066A1tF
|
||||
github.com/v2fly/ss-bloomring v0.0.0-20210312155135-28617310f63e/go.mod h1:5t19P9LBIrNamL6AcMQOncg/r10y3Pc01AbHeMhwlpU=
|
||||
github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU=
|
||||
github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM=
|
||||
github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 h1:gga7acRE695APm9hlsSMoOoE65U4/TcqNj90mc69Rlg=
|
||||
github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0=
|
||||
github.com/xtls/reality v0.0.0-20230331223127-176a94313eda h1:psRJD2RrZbnI0OWyHvXfgYCPqlRM5q5SPDcjDoDBWhE=
|
||||
github.com/xtls/reality v0.0.0-20230331223127-176a94313eda/go.mod h1:rkuAY1S9F8eI8gDiPDYvACE8e2uwkyg8qoOTuwWov7Y=
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
@@ -262,15 +256,13 @@ golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5h
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220731174439-a90be440212d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU=
|
||||
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
|
@@ -1,113 +0,0 @@
|
||||
package conf
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/netip"
|
||||
|
||||
"github.com/sagernet/sing/common"
|
||||
"github.com/xtls/xray-core/app/tun"
|
||||
)
|
||||
|
||||
type TunConfig struct {
|
||||
InterfaceName string `json:"interface_name,omitempty"`
|
||||
MTU uint32 `json:"mtu,omitempty"`
|
||||
Inet4Address Listable[ListenPrefix] `json:"inet4_address,omitempty"`
|
||||
Inet6Address Listable[ListenPrefix] `json:"inet6_address,omitempty"`
|
||||
AutoRoute bool `json:"auto_route,omitempty"`
|
||||
StrictRoute bool `json:"strict_route,omitempty"`
|
||||
Inet4RouteAddress Listable[ListenPrefix] `json:"inet4_route_address,omitempty"`
|
||||
Inet6RouteAddress Listable[ListenPrefix] `json:"inet6_route_address,omitempty"`
|
||||
IncludeUID Listable[uint32] `json:"include_uid,omitempty"`
|
||||
IncludeUIDRange Listable[string] `json:"include_uid_range,omitempty"`
|
||||
ExcludeUID Listable[uint32] `json:"exclude_uid,omitempty"`
|
||||
ExcludeUIDRange Listable[string] `json:"exclude_uid_range,omitempty"`
|
||||
IncludeAndroidUser Listable[int] `json:"include_android_user,omitempty"`
|
||||
IncludePackage Listable[string] `json:"include_package,omitempty"`
|
||||
ExcludePackage Listable[string] `json:"exclude_package,omitempty"`
|
||||
EndpointIndependentNat bool `json:"endpoint_independent_nat,omitempty"`
|
||||
UDPTimeout int64 `json:"udp_timeout,omitempty"`
|
||||
Stack string `json:"stack,omitempty"`
|
||||
|
||||
AutoDetectInterface bool `json:"auto_detect_interface,omitempty"`
|
||||
OverrideAndroidVPN bool `json:"override_android_vpn,omitempty"`
|
||||
}
|
||||
|
||||
func (f *TunConfig) Build() (*tun.Config, error) {
|
||||
var config tun.Config
|
||||
config.InterfaceName = f.InterfaceName
|
||||
config.Mtu = f.MTU
|
||||
config.Inet4Address = common.Map(common.Map(f.Inet4Address, ListenPrefix.Build), netip.Prefix.String)
|
||||
config.Inet6Address = common.Map(common.Map(f.Inet6Address, ListenPrefix.Build), netip.Prefix.String)
|
||||
config.AutoRoute = f.AutoRoute
|
||||
config.StrictRoute = f.StrictRoute
|
||||
config.Inet4RouteAddress = common.Map(common.Map(f.Inet4RouteAddress, ListenPrefix.Build), netip.Prefix.String)
|
||||
config.Inet6RouteAddress = common.Map(common.Map(f.Inet6RouteAddress, ListenPrefix.Build), netip.Prefix.String)
|
||||
config.IncludeUid = f.IncludeUID
|
||||
config.IncludeUidRange = f.IncludeUIDRange
|
||||
config.ExcludeUid = f.ExcludeUID
|
||||
config.ExcludeUidRange = f.ExcludeUIDRange
|
||||
config.IncludeAndroidUser = common.Map(f.IncludeAndroidUser, func(it int) int32 {
|
||||
return int32(it)
|
||||
})
|
||||
config.IncludePackage = f.IncludePackage
|
||||
config.ExcludePackage = f.ExcludePackage
|
||||
config.EndpointIndependentNat = f.EndpointIndependentNat
|
||||
config.UdpTimeout = f.UDPTimeout
|
||||
config.Stack = f.Stack
|
||||
// for xray
|
||||
config.AutoDetectInterface = f.AutoDetectInterface
|
||||
config.OverrideAndroidVpn = f.OverrideAndroidVPN
|
||||
return &config, nil
|
||||
}
|
||||
|
||||
type Listable[T comparable] []T
|
||||
|
||||
func (l Listable[T]) MarshalJSON() ([]byte, error) {
|
||||
arrayList := []T(l)
|
||||
if len(arrayList) == 1 {
|
||||
return json.Marshal(arrayList[0])
|
||||
}
|
||||
return json.Marshal(arrayList)
|
||||
}
|
||||
|
||||
func (l *Listable[T]) UnmarshalJSON(content []byte) error {
|
||||
err := json.Unmarshal(content, (*[]T)(l))
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
var singleItem T
|
||||
err = json.Unmarshal(content, &singleItem)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*l = []T{singleItem}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ListenPrefix netip.Prefix
|
||||
|
||||
func (p ListenPrefix) MarshalJSON() ([]byte, error) {
|
||||
prefix := netip.Prefix(p)
|
||||
if !prefix.IsValid() {
|
||||
return json.Marshal(nil)
|
||||
}
|
||||
return json.Marshal(prefix.String())
|
||||
}
|
||||
|
||||
func (p *ListenPrefix) UnmarshalJSON(bytes []byte) error {
|
||||
var value string
|
||||
err := json.Unmarshal(bytes, &value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
prefix, err := netip.ParsePrefix(value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*p = ListenPrefix(prefix)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p ListenPrefix) Build() netip.Prefix {
|
||||
return netip.Prefix(p)
|
||||
}
|
@@ -130,6 +130,24 @@ func (m *MuxConfig) Build() (*proxyman.MultiplexingConfig, error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
type SingMuxConfig struct {
|
||||
Enabled bool `json:"enabled"`
|
||||
Protocol string `json:"protocol"`
|
||||
MaxConnections int `json:"max_connections"`
|
||||
MinStreams int `json:"min_streams"`
|
||||
MaxStreams int `json:"max_streams"`
|
||||
}
|
||||
|
||||
func (m *SingMuxConfig) Build() (*proxyman.SingMultiplexConfig, error) {
|
||||
return &proxyman.SingMultiplexConfig{
|
||||
Enabled: m.Enabled,
|
||||
Protocol: m.Protocol,
|
||||
MaxConnections: int32(m.MaxConnections),
|
||||
MinStreams: int32(m.MinStreams),
|
||||
MaxStreams: int32(m.MaxStreams),
|
||||
}, nil
|
||||
}
|
||||
|
||||
type InboundDetourAllocationConfig struct {
|
||||
Strategy string `json:"strategy"`
|
||||
Concurrency *uint32 `json:"concurrency"`
|
||||
@@ -278,13 +296,14 @@ func (c *InboundDetourConfig) Build() (*core.InboundHandlerConfig, error) {
|
||||
}
|
||||
|
||||
type OutboundDetourConfig struct {
|
||||
Protocol string `json:"protocol"`
|
||||
SendThrough *Address `json:"sendThrough"`
|
||||
Tag string `json:"tag"`
|
||||
Settings *json.RawMessage `json:"settings"`
|
||||
StreamSetting *StreamConfig `json:"streamSettings"`
|
||||
ProxySettings *ProxyConfig `json:"proxySettings"`
|
||||
MuxSettings *MuxConfig `json:"mux"`
|
||||
Protocol string `json:"protocol"`
|
||||
SendThrough *Address `json:"sendThrough"`
|
||||
Tag string `json:"tag"`
|
||||
Settings *json.RawMessage `json:"settings"`
|
||||
StreamSetting *StreamConfig `json:"streamSettings"`
|
||||
ProxySettings *ProxyConfig `json:"proxySettings"`
|
||||
MuxSettings *MuxConfig `json:"mux"`
|
||||
SingMuxSettings *SingMuxConfig `json:"smux"`
|
||||
}
|
||||
|
||||
func (c *OutboundDetourConfig) checkChainProxyConfig() error {
|
||||
@@ -347,6 +366,13 @@ func (c *OutboundDetourConfig) Build() (*core.OutboundHandlerConfig, error) {
|
||||
}
|
||||
senderSettings.MultiplexSettings = ms
|
||||
}
|
||||
if c.SingMuxSettings != nil {
|
||||
ms, err := c.SingMuxSettings.Build()
|
||||
if err != nil {
|
||||
return nil, newError("failed to build sing-mux config.").Base(err)
|
||||
}
|
||||
senderSettings.SmuxSettings = ms
|
||||
}
|
||||
|
||||
settings := []byte("{}")
|
||||
if c.Settings != nil {
|
||||
@@ -410,7 +436,6 @@ type Config struct {
|
||||
Reverse *ReverseConfig `json:"reverse"`
|
||||
FakeDNS *FakeDNSConfig `json:"fakeDns"`
|
||||
Observatory *ObservatoryConfig `json:"observatory"`
|
||||
Tun *TunConfig `json:"tun"`
|
||||
}
|
||||
|
||||
func (c *Config) findInboundTag(tag string) int {
|
||||
@@ -475,10 +500,6 @@ func (c *Config) Override(o *Config, fn string) {
|
||||
c.Observatory = o.Observatory
|
||||
}
|
||||
|
||||
if o.Tun != nil {
|
||||
c.Tun = o.Tun
|
||||
}
|
||||
|
||||
// deprecated attrs... keep them for now
|
||||
if o.InboundConfig != nil {
|
||||
c.InboundConfig = o.InboundConfig
|
||||
@@ -642,14 +663,6 @@ func (c *Config) Build() (*core.Config, error) {
|
||||
config.App = append(config.App, serial.ToTypedMessage(r))
|
||||
}
|
||||
|
||||
if c.Tun != nil {
|
||||
r, err := c.Tun.Build()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
config.App = append(config.App, serial.ToTypedMessage(r))
|
||||
}
|
||||
|
||||
var inbounds []InboundDetourConfig
|
||||
|
||||
if c.InboundConfig != nil {
|
||||
|
@@ -16,7 +16,6 @@ import (
|
||||
|
||||
// Developer preview services
|
||||
_ "github.com/xtls/xray-core/app/observatory/command"
|
||||
_ "github.com/xtls/xray-core/app/tun"
|
||||
|
||||
// Other optional features.
|
||||
_ "github.com/xtls/xray-core/app/dns"
|
||||
|
@@ -1,8 +1,9 @@
|
||||
package grpc
|
||||
|
||||
import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestConfig_GetServiceName(t *testing.T) {
|
||||
|
Reference in New Issue
Block a user